Implement the 'authentication-failure' and 'authentication-type-failure'
notifications defined in the frr-ripd YANG module.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This command deletes all received routes from the RIP routing table.
It should be used with caution as it can create black holes in the
network until RIP reconverges. Very useful to make automated testing
(e.g. ANVL) more predictable, since the internal state of ripd can be
cleared after each test.
Implement the command using a YANG RPC so that it can be executed by
other northbound clients in addition to the CLI.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Support for fetching operational data is experimental at this point.
Locks must be introduced to ensure the peer_list global variable won't
be modified while we're iterating asynchronously over it (or iterating
from a separate pthread).
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
We can now leverage the new northbound API to perform a full configuration
reload in ripd without the need for external help (i.e. frr-reload.py).
When vty_read_config() is called with the 'config' parameter set to
NULL, it performs a new configuration transaction where the running
configuration is *replaced* by the provided configuration file. With that
said, we don't need to do anything other than calling this function in
the SIGHUP handler of all FRR daemons. If a daemon hasn't been converted
to the new northbound model, vty_read_config() will simply *merge*
the configuration file into the running configuration.
The calls to rip_clean() and rip_reset() in the SIGUP handler were
changing configuration variables directly, bypassing the northbound
layer. Configuration variables should be changed only by the northbound
callbacks, and failure to respect that inevitably leads to inconsistencies
and crashes. Fix this.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Now that "router rip" and all underlying commands were converted to the
new northbound model, there's no need to use the qobj infrastructure to
keep track of the 'rip' global variable anymore.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Trivial conversion. Use the northbound 'apply_finish()' callback so
we'll call rip_event() only once even if we change the three RIP timers
at the same time.
Convert the timers to uint32_t to match their representation in the
YANG model.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Trivial conversion. Remove the rip->route routing table and associated
code because this variable was used only to show the running
configuration.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Trivial conversion. As usual, combine multiple DEFUNs into a single
DEFPY for simplicity.
As a bonus of the northbound conversion, this commit fixes the
redistribution of certain protocols into ripd. The 'redist_type' array
used by the "redistribute" commands was terribly outdated, which was
preventing the CLI to parse correctly certain protocols like isis
and babel.
Remove the route_map hooks installed by rip_route_map_init() since they
were redundant (rip_init() already takes care of that).
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
In ripd, the "passive-interface default" command has the following
behavior:
* All interfaces are converted to the passive mode;
* The "passive-interface IFNAME" command becomes a no-operation and
"passive-interface IFNAME" statements are removed from the running
configuration.
* The "no passive-interface IFNAME" can be used to remove interfaces
from the passive mode.
This command was modeled using the following YANG data nodes in the
frr-ripd module:
leaf passive-default {
type boolean;
default "false";
description
"Control whether interfaces are in the passive mode
by default or not.";
}
leaf-list passive-interface {
when "../passive-default = 'false'";
type string {
length "1..16";
}
description
"A list of interfaces where the sending of RIP packets
is disabled.";
}
leaf-list non-passive-interface {
when "../passive-default = 'true'";
type string {
length "1..16";
}
description
"A list of interfaces where the sending of RIP packets
is enabled.";
}
The 'when' statements guarantee that the list of passive interfaces
is cleared when the "passive-interface default" command is entered
(likewise, they guarantee that the list of non-passive interfaces is
cleared when the "passive-interface default" command is removed). This
matches exactly the behavior we want to model.
Finally, move the 'passive_default' global variable into the
'rip' structure where it belongs. This fixed the bug where the
"passive-interface default" command was being retained after a "no router
rip" + "router rip".
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Remove the rip_offset_list_set() and rip_offset_list_unset() functions
since they set/unset multiple configuration options at the same time. The
northbound callbacks need to set/unset configuration options individually.
The frr-ripd YANG module models the "offset-list" command using a list
keyed by the 'interface' and 'direction' leafs. One important detail is
that the IFNAME parameter is optional, and when it's not present it means
we want to match all interfaces. This is modeled using an interface name
of '*' since key lists are mandatory by definition in YANG.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
The frr-ripd YANG module models the ripd "network" command using two
separate leaf-lists for simplicity: one leaf-list for interfaces and
another leaf-list for actual networks. In the 'cli_show' callbacks,
display the "network" command for entries of both leaf-lists.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Make rip_neighbor_add() and rip_neighbor_delete() return northbound
error codes since their return values are used as the return value of
some northbound callbacks.
These functions shouldn't fail in normal conditions because the northbound
layer guarantees it will never call the 'create' or 'delete' callback
more than once for the same object. Hence any failure in those functions
would indicate an internal inconsistency that needs to be investigated
(by returning NB_ERR the northbound will log a detailed error message
indicating the xpath of the object, the event and the callback where
the error happened).
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
The "distance (1-255) A.B.C.D/M [WORD]" command was modeled using a
YANG list, which makes it a little bit more complicated to convert to
the new northbound model.
The rip_distance_set() and rip_distance_unset() functions were removed
since they set/unset multiple configuration options at the same time. The
northbound callbacks need to set/unset configuration options individually.
When a distance list is created, use yang_dnode_set_entry() to store
a pointer in the configuration node, and retrieve this pointer in the
other callbacks using yang_dnode_get_entry().
The 'rip_distance' structure was moved to ripd.h so that it can be used
in the rip_northbound.c file.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Trivial conversion.
rip->default_metric was converted to an uint8_t to match the way it's
defined in the YANG module.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Trivial conversion.
'rip->default_information_route_map' was removed since it wasn't being
used anywhere.
'rip->default_information' was removed too because it was being used only
to display the running configuration and thus is not necessary anymore.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Trivial conversion. The rip->ecmp variable was converted to a boolean to
match the way it's defined in the YANG module.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
* Implement the northbound callbacks associated to the
'/frr-ripd:ripd/instance' YANG path (the code is mostly a copy and paste
from the original "router rip" DEFUNs);
* Move rip_create_socket() out of rip_create() since creating a socket
is an error-prone operation and thus needs to be performed separately
during the NB_EV_PREPARE phase;
* On rip_create(), fetch the defaults from the frr-ripd YANG model;
* Convert the "[no] router rip" CLI commands to be dumb wrappers around
the northbound callbacks;
* On config_write_rip(), write logic to call all 'cli_show' northbound
callbacks defined under the '/frr-ripd:ripd/instance' YANG path.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Introduce frr-ripd.yang, which defines a model for managing the FRR
ripd daemon. Also add frr-route-types.yang which defines typedefs for
FRR route types.
Update the 'frr_yang_module_info' array of ripd with the new 'frr-ripd'
module.
Add two new files (rip_cli.[ch]) which should contain all ripd commands
converted to the new northbound model. Centralizing all commands in a
single place will facilitate the process of moving the CLI to a separate
program in the future.
Add automatically generated stub callbacks in rip_northbound.c. These
callbacks will be implemented gradually in the following commits.
Add example JSON/XML ripd configurations in yang/examples/.
Add the confd.frr-ripd.yang YANG module with annotations specific to
the ConfD daemon.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
The following types are nonstandard:
- u_char
- u_short
- u_int
- u_long
- u_int8_t
- u_int16_t
- u_int32_t
Replace them with the C99 standard types:
- uint8_t
- unsigned short
- unsigned int
- unsigned long
- uint8_t
- uint16_t
- uint32_t
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Allow rip_redistribute_add to receive and properly store
the nexthop type passed up from zebra.
Additionally display the different nexthop types appropriately.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
RIP is not using the nexthop data structure and as such when
it does not fully understand when it receives some of the
more exotic nexthop types what to do with it. This is the
start of a series of commits to allow RIP to start understanding
and properly displaying information about different nexthop
types.
Signed-off-by: Donald Sharp <sharpd@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>
The way thread.c is written, a caller who wishes to be able to cancel a
thread or avoid scheduling it twice must keep a reference to the thread.
Typically this is done with a long lived pointer whose value is checked
for null in order to know if the thread is currently scheduled. The
check-and-schedule idiom is so common that several wrapper macros in
thread.h existed solely to provide it.
This patch removes those macros and adds a new parameter to all
thread_add_* functions which is a pointer to the struct thread * to
store the result of a scheduling call. If the value passed is non-null,
the thread will only be scheduled if the value is null. This helps with
consistency.
A Coccinelle spatch has been used to transform code of the form:
if (t == NULL)
t = thread_add_* (...)
to the form
thread_add_* (..., &t)
The THREAD_ON macros have also been transformed to the underlying
thread.c calls.
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This means there are no ties into the SNMP code anymore other than the
init call at startup.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
* Simplify the RIP_TIMER_OFF macro and use it on more places;
* Be more explicit when creating the RIP UDP socket - cosmetic change
since socket(AF_INET,SOCK_DGRAM,0) defaults to UDP on every known
UNIX/Linux platform.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
RFC 2453 says (section 5.1):
"(...) For completeness, routers should also implement a receive control
switch which would determine whether to accept, RIP-1 only, RIP-2 only,
both, or none. It should also be configurable on a per-interface basis".
For the "ip rip send version" command, we don't need to implement the
"none" option because there's already the "passive-interface" command
for that.
Fixes IxANVL RIP test 16.8.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This command allows ripd to send v2 updates as broadcast packets instead
of multicast packets. Useful as a technique to help with RIPv1/v2
interop issues.
Fixes IxANVL RIP test 16.2
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This patch improves zebra,ripd,ripngd,ospfd and bgpd so that they can
make use of 32-bit route tags in the case of zebra,ospf,bgp or 16-bit
route-tags in the case of ripd,ripngd.
It is based on the following patch:
commit d25764028829a3a30cdbabe85f32408a63cccadf
Author: Paul Jakma <paul.jakma@hpe.com>
Date: Fri Jul 1 14:23:45 2016 +0100
*: Widen width of Zserv routing tag field.
But also contains the changes which make this actually useful for all
the daemons.
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
* rip_interface.c: Default for split_horizon_default differed between
rip_interface_new and rip_interface_reset, causing at least some issues
after interface events. See patchwork #604. Fix, and consolidate code.
(rip_interface_{reset,clean}) rename these to 'interface', as that's more
appropriate. Spin the ri specific bodies of these functions out to
rip_interface_{reset,clean} helpers. Factor out the overlaps, so
rip_interface_reset uses rip_interface_clean.
(rip_interface_new) just use rip_interface_reset.
* ripd.h: Update for (rip_interface_{reset,clean})
Reported by xufeng zhang, with a suggested fix on which this commit expands.
See patchwork #604. This commit addresses only the split-horizon
discrepency, issue #2. The other issue they reported, #1, is not addressed,
though suggested fix seems inappropriate.
Cc: xufeng.zhang@windriver.com
This is a rather large mechanical commit that splits up the memory types
defined in lib/memtypes.c and distributes them into *_memory.[ch] files
in the individual daemons.
The zebra change is slightly annoying because there is no nice place to
put the #include "zebra_memory.h" statement.
bgpd, ospf6d, isisd and some tests were reusing MTYPEs defined in the
library for its own use. This is bad practice and would break when the
memtype are made static.
Acked-by: Vincent JARDIN <vincent.jardin@6wind.com>
Acked-by: Donald Sharp <sharpd@cumulusnetworks.com>
[CF: rebased for cmaster-next]
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Signed-off-by: Christian Franke <chris@opensourcerouting.org>
Introduce a new command "[no] allow-ecmp" to enable/disable the
ECMP feature in RIP. By default, ECMP is not allowed.
Once ECMP is disabled, only one route entry can exist in the list.
* rip_zebra.c: adjust a debugging information, which shows the number
of nexthops according to whether ECMP is enabled.
* ripd.c: rip_ecmp_add() will reject the new route if ECMP is not
allowed and some entry already exists.
A new configurable command "allow-ecmp" is added to control
whether ECMP is allowed.
When ECMP is disabled, rip_ecmp_disable() is called to
remove the multiple nexthops.
* ripd.h: Add a new member "ecmp" to "struct rip", indicating whether
ECMP is allowed or not.
Signed-off-by: Feng Lu <lu.feng@6wind.com>
Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
(cherry picked from commit 0b74a0a5db7bcf65bf68c44b547b02b1310b5cdb)
* Each node in the routing table is changed into a list, holding
the multiple equal-cost paths.
* If one of the multiple entries gets less-preferred (greater
metric or greater distance), it will be directly deleted instead
of starting a garbage-collection timer for it.
The garbage-collection timer is started only when the last entry
in the list gets INFINITY.
* Some new functions are used to maintain the ECMP list. And hence
rip_rte_process(), rip_redistribute_add() and rip_timeout() are
significantly simplified.
* rip_zebra_ipv4_add() and rip_zebra_ipv4_delete() now can share
the common code. The common part is moved to rip_zebra_ipv4_send().
Signed-off-by: Feng Lu <lu.feng@6wind.com>
Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
(cherry picked from commit b397cf4f0fc484c5ebfc8a680090055c8e6cbe32)
Conflicts:
ripd/rip_zebra.c
RIP_MAX_RTE is defined in ripd.h as 25 but is in fact the
result of a formula. More over it is not used in the code:
the code itself includes the fomula. This makes it un-clear
for maintenance.
Signed-off-by: Feng Lu <lu.feng@6wind.com>
Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
(cherry picked from commit 342a31bfda)
zclient.c depended upon link time inclusion of a
extern struct thread_master *master. This is a violation of the
namespace of the calling daemon. If a library needs the pointer
pass it in and save it for future use.
This code change also makes the zclient code consistent with
the other lib functions that need to schedule work on your behalf
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
RIP_MAX_RTE is defined in ripd.h as 25 but is in fact the
result of a formula. More over it is not used in the code:
the code itself includes the fomula. This makes it un-clear
for maintenance.
Signed-off-by: Feng Lu <lu.feng@6wind.com>
Reviewed-by: Alain Ritoux <alain.ritoux@6wind.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
* ripd/rip_interface.c
* rip_request_neighbor(): comment out, unused
* rip_request_neighbor_all(): idem
* rip_interface_up(): Cast flags otherwise compiler complains
about %lld not matching uint64_t on 64 bit x86. Print in hex
since flags are bit field.
* rip_interface_add(): idem
* rip_interface_delete(): idem
* ripd/rip_zebra.c
* rip_redistribute_set(): comment out, unused
* ripd/ripd.h
* rip_redistribute_check(): move prototype here so compiler
can check function against prototype
* ripd/ripd.c
* rip_update_default_metric(): comment out, unused
* ripd.c: (rip_response_process) Instead of calling
rip_interface.c:if_valid_neighbor(), call the equivalent
library function if_lookup_address().
* rip_interface.c: (if_valid_neighbor) Remove function, since it is
essentially equivalent to the if_lookup_address() library function.
* ripd.h: (if_valid_neighbor) Remove function declaration.