The netlink_vrf_change() function is called both when a VRF device
is created in the Linux kernel and when it is activated. This
commit changes this function to perform the VRF misconfiguration
detection only when the VRF device is created, as doing the check
twice would cause a false positive followed by a hard failure (not
to mention the double check is unnecessary since the VRF table ID
can't change once the device is created).
Fixes#6319.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Currently the linux kernel allows you to specify the same
table id -> multiple vrf's. While I am arguing with
the kernel people about proper behavior here let's
just remove this as a possiblity from happening and
mark it a zebra stopable misconfiguration.
(Effectively we are preventing a crash down the line
as that all over FRR we assume it's a unique
mapping not a many to one).
Why fail hard? Because we hope to get the person
who misconfigured it to actually notice immediately
not hours or days down the line when shit hits the fan.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The netlink_request function takes a `struct nlmsghdr *`
pointer from a common pattern that we use:
struct {
struct nlmsghdr n;
struct fib_rule_hdr frh;
char buf[NL_PKT_BUF_SIZE];
} req;
We were calling it `netlink_request(Socket, &req.n)`
The problem here is that coverity, rightly so, sees that
we access the data after the nlmsghdr in netlink_request and
tells us we have an read beyond end of the structure. While
we know we haven't mangled anything up here because of manual
inspection coverity doesn't have this knowledge implicitly.
So let's modify the code call to netlink_request to pass in the
void pointer of the req structure itself, cast to the appropriate
data structure in the function and do the right thing. Hopefully
the coverity SA will be happy and we can move on with our life.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Move the supports_nh bool indicating whether the kernel we are
using supports nexthop objects into the netlink kernel interface
itself. Since only linux and netlink support nexthop object APIs
for now this is fine.
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
On restart, if we failed to remove any nexthop objects due
to a kill -9 or such event, sweep them if we aren't using them.
Add a proto field to handle this and remove the is_kernel bool.
Add a dupicate flag that indicates this nexthop group is only
present in our ID hashtable. It is a dupicate nexthop we received
from the kernel, therefore we cannot hash on it.
Make the idcounter globally accessible so that kernel updates
increment it as soon as we receive them, not when we handle them.
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
Added a check on startup for determining if the kernel supports
nexthop objects. It sets an appropriate bool on the zebra namespace
struct.
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
Add all the neccessary code to allow nexthops to be processed
in separate dataplane contexts with the netlink dataplane kernel
provider.
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
Add the functionality to parse new nexthop group messages
from the kernel and insert them into the appropriate hash
tables. Parsing is done at startup between interface and
interface address lookup. Add functionality to parse
changes to nexthops we already have. Add functionality
to parse delete nexthop messages from the kernel and
remove them from our table.
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
Separate interface lookup into its own function.
We need to know interfaces for reading in nexthop
information, but we need to know nexthops for reading
in the interface addresses. We will read in nexthops
between the two.
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
Since we don't have a daemon who's job is to handle kernel
routes and we don't get an explicit route delete anymore if
nexthops become unreachable from the kernel, zebra must
re-process kernel routes itself to make sure they are still valid.
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
Cleanup the interface creation apis to make it more
clear what they are doing.
Make it explicit that the creation via name/ifindex will
only add it to the appropriate list.
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
We were storing the interface description irrelevant of whether
or not it was a newlink or dellink. This makes no sense.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This change addresses the following :
1. Ensures zlog_debug should be under DEBUG macro check
2. Ensures zlog_err and zlog_warn wherever applicable.
3. Removed few posivite logs from fpm handling, whose frequency is high.
Signed-off-by: vishaldhingra <vdhingra@vmware.com>
speed interface is done 15 seconds after interface creation. during that
time, the vrf or the interface may have disappeared. to protect this,
return an error in case it is not possible to create a vrf socket or it
is not possible to get speed of an interface because of a missing
device.
Signed-off-by: Julien Floret <julien.floret@6wind.com>
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Since we are now away from the dual use of the destination field, there
is no need to single out /32 addresses as broadcast. This was bugged
anyway, since the same /32 criteria was used for IPv6 addresses as well,
when `connected_check_ptp` is called in `connected_delete_ipv6`.
Fixes: 3053
Signed-off-by: Juergen Werner <juergen@opensourcerouting.org>
The `destination` field of the connection structure was used to store
the broadcast address, if the connection was not p2p. This multipurpose
is not very evident and the benefits over calculating the bcast address
on the fly minimal.
Signed-off-by: Juergen Werner <juergen@opensourcerouting.org>
In if_netlink.c, when an interface structure, ifp, is first created,
its possible for the master to come up after the slave interface does.
This means, the slave interface has no way to display the master's ifname
in show outputs. To fix this, we need to allow creation by ifindex instead
of by ifname so that this issue is handled.
Signed-off-by: Dinesh G Dutt<5016467+ddutt@users.noreply.github.com>
When interfaces change while they are up, Zebra sends if_up
notifications with the updated interface info. Change Zebra to send
if_down notifications with interface info when the interface changes
while it is down.
VRRP, at the least, needs these to know about MAC changes while an
interface is down.
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Field vrf_id is replaced by the pointer of the struct vrf *.
For that all other code referencing to (interface)->vrf_id is replaced.
This work should not change the behaviour.
It is just a continuation work toward having an interface API handling
vrf pointer only.
some new generic functions are created in vrf:
vrf_to_id, vrf_to_name,
a zebra function is also created:
zvrf_info_lookup
an ospf function is also created:
ospf_lookup_by_vrf
it is to be noted that now that interface has a vrf pointer, some more
optimisations could be thought through all the rest of the code. as
example, many structure store the vrf_id. those structures could get
the exact vrf structure if inherited from an interface vrf context.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
vrf_id parameter is replaced with struct vrf * parameter. It is
needed to create vrf structure before entering in the fuction.
an error is generated in case the vrf parameter is missing.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
there may be cases where the vrf is yet allocated from the vty, and the
discovery process did not make the relationship between the vrf_id and
the name of the vrf. For instance, by parsing an interface belonging to
vrf-id X, it is not sure that vrf-id X and vrfname XX are talking about
the same vrf. For that, lets allocate the vrf, and lets try to detect
there is a duplicate case in vrf, so that the merge can be done without
any impact for the user.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
vrf pointer is used as reference when calling if_get_by_name() function.
this will permit to create interfaces with an unknown vrf_id, since it
is only necessary to get the vrf structure to store the interfaces.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
The alias/description of an interface in linux was being
used to override the internal description. As such let's
fix the display to keep track of both if we have it.
Config in FRR:
!
interface docker0
description another combination
!
interface enp3s0
description BAMBOOZLE ME WILL YOU
!
Config in linux:
sharpd@robot ~/f/zebra> ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
alias This is the loopback you cabbage
2: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP mode DEFAULT group default qlen 1000
link/ether 74:d0:2b:9c:16:eb brd ff:ff:ff:ff:ff:ff
alias HI HI HI
Now the 'show int descr' command:
robot# show int description
Interface Status Protocol Description
docker0 up down another combination
enp3s0 up up BAMBOOZLE ME WILL YOU
HI HI HI
lo up up This is the loopback you cabbage
Fixes: #4191
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Start using the dataplane for interface-address programming,
on netlink platforms. Other platforms just stubbed at this
point.
Signed-off-by: Mark Stapp <mjs@voltanet.io>
L3VNI keeps reference to svi interface (ifp).
When a netlink change received there is no flag
that mac has changed. Currently simply overwrite
interface's (ifp) hw_addr (MAC) field.
For originating EVPN type-2 and type-5 routes due to VNI
MAC change, comparison is required to check existing MAC
vs. netlink change MAC field.
Ticket:CM-23850
Reviewed By:CCR-8283
Testing Done:
Validate EVPN type-5 routes originated upon changing MAC address
of L3VNI's SVI inteface via ip link set cmd.
checked show bgp l2vpn evpn route and Rmac field contains new
MAC address.
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
The ifa_flags value in the netlink message was originally a uint8_t
value. The linux kernel quickly ran out of 8 bits of data to
pass and the IFA_FLAGS value was added to the netlink message to allow
more than 8 bits of data to be passed. So replace the ifa_flags
with the IFA_FLAGS value if it exists in the interface netlink
message.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
MACVLAN devices are typically used for applications such as VRR/VRRP that
require a second MAC address (virtual). These devices have a corresponding
SVI/VLAN device -
root@TORC11:~# ip addr show vlan1002
39: vlan1002@bridge: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9152 qdisc noqueue master vrf1 state UP group default
link/ether 00:02:00:00:00:2e brd ff:ff:ff:ff:ff:ff
inet6 2001:aa:1::2/64 scope global
valid_lft forever preferred_lft forever
root@TORC11:~# ip addr show vlan1002-v0
40: vlan1002-v0@vlan1002: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9152 qdisc noqueue master vrf1 state UP group default
link/ether 00:00:5e:00:01:01 brd ff:ff:ff:ff:ff:ff
inet6 2001:aa:1::a/64 metric 1024 scope global
valid_lft forever preferred_lft forever
root@TORC11:~#
The macvlan device is used primarily for RX (VR-IP/VR-MAC). And TX is via
the SVI. To acheive that functionality the macvlan network's metric
is set to a higher value.
Zebra currently ignores the devaddr metric sent by the kernel and hardcodes
it to 0. This commit eliminates that hardcoding. If the devaddr metric
is available (METRIC_MAX) it is used for setting up the connected route
otherwise we fallback to the dev/interface metric.
Setting the macvlan metric to a higher value ensures that zebra will always
select the connected route on the SVI (and subsequently use it for next hop
resolution etc.) -
root@TORC11:~# vtysh -c "show ip route vrf vrf1 2001:aa:1::/64"
Routing entry for 2001:aa:1::/64
Known via "connected", distance 0, metric 1024, vrf vrf1
Last update 11:30:56 ago
* directly connected, vlan1002-v0
Routing entry for 2001:aa:1::/64
Known via "connected", distance 0, metric 0, vrf vrf1, best
Last update 11:30:56 ago
* directly connected, vlan1002
root@TORC11:~#
Ticket: CM-23511
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
zebra uses the SIOCETHTOOL ioctl with the ETHTOOL_GSET command to
fetch the speed of interfaces from the kernel. The only problem is
that ETHTOOL_GSET returns EOPNOTSUPP when the given interface is a
virtual interface. This leads to zebra emitting warnings like this
at startup:
ZEBRA: IOCTL failure to read interface lo speed: 95 Operation not supported
ZEBRA: IOCTL failure to read interface dummy0 speed: 95 Operation not supported
ZEBRA: IOCTL failure to read interface ovs-system speed: 95 Operation not supported
Silence these warnings by ignoring EOPNOTSUPP errors, since we know
they are harmless. This is similar to how we handle EINVAL errors
from the BSD SIOCGIFMEDIA ioctl (commit c69f2c1ff).
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Make netlink_request api generic where it can be used
for dump or querying specific information request.
nelink request nlm flags (NLM_F_ROOT | NLM_F_MATCH) are
used to dump purpose, if client wants to query spcific
MAC or IP using netlink_request does not require to set
them.
nlm struct is passed by the caller of netlink_request,
it can also set the nlm request flags.
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
The interface type can be a bond or a bond slave, add some
code to note this and to display it as part of a show interface
command.
Signed-off-by: Dinesh Dutt <didutt@gmail.com>
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The frr-interface YANG module models interfaces using a YANG list keyed
by the interface name and the interface VRF. Interfaces can't be keyed
only by their name since interface names might not be globally unique
when the netns VRF backend is in use. When using the VRF-Lite backend,
however, interface names *must* be globally unique. In this case, we need
to validate the uniqueness of interface names inside the appropriate
northbound callback since this constraint can't be expressed in the
YANG language. We must also ensure that only inactive interfaces can be
removed, among other things we need to validate in the northbound layer.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Reduce or eliminate use of global zebra_ns structs in
a couple of netlink/kernel code paths, so that those paths
can potentially be made asynch eventually.
Signed-off-by: Mark Stapp <mjs@voltanet.io>
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The block comments from a couple commits were not following
proper style. Fix.
Fix SA warning that had snuck in.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Netdevices are not sorted in any fashion by the kernel during the initial
interface nldump. So you can get an upper device (such as an SVI) before
its corresponding lower device (bridge).
To fix this problem we skip resolving link dependencies during handling of
nldump notifications. Resolving instead at the end (when all the devices
are present)
Signed-off-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Ticket: CM-22388, CM-21796
Reviewed By: CCR-7845
Testing Done:
1. verified on a setup with missing linkages
2. automation - evpn-min
When we are displaying data about a netlink message
in debugs or errors, print out the message type
as a string instead of a number.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This crash occurs only with netns implementation.
vrf meaning is different regarging its implementation (netns or
vrf-lite)
- With vrf-lite implementation vrf is a property of the interface that
can be changed as the speed or the state (iproute2 command: "ip link
set dev IF_NAME master VRF_NAME"). All interfaces of the system are in
the same netns and so interface name is unique.
- With netns implementation vrf is a characteristic of the interface
that CANNOT be changed: it is the id of the netns where the interface
is located. To change the vrf of an interface (iproute2 command to
move an interface "ip netns exec VRF_NAME1 ip link set dev IF_NAME
netns VRF_NAME2") the interface is deleted from the old vrf and
created in the new vrf.
Interface name is not unique, the same name can be present in the
different netns (typically the lo interface) and search of interface
must be done by the tuple (interface name, netns id).
Current tests on the vrf implementation (vrf-lite or netns) are not
sufficient. In some cases (for example when an interface is moved from
a vrf X to the default vrf and then move back to VRF X) we can have a
corruption message and then a crash of zebra.
To avoid this corruption test on the vrf implementation, needed when an
interface changes, has been rewritten:
- For all interface changes except deletion the if_get_by_name function,
that checks if an interface exists and creates or updates it if
needed, is changed:
* The vrf-lite implementation is unchanged: search of the interface
is based only on the name and update the vrf-id if needed.
* The netns implementation search of the interface is based on the
(name, vrf-id) tuple and interface is created if not found, the
vrf-id is never updated.
- deletion of an interface (reception of a RTM_DELLINK netlink message):
* The vrf-lite implementation is unchanged: the interface
information are cleared and the interface is moved to the default
vrf if it does not belong to (to allow vrf deletion)
* The netns implementation is changed: only the interface
information are cleared and the interface stays in its vrf to
avoid conflict with interface with the same name in the default
vrf.
This implementation reverts (partially or totally):
commit 393ec5424e ("zebra: fix missing node attribute set in ifp")
commit e9e9b1150f ("lib: create interface even if name is the same")
commit 9373219c67 ("zebra: improve logs when replacing interface to an
other netns")
Fixes: b53686c52a ("zebra: delete interface that disappeared")
Signed-off-by: Thibaut Collet <thibaut.collet@6wind.com>
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
when interface is a virtual ethernet interface, then there is no need to
update link pointer of interface.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This function is changed so that the interface index is searched across
the correct namespace.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Prefix length validation checks should be returning an error
rather than 0. Switch to that and make them error messages.
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
Zebra needed a check that varifies the prefix length
of an address is a valid length when receiving route
changes and interface address changes.
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
Zebra needed a check for mtu from the message it
received from the kernel before adding the new link.
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
The zebra netlink socket was attempting to read netlink
messages with invalid address families in a couple areas.
Added filters and warn messages.
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
When we receive a netlink message from the kernel we have
handler functions for when we send a netlink command, if these
return a failure ( < 0 ) then we output that we had a parse
issue. But if all we get is:
2018-06-21T23:47:45.298156+00:00 qct-ix1-08 zebra[1484]: netlink-cmd (NS 0) filter function error
Then it is not very useful to figure out *where* the error happened.
Add more error code when in a decode path to hopefully allow us
to figure out where this message is coming from.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
The IFLA_INFO_SLAVE_KIND constant is always defined now that we imported
our own copies of the Linux kernel headers. Remove the preprocessor
checks since they aren't necessary anymore.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
With:
commit ba7773964c
Author: Renato Westphal <renato@opensourcerouting.org>
Date: Wed Sep 20 22:12:56 2017 -0300
We added our own copy of if_link.h (among others). This
file unconditionally defines IFLA_WIRELESS, so we don't need
the conditional defines in the if_netlink.c code...
Issue: https://github.com/FRRouting/frr/issues/2299
Signed-off-by: Arthur Jones <arthur.jones@riverbed.com>
When checking for a duplicate interface in an other NETNS, one may find
an interface in default VRF. That interface may have been moved to that
default VRF, for further action. Prevent from doing any action at this
point.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
The log information is better displated.
Also the variable name fits better with other_ifp, than with old_ifp.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Zebra did not have a handler for tunnels in v6 for
some reason. Add code to handle the broadcast address
for both addition and deletion.
This appears to fix the crash. There might still need
to be some work to make the code `work` properly for
this type of tunnel.
Fixes: #2063
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
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>
When moving interfaces to an other place, like other netns, the
remaining interface is still present, with inactive status.
Now, that interface is deleted from the list, if the interface appears
on an other netns. If not, the interface is kept.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
The table id of the vrf is being given to us as part
of the vrf creation netlink callback. Unfortunately it
was being set in the zvrf *after* the vrf_enable callback.
This didn't used to matter until we started having config data
stored on the side that we needed to act on when the vrf
came up enough to start working.
So when we were storing static routes and installing them
they were being pushed into the default table for non-default
vrf's.
Ticket: CM-19141
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
musl-libc is a lightweight libc used by alpine linux:
https://www.musl-libc.org/
AFAICT, this is the only change to the source needed to get
basic frr support compiling on musl.
Two changes in one patch, get ethhdr from netinet/if_ether.h
and replace the only __caddr_t I could find in the source base
with caddr_t.
Testing done:
Compiled apk packages using a docker environment (patches
coming soon) also compiled redhat and debian using a similar
docker environment (RFC patches for those changes are queued
up too)...
Issue: https://github.com/FRRouting/frr/issues/1859
Signed-off-by: Arthur Jones <arthur.jones@riverbed.com>
Move setting vrf loopback flag on ifp after
zebra vrf type is set (ziftype).
Zebra connected not to announce unnumbered for
VRF interface (similar to loopback).
Ticket:CM-19914
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com
Because socket creation is tightly linked with socket binding for vrf
lite, the proposal is made to extend socket creation APIs and to create
a new API called vrf_bind that applies to vrf lite. The passed interface
name is the interface that will be bound to the socket passed.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
That API can be used to wrap the ioctl call with various vrf instances.
This permits transparently doing the ioctl() call without taking into
consideration the vrf backend kind.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
When interfaces are located on different NETNS ( different VRF), then a
switch from netns context is necessary when calling setns(). The VRF
apis to switch and switch back are called, so that the ioctl will work
accordingly.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Upon following calls: interface poll, address poll, route poll, and
ICMPv6 handling, each new Namespace is being parsed. For that, the
socket operations need to switch from one NS to one other, to get the
necessary information.
As of now, there is a crash when dumping interfaces, through show
running-config.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
The netns backend is chosen by VRF if a runtime flag named vrfwnetns is
selected when running zebra.
In the case the NETNS backend is chosen, in some case the VRFID value is
being assigned the value of the NSID. Within the perimeter of that work,
this is why the vrf_lookup_by_table function is extended with a new
parameter.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>