When the routemap code was rewritten for performance the
code to track the number of times a particular section of
a route-map was applied was not correctly updated. In
this case I found another sequence of events where the
number of times a section was invoked was not being correctly
kept.
Effectively in this case when route_map_get_index is called
and returns an index the route map has been applied( see that
skip_match_clause is set to true and then in the for loop
below the skip_match_clause is tested and index->applied is
incremented.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
The re->flags and re->status in debugs were being dumped as hex values.
I can never quickly decode this. Here is an idea. Let's let FRR do
it for me.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
Add an API that allows IGP client daemons to register/unregister
RLFAs with ldpd.
IGP daemons need to be able to query the LDP labels needed by RLFAs
and monitor label updates that might affect those RLFAs. This is
similar to the NHT mechanism used by bgpd to resolve and monitor
recursive nexthops.
This API is based on the following ZAPI opaque messages:
* LDP_RLFA_REGISTER: used by IGP daemons to register an RLFA with ldpd.
* LDP_RLFA_UNREGISTER_ALL: used by IGP daemons to unregister all of
their RLFAs with ldpd.
* LDP_RLFA_LABELS: used by ldpd to send RLFA labels to the registered
clients.
For each RLFA, ldpd needs to return the following labels:
* Outer label(s): the labels advertised by the adjacent routers to
reach the PQ node;
* Inner label: the label advertised by the PQ node to reach the RLFA
destination.
For the inner label, ldpd automatically establishes a targeted
neighborship with the PQ node if one doesn't already exist. For that
to work, the PQ node needs to be configured to accept targeted hello
messages. If that doesn't happen, ldpd doesn't send a response to
the IGP client daemon which in turn won't be able to activate the
previously computed RLFA.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Define new models for Link State Database a.k.a TED
and functions to manipulate the new database as well as exchange Link State
information through ZAPI Opaque message.
Signed-off-by: Olivier Dugeon <olivier.dugeon@orange.com>
There exists a possibilty that route map dependencies
have gotten wrong. Prevent the crash and warn the user
that we may be in trouble.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
Route-maps contain a hash of hash's that contain the
container type name ( say community or access list or whatever )
and then it has a hash of route-maps that this maps too
Suppose you have this:
!
frr version 7.3.1
frr defaults traditional
hostname eva
log stdout
!
debug route-map
!
router bgp 239
neighbor 192.168.161.2 remote-as external
!
address-family ipv4 unicast
neighbor 192.168.161.2 route-map foo in
exit-address-family
!
bgp community-list standard 7000:40002 permit 7000:40002
bgp community-list standard 7000:40002 permit 7000:40003
!
route-map foo deny 20
match community 7000:40002
!
route-map foo permit 10
!
line vty
!
end
You have a community hash which has an
7000:40002 entry
This entry has a hash of routemaps that are referencing it. In this above
example it would have `foo` as the single entry.
Given the above config if you do this:
eva# conf
eva(config)# route-map foo deny 20
eva(config-route-map)# match community 7000:4003
eva(config-route-map)#
We would expect the `7000:40002` community hash to no longer have
a reference to the `foo` routemap. Instead we see the code doing this:
2020/12/18 13:47:12 BGP: bgpd 7.3.1 starting: vty@2605, bgp@<all>:179
2020/12/18 13:47:47 BGP: Add route-map foo
2020/12/18 13:47:47 BGP: Route-map foo add sequence 10, type: permit
2020/12/18 13:47:57 BGP: Route-map foo add sequence 20, type: deny
2020/12/18 13:48:05 BGP: Adding dependency for filter 7000:40002 in route-map foo
2020/12/18 13:48:05 BGP: route_map_print_dependency: Dependency for 7000:40002: foo
2020/12/18 13:48:41 BGP: bgp_update_receive: rcvd End-of-RIB for IPv4 Unicast from 192.168.161.2 in vrf default
2020/12/18 13:49:19 BGP: Deleting dependency for filter 7000:4003 in route-map foo
2020/12/18 13:49:19 BGP: Adding dependency for filter 7000:4003 in route-map foo
2020/12/18 13:49:19 BGP: route_map_print_dependency: Dependency for 7000:4003: foo
Note how the code attempts to remove the dependency for `7000:4003` instead of the
dependency for `7000:40002`. Then we create a new hash for `7000:4003` and then
install the routemap name in it.
This is wrong. We should remove the `7000:40002` dependency and then install
a dependency for `7000:4003`.
Fix the code to do the right thing.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
This new dynamic module makes pathd behave as a PCC for dynamic candidate path
using the external library pcpelib https://github.com/volta-networks/pceplib .
The candidate paths defined as dynamic will trigger computation requests to the
configured PCE, and the PCE response will be used to update the policy.
It supports multiple PCE. The one with smaller precedence will be elected
as the master PCE, and only if the connection repeatedly fails, the PCC will
switch to another PCE.
Example of configuration:
segment-routing
traffic-eng
pcep
pce-config CONF
source-address ip 10.10.10.10
sr-draft07
!
pce PCE1
config CONF
address ip 1.1.1.1
!
pce PCE2
config CONF
address ip 2.2.2.2
!
pcc
peer PCE1 precedence 10
peer PCE2 precedence 20
!
!
!
!
Co-authored-by: Brady Johnson <brady@voltanet.io>
Co-authored-by: Emanuele Di Pascale <emanuele@voltanet.io>
Co-authored-by: GalaxyGorilla <sascha@netdef.org>
Co-authored-by: Javier Garcia <javier.garcia@voltanet.io>
Co-authored-by: Renato Westphal <renato@opensourcerouting.org>
Co-authored-by: Sebastien Merle <sebastien@netdef.org>
Signed-off-by: Sebastien Merle <sebastien@netdef.org>
This new daemon manages Segment-Routing Traffic-Engineering
(SR-TE) Policies and installs them into zebra. It provides
the usual yang support and vtysh commands to define or change
SR-TE Policies.
In a nutshell SR-TE Policies provide the possibility to steer
traffic through a (possibly dynamic) list of Segment Routing
segments to the endpoint of the policy. This list of segments
is part of a Candidate Path which again belongs to the SR-TE
Policy. SR-TE Policies are uniquely identified by their color
and endpoint. The color can be used to e.g. match BGP
communities on incoming traffic.
There can be multiple Candidate Paths for a single
policy, the active Candidate Path is chosen according to
certain conditions of which the most important is its
preference. Candidate Paths can be explicit (fixed list of
segments) or dynamic (list of segment comes from e.g. PCEP, see
below).
Configuration example:
segment-routing
traffic-eng
segment-list SL
index 10 mpls label 1111
index 20 mpls label 2222
!
policy color 4 endpoint 10.10.10.4
name POL4
binding-sid 104
candidate-path preference 100 name exp explicit segment-list SL
candidate-path preference 200 name dyn dynamic
!
!
!
There is an important connection between dynamic Candidate
Paths and the overall topic of Path Computation. Later on for
pathd a dynamic module will be introduced that is capable
of communicating via the PCEP protocol with a PCE (Path
Computation Element) which again is capable of calculating
paths according to its local TED (Traffic Engineering Database).
This dynamic module will be able to inject the mentioned
dynamic Candidate Paths into pathd based on calculated paths
from a PCE.
https://tools.ietf.org/html/draft-ietf-spring-segment-routing-policy-06
Co-authored-by: Sebastien Merle <sebastien@netdef.org>
Co-authored-by: Renato Westphal <renato@opensourcerouting.org>
Co-authored-by: GalaxyGorilla <sascha@netdef.org>
Co-authored-by: Emanuele Di Pascale <emanuele@voltanet.io>
Signed-off-by: Sebastien Merle <sebastien@netdef.org>
Currently when nhrp shortcuts are purged they will not be recreated. This
patch fixes that by ensuring the shortcut routes get purged correctly.
This situation can be reproduced by first allowing a shortcut to be created
then clearing the shortcut:
clear ip nhrp cache
clear ip nhrp shortcuts
Signed-off-by: Reuben Dowle <reuben.dowle@4rf.com>
There exists a world where some people have put `end` in their
configuration. Then vtysh will command search for it and find
it and then bad things happen.
Ticket: CM-32665
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
Removing the obsolete ldp-sync periodic 'hello' message.
When ldp-sync is configured, IGPs take action if the LDP process goes down.
The IGPs have been updated to use the zapi client close callback to detect
the LDP process going down.
Signed-off-by: Karen Schoener <karen@voltanet.io>
Add a bit of code that allows for opaque data to be
sent from an upper level protocol to zebra. This is just
pass through data that will be used as part of displaying
useful data about a route in a `show ip route` command
in future commits.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
Keep the previous CLI behavior of silently ignoring access lists which
contain the same value.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Don't allow users to create multiple entries in the same list with the
same value to keep the behavior previously to northbound migration.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Keep the previous CLI behavior of silently ignoring access lists which
contain the same value.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Don't allow users to create multiple rules in the same list with the
same value to keep the behavior previously to northbound migration.
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Currently, IGPs are coded to receive a 'hello' message from LDP every second.
Intermittently, LDP Sync topotests are failing because the IGPs fail to
receive this 'hello' message every second.
When the LDP Sync topotests fail, LDP logs show that LDP is processing
zapi messages for 1-2 seconds.
This is a shortterm fix, in order to prevent CI pipeline failures.
The longterm fix is in progress.
Signed-off-by: Karen Schoener <karen@voltanet.io>
Specify default via --with-scriptdir at compile time, override default
with --scriptdir at runtime. If unspecified, it's {sysconfdir}/scripts
(usually /etc/frr/scripts)
Signed-off-by: Quentin Young <qlyoung@nvidia.com>
This implements the ability to get results out from lua scripts after
they've run.
For each C type we support passing to Lua, there is a corresponding
`struct frrscript_codec`. This struct contains a typename field - just a
string identifying the type - and two function pointers. The first
function pointer, encode, takes a lua_State and a pointer to the C value
and pushes some corresponding Lua representation onto the stack. The
second, decode, assumes there is some Lua value on the stack and decodes
it into the corresponding C value.
Each supported type's `struct frrscript_codec` is registered with the
scripting stuff in the library, which creates a mapping between the type
name (string) and the `struct frrscript_codec`. When calling a script,
you specify arguments by passing an array of `struct frrscript_env`.
Each of these structs has a void *, a type name, and a desired binding
name. The type names are used to look up the appropriate function to
encode the pointed-at value onto the Lua stack, then bind the pushed
value to the provided binding name, so that the converted value is
accessible by that name within the script.
Results work in a similar way. After a script runs, call
frrscript_get_result() with the script and a `struct frrscript_env`.
The typename and name fields are used to fetch the Lua value from the
script's environment and use the registered decoder for the typename to
convert the Lua value back into a C value, which is returned from the
function. The caller is responsible for freeing these.
frrscript_call()'s macro foo has been stripped, as the underlying
function now takes fixed arrays. varargs have awful performance
characteristics, they're hard to read, and structs are more defined than
an order sensitive list.
Signed-off-by: Quentin Young <qlyoung@nvidia.com>
None of the core lua_push* functions return anything, and it helps to
not have to wrap those when using them as function pointers for our
encoder system, so change the type of our custom encoders to return void
as well.
Signed-off-by: Quentin Young <qlyoung@nvidia.com>