2023-02-08 13:17:09 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2002-12-13 21:15:29 +01:00
|
|
|
/*
|
|
|
|
* Address linked list routine.
|
|
|
|
* Copyright (C) 1997, 98 Kunihiro Ishiguro
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
|
|
|
#include "prefix.h"
|
|
|
|
#include "linklist.h"
|
|
|
|
#include "if.h"
|
|
|
|
#include "table.h"
|
|
|
|
#include "rib.h"
|
|
|
|
#include "table.h"
|
|
|
|
#include "log.h"
|
2005-11-03 Paul Jakma <paul.jakma@sun.com>
* connected.{c,h}: Include memory.h
(connected_add_ipv4) Use MTYPE for ifc label.
(connected_add_ipv6) Also should accept label. Store it in ifp.
(connected_del_ipv4) Taking label as argument is pointless.
* rt_netlink.c: (netlink_interface_addr) update label usage
for connected_{add,delete} functions.
* if_ioctl.c: (if_getaddrs) NULL label for connected_add_ipv6.
* if_ioctl_solaris.c: (interface_list_ioctl) Pass LIFC_NOXMIT
so we also find out about NOXMIT interfaces like VNI.
Bit of hackery to turn interface names into the primary
interface name, later with routing socket messages we only
will about primary interfaces anyway, so we must normalise
the name.
(if_get_addr) take label as argument, so it can
be passed to connected_add.
If label is provided, then it is interface name to issue the
ioctl for address information on, not the ifp name.
(interface_list) List AF_UNSPEC too, just in case.
* if_proc.c: (ifaddr_proc_ipv6) label for connected_add_ipv6.
* interface.c: (if_addr_wakeup) Some very bogus code - sets
IFF_RUNNING - add comment.
(if_refresh)
(ip_address_install) Use MTYPE for ifc label.
* ioctl_solaris.c: (if_mangle_up) New function. Hackery to make
IFF_UP reflect whether any addresses are left on the
interface, as we get signalled for IFF_UP flags change on the
primary interface only. Logical interfaces dont generate
IFINFO, but we do get an RTM_DELADDR.
(if_get_flags) Call if_mangle_up before return.
* kernel_socket.c: (ifam_read) Fixup calls to
connected_{add,delete} to match above changes. Rename gate
variable to brd, less confusing.
Pass the interface name as a label, if it is not same name
as ifp->name.
2005-11-03 13:35:21 +01:00
|
|
|
#include "memory.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2016-10-06 21:56:13 +02:00
|
|
|
#include "vty.h"
|
2015-10-21 07:37:32 +02:00
|
|
|
#include "zebra/debug.h"
|
2002-12-13 21:15:29 +01:00
|
|
|
#include "zebra/zserv.h"
|
|
|
|
#include "zebra/redistribute.h"
|
2004-10-03 20:46:08 +02:00
|
|
|
#include "zebra/interface.h"
|
2005-06-28 19:17:12 +02:00
|
|
|
#include "zebra/connected.h"
|
2015-12-07 22:05:34 +01:00
|
|
|
#include "zebra/rtadv.h"
|
2016-04-16 04:19:37 +02:00
|
|
|
#include "zebra/zebra_mpls.h"
|
2018-08-16 22:10:32 +02:00
|
|
|
#include "zebra/zebra_errors.h"
|
2020-09-28 21:22:52 +02:00
|
|
|
#include "zebra/zebra_router.h"
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2013-01-24 15:04:49 +01:00
|
|
|
/* communicate the withdrawal of a connected address */
|
2005-09-12 18:58:52 +02:00
|
|
|
static void connected_withdraw(struct connected *ifc)
|
|
|
|
{
|
|
|
|
if (!ifc)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* Update interface address information to protocol daemon. */
|
|
|
|
if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
|
|
|
|
zebra_interface_address_delete_update(ifc->ifp, ifc);
|
|
|
|
|
2013-01-24 15:04:44 +01:00
|
|
|
if (ifc->address->family == AF_INET)
|
|
|
|
if_subnet_delete(ifc->ifp, ifc);
|
|
|
|
|
2017-08-31 19:47:26 +02:00
|
|
|
connected_down(ifc->ifp, ifc);
|
2005-09-12 18:58:52 +02:00
|
|
|
|
|
|
|
UNSET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
|
|
|
|
}
|
|
|
|
|
2013-01-24 15:04:48 +01:00
|
|
|
/* The address is not in the kernel anymore, so clear the flag */
|
|
|
|
UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
|
|
|
|
|
2006-05-21 06:04:49 +02:00
|
|
|
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) {
|
2023-11-22 19:05:41 +01:00
|
|
|
if_connected_del(ifc->ifp->connected, ifc);
|
2019-10-30 01:16:28 +01:00
|
|
|
connected_free(&ifc);
|
2006-05-21 06:04:49 +02:00
|
|
|
}
|
2005-09-12 18:58:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void connected_announce(struct interface *ifp, struct connected *ifc)
|
|
|
|
{
|
|
|
|
if (!ifc)
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-11-16 16:01:03 +01:00
|
|
|
if (!if_is_loopback(ifp) && ifc->address->family == AF_INET) {
|
2021-07-01 17:05:11 +02:00
|
|
|
if (ifc->address->prefixlen == IPV4_MAX_BITLEN)
|
2015-05-20 03:04:26 +02:00
|
|
|
SET_FLAG(ifc->flags, ZEBRA_IFA_UNNUMBERED);
|
|
|
|
else
|
|
|
|
UNSET_FLAG(ifc->flags, ZEBRA_IFA_UNNUMBERED);
|
2015-05-20 02:58:13 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2023-11-22 19:05:41 +01:00
|
|
|
if_connected_add_tail(ifp->connected, ifc);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2005-09-12 18:58:52 +02:00
|
|
|
/* Update interface address information to protocol daemon. */
|
2013-01-24 15:04:49 +01:00
|
|
|
if (ifc->address->family == AF_INET)
|
|
|
|
if_subnet_add(ifp, ifc);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2013-01-24 15:04:49 +01:00
|
|
|
zebra_interface_address_add_update(ifp, ifc);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2013-01-24 15:04:49 +01:00
|
|
|
if (if_is_operative(ifp)) {
|
2017-08-30 00:23:08 +02:00
|
|
|
connected_up(ifp, ifc);
|
2005-09-12 18:58:52 +02:00
|
|
|
}
|
|
|
|
}
|
2014-06-04 06:53:35 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* If same interface address is already exist... */
|
2010-01-30 12:10:23 +01:00
|
|
|
struct connected *connected_check(struct interface *ifp,
|
|
|
|
union prefixconstptr pu)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2010-01-30 12:10:23 +01:00
|
|
|
const struct prefix *p = pu.p;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct connected *ifc;
|
|
|
|
|
2023-11-22 19:05:41 +01:00
|
|
|
frr_each (if_connected, ifp->connected, ifc)
|
2005-04-07 Paul Jakma <paul.jakma@sun.com>
* (global): Fix up list loops to match changes in lib/linklist,
and some basic auditing of usage.
* configure.ac: define QUAGGA_NO_DEPRECATED_INTERFACES
* HACKING: Add notes about deprecating interfaces and commands.
* lib/linklist.h: Add usage comments.
Rename getdata macro to listgetdata.
Rename nextnode to listnextnode and fix its odd behaviour to be
less dangerous.
Make listgetdata macro assert node is not null, NULL list entries
should be bug condition.
ALL_LIST_ELEMENTS, new macro, forward-referencing macro for use
with for loop, Suggested by Jim Carlson of Sun.
Add ALL_LIST_ELEMENTS_RO for cases which obviously do not need the
"safety" of previous macro.
LISTNODE_ADD and DELETE macros renamed to ATTACH, DETACH, to
distinguish from the similarly named functions, and reflect their
effect better.
Add a QUAGGA_NO_DEPRECATED_INTERFACES define guarded section
with the old defines which were modified above,
for backwards compatibility - guarded to prevent Quagga using it..
* lib/linklist.c: fix up for linklist.h changes.
* ospf6d/ospf6_abr.c: (ospf6_abr_examin_brouter) change to a single
scan of the area list, rather than scanning all areas first for
INTER_ROUTER and then again for INTER_NETWORK. According to
16.2, the scan should be area specific anyway, and further
ospf6d does not seem to implement 16.3 anyway.
2005-04-07 09:30:20 +02:00
|
|
|
if (prefix_same(ifc->address, p))
|
|
|
|
return ifc;
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-01-30 12:10:23 +01:00
|
|
|
/* same, but with peer address */
|
|
|
|
struct connected *connected_check_ptp(struct interface *ifp,
|
|
|
|
union prefixconstptr pu,
|
|
|
|
union prefixconstptr du)
|
|
|
|
{
|
|
|
|
const struct prefix *p = pu.p;
|
|
|
|
const struct prefix *d = du.p;
|
|
|
|
struct connected *ifc;
|
|
|
|
|
2023-11-22 19:05:41 +01:00
|
|
|
frr_each (if_connected, ifp->connected, ifc) {
|
2010-01-30 12:10:23 +01:00
|
|
|
if (!prefix_same(ifc->address, p))
|
|
|
|
continue;
|
|
|
|
if (!CONNECTED_PEER(ifc) && !d)
|
|
|
|
return ifc;
|
|
|
|
if (CONNECTED_PEER(ifc) && d
|
|
|
|
&& prefix_same(ifc->destination, d))
|
|
|
|
return ifc;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2013-01-24 15:04:49 +01:00
|
|
|
/* Check if two ifc's describe the same address in the same state */
|
2006-06-15 20:10:47 +02:00
|
|
|
static int connected_same(struct connected *ifc1, struct connected *ifc2)
|
|
|
|
{
|
|
|
|
if (ifc1->ifp != ifc2->ifp)
|
|
|
|
return 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-08-10 11:52:03 +02:00
|
|
|
if (ifc1->flags != ifc2->flags)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (ifc1->conf != ifc2->conf)
|
|
|
|
return 0;
|
|
|
|
|
2006-06-15 20:10:47 +02:00
|
|
|
if (ifc1->destination)
|
|
|
|
if (!ifc2->destination)
|
|
|
|
return 0;
|
|
|
|
if (ifc2->destination)
|
|
|
|
if (!ifc1->destination)
|
|
|
|
return 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2006-06-15 20:10:47 +02:00
|
|
|
if (ifc1->destination && ifc2->destination)
|
|
|
|
if (!prefix_same(ifc1->destination, ifc2->destination))
|
|
|
|
return 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2006-06-15 20:10:47 +02:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2013-01-24 15:04:46 +01:00
|
|
|
/* Handle changes to addresses and send the neccesary announcements
|
|
|
|
* to clients. */
|
|
|
|
static void connected_update(struct interface *ifp, struct connected *ifc)
|
2006-06-15 20:10:47 +02:00
|
|
|
{
|
|
|
|
struct connected *current;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2006-06-15 20:10:47 +02:00
|
|
|
/* Check same connected route. */
|
2010-01-30 12:10:23 +01:00
|
|
|
current = connected_check_ptp(ifp, ifc->address, ifc->destination);
|
|
|
|
if (current) {
|
2006-06-15 20:10:47 +02:00
|
|
|
if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED))
|
|
|
|
SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2006-06-15 20:10:47 +02:00
|
|
|
/* Avoid spurious withdraws, this might be just the kernel
|
|
|
|
* 'reflecting'
|
|
|
|
* back an address we have already added.
|
|
|
|
*/
|
2013-01-24 15:04:49 +01:00
|
|
|
if (connected_same(current, ifc)) {
|
2006-06-15 20:10:47 +02:00
|
|
|
/* nothing to do */
|
2019-10-30 01:16:28 +01:00
|
|
|
connected_free(&ifc);
|
2013-01-24 15:04:46 +01:00
|
|
|
return;
|
2006-06-15 20:10:47 +02:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2013-01-24 15:04:46 +01:00
|
|
|
/* Clear the configured flag on the old ifc, so it will be freed
|
|
|
|
* by
|
|
|
|
* connected withdraw. */
|
2006-06-15 20:10:47 +02:00
|
|
|
UNSET_FLAG(current->conf, ZEBRA_IFC_CONFIGURED);
|
|
|
|
connected_withdraw(
|
|
|
|
current); /* implicit withdraw - freebsd does this */
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2013-01-24 15:04:49 +01:00
|
|
|
/* If the connected is new or has changed, announce it, if it is usable
|
|
|
|
*/
|
|
|
|
if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
|
|
|
|
connected_announce(ifp, ifc);
|
2006-06-15 20:10:47 +02:00
|
|
|
}
|
|
|
|
|
2024-10-14 17:25:32 +02:00
|
|
|
/*
|
|
|
|
* This function goes through and handles the deletion of a kernel route that happened
|
|
|
|
* to be the exact same as the connected route, so that the connected route wins.
|
|
|
|
* This can happen during processing if we happen to receive events in a slightly
|
|
|
|
* unexpected order. This is similiar to code in the other direction where if we
|
|
|
|
* have a kernel route don't install it if it perfectly matches a connected route.
|
|
|
|
*/
|
|
|
|
static void connected_remove_kernel_for_connected(afi_t afi, safi_t safi, struct zebra_vrf *zvrf,
|
|
|
|
struct prefix *p, struct nexthop *nh)
|
|
|
|
{
|
|
|
|
struct route_node *rn;
|
|
|
|
struct route_entry *re;
|
|
|
|
rib_dest_t *dest;
|
|
|
|
struct route_table *table = zebra_vrf_table(afi, SAFI_UNICAST, zvrf->vrf->vrf_id);
|
|
|
|
|
2024-10-17 13:42:47 +02:00
|
|
|
if (!table)
|
|
|
|
return;
|
|
|
|
|
2024-10-14 17:25:32 +02:00
|
|
|
rn = route_node_match(table, p);
|
|
|
|
if (!rn)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!prefix_same(&rn->p, p))
|
|
|
|
return;
|
|
|
|
|
|
|
|
dest = rib_dest_from_rnode(rn);
|
|
|
|
if (!dest || !dest->selected_fib)
|
|
|
|
return;
|
|
|
|
|
|
|
|
re = dest->selected_fib;
|
|
|
|
if (re->type != ZEBRA_ROUTE_KERNEL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_KERNEL, 0, 0, p, NULL, nh, 0,
|
|
|
|
zvrf->table_id, 0, 0, false);
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Called from if_up(). */
|
2017-08-30 00:23:08 +02:00
|
|
|
void connected_up(struct interface *ifp, struct connected *ifc)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2017-08-30 00:23:08 +02:00
|
|
|
afi_t afi;
|
*: Introduce Local Host Routes to FRR
Create Local routes in FRR:
S 0.0.0.0/0 [1/0] via 192.168.119.1, enp39s0, weight 1, 00:03:46
K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp39s0, 00:03:51
O 192.168.119.0/24 [110/100] is directly connected, enp39s0, weight 1, 00:03:46
C>* 192.168.119.0/24 is directly connected, enp39s0, 00:03:51
L>* 192.168.119.224/32 is directly connected, enp39s0, 00:03:51
O 192.168.119.229/32 [110/100] via 0.0.0.0, enp39s0 inactive, weight 1, 00:03:46
C>* 192.168.119.229/32 is directly connected, enp39s0, 00:03:46
Create ability to redistribute local routes.
Modify tests to support this change.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-01-05 00:32:43 +01:00
|
|
|
struct prefix p, plocal;
|
2017-08-28 01:30:16 +02:00
|
|
|
struct nexthop nh = {
|
2018-02-08 15:12:12 +01:00
|
|
|
.type = NEXTHOP_TYPE_IFINDEX,
|
|
|
|
.ifindex = ifp->ifindex,
|
2021-10-22 00:17:40 +02:00
|
|
|
.vrf_id = ifp->vrf->vrf_id,
|
2024-02-22 21:53:45 +01:00
|
|
|
.weight = 1,
|
2017-08-28 01:30:16 +02:00
|
|
|
};
|
2019-05-06 16:41:40 +02:00
|
|
|
struct zebra_vrf *zvrf;
|
zebra: set connected route metric based on the devaddr metric
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>
2019-01-15 00:45:33 +01:00
|
|
|
uint32_t metric;
|
2020-09-28 21:22:52 +02:00
|
|
|
uint32_t flags = 0;
|
zebra: Allow one connected route per network mask on a interface
Currently FRR reads the kernel for interface state and FRR
creates a connected route per address on an interface. If
you are in a situation where you have multiple addresses
on an interface just create 1 connected route for them:
sharpd@eva:/tmp/topotests$ vtysh -c "show int dummy302"
Interface dummy302 is up, line protocol is up
Link ups: 0 last: (never)
Link downs: 0 last: (never)
vrf: default
index 3279 metric 0 mtu 1500 speed 0
flags: <UP,BROADCAST,RUNNING,NOARP>
Type: Ethernet
HWaddr: aa:4a:ed:95:9f:18
inet 10.4.1.1/24
inet 10.4.1.2/24 secondary
inet 10.4.1.3/24 secondary
inet 10.4.1.4/24 secondary
inet 10.4.1.5/24 secondary
inet6 fe80::a84a:edff:fe95:9f18/64
Interface Type Other
Interface Slave Type None
protodown: off
sharpd@eva:/tmp/topotests$ vtysh -c "show ip route connected"
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
C>* 10.4.1.0/24 is directly connected, dummy302, 00:10:03
C>* 192.168.161.0/24 is directly connected, enp39s0, 00:10:03
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2021-04-20 01:23:45 +02:00
|
|
|
uint32_t count = 0;
|
|
|
|
struct connected *c;
|
*: Introduce Local Host Routes to FRR
Create Local routes in FRR:
S 0.0.0.0/0 [1/0] via 192.168.119.1, enp39s0, weight 1, 00:03:46
K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp39s0, 00:03:51
O 192.168.119.0/24 [110/100] is directly connected, enp39s0, weight 1, 00:03:46
C>* 192.168.119.0/24 is directly connected, enp39s0, 00:03:51
L>* 192.168.119.224/32 is directly connected, enp39s0, 00:03:51
O 192.168.119.229/32 [110/100] via 0.0.0.0, enp39s0 inactive, weight 1, 00:03:46
C>* 192.168.119.229/32 is directly connected, enp39s0, 00:03:46
Create ability to redistribute local routes.
Modify tests to support this change.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-01-05 00:32:43 +01:00
|
|
|
bool install_local = true;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-10-22 00:17:40 +02:00
|
|
|
zvrf = ifp->vrf->info;
|
2019-05-06 16:41:40 +02:00
|
|
|
if (!zvrf) {
|
2020-03-05 19:17:54 +01:00
|
|
|
flog_err(
|
|
|
|
EC_ZEBRA_VRF_NOT_FOUND,
|
2021-10-22 00:17:40 +02:00
|
|
|
"%s: Received Up for interface but no associated zvrf: %s(%d)",
|
|
|
|
__func__, ifp->vrf->name, ifp->vrf->vrf_id);
|
2019-05-06 16:41:40 +02:00
|
|
|
return;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-05-11 21:57:39 +02:00
|
|
|
/* Ensure 'down' flag is cleared */
|
|
|
|
UNSET_FLAG(ifc->conf, ZEBRA_IFC_DOWN);
|
|
|
|
|
2021-06-02 19:03:52 +02:00
|
|
|
prefix_copy(&p, CONNECTED_PREFIX(ifc));
|
*: Introduce Local Host Routes to FRR
Create Local routes in FRR:
S 0.0.0.0/0 [1/0] via 192.168.119.1, enp39s0, weight 1, 00:03:46
K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp39s0, 00:03:51
O 192.168.119.0/24 [110/100] is directly connected, enp39s0, weight 1, 00:03:46
C>* 192.168.119.0/24 is directly connected, enp39s0, 00:03:51
L>* 192.168.119.224/32 is directly connected, enp39s0, 00:03:51
O 192.168.119.229/32 [110/100] via 0.0.0.0, enp39s0 inactive, weight 1, 00:03:46
C>* 192.168.119.229/32 is directly connected, enp39s0, 00:03:46
Create ability to redistribute local routes.
Modify tests to support this change.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-01-05 00:32:43 +01:00
|
|
|
prefix_copy(&plocal, ifc->address);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Apply mask to the network. */
|
2016-08-24 08:20:47 +02:00
|
|
|
apply_mask(&p);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-08-30 00:23:08 +02:00
|
|
|
afi = family2afi(p.family);
|
|
|
|
|
|
|
|
switch (afi) {
|
|
|
|
case AFI_IP:
|
|
|
|
/*
|
|
|
|
* In case of connected address is 0.0.0.0/0 we treat it tunnel
|
|
|
|
* address.
|
|
|
|
*/
|
|
|
|
if (prefix_ipv4_any((struct prefix_ipv4 *)&p))
|
|
|
|
return;
|
*: Introduce Local Host Routes to FRR
Create Local routes in FRR:
S 0.0.0.0/0 [1/0] via 192.168.119.1, enp39s0, weight 1, 00:03:46
K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp39s0, 00:03:51
O 192.168.119.0/24 [110/100] is directly connected, enp39s0, weight 1, 00:03:46
C>* 192.168.119.0/24 is directly connected, enp39s0, 00:03:51
L>* 192.168.119.224/32 is directly connected, enp39s0, 00:03:51
O 192.168.119.229/32 [110/100] via 0.0.0.0, enp39s0 inactive, weight 1, 00:03:46
C>* 192.168.119.229/32 is directly connected, enp39s0, 00:03:46
Create ability to redistribute local routes.
Modify tests to support this change.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-01-05 00:32:43 +01:00
|
|
|
|
|
|
|
plocal.prefixlen = IPV4_MAX_BITLEN;
|
2017-08-30 00:23:08 +02:00
|
|
|
break;
|
|
|
|
case AFI_IP6:
|
2019-09-03 21:22:38 +02:00
|
|
|
#ifndef GNU_LINUX
|
2017-08-30 00:23:08 +02:00
|
|
|
/* XXX: It is already done by rib_bogus_ipv6 within rib_add */
|
|
|
|
if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6))
|
|
|
|
return;
|
|
|
|
#endif
|
*: Introduce Local Host Routes to FRR
Create Local routes in FRR:
S 0.0.0.0/0 [1/0] via 192.168.119.1, enp39s0, weight 1, 00:03:46
K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp39s0, 00:03:51
O 192.168.119.0/24 [110/100] is directly connected, enp39s0, weight 1, 00:03:46
C>* 192.168.119.0/24 is directly connected, enp39s0, 00:03:51
L>* 192.168.119.224/32 is directly connected, enp39s0, 00:03:51
O 192.168.119.229/32 [110/100] via 0.0.0.0, enp39s0 inactive, weight 1, 00:03:46
C>* 192.168.119.229/32 is directly connected, enp39s0, 00:03:46
Create ability to redistribute local routes.
Modify tests to support this change.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-01-05 00:32:43 +01:00
|
|
|
|
|
|
|
if (IN6_IS_ADDR_LINKLOCAL(&plocal.u.prefix6))
|
|
|
|
install_local = false;
|
|
|
|
|
|
|
|
plocal.prefixlen = IPV6_MAX_BITLEN;
|
2017-08-30 00:23:08 +02:00
|
|
|
break;
|
2023-01-30 16:05:58 +01:00
|
|
|
case AFI_UNSPEC:
|
|
|
|
case AFI_L2VPN:
|
|
|
|
case AFI_MAX:
|
2018-09-13 21:21:05 +02:00
|
|
|
flog_warn(EC_ZEBRA_CONNECTED_AFI_UNKNOWN,
|
2018-08-16 22:10:32 +02:00
|
|
|
"Received unknown AFI: %s", afi2str(afi));
|
2002-12-13 21:15:29 +01:00
|
|
|
return;
|
2017-08-30 00:23:08 +02:00
|
|
|
break;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
zebra: set connected route metric based on the devaddr metric
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>
2019-01-15 00:45:33 +01:00
|
|
|
metric = (ifc->metric < (uint32_t)METRIC_MAX) ?
|
|
|
|
ifc->metric : ifp->metric;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-09-28 21:22:52 +02:00
|
|
|
/*
|
|
|
|
* Since we are hand creating the connected routes
|
|
|
|
* in our main routing table, *if* we are working
|
|
|
|
* in an offloaded environment then we need to
|
|
|
|
* pretend like the route is offloaded so everything
|
|
|
|
* else will work
|
|
|
|
*/
|
|
|
|
if (zrouter.asic_offloaded)
|
|
|
|
flags |= ZEBRA_FLAG_OFFLOADED;
|
|
|
|
|
zebra: Allow one connected route per network mask on a interface
Currently FRR reads the kernel for interface state and FRR
creates a connected route per address on an interface. If
you are in a situation where you have multiple addresses
on an interface just create 1 connected route for them:
sharpd@eva:/tmp/topotests$ vtysh -c "show int dummy302"
Interface dummy302 is up, line protocol is up
Link ups: 0 last: (never)
Link downs: 0 last: (never)
vrf: default
index 3279 metric 0 mtu 1500 speed 0
flags: <UP,BROADCAST,RUNNING,NOARP>
Type: Ethernet
HWaddr: aa:4a:ed:95:9f:18
inet 10.4.1.1/24
inet 10.4.1.2/24 secondary
inet 10.4.1.3/24 secondary
inet 10.4.1.4/24 secondary
inet 10.4.1.5/24 secondary
inet6 fe80::a84a:edff:fe95:9f18/64
Interface Type Other
Interface Slave Type None
protodown: off
sharpd@eva:/tmp/topotests$ vtysh -c "show ip route connected"
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
C>* 10.4.1.0/24 is directly connected, dummy302, 00:10:03
C>* 192.168.161.0/24 is directly connected, enp39s0, 00:10:03
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2021-04-20 01:23:45 +02:00
|
|
|
/*
|
|
|
|
* It's possible to add the same network and mask
|
|
|
|
* to an interface over and over. This would
|
|
|
|
* result in an equivalent number of connected
|
|
|
|
* routes. Just add one connected route in
|
|
|
|
* for all the addresses on an interface that
|
|
|
|
* resolve to the same network and mask
|
|
|
|
*/
|
2023-11-22 19:05:41 +01:00
|
|
|
frr_each (if_connected, ifp->connected, c) {
|
2021-06-02 19:03:52 +02:00
|
|
|
struct prefix cp;
|
zebra: Allow one connected route per network mask on a interface
Currently FRR reads the kernel for interface state and FRR
creates a connected route per address on an interface. If
you are in a situation where you have multiple addresses
on an interface just create 1 connected route for them:
sharpd@eva:/tmp/topotests$ vtysh -c "show int dummy302"
Interface dummy302 is up, line protocol is up
Link ups: 0 last: (never)
Link downs: 0 last: (never)
vrf: default
index 3279 metric 0 mtu 1500 speed 0
flags: <UP,BROADCAST,RUNNING,NOARP>
Type: Ethernet
HWaddr: aa:4a:ed:95:9f:18
inet 10.4.1.1/24
inet 10.4.1.2/24 secondary
inet 10.4.1.3/24 secondary
inet 10.4.1.4/24 secondary
inet 10.4.1.5/24 secondary
inet6 fe80::a84a:edff:fe95:9f18/64
Interface Type Other
Interface Slave Type None
protodown: off
sharpd@eva:/tmp/topotests$ vtysh -c "show ip route connected"
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
C>* 10.4.1.0/24 is directly connected, dummy302, 00:10:03
C>* 192.168.161.0/24 is directly connected, enp39s0, 00:10:03
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2021-04-20 01:23:45 +02:00
|
|
|
|
2021-06-02 19:03:52 +02:00
|
|
|
prefix_copy(&cp, CONNECTED_PREFIX(c));
|
zebra: Allow one connected route per network mask on a interface
Currently FRR reads the kernel for interface state and FRR
creates a connected route per address on an interface. If
you are in a situation where you have multiple addresses
on an interface just create 1 connected route for them:
sharpd@eva:/tmp/topotests$ vtysh -c "show int dummy302"
Interface dummy302 is up, line protocol is up
Link ups: 0 last: (never)
Link downs: 0 last: (never)
vrf: default
index 3279 metric 0 mtu 1500 speed 0
flags: <UP,BROADCAST,RUNNING,NOARP>
Type: Ethernet
HWaddr: aa:4a:ed:95:9f:18
inet 10.4.1.1/24
inet 10.4.1.2/24 secondary
inet 10.4.1.3/24 secondary
inet 10.4.1.4/24 secondary
inet 10.4.1.5/24 secondary
inet6 fe80::a84a:edff:fe95:9f18/64
Interface Type Other
Interface Slave Type None
protodown: off
sharpd@eva:/tmp/topotests$ vtysh -c "show ip route connected"
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
C>* 10.4.1.0/24 is directly connected, dummy302, 00:10:03
C>* 192.168.161.0/24 is directly connected, enp39s0, 00:10:03
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2021-04-20 01:23:45 +02:00
|
|
|
apply_mask(&cp);
|
|
|
|
|
2021-05-11 21:57:39 +02:00
|
|
|
if (prefix_same(&cp, &p) &&
|
|
|
|
!CHECK_FLAG(c->conf, ZEBRA_IFC_DOWN))
|
zebra: Allow one connected route per network mask on a interface
Currently FRR reads the kernel for interface state and FRR
creates a connected route per address on an interface. If
you are in a situation where you have multiple addresses
on an interface just create 1 connected route for them:
sharpd@eva:/tmp/topotests$ vtysh -c "show int dummy302"
Interface dummy302 is up, line protocol is up
Link ups: 0 last: (never)
Link downs: 0 last: (never)
vrf: default
index 3279 metric 0 mtu 1500 speed 0
flags: <UP,BROADCAST,RUNNING,NOARP>
Type: Ethernet
HWaddr: aa:4a:ed:95:9f:18
inet 10.4.1.1/24
inet 10.4.1.2/24 secondary
inet 10.4.1.3/24 secondary
inet 10.4.1.4/24 secondary
inet 10.4.1.5/24 secondary
inet6 fe80::a84a:edff:fe95:9f18/64
Interface Type Other
Interface Slave Type None
protodown: off
sharpd@eva:/tmp/topotests$ vtysh -c "show ip route connected"
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
C>* 10.4.1.0/24 is directly connected, dummy302, 00:10:03
C>* 192.168.161.0/24 is directly connected, enp39s0, 00:10:03
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2021-04-20 01:23:45 +02:00
|
|
|
count++;
|
|
|
|
|
|
|
|
if (count >= 2)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
zebra: Add connected with noprefixroute
Add ability for the connected routes to know
if they are a prefix route or not.
sharpd@eva:/work/home/sharpd/frr1$ ip addr show dev dummy1
13: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
link/ether aa:93:ce:ce:3f:62 brd ff:ff:ff:ff:ff:ff
inet 192.168.55.1/24 scope global noprefixroute dummy1
valid_lft forever preferred_lft forever
inet 192.168.56.1/24 scope global dummy1
valid_lft forever preferred_lft forever
inet6 fe80::a893:ceff:fece:3f62/64 scope link
valid_lft forever preferred_lft forever
sharpd@eva:/work/home/sharpd/frr1$ sudo vtysh -c "show int dummy1"
Interface dummy1 is up, line protocol is up
Link ups: 0 last: (never)
Link downs: 0 last: (never)
vrf: default
index 13 metric 0 mtu 1500 speed 0 txqlen 1000
flags: <UP,BROADCAST,RUNNING,NOARP>
Type: Ethernet
HWaddr: aa:93:ce:ce:3f:62
inet 192.168.55.1/24 noprefixroute
inet 192.168.56.1/24
inet6 fe80::a893:ceff:fece:3f62/64
Interface Type Other
Interface Slave Type None
protodown: off
sharpd@eva:/work/home/sharpd/frr1$ sudo vtysh -c "show ip route"
Codes: K - kernel route, C - connected, L - local, S - static,
R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric, t - Table-Direct,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp13s0, 00:00:08
K>* 169.254.0.0/16 [0/1000] is directly connected, virbr2 linkdown, 00:00:08
L>* 192.168.44.1/32 is directly connected, dummy2, 00:00:08
L>* 192.168.55.1/32 is directly connected, dummy1, 00:00:08
C>* 192.168.56.0/24 is directly connected, dummy1, 00:00:08
L>* 192.168.56.1/32 is directly connected, dummy1, 00:00:08
L>* 192.168.119.205/32 is directly connected, enp13s0, 00:00:08
sharpd@eva:/work/home/sharpd/frr1$ ip route show
default via 192.168.119.1 dev enp13s0 proto dhcp metric 100
169.254.0.0/16 dev virbr2 scope link metric 1000 linkdown
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
192.168.45.0/24 dev virbr2 proto kernel scope link src 192.168.45.1 linkdown
192.168.56.0/24 dev dummy1 proto kernel scope link src 192.168.56.1
192.168.119.0/24 dev enp13s0 proto kernel scope link src 192.168.119.205 metric 100
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
sharpd@eva:/work/home/sharpd/frr1$ ip route show table 255
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
local 172.17.0.1 dev docker0 proto kernel scope host src 172.17.0.1
broadcast 172.17.255.255 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
local 192.168.44.1 dev dummy2 proto kernel scope host src 192.168.44.1
broadcast 192.168.44.255 dev dummy2 proto kernel scope link src 192.168.44.1
local 192.168.45.1 dev virbr2 proto kernel scope host src 192.168.45.1
broadcast 192.168.45.255 dev virbr2 proto kernel scope link src 192.168.45.1 linkdown
local 192.168.55.1 dev dummy1 proto kernel scope host src 192.168.55.1
broadcast 192.168.55.255 dev dummy1 proto kernel scope link src 192.168.55.1
local 192.168.56.1 dev dummy1 proto kernel scope host src 192.168.56.1
broadcast 192.168.56.255 dev dummy1 proto kernel scope link src 192.168.56.1
local 192.168.119.205 dev enp13s0 proto kernel scope host src 192.168.119.205
broadcast 192.168.119.255 dev enp13s0 proto kernel scope link src 192.168.119.205
local 192.168.122.1 dev virbr0 proto kernel scope host src 192.168.122.1
broadcast 192.168.122.255 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
Fixes: #14952
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-12-06 14:33:31 +01:00
|
|
|
if (!CHECK_FLAG(ifc->flags, ZEBRA_IFA_NOPREFIXROUTE)) {
|
2024-10-14 17:25:32 +02:00
|
|
|
connected_remove_kernel_for_connected(afi, SAFI_UNICAST, zvrf, &p, &nh);
|
|
|
|
|
zebra: Add connected with noprefixroute
Add ability for the connected routes to know
if they are a prefix route or not.
sharpd@eva:/work/home/sharpd/frr1$ ip addr show dev dummy1
13: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
link/ether aa:93:ce:ce:3f:62 brd ff:ff:ff:ff:ff:ff
inet 192.168.55.1/24 scope global noprefixroute dummy1
valid_lft forever preferred_lft forever
inet 192.168.56.1/24 scope global dummy1
valid_lft forever preferred_lft forever
inet6 fe80::a893:ceff:fece:3f62/64 scope link
valid_lft forever preferred_lft forever
sharpd@eva:/work/home/sharpd/frr1$ sudo vtysh -c "show int dummy1"
Interface dummy1 is up, line protocol is up
Link ups: 0 last: (never)
Link downs: 0 last: (never)
vrf: default
index 13 metric 0 mtu 1500 speed 0 txqlen 1000
flags: <UP,BROADCAST,RUNNING,NOARP>
Type: Ethernet
HWaddr: aa:93:ce:ce:3f:62
inet 192.168.55.1/24 noprefixroute
inet 192.168.56.1/24
inet6 fe80::a893:ceff:fece:3f62/64
Interface Type Other
Interface Slave Type None
protodown: off
sharpd@eva:/work/home/sharpd/frr1$ sudo vtysh -c "show ip route"
Codes: K - kernel route, C - connected, L - local, S - static,
R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric, t - Table-Direct,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp13s0, 00:00:08
K>* 169.254.0.0/16 [0/1000] is directly connected, virbr2 linkdown, 00:00:08
L>* 192.168.44.1/32 is directly connected, dummy2, 00:00:08
L>* 192.168.55.1/32 is directly connected, dummy1, 00:00:08
C>* 192.168.56.0/24 is directly connected, dummy1, 00:00:08
L>* 192.168.56.1/32 is directly connected, dummy1, 00:00:08
L>* 192.168.119.205/32 is directly connected, enp13s0, 00:00:08
sharpd@eva:/work/home/sharpd/frr1$ ip route show
default via 192.168.119.1 dev enp13s0 proto dhcp metric 100
169.254.0.0/16 dev virbr2 scope link metric 1000 linkdown
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
192.168.45.0/24 dev virbr2 proto kernel scope link src 192.168.45.1 linkdown
192.168.56.0/24 dev dummy1 proto kernel scope link src 192.168.56.1
192.168.119.0/24 dev enp13s0 proto kernel scope link src 192.168.119.205 metric 100
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
sharpd@eva:/work/home/sharpd/frr1$ ip route show table 255
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
local 172.17.0.1 dev docker0 proto kernel scope host src 172.17.0.1
broadcast 172.17.255.255 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
local 192.168.44.1 dev dummy2 proto kernel scope host src 192.168.44.1
broadcast 192.168.44.255 dev dummy2 proto kernel scope link src 192.168.44.1
local 192.168.45.1 dev virbr2 proto kernel scope host src 192.168.45.1
broadcast 192.168.45.255 dev virbr2 proto kernel scope link src 192.168.45.1 linkdown
local 192.168.55.1 dev dummy1 proto kernel scope host src 192.168.55.1
broadcast 192.168.55.255 dev dummy1 proto kernel scope link src 192.168.55.1
local 192.168.56.1 dev dummy1 proto kernel scope host src 192.168.56.1
broadcast 192.168.56.255 dev dummy1 proto kernel scope link src 192.168.56.1
local 192.168.119.205 dev enp13s0 proto kernel scope host src 192.168.119.205
broadcast 192.168.119.255 dev enp13s0 proto kernel scope link src 192.168.119.205
local 192.168.122.1 dev virbr0 proto kernel scope host src 192.168.122.1
broadcast 192.168.122.255 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
Fixes: #14952
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-12-06 14:33:31 +01:00
|
|
|
rib_add(afi, SAFI_UNICAST, zvrf->vrf->vrf_id,
|
|
|
|
ZEBRA_ROUTE_CONNECT, 0, flags, &p, NULL, &nh, 0,
|
|
|
|
zvrf->table_id, metric, 0, 0, 0, false);
|
2020-09-28 21:22:52 +02:00
|
|
|
|
2024-10-14 17:25:32 +02:00
|
|
|
connected_remove_kernel_for_connected(afi, SAFI_MULTICAST, zvrf, &p, &nh);
|
zebra: Add connected with noprefixroute
Add ability for the connected routes to know
if they are a prefix route or not.
sharpd@eva:/work/home/sharpd/frr1$ ip addr show dev dummy1
13: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
link/ether aa:93:ce:ce:3f:62 brd ff:ff:ff:ff:ff:ff
inet 192.168.55.1/24 scope global noprefixroute dummy1
valid_lft forever preferred_lft forever
inet 192.168.56.1/24 scope global dummy1
valid_lft forever preferred_lft forever
inet6 fe80::a893:ceff:fece:3f62/64 scope link
valid_lft forever preferred_lft forever
sharpd@eva:/work/home/sharpd/frr1$ sudo vtysh -c "show int dummy1"
Interface dummy1 is up, line protocol is up
Link ups: 0 last: (never)
Link downs: 0 last: (never)
vrf: default
index 13 metric 0 mtu 1500 speed 0 txqlen 1000
flags: <UP,BROADCAST,RUNNING,NOARP>
Type: Ethernet
HWaddr: aa:93:ce:ce:3f:62
inet 192.168.55.1/24 noprefixroute
inet 192.168.56.1/24
inet6 fe80::a893:ceff:fece:3f62/64
Interface Type Other
Interface Slave Type None
protodown: off
sharpd@eva:/work/home/sharpd/frr1$ sudo vtysh -c "show ip route"
Codes: K - kernel route, C - connected, L - local, S - static,
R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric, t - Table-Direct,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp13s0, 00:00:08
K>* 169.254.0.0/16 [0/1000] is directly connected, virbr2 linkdown, 00:00:08
L>* 192.168.44.1/32 is directly connected, dummy2, 00:00:08
L>* 192.168.55.1/32 is directly connected, dummy1, 00:00:08
C>* 192.168.56.0/24 is directly connected, dummy1, 00:00:08
L>* 192.168.56.1/32 is directly connected, dummy1, 00:00:08
L>* 192.168.119.205/32 is directly connected, enp13s0, 00:00:08
sharpd@eva:/work/home/sharpd/frr1$ ip route show
default via 192.168.119.1 dev enp13s0 proto dhcp metric 100
169.254.0.0/16 dev virbr2 scope link metric 1000 linkdown
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
192.168.45.0/24 dev virbr2 proto kernel scope link src 192.168.45.1 linkdown
192.168.56.0/24 dev dummy1 proto kernel scope link src 192.168.56.1
192.168.119.0/24 dev enp13s0 proto kernel scope link src 192.168.119.205 metric 100
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
sharpd@eva:/work/home/sharpd/frr1$ ip route show table 255
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
local 172.17.0.1 dev docker0 proto kernel scope host src 172.17.0.1
broadcast 172.17.255.255 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
local 192.168.44.1 dev dummy2 proto kernel scope host src 192.168.44.1
broadcast 192.168.44.255 dev dummy2 proto kernel scope link src 192.168.44.1
local 192.168.45.1 dev virbr2 proto kernel scope host src 192.168.45.1
broadcast 192.168.45.255 dev virbr2 proto kernel scope link src 192.168.45.1 linkdown
local 192.168.55.1 dev dummy1 proto kernel scope host src 192.168.55.1
broadcast 192.168.55.255 dev dummy1 proto kernel scope link src 192.168.55.1
local 192.168.56.1 dev dummy1 proto kernel scope host src 192.168.56.1
broadcast 192.168.56.255 dev dummy1 proto kernel scope link src 192.168.56.1
local 192.168.119.205 dev enp13s0 proto kernel scope host src 192.168.119.205
broadcast 192.168.119.255 dev enp13s0 proto kernel scope link src 192.168.119.205
local 192.168.122.1 dev virbr0 proto kernel scope host src 192.168.122.1
broadcast 192.168.122.255 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
Fixes: #14952
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-12-06 14:33:31 +01:00
|
|
|
rib_add(afi, SAFI_MULTICAST, zvrf->vrf->vrf_id,
|
|
|
|
ZEBRA_ROUTE_CONNECT, 0, flags, &p, NULL, &nh, 0,
|
|
|
|
zvrf->table_id, metric, 0, 0, 0, false);
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
*: Introduce Local Host Routes to FRR
Create Local routes in FRR:
S 0.0.0.0/0 [1/0] via 192.168.119.1, enp39s0, weight 1, 00:03:46
K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp39s0, 00:03:51
O 192.168.119.0/24 [110/100] is directly connected, enp39s0, weight 1, 00:03:46
C>* 192.168.119.0/24 is directly connected, enp39s0, 00:03:51
L>* 192.168.119.224/32 is directly connected, enp39s0, 00:03:51
O 192.168.119.229/32 [110/100] via 0.0.0.0, enp39s0 inactive, weight 1, 00:03:46
C>* 192.168.119.229/32 is directly connected, enp39s0, 00:03:46
Create ability to redistribute local routes.
Modify tests to support this change.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-01-05 00:32:43 +01:00
|
|
|
if (install_local) {
|
|
|
|
rib_add(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_LOCAL,
|
|
|
|
0, flags, &plocal, NULL, &nh, 0, zvrf->table_id, 0, 0,
|
|
|
|
0, 0, false);
|
|
|
|
rib_add(afi, SAFI_MULTICAST, zvrf->vrf->vrf_id,
|
|
|
|
ZEBRA_ROUTE_LOCAL, 0, flags, &plocal, NULL, &nh, 0,
|
|
|
|
zvrf->table_id, 0, 0, 0, 0, false);
|
|
|
|
}
|
|
|
|
|
2016-04-16 04:19:37 +02:00
|
|
|
/* Schedule LSP forwarding entries for processing, if appropriate. */
|
2019-05-06 16:41:40 +02:00
|
|
|
if (zvrf->vrf->vrf_id == VRF_DEFAULT) {
|
2020-10-18 13:33:54 +02:00
|
|
|
if (IS_ZEBRA_DEBUG_MPLS)
|
2017-08-30 00:23:08 +02:00
|
|
|
zlog_debug(
|
2020-10-18 13:33:54 +02:00
|
|
|
"%u: IF %s IP %pFX address add/up, scheduling MPLS processing",
|
|
|
|
zvrf->vrf->vrf_id, ifp->name, &p);
|
2019-05-06 16:41:40 +02:00
|
|
|
mpls_mark_lsps_for_processing(zvrf, &p);
|
2016-04-16 04:19:37 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Add connected IPv4 route to the interface. */
|
2021-07-08 16:10:14 +02:00
|
|
|
void connected_add_ipv4(struct interface *ifp, int flags,
|
|
|
|
const struct in_addr *addr, uint16_t prefixlen,
|
|
|
|
const struct in_addr *dest, const char *label,
|
|
|
|
uint32_t metric)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct prefix_ipv4 *p;
|
|
|
|
struct connected *ifc;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 02:47:23 +02:00
|
|
|
if (ipv4_martian(addr))
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Make connected structure. */
|
|
|
|
ifc = connected_new();
|
|
|
|
ifc->ifp = ifp;
|
|
|
|
ifc->flags = flags;
|
zebra: set connected route metric based on the devaddr metric
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>
2019-01-15 00:45:33 +01:00
|
|
|
ifc->metric = metric;
|
2013-01-24 15:04:48 +01:00
|
|
|
/* If we get a notification from the kernel,
|
|
|
|
* we can safely assume the address is known to the kernel */
|
|
|
|
SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
|
2022-04-11 05:58:14 +02:00
|
|
|
if (!if_is_operative(ifp))
|
|
|
|
SET_FLAG(ifc->conf, ZEBRA_IFC_DOWN);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Allocate new connected address. */
|
|
|
|
p = prefix_ipv4_new();
|
|
|
|
p->family = AF_INET;
|
|
|
|
p->prefix = *addr;
|
2021-07-01 16:42:03 +02:00
|
|
|
p->prefixlen =
|
|
|
|
CHECK_FLAG(flags, ZEBRA_IFA_PEER) ? IPV4_MAX_BITLEN : prefixlen;
|
2002-12-13 21:15:29 +01:00
|
|
|
ifc->address = (struct prefix *)p;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-08-10 11:52:03 +02:00
|
|
|
/* If there is a peer address. */
|
|
|
|
if (CONNECTED_PEER(ifc)) {
|
2004-10-19 21:44:43 +02:00
|
|
|
/* validate the destination address */
|
2019-08-10 11:52:03 +02:00
|
|
|
if (dest) {
|
|
|
|
p = prefix_ipv4_new();
|
|
|
|
p->family = AF_INET;
|
|
|
|
p->prefix = *dest;
|
|
|
|
p->prefixlen = prefixlen;
|
|
|
|
ifc->destination = (struct prefix *)p;
|
|
|
|
|
|
|
|
if (IPV4_ADDR_SAME(addr, dest))
|
2018-08-16 22:10:32 +02:00
|
|
|
flog_warn(
|
2018-09-13 21:21:05 +02:00
|
|
|
EC_ZEBRA_IFACE_SAME_LOCAL_AS_PEER,
|
2021-03-12 02:57:47 +01:00
|
|
|
"interface %s has same local and peer address %pI4, routing protocols may malfunction",
|
2020-10-21 19:57:06 +02:00
|
|
|
ifp->name, addr);
|
2004-10-19 21:44:43 +02:00
|
|
|
} else {
|
2018-08-16 22:10:32 +02:00
|
|
|
zlog_debug(
|
2021-03-12 02:57:47 +01:00
|
|
|
"%s called for interface %s with peer flag set, but no peer address supplied",
|
[PtP over ethernet] New peer flag allows much more addressing flexibility
2006-12-12 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* if.h: (struct connected) Add new ZEBRA_IFA_PEER flag indicating
whether a peer address has been configured. Comment now shows
the new interpretation of the destination addr: if ZEBRA_IFA_PEER
is set, then it must contain the destination address, otherwise
it may contain the broadcast address or be NULL.
(CONNECTED_DEST_HOST,CONNECTED_POINTOPOINT_HOST) Remove obsolete
macros that were specific to IPv4 and not fully general.
(CONNECTED_PEER) New macro to check ZEBRA_IFA_PEER flag.
(CONNECTED_PREFIX) New macro giving the prefix to insert into
the RIB: if CONNECTED_PEER, then use the destination (peer) address,
else use the address field.
(CONNECTED_ID) New macro to come up with an identifying address
for the struct connected.
* if.c: (if_lookup_address, connected_lookup_address) Streamline
logic with new CONNECTED_PREFIX macro.
* prefix.h: (PREFIX_COPY_IPV4, PREFIX_COPY_IPV6) New macros
for better performance than the general prefix_copy function.
* zclient.c: (zebra_interface_address_read) For non-null destination
addresses, set prefixlen to equal the address prefixlen. This
is needed to get the new CONNECTED_PREFIX macro to work properly.
* connected.c: (connected_up_ipv4, connected_down_ipv4,
connected_up_ipv6, connected_down_ipv6) Simplify logic using the
new CONNECTED_PREFIX macro.
(connected_add_ipv4) Set prefixlen in destination addresses (required
by the CONNECTED_PREFIX macro). Use CONNECTED_PEER macro instead
of testing for IFF_POINTOPOINT. Delete invalid warning message.
Warn about cases where the ZEBRA_IFA_PEER is set but no
destination address has been supplied (and turn off the flag).
(connected_add_ipv6) Add new flags argument so callers may set
the ZEBRA_IFA_PEER flag. If peer/broadcast address satisfies
IN6_IS_ADDR_UNSPECIFIED, then reject it with a warning.
Set prefixlen in destination address so CONNECTED_PREFIX will work.
* connected.h: (connected_add_ipv6) Add new flags argument so
callers may set the ZEBRA_IFA_PEER flag.
* interface.c: (connected_dump_vty) Use CONNECTED_PEER macro
to decide whether the destination address is a peer or broadcast
address (instead of checking IFF_BROADCAST and IFF_POINTOPOINT).
* if_ioctl.c: (if_getaddrs) Instead of setting a peer address
only when the IFF_POINTOPOINT is set, we now accept a peer
address whenever it is available and not the same as the local
address. Otherwise (no peer address assigned), we check
for a broadcast address (regardless of the IFF_BROADCAST flag).
And must now pass a flags value of ZEBRA_IFA_PEER to
connected_add_ipv4 when a peer address is assigned.
The same new logic is used with the IPv6 code as well (and we
pass the new flags argument to connected_add_ipv6).
(if_get_addr) Do not bother to check IFF_POINTOPOINT: just
issue the SIOCGIFDSTADDR ioctl and see if we get back
a peer address not matching the local address (and set
the ZEBRA_IFA_PEER in that case). If there's no peer address,
try to grab SIOCGIFBRDADDR regardless of whether IFF_BROADCAST is set.
* if_ioctl_solaris.c: (if_get_addr) Just try the SIOCGLIFDSTADDR ioctl
without bothering to check the IFF_POINTOPOINT flag. And if
no peer address was found, just try the SIOCGLIFBRDADDR ioctl
without checking the IFF_BROADCAST flag. Call connected_add_ipv4
and connected_add_ipv6 with appropriate flags.
* if_proc.c: (ifaddr_proc_ipv6) Must pass new flags argument to
connected_add_ipv6.
* kernel_socket.c: (ifam_read) Must pass new flags argument to
connected_add_ipv6.
* rt_netlink.c: (netlink_interface_addr) Copy logic from iproute2
to determine local and possible peer address (so there's no longer
a test for IFF_POINTOPOINT). Set ZEBRA_IFA_PEER flag appropriately.
Pass new flags argument to connected_add_ipv6.
(netlink_address) Test !CONNECTED_PEER instead of if_is_broadcast
to determine whether the connected destination address is a
broadcast address.
* bgp_nexthop.c: (bgp_connected_add, bgp_connected_delete)
Simplify logic by using new CONNECTED_PREFIX macro.
* ospf_interface.c: (ospf_if_is_configured, ospf_if_lookup_by_prefix,
ospf_if_lookup_recv_if) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_lsa.c: (lsa_link_ptop_set) Using the new CONNECTED_PREFIX
macro, both options collapse into the same code.
* ospf_snmp.c: (ospf_snmp_if_update) Simplify logic using new
CONNECTED_ID macro.
(ospf_snmp_is_if_have_addr) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_vty.c: (show_ip_ospf_interface_sub) Use new CONNECTED_PEER macro
instead of testing the IFF_POINTOPOINT flag.
* ospfd.c: (ospf_network_match_iface) Use new CONNECTED_PEER macro
instead of testing with if_is_pointopoint. And add commented-out
code to implement alternative (in my opinion) more elegant behavior
that has no special-case treatment for PtP addresses.
(ospf_network_run) Use new CONNECTED_ID macro to simplify logic.
* rip_interface.c: (rip_interface_multicast_set) Use new CONNECTED_ID
macro to simplify logic.
(rip_request_interface_send) Fix minor bug: ipv4_broadcast_addr does
not give a useful result if prefixlen is 32 (we require a peer
address in such cases).
* ripd.c: (rip_update_interface) Fix same bug as above.
2006-12-12 20:18:21 +01:00
|
|
|
__func__, ifp->name);
|
|
|
|
UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
[PtP over ethernet] New peer flag allows much more addressing flexibility
2006-12-12 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* if.h: (struct connected) Add new ZEBRA_IFA_PEER flag indicating
whether a peer address has been configured. Comment now shows
the new interpretation of the destination addr: if ZEBRA_IFA_PEER
is set, then it must contain the destination address, otherwise
it may contain the broadcast address or be NULL.
(CONNECTED_DEST_HOST,CONNECTED_POINTOPOINT_HOST) Remove obsolete
macros that were specific to IPv4 and not fully general.
(CONNECTED_PEER) New macro to check ZEBRA_IFA_PEER flag.
(CONNECTED_PREFIX) New macro giving the prefix to insert into
the RIB: if CONNECTED_PEER, then use the destination (peer) address,
else use the address field.
(CONNECTED_ID) New macro to come up with an identifying address
for the struct connected.
* if.c: (if_lookup_address, connected_lookup_address) Streamline
logic with new CONNECTED_PREFIX macro.
* prefix.h: (PREFIX_COPY_IPV4, PREFIX_COPY_IPV6) New macros
for better performance than the general prefix_copy function.
* zclient.c: (zebra_interface_address_read) For non-null destination
addresses, set prefixlen to equal the address prefixlen. This
is needed to get the new CONNECTED_PREFIX macro to work properly.
* connected.c: (connected_up_ipv4, connected_down_ipv4,
connected_up_ipv6, connected_down_ipv6) Simplify logic using the
new CONNECTED_PREFIX macro.
(connected_add_ipv4) Set prefixlen in destination addresses (required
by the CONNECTED_PREFIX macro). Use CONNECTED_PEER macro instead
of testing for IFF_POINTOPOINT. Delete invalid warning message.
Warn about cases where the ZEBRA_IFA_PEER is set but no
destination address has been supplied (and turn off the flag).
(connected_add_ipv6) Add new flags argument so callers may set
the ZEBRA_IFA_PEER flag. If peer/broadcast address satisfies
IN6_IS_ADDR_UNSPECIFIED, then reject it with a warning.
Set prefixlen in destination address so CONNECTED_PREFIX will work.
* connected.h: (connected_add_ipv6) Add new flags argument so
callers may set the ZEBRA_IFA_PEER flag.
* interface.c: (connected_dump_vty) Use CONNECTED_PEER macro
to decide whether the destination address is a peer or broadcast
address (instead of checking IFF_BROADCAST and IFF_POINTOPOINT).
* if_ioctl.c: (if_getaddrs) Instead of setting a peer address
only when the IFF_POINTOPOINT is set, we now accept a peer
address whenever it is available and not the same as the local
address. Otherwise (no peer address assigned), we check
for a broadcast address (regardless of the IFF_BROADCAST flag).
And must now pass a flags value of ZEBRA_IFA_PEER to
connected_add_ipv4 when a peer address is assigned.
The same new logic is used with the IPv6 code as well (and we
pass the new flags argument to connected_add_ipv6).
(if_get_addr) Do not bother to check IFF_POINTOPOINT: just
issue the SIOCGIFDSTADDR ioctl and see if we get back
a peer address not matching the local address (and set
the ZEBRA_IFA_PEER in that case). If there's no peer address,
try to grab SIOCGIFBRDADDR regardless of whether IFF_BROADCAST is set.
* if_ioctl_solaris.c: (if_get_addr) Just try the SIOCGLIFDSTADDR ioctl
without bothering to check the IFF_POINTOPOINT flag. And if
no peer address was found, just try the SIOCGLIFBRDADDR ioctl
without checking the IFF_BROADCAST flag. Call connected_add_ipv4
and connected_add_ipv6 with appropriate flags.
* if_proc.c: (ifaddr_proc_ipv6) Must pass new flags argument to
connected_add_ipv6.
* kernel_socket.c: (ifam_read) Must pass new flags argument to
connected_add_ipv6.
* rt_netlink.c: (netlink_interface_addr) Copy logic from iproute2
to determine local and possible peer address (so there's no longer
a test for IFF_POINTOPOINT). Set ZEBRA_IFA_PEER flag appropriately.
Pass new flags argument to connected_add_ipv6.
(netlink_address) Test !CONNECTED_PEER instead of if_is_broadcast
to determine whether the connected destination address is a
broadcast address.
* bgp_nexthop.c: (bgp_connected_add, bgp_connected_delete)
Simplify logic by using new CONNECTED_PREFIX macro.
* ospf_interface.c: (ospf_if_is_configured, ospf_if_lookup_by_prefix,
ospf_if_lookup_recv_if) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_lsa.c: (lsa_link_ptop_set) Using the new CONNECTED_PREFIX
macro, both options collapse into the same code.
* ospf_snmp.c: (ospf_snmp_if_update) Simplify logic using new
CONNECTED_ID macro.
(ospf_snmp_is_if_have_addr) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_vty.c: (show_ip_ospf_interface_sub) Use new CONNECTED_PEER macro
instead of testing the IFF_POINTOPOINT flag.
* ospfd.c: (ospf_network_match_iface) Use new CONNECTED_PEER macro
instead of testing with if_is_pointopoint. And add commented-out
code to implement alternative (in my opinion) more elegant behavior
that has no special-case treatment for PtP addresses.
(ospf_network_run) Use new CONNECTED_ID macro to simplify logic.
* rip_interface.c: (rip_interface_multicast_set) Use new CONNECTED_ID
macro to simplify logic.
(rip_request_interface_send) Fix minor bug: ipv4_broadcast_addr does
not give a useful result if prefixlen is 32 (we require a peer
address in such cases).
* ripd.c: (rip_update_interface) Fix same bug as above.
2006-12-12 20:18:21 +01:00
|
|
|
}
|
|
|
|
|
2019-08-10 11:52:03 +02:00
|
|
|
/* no destination address was supplied */
|
2021-07-01 16:42:03 +02:00
|
|
|
if (!dest && (prefixlen == IPV4_MAX_BITLEN) && if_is_pointopoint(ifp))
|
2019-08-10 11:52:03 +02:00
|
|
|
zlog_debug(
|
2021-03-12 02:57:47 +01:00
|
|
|
"PtP interface %s with addr %pI4/%d needs a peer address",
|
2020-10-21 19:57:06 +02:00
|
|
|
ifp->name, addr, prefixlen);
|
2019-08-10 11:52:03 +02:00
|
|
|
|
[PtP over ethernet] New peer flag allows much more addressing flexibility
2006-12-12 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* if.h: (struct connected) Add new ZEBRA_IFA_PEER flag indicating
whether a peer address has been configured. Comment now shows
the new interpretation of the destination addr: if ZEBRA_IFA_PEER
is set, then it must contain the destination address, otherwise
it may contain the broadcast address or be NULL.
(CONNECTED_DEST_HOST,CONNECTED_POINTOPOINT_HOST) Remove obsolete
macros that were specific to IPv4 and not fully general.
(CONNECTED_PEER) New macro to check ZEBRA_IFA_PEER flag.
(CONNECTED_PREFIX) New macro giving the prefix to insert into
the RIB: if CONNECTED_PEER, then use the destination (peer) address,
else use the address field.
(CONNECTED_ID) New macro to come up with an identifying address
for the struct connected.
* if.c: (if_lookup_address, connected_lookup_address) Streamline
logic with new CONNECTED_PREFIX macro.
* prefix.h: (PREFIX_COPY_IPV4, PREFIX_COPY_IPV6) New macros
for better performance than the general prefix_copy function.
* zclient.c: (zebra_interface_address_read) For non-null destination
addresses, set prefixlen to equal the address prefixlen. This
is needed to get the new CONNECTED_PREFIX macro to work properly.
* connected.c: (connected_up_ipv4, connected_down_ipv4,
connected_up_ipv6, connected_down_ipv6) Simplify logic using the
new CONNECTED_PREFIX macro.
(connected_add_ipv4) Set prefixlen in destination addresses (required
by the CONNECTED_PREFIX macro). Use CONNECTED_PEER macro instead
of testing for IFF_POINTOPOINT. Delete invalid warning message.
Warn about cases where the ZEBRA_IFA_PEER is set but no
destination address has been supplied (and turn off the flag).
(connected_add_ipv6) Add new flags argument so callers may set
the ZEBRA_IFA_PEER flag. If peer/broadcast address satisfies
IN6_IS_ADDR_UNSPECIFIED, then reject it with a warning.
Set prefixlen in destination address so CONNECTED_PREFIX will work.
* connected.h: (connected_add_ipv6) Add new flags argument so
callers may set the ZEBRA_IFA_PEER flag.
* interface.c: (connected_dump_vty) Use CONNECTED_PEER macro
to decide whether the destination address is a peer or broadcast
address (instead of checking IFF_BROADCAST and IFF_POINTOPOINT).
* if_ioctl.c: (if_getaddrs) Instead of setting a peer address
only when the IFF_POINTOPOINT is set, we now accept a peer
address whenever it is available and not the same as the local
address. Otherwise (no peer address assigned), we check
for a broadcast address (regardless of the IFF_BROADCAST flag).
And must now pass a flags value of ZEBRA_IFA_PEER to
connected_add_ipv4 when a peer address is assigned.
The same new logic is used with the IPv6 code as well (and we
pass the new flags argument to connected_add_ipv6).
(if_get_addr) Do not bother to check IFF_POINTOPOINT: just
issue the SIOCGIFDSTADDR ioctl and see if we get back
a peer address not matching the local address (and set
the ZEBRA_IFA_PEER in that case). If there's no peer address,
try to grab SIOCGIFBRDADDR regardless of whether IFF_BROADCAST is set.
* if_ioctl_solaris.c: (if_get_addr) Just try the SIOCGLIFDSTADDR ioctl
without bothering to check the IFF_POINTOPOINT flag. And if
no peer address was found, just try the SIOCGLIFBRDADDR ioctl
without checking the IFF_BROADCAST flag. Call connected_add_ipv4
and connected_add_ipv6 with appropriate flags.
* if_proc.c: (ifaddr_proc_ipv6) Must pass new flags argument to
connected_add_ipv6.
* kernel_socket.c: (ifam_read) Must pass new flags argument to
connected_add_ipv6.
* rt_netlink.c: (netlink_interface_addr) Copy logic from iproute2
to determine local and possible peer address (so there's no longer
a test for IFF_POINTOPOINT). Set ZEBRA_IFA_PEER flag appropriately.
Pass new flags argument to connected_add_ipv6.
(netlink_address) Test !CONNECTED_PEER instead of if_is_broadcast
to determine whether the connected destination address is a
broadcast address.
* bgp_nexthop.c: (bgp_connected_add, bgp_connected_delete)
Simplify logic by using new CONNECTED_PREFIX macro.
* ospf_interface.c: (ospf_if_is_configured, ospf_if_lookup_by_prefix,
ospf_if_lookup_recv_if) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_lsa.c: (lsa_link_ptop_set) Using the new CONNECTED_PREFIX
macro, both options collapse into the same code.
* ospf_snmp.c: (ospf_snmp_if_update) Simplify logic using new
CONNECTED_ID macro.
(ospf_snmp_is_if_have_addr) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_vty.c: (show_ip_ospf_interface_sub) Use new CONNECTED_PEER macro
instead of testing the IFF_POINTOPOINT flag.
* ospfd.c: (ospf_network_match_iface) Use new CONNECTED_PEER macro
instead of testing with if_is_pointopoint. And add commented-out
code to implement alternative (in my opinion) more elegant behavior
that has no special-case treatment for PtP addresses.
(ospf_network_run) Use new CONNECTED_ID macro to simplify logic.
* rip_interface.c: (rip_interface_multicast_set) Use new CONNECTED_ID
macro to simplify logic.
(rip_request_interface_send) Fix minor bug: ipv4_broadcast_addr does
not give a useful result if prefixlen is 32 (we require a peer
address in such cases).
* ripd.c: (rip_update_interface) Fix same bug as above.
2006-12-12 20:18:21 +01:00
|
|
|
/* Label of this address. */
|
|
|
|
if (label)
|
|
|
|
ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* For all that I know an IPv4 address is always ready when we receive
|
|
|
|
* the notification. So it should be safe to set the REAL flag here. */
|
2005-11-03 Paul Jakma <paul.jakma@sun.com>
* connected.{c,h}: Include memory.h
(connected_add_ipv4) Use MTYPE for ifc label.
(connected_add_ipv6) Also should accept label. Store it in ifp.
(connected_del_ipv4) Taking label as argument is pointless.
* rt_netlink.c: (netlink_interface_addr) update label usage
for connected_{add,delete} functions.
* if_ioctl.c: (if_getaddrs) NULL label for connected_add_ipv6.
* if_ioctl_solaris.c: (interface_list_ioctl) Pass LIFC_NOXMIT
so we also find out about NOXMIT interfaces like VNI.
Bit of hackery to turn interface names into the primary
interface name, later with routing socket messages we only
will about primary interfaces anyway, so we must normalise
the name.
(if_get_addr) take label as argument, so it can
be passed to connected_add.
If label is provided, then it is interface name to issue the
ioctl for address information on, not the ifp name.
(interface_list) List AF_UNSPEC too, just in case.
* if_proc.c: (ifaddr_proc_ipv6) label for connected_add_ipv6.
* interface.c: (if_addr_wakeup) Some very bogus code - sets
IFF_RUNNING - add comment.
(if_refresh)
(ip_address_install) Use MTYPE for ifc label.
* ioctl_solaris.c: (if_mangle_up) New function. Hackery to make
IFF_UP reflect whether any addresses are left on the
interface, as we get signalled for IFF_UP flags change on the
primary interface only. Logical interfaces dont generate
IFINFO, but we do get an RTM_DELADDR.
(if_get_flags) Call if_mangle_up before return.
* kernel_socket.c: (ifam_read) Fixup calls to
connected_{add,delete} to match above changes. Rename gate
variable to brd, less confusing.
Pass the interface name as a label, if it is not same name
as ifp->name.
2005-11-03 13:35:21 +01:00
|
|
|
SET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2013-01-24 15:04:46 +01:00
|
|
|
connected_update(ifp, ifc);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2017-08-31 19:47:26 +02:00
|
|
|
void connected_down(struct interface *ifp, struct connected *ifc)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2017-08-31 19:47:26 +02:00
|
|
|
afi_t afi;
|
*: Introduce Local Host Routes to FRR
Create Local routes in FRR:
S 0.0.0.0/0 [1/0] via 192.168.119.1, enp39s0, weight 1, 00:03:46
K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp39s0, 00:03:51
O 192.168.119.0/24 [110/100] is directly connected, enp39s0, weight 1, 00:03:46
C>* 192.168.119.0/24 is directly connected, enp39s0, 00:03:51
L>* 192.168.119.224/32 is directly connected, enp39s0, 00:03:51
O 192.168.119.229/32 [110/100] via 0.0.0.0, enp39s0 inactive, weight 1, 00:03:46
C>* 192.168.119.229/32 is directly connected, enp39s0, 00:03:46
Create ability to redistribute local routes.
Modify tests to support this change.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-01-05 00:32:43 +01:00
|
|
|
struct prefix p, plocal;
|
2017-08-28 01:30:16 +02:00
|
|
|
struct nexthop nh = {
|
2018-02-08 15:12:12 +01:00
|
|
|
.type = NEXTHOP_TYPE_IFINDEX,
|
|
|
|
.ifindex = ifp->ifindex,
|
2021-10-22 00:17:40 +02:00
|
|
|
.vrf_id = ifp->vrf->vrf_id,
|
2017-08-28 01:30:16 +02:00
|
|
|
};
|
2023-01-11 16:14:11 +01:00
|
|
|
struct zebra_vrf *zvrf;
|
|
|
|
uint32_t count = 0;
|
zebra: Allow one connected route per network mask on a interface
Currently FRR reads the kernel for interface state and FRR
creates a connected route per address on an interface. If
you are in a situation where you have multiple addresses
on an interface just create 1 connected route for them:
sharpd@eva:/tmp/topotests$ vtysh -c "show int dummy302"
Interface dummy302 is up, line protocol is up
Link ups: 0 last: (never)
Link downs: 0 last: (never)
vrf: default
index 3279 metric 0 mtu 1500 speed 0
flags: <UP,BROADCAST,RUNNING,NOARP>
Type: Ethernet
HWaddr: aa:4a:ed:95:9f:18
inet 10.4.1.1/24
inet 10.4.1.2/24 secondary
inet 10.4.1.3/24 secondary
inet 10.4.1.4/24 secondary
inet 10.4.1.5/24 secondary
inet6 fe80::a84a:edff:fe95:9f18/64
Interface Type Other
Interface Slave Type None
protodown: off
sharpd@eva:/tmp/topotests$ vtysh -c "show ip route connected"
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
C>* 10.4.1.0/24 is directly connected, dummy302, 00:10:03
C>* 192.168.161.0/24 is directly connected, enp39s0, 00:10:03
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2021-04-20 01:23:45 +02:00
|
|
|
struct connected *c;
|
*: Introduce Local Host Routes to FRR
Create Local routes in FRR:
S 0.0.0.0/0 [1/0] via 192.168.119.1, enp39s0, weight 1, 00:03:46
K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp39s0, 00:03:51
O 192.168.119.0/24 [110/100] is directly connected, enp39s0, weight 1, 00:03:46
C>* 192.168.119.0/24 is directly connected, enp39s0, 00:03:51
L>* 192.168.119.224/32 is directly connected, enp39s0, 00:03:51
O 192.168.119.229/32 [110/100] via 0.0.0.0, enp39s0 inactive, weight 1, 00:03:46
C>* 192.168.119.229/32 is directly connected, enp39s0, 00:03:46
Create ability to redistribute local routes.
Modify tests to support this change.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-01-05 00:32:43 +01:00
|
|
|
bool remove_local = true;
|
2019-05-06 16:41:40 +02:00
|
|
|
|
2021-10-22 00:17:40 +02:00
|
|
|
zvrf = ifp->vrf->info;
|
2019-05-06 16:41:40 +02:00
|
|
|
if (!zvrf) {
|
2020-03-05 19:17:54 +01:00
|
|
|
flog_err(
|
|
|
|
EC_ZEBRA_VRF_NOT_FOUND,
|
2021-10-22 00:17:40 +02:00
|
|
|
"%s: Received Down for interface but no associated zvrf: %s(%d)",
|
|
|
|
__func__, ifp->vrf->name, ifp->vrf->vrf_id);
|
2019-05-06 16:41:40 +02:00
|
|
|
return;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
|
|
|
|
return;
|
|
|
|
|
2021-05-11 21:57:39 +02:00
|
|
|
/* Skip if we've already done this; this can happen if we have a
|
|
|
|
* config change that takes an interface down, then we receive kernel
|
|
|
|
* notifications about the downed interface and its addresses.
|
|
|
|
*/
|
|
|
|
if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_DOWN)) {
|
|
|
|
if (IS_ZEBRA_DEBUG_RIB)
|
|
|
|
zlog_debug("%s: ifc %p, %pFX already DOWN",
|
|
|
|
__func__, ifc, ifc->address);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2021-06-02 19:03:52 +02:00
|
|
|
prefix_copy(&p, CONNECTED_PREFIX(ifc));
|
*: Introduce Local Host Routes to FRR
Create Local routes in FRR:
S 0.0.0.0/0 [1/0] via 192.168.119.1, enp39s0, weight 1, 00:03:46
K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp39s0, 00:03:51
O 192.168.119.0/24 [110/100] is directly connected, enp39s0, weight 1, 00:03:46
C>* 192.168.119.0/24 is directly connected, enp39s0, 00:03:51
L>* 192.168.119.224/32 is directly connected, enp39s0, 00:03:51
O 192.168.119.229/32 [110/100] via 0.0.0.0, enp39s0 inactive, weight 1, 00:03:46
C>* 192.168.119.229/32 is directly connected, enp39s0, 00:03:46
Create ability to redistribute local routes.
Modify tests to support this change.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-01-05 00:32:43 +01:00
|
|
|
prefix_copy(&plocal, ifc->address);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
|
|
|
/* Apply mask to the network. */
|
2016-08-24 07:39:08 +02:00
|
|
|
apply_mask(&p);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2017-08-31 19:47:26 +02:00
|
|
|
afi = family2afi(p.family);
|
|
|
|
|
|
|
|
switch (afi) {
|
|
|
|
case AFI_IP:
|
|
|
|
/*
|
|
|
|
* In case of connected address is 0.0.0.0/0 we treat it tunnel
|
|
|
|
* address.
|
|
|
|
*/
|
|
|
|
if (prefix_ipv4_any((struct prefix_ipv4 *)&p))
|
|
|
|
return;
|
*: Introduce Local Host Routes to FRR
Create Local routes in FRR:
S 0.0.0.0/0 [1/0] via 192.168.119.1, enp39s0, weight 1, 00:03:46
K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp39s0, 00:03:51
O 192.168.119.0/24 [110/100] is directly connected, enp39s0, weight 1, 00:03:46
C>* 192.168.119.0/24 is directly connected, enp39s0, 00:03:51
L>* 192.168.119.224/32 is directly connected, enp39s0, 00:03:51
O 192.168.119.229/32 [110/100] via 0.0.0.0, enp39s0 inactive, weight 1, 00:03:46
C>* 192.168.119.229/32 is directly connected, enp39s0, 00:03:46
Create ability to redistribute local routes.
Modify tests to support this change.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-01-05 00:32:43 +01:00
|
|
|
|
|
|
|
plocal.prefixlen = IPV4_MAX_BITLEN;
|
2017-08-31 19:47:26 +02:00
|
|
|
break;
|
|
|
|
case AFI_IP6:
|
|
|
|
if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6))
|
|
|
|
return;
|
*: Introduce Local Host Routes to FRR
Create Local routes in FRR:
S 0.0.0.0/0 [1/0] via 192.168.119.1, enp39s0, weight 1, 00:03:46
K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp39s0, 00:03:51
O 192.168.119.0/24 [110/100] is directly connected, enp39s0, weight 1, 00:03:46
C>* 192.168.119.0/24 is directly connected, enp39s0, 00:03:51
L>* 192.168.119.224/32 is directly connected, enp39s0, 00:03:51
O 192.168.119.229/32 [110/100] via 0.0.0.0, enp39s0 inactive, weight 1, 00:03:46
C>* 192.168.119.229/32 is directly connected, enp39s0, 00:03:46
Create ability to redistribute local routes.
Modify tests to support this change.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-01-05 00:32:43 +01:00
|
|
|
|
|
|
|
plocal.prefixlen = IPV6_MAX_BITLEN;
|
|
|
|
|
|
|
|
if (IN6_IS_ADDR_LINKLOCAL(&plocal.u.prefix6))
|
|
|
|
remove_local = false;
|
|
|
|
|
2017-08-31 19:47:26 +02:00
|
|
|
break;
|
2023-01-30 16:05:58 +01:00
|
|
|
case AFI_UNSPEC:
|
|
|
|
case AFI_L2VPN:
|
|
|
|
case AFI_MAX:
|
2019-08-23 14:28:43 +02:00
|
|
|
zlog_warn("Unknown AFI: %s", afi2str(afi));
|
2017-08-31 19:47:26 +02:00
|
|
|
break;
|
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
|
2021-05-11 21:57:39 +02:00
|
|
|
/* Mark the address as 'down' */
|
|
|
|
SET_FLAG(ifc->conf, ZEBRA_IFC_DOWN);
|
|
|
|
|
zebra: Allow one connected route per network mask on a interface
Currently FRR reads the kernel for interface state and FRR
creates a connected route per address on an interface. If
you are in a situation where you have multiple addresses
on an interface just create 1 connected route for them:
sharpd@eva:/tmp/topotests$ vtysh -c "show int dummy302"
Interface dummy302 is up, line protocol is up
Link ups: 0 last: (never)
Link downs: 0 last: (never)
vrf: default
index 3279 metric 0 mtu 1500 speed 0
flags: <UP,BROADCAST,RUNNING,NOARP>
Type: Ethernet
HWaddr: aa:4a:ed:95:9f:18
inet 10.4.1.1/24
inet 10.4.1.2/24 secondary
inet 10.4.1.3/24 secondary
inet 10.4.1.4/24 secondary
inet 10.4.1.5/24 secondary
inet6 fe80::a84a:edff:fe95:9f18/64
Interface Type Other
Interface Slave Type None
protodown: off
sharpd@eva:/tmp/topotests$ vtysh -c "show ip route connected"
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
C>* 10.4.1.0/24 is directly connected, dummy302, 00:10:03
C>* 192.168.161.0/24 is directly connected, enp39s0, 00:10:03
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2021-04-20 01:23:45 +02:00
|
|
|
/*
|
|
|
|
* It's possible to have X number of addresses
|
|
|
|
* on a interface that all resolve to the same
|
|
|
|
* network and mask. Find them and just
|
|
|
|
* allow the deletion when are removing the last
|
|
|
|
* one.
|
|
|
|
*/
|
2023-11-22 19:05:41 +01:00
|
|
|
frr_each (if_connected, ifp->connected, c) {
|
zebra: Allow one connected route per network mask on a interface
Currently FRR reads the kernel for interface state and FRR
creates a connected route per address on an interface. If
you are in a situation where you have multiple addresses
on an interface just create 1 connected route for them:
sharpd@eva:/tmp/topotests$ vtysh -c "show int dummy302"
Interface dummy302 is up, line protocol is up
Link ups: 0 last: (never)
Link downs: 0 last: (never)
vrf: default
index 3279 metric 0 mtu 1500 speed 0
flags: <UP,BROADCAST,RUNNING,NOARP>
Type: Ethernet
HWaddr: aa:4a:ed:95:9f:18
inet 10.4.1.1/24
inet 10.4.1.2/24 secondary
inet 10.4.1.3/24 secondary
inet 10.4.1.4/24 secondary
inet 10.4.1.5/24 secondary
inet6 fe80::a84a:edff:fe95:9f18/64
Interface Type Other
Interface Slave Type None
protodown: off
sharpd@eva:/tmp/topotests$ vtysh -c "show ip route connected"
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
C>* 10.4.1.0/24 is directly connected, dummy302, 00:10:03
C>* 192.168.161.0/24 is directly connected, enp39s0, 00:10:03
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2021-04-20 01:23:45 +02:00
|
|
|
struct prefix cp;
|
|
|
|
|
2021-06-02 19:03:52 +02:00
|
|
|
prefix_copy(&cp, CONNECTED_PREFIX(c));
|
zebra: Allow one connected route per network mask on a interface
Currently FRR reads the kernel for interface state and FRR
creates a connected route per address on an interface. If
you are in a situation where you have multiple addresses
on an interface just create 1 connected route for them:
sharpd@eva:/tmp/topotests$ vtysh -c "show int dummy302"
Interface dummy302 is up, line protocol is up
Link ups: 0 last: (never)
Link downs: 0 last: (never)
vrf: default
index 3279 metric 0 mtu 1500 speed 0
flags: <UP,BROADCAST,RUNNING,NOARP>
Type: Ethernet
HWaddr: aa:4a:ed:95:9f:18
inet 10.4.1.1/24
inet 10.4.1.2/24 secondary
inet 10.4.1.3/24 secondary
inet 10.4.1.4/24 secondary
inet 10.4.1.5/24 secondary
inet6 fe80::a84a:edff:fe95:9f18/64
Interface Type Other
Interface Slave Type None
protodown: off
sharpd@eva:/tmp/topotests$ vtysh -c "show ip route connected"
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
C>* 10.4.1.0/24 is directly connected, dummy302, 00:10:03
C>* 192.168.161.0/24 is directly connected, enp39s0, 00:10:03
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2021-04-20 01:23:45 +02:00
|
|
|
apply_mask(&cp);
|
|
|
|
|
2023-01-11 16:14:11 +01:00
|
|
|
if (prefix_same(&p, &cp) &&
|
|
|
|
!CHECK_FLAG(c->conf, ZEBRA_IFC_DOWN))
|
|
|
|
count++;
|
zebra: Allow one connected route per network mask on a interface
Currently FRR reads the kernel for interface state and FRR
creates a connected route per address on an interface. If
you are in a situation where you have multiple addresses
on an interface just create 1 connected route for them:
sharpd@eva:/tmp/topotests$ vtysh -c "show int dummy302"
Interface dummy302 is up, line protocol is up
Link ups: 0 last: (never)
Link downs: 0 last: (never)
vrf: default
index 3279 metric 0 mtu 1500 speed 0
flags: <UP,BROADCAST,RUNNING,NOARP>
Type: Ethernet
HWaddr: aa:4a:ed:95:9f:18
inet 10.4.1.1/24
inet 10.4.1.2/24 secondary
inet 10.4.1.3/24 secondary
inet 10.4.1.4/24 secondary
inet 10.4.1.5/24 secondary
inet6 fe80::a84a:edff:fe95:9f18/64
Interface Type Other
Interface Slave Type None
protodown: off
sharpd@eva:/tmp/topotests$ vtysh -c "show ip route connected"
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
C>* 10.4.1.0/24 is directly connected, dummy302, 00:10:03
C>* 192.168.161.0/24 is directly connected, enp39s0, 00:10:03
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2021-04-20 01:23:45 +02:00
|
|
|
|
2023-01-11 16:14:11 +01:00
|
|
|
if (count >= 1)
|
zebra: Allow one connected route per network mask on a interface
Currently FRR reads the kernel for interface state and FRR
creates a connected route per address on an interface. If
you are in a situation where you have multiple addresses
on an interface just create 1 connected route for them:
sharpd@eva:/tmp/topotests$ vtysh -c "show int dummy302"
Interface dummy302 is up, line protocol is up
Link ups: 0 last: (never)
Link downs: 0 last: (never)
vrf: default
index 3279 metric 0 mtu 1500 speed 0
flags: <UP,BROADCAST,RUNNING,NOARP>
Type: Ethernet
HWaddr: aa:4a:ed:95:9f:18
inet 10.4.1.1/24
inet 10.4.1.2/24 secondary
inet 10.4.1.3/24 secondary
inet 10.4.1.4/24 secondary
inet 10.4.1.5/24 secondary
inet6 fe80::a84a:edff:fe95:9f18/64
Interface Type Other
Interface Slave Type None
protodown: off
sharpd@eva:/tmp/topotests$ vtysh -c "show ip route connected"
Codes: K - kernel route, C - connected, S - static, R - RIP,
O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
C>* 10.4.1.0/24 is directly connected, dummy302, 00:10:03
C>* 192.168.161.0/24 is directly connected, enp39s0, 00:10:03
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2021-04-20 01:23:45 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-08-31 19:47:26 +02:00
|
|
|
/*
|
|
|
|
* Same logic as for connected_up(): push the changes into the
|
|
|
|
* head.
|
|
|
|
*/
|
zebra: Add connected with noprefixroute
Add ability for the connected routes to know
if they are a prefix route or not.
sharpd@eva:/work/home/sharpd/frr1$ ip addr show dev dummy1
13: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
link/ether aa:93:ce:ce:3f:62 brd ff:ff:ff:ff:ff:ff
inet 192.168.55.1/24 scope global noprefixroute dummy1
valid_lft forever preferred_lft forever
inet 192.168.56.1/24 scope global dummy1
valid_lft forever preferred_lft forever
inet6 fe80::a893:ceff:fece:3f62/64 scope link
valid_lft forever preferred_lft forever
sharpd@eva:/work/home/sharpd/frr1$ sudo vtysh -c "show int dummy1"
Interface dummy1 is up, line protocol is up
Link ups: 0 last: (never)
Link downs: 0 last: (never)
vrf: default
index 13 metric 0 mtu 1500 speed 0 txqlen 1000
flags: <UP,BROADCAST,RUNNING,NOARP>
Type: Ethernet
HWaddr: aa:93:ce:ce:3f:62
inet 192.168.55.1/24 noprefixroute
inet 192.168.56.1/24
inet6 fe80::a893:ceff:fece:3f62/64
Interface Type Other
Interface Slave Type None
protodown: off
sharpd@eva:/work/home/sharpd/frr1$ sudo vtysh -c "show ip route"
Codes: K - kernel route, C - connected, L - local, S - static,
R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric, t - Table-Direct,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp13s0, 00:00:08
K>* 169.254.0.0/16 [0/1000] is directly connected, virbr2 linkdown, 00:00:08
L>* 192.168.44.1/32 is directly connected, dummy2, 00:00:08
L>* 192.168.55.1/32 is directly connected, dummy1, 00:00:08
C>* 192.168.56.0/24 is directly connected, dummy1, 00:00:08
L>* 192.168.56.1/32 is directly connected, dummy1, 00:00:08
L>* 192.168.119.205/32 is directly connected, enp13s0, 00:00:08
sharpd@eva:/work/home/sharpd/frr1$ ip route show
default via 192.168.119.1 dev enp13s0 proto dhcp metric 100
169.254.0.0/16 dev virbr2 scope link metric 1000 linkdown
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
192.168.45.0/24 dev virbr2 proto kernel scope link src 192.168.45.1 linkdown
192.168.56.0/24 dev dummy1 proto kernel scope link src 192.168.56.1
192.168.119.0/24 dev enp13s0 proto kernel scope link src 192.168.119.205 metric 100
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
sharpd@eva:/work/home/sharpd/frr1$ ip route show table 255
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
local 172.17.0.1 dev docker0 proto kernel scope host src 172.17.0.1
broadcast 172.17.255.255 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
local 192.168.44.1 dev dummy2 proto kernel scope host src 192.168.44.1
broadcast 192.168.44.255 dev dummy2 proto kernel scope link src 192.168.44.1
local 192.168.45.1 dev virbr2 proto kernel scope host src 192.168.45.1
broadcast 192.168.45.255 dev virbr2 proto kernel scope link src 192.168.45.1 linkdown
local 192.168.55.1 dev dummy1 proto kernel scope host src 192.168.55.1
broadcast 192.168.55.255 dev dummy1 proto kernel scope link src 192.168.55.1
local 192.168.56.1 dev dummy1 proto kernel scope host src 192.168.56.1
broadcast 192.168.56.255 dev dummy1 proto kernel scope link src 192.168.56.1
local 192.168.119.205 dev enp13s0 proto kernel scope host src 192.168.119.205
broadcast 192.168.119.255 dev enp13s0 proto kernel scope link src 192.168.119.205
local 192.168.122.1 dev virbr0 proto kernel scope host src 192.168.122.1
broadcast 192.168.122.255 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
Fixes: #14952
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-12-06 14:33:31 +01:00
|
|
|
if (!CHECK_FLAG(ifc->flags, ZEBRA_IFA_NOPREFIXROUTE)) {
|
|
|
|
rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id,
|
|
|
|
ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, &nh, 0,
|
|
|
|
zvrf->table_id, 0, 0, false);
|
2002-12-13 21:15:29 +01:00
|
|
|
|
zebra: Add connected with noprefixroute
Add ability for the connected routes to know
if they are a prefix route or not.
sharpd@eva:/work/home/sharpd/frr1$ ip addr show dev dummy1
13: dummy1: <BROADCAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000
link/ether aa:93:ce:ce:3f:62 brd ff:ff:ff:ff:ff:ff
inet 192.168.55.1/24 scope global noprefixroute dummy1
valid_lft forever preferred_lft forever
inet 192.168.56.1/24 scope global dummy1
valid_lft forever preferred_lft forever
inet6 fe80::a893:ceff:fece:3f62/64 scope link
valid_lft forever preferred_lft forever
sharpd@eva:/work/home/sharpd/frr1$ sudo vtysh -c "show int dummy1"
Interface dummy1 is up, line protocol is up
Link ups: 0 last: (never)
Link downs: 0 last: (never)
vrf: default
index 13 metric 0 mtu 1500 speed 0 txqlen 1000
flags: <UP,BROADCAST,RUNNING,NOARP>
Type: Ethernet
HWaddr: aa:93:ce:ce:3f:62
inet 192.168.55.1/24 noprefixroute
inet 192.168.56.1/24
inet6 fe80::a893:ceff:fece:3f62/64
Interface Type Other
Interface Slave Type None
protodown: off
sharpd@eva:/work/home/sharpd/frr1$ sudo vtysh -c "show ip route"
Codes: K - kernel route, C - connected, L - local, S - static,
R - RIP, O - OSPF, I - IS-IS, B - BGP, E - EIGRP, N - NHRP,
T - Table, v - VNC, V - VNC-Direct, A - Babel, D - SHARP,
F - PBR, f - OpenFabric, t - Table-Direct,
> - selected route, * - FIB route, q - queued, r - rejected, b - backup
t - trapped, o - offload failure
K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp13s0, 00:00:08
K>* 169.254.0.0/16 [0/1000] is directly connected, virbr2 linkdown, 00:00:08
L>* 192.168.44.1/32 is directly connected, dummy2, 00:00:08
L>* 192.168.55.1/32 is directly connected, dummy1, 00:00:08
C>* 192.168.56.0/24 is directly connected, dummy1, 00:00:08
L>* 192.168.56.1/32 is directly connected, dummy1, 00:00:08
L>* 192.168.119.205/32 is directly connected, enp13s0, 00:00:08
sharpd@eva:/work/home/sharpd/frr1$ ip route show
default via 192.168.119.1 dev enp13s0 proto dhcp metric 100
169.254.0.0/16 dev virbr2 scope link metric 1000 linkdown
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
192.168.45.0/24 dev virbr2 proto kernel scope link src 192.168.45.1 linkdown
192.168.56.0/24 dev dummy1 proto kernel scope link src 192.168.56.1
192.168.119.0/24 dev enp13s0 proto kernel scope link src 192.168.119.205 metric 100
192.168.122.0/24 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
sharpd@eva:/work/home/sharpd/frr1$ ip route show table 255
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
local 172.17.0.1 dev docker0 proto kernel scope host src 172.17.0.1
broadcast 172.17.255.255 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
local 192.168.44.1 dev dummy2 proto kernel scope host src 192.168.44.1
broadcast 192.168.44.255 dev dummy2 proto kernel scope link src 192.168.44.1
local 192.168.45.1 dev virbr2 proto kernel scope host src 192.168.45.1
broadcast 192.168.45.255 dev virbr2 proto kernel scope link src 192.168.45.1 linkdown
local 192.168.55.1 dev dummy1 proto kernel scope host src 192.168.55.1
broadcast 192.168.55.255 dev dummy1 proto kernel scope link src 192.168.55.1
local 192.168.56.1 dev dummy1 proto kernel scope host src 192.168.56.1
broadcast 192.168.56.255 dev dummy1 proto kernel scope link src 192.168.56.1
local 192.168.119.205 dev enp13s0 proto kernel scope host src 192.168.119.205
broadcast 192.168.119.255 dev enp13s0 proto kernel scope link src 192.168.119.205
local 192.168.122.1 dev virbr0 proto kernel scope host src 192.168.122.1
broadcast 192.168.122.255 dev virbr0 proto kernel scope link src 192.168.122.1 linkdown
Fixes: #14952
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-12-06 14:33:31 +01:00
|
|
|
rib_delete(afi, SAFI_MULTICAST, zvrf->vrf->vrf_id,
|
|
|
|
ZEBRA_ROUTE_CONNECT, 0, 0, &p, NULL, &nh, 0,
|
|
|
|
zvrf->table_id, 0, 0, false);
|
|
|
|
}
|
2012-04-02 20:01:29 +02:00
|
|
|
|
*: Introduce Local Host Routes to FRR
Create Local routes in FRR:
S 0.0.0.0/0 [1/0] via 192.168.119.1, enp39s0, weight 1, 00:03:46
K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp39s0, 00:03:51
O 192.168.119.0/24 [110/100] is directly connected, enp39s0, weight 1, 00:03:46
C>* 192.168.119.0/24 is directly connected, enp39s0, 00:03:51
L>* 192.168.119.224/32 is directly connected, enp39s0, 00:03:51
O 192.168.119.229/32 [110/100] via 0.0.0.0, enp39s0 inactive, weight 1, 00:03:46
C>* 192.168.119.229/32 is directly connected, enp39s0, 00:03:46
Create ability to redistribute local routes.
Modify tests to support this change.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-01-05 00:32:43 +01:00
|
|
|
if (remove_local) {
|
|
|
|
rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id,
|
|
|
|
ZEBRA_ROUTE_LOCAL, 0, 0, &plocal, NULL, &nh, 0,
|
|
|
|
zvrf->table_id, 0, 0, false);
|
|
|
|
|
|
|
|
rib_delete(afi, SAFI_MULTICAST, zvrf->vrf->vrf_id,
|
|
|
|
ZEBRA_ROUTE_LOCAL, 0, 0, &plocal, NULL, &nh, 0,
|
|
|
|
zvrf->table_id, 0, 0, false);
|
|
|
|
}
|
|
|
|
|
2016-04-16 04:19:37 +02:00
|
|
|
/* Schedule LSP forwarding entries for processing, if appropriate. */
|
2019-05-06 16:41:40 +02:00
|
|
|
if (zvrf->vrf->vrf_id == VRF_DEFAULT) {
|
2020-10-18 13:33:54 +02:00
|
|
|
if (IS_ZEBRA_DEBUG_MPLS)
|
2017-08-31 19:35:53 +02:00
|
|
|
zlog_debug(
|
2020-10-18 13:33:54 +02:00
|
|
|
"%u: IF %s IP %pFX address down, scheduling MPLS processing",
|
|
|
|
zvrf->vrf->vrf_id, ifp->name, &p);
|
2019-05-06 16:41:40 +02:00
|
|
|
mpls_mark_lsps_for_processing(zvrf, &p);
|
2016-04-16 04:19:37 +02:00
|
|
|
}
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2017-08-31 00:34:48 +02:00
|
|
|
static void connected_delete_helper(struct connected *ifc, struct prefix *p)
|
|
|
|
{
|
|
|
|
struct interface *ifp;
|
|
|
|
|
|
|
|
if (!ifc)
|
|
|
|
return;
|
|
|
|
ifp = ifc->ifp;
|
|
|
|
|
|
|
|
connected_withdraw(ifc);
|
|
|
|
|
|
|
|
/* Schedule LSP forwarding entries for processing, if appropriate. */
|
2021-10-22 00:17:40 +02:00
|
|
|
if (ifp->vrf->vrf_id == VRF_DEFAULT) {
|
2020-10-18 13:33:54 +02:00
|
|
|
if (IS_ZEBRA_DEBUG_MPLS)
|
2017-08-31 19:35:53 +02:00
|
|
|
zlog_debug(
|
2020-10-18 13:33:54 +02:00
|
|
|
"%u: IF %s IP %pFX address delete, scheduling MPLS processing",
|
2021-10-22 00:17:40 +02:00
|
|
|
ifp->vrf->vrf_id, ifp->name, p);
|
|
|
|
mpls_mark_lsps_for_processing(ifp->vrf->info, p);
|
2017-08-31 00:34:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Delete connected IPv4 route to the interface. */
|
|
|
|
void connected_delete_ipv4(struct interface *ifp, int flags,
|
2021-07-08 16:10:14 +02:00
|
|
|
const struct in_addr *addr, uint16_t prefixlen,
|
|
|
|
const struct in_addr *dest)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2017-08-31 00:34:48 +02:00
|
|
|
struct prefix p, d;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct connected *ifc;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&p, 0, sizeof(p));
|
2002-12-13 21:15:29 +01:00
|
|
|
p.family = AF_INET;
|
2017-08-31 00:34:48 +02:00
|
|
|
p.u.prefix4 = *addr;
|
2021-07-01 16:42:03 +02:00
|
|
|
p.prefixlen =
|
|
|
|
CHECK_FLAG(flags, ZEBRA_IFA_PEER) ? IPV4_MAX_BITLEN : prefixlen;
|
2010-01-30 12:10:23 +01:00
|
|
|
|
2019-08-10 11:52:03 +02:00
|
|
|
if (dest) {
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&d, 0, sizeof(d));
|
2010-01-30 12:10:23 +01:00
|
|
|
d.family = AF_INET;
|
2019-08-10 11:52:03 +02:00
|
|
|
d.u.prefix4 = *dest;
|
2010-01-30 12:10:23 +01:00
|
|
|
d.prefixlen = prefixlen;
|
2017-08-31 00:34:48 +02:00
|
|
|
ifc = connected_check_ptp(ifp, &p, &d);
|
2010-01-30 12:10:23 +01:00
|
|
|
} else
|
2017-08-31 00:34:48 +02:00
|
|
|
ifc = connected_check_ptp(ifp, &p, NULL);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-08-31 00:34:48 +02:00
|
|
|
connected_delete_helper(ifc, &p);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Add connected IPv6 route to the interface. */
|
2021-07-08 16:10:14 +02:00
|
|
|
void connected_add_ipv6(struct interface *ifp, int flags,
|
|
|
|
const struct in6_addr *addr,
|
|
|
|
const struct in6_addr *dest, uint16_t prefixlen,
|
zebra: set connected route metric based on the devaddr metric
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>
2019-01-15 00:45:33 +01:00
|
|
|
const char *label, uint32_t metric)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
|
|
|
struct prefix_ipv6 *p;
|
|
|
|
struct connected *ifc;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-05-20 02:47:23 +02:00
|
|
|
if (ipv6_martian(addr))
|
|
|
|
return;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Make connected structure. */
|
|
|
|
ifc = connected_new();
|
|
|
|
ifc->ifp = ifp;
|
[PtP over ethernet] New peer flag allows much more addressing flexibility
2006-12-12 Andrew J. Schorr <ajschorr@alumni.princeton.edu>
* if.h: (struct connected) Add new ZEBRA_IFA_PEER flag indicating
whether a peer address has been configured. Comment now shows
the new interpretation of the destination addr: if ZEBRA_IFA_PEER
is set, then it must contain the destination address, otherwise
it may contain the broadcast address or be NULL.
(CONNECTED_DEST_HOST,CONNECTED_POINTOPOINT_HOST) Remove obsolete
macros that were specific to IPv4 and not fully general.
(CONNECTED_PEER) New macro to check ZEBRA_IFA_PEER flag.
(CONNECTED_PREFIX) New macro giving the prefix to insert into
the RIB: if CONNECTED_PEER, then use the destination (peer) address,
else use the address field.
(CONNECTED_ID) New macro to come up with an identifying address
for the struct connected.
* if.c: (if_lookup_address, connected_lookup_address) Streamline
logic with new CONNECTED_PREFIX macro.
* prefix.h: (PREFIX_COPY_IPV4, PREFIX_COPY_IPV6) New macros
for better performance than the general prefix_copy function.
* zclient.c: (zebra_interface_address_read) For non-null destination
addresses, set prefixlen to equal the address prefixlen. This
is needed to get the new CONNECTED_PREFIX macro to work properly.
* connected.c: (connected_up_ipv4, connected_down_ipv4,
connected_up_ipv6, connected_down_ipv6) Simplify logic using the
new CONNECTED_PREFIX macro.
(connected_add_ipv4) Set prefixlen in destination addresses (required
by the CONNECTED_PREFIX macro). Use CONNECTED_PEER macro instead
of testing for IFF_POINTOPOINT. Delete invalid warning message.
Warn about cases where the ZEBRA_IFA_PEER is set but no
destination address has been supplied (and turn off the flag).
(connected_add_ipv6) Add new flags argument so callers may set
the ZEBRA_IFA_PEER flag. If peer/broadcast address satisfies
IN6_IS_ADDR_UNSPECIFIED, then reject it with a warning.
Set prefixlen in destination address so CONNECTED_PREFIX will work.
* connected.h: (connected_add_ipv6) Add new flags argument so
callers may set the ZEBRA_IFA_PEER flag.
* interface.c: (connected_dump_vty) Use CONNECTED_PEER macro
to decide whether the destination address is a peer or broadcast
address (instead of checking IFF_BROADCAST and IFF_POINTOPOINT).
* if_ioctl.c: (if_getaddrs) Instead of setting a peer address
only when the IFF_POINTOPOINT is set, we now accept a peer
address whenever it is available and not the same as the local
address. Otherwise (no peer address assigned), we check
for a broadcast address (regardless of the IFF_BROADCAST flag).
And must now pass a flags value of ZEBRA_IFA_PEER to
connected_add_ipv4 when a peer address is assigned.
The same new logic is used with the IPv6 code as well (and we
pass the new flags argument to connected_add_ipv6).
(if_get_addr) Do not bother to check IFF_POINTOPOINT: just
issue the SIOCGIFDSTADDR ioctl and see if we get back
a peer address not matching the local address (and set
the ZEBRA_IFA_PEER in that case). If there's no peer address,
try to grab SIOCGIFBRDADDR regardless of whether IFF_BROADCAST is set.
* if_ioctl_solaris.c: (if_get_addr) Just try the SIOCGLIFDSTADDR ioctl
without bothering to check the IFF_POINTOPOINT flag. And if
no peer address was found, just try the SIOCGLIFBRDADDR ioctl
without checking the IFF_BROADCAST flag. Call connected_add_ipv4
and connected_add_ipv6 with appropriate flags.
* if_proc.c: (ifaddr_proc_ipv6) Must pass new flags argument to
connected_add_ipv6.
* kernel_socket.c: (ifam_read) Must pass new flags argument to
connected_add_ipv6.
* rt_netlink.c: (netlink_interface_addr) Copy logic from iproute2
to determine local and possible peer address (so there's no longer
a test for IFF_POINTOPOINT). Set ZEBRA_IFA_PEER flag appropriately.
Pass new flags argument to connected_add_ipv6.
(netlink_address) Test !CONNECTED_PEER instead of if_is_broadcast
to determine whether the connected destination address is a
broadcast address.
* bgp_nexthop.c: (bgp_connected_add, bgp_connected_delete)
Simplify logic by using new CONNECTED_PREFIX macro.
* ospf_interface.c: (ospf_if_is_configured, ospf_if_lookup_by_prefix,
ospf_if_lookup_recv_if) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_lsa.c: (lsa_link_ptop_set) Using the new CONNECTED_PREFIX
macro, both options collapse into the same code.
* ospf_snmp.c: (ospf_snmp_if_update) Simplify logic using new
CONNECTED_ID macro.
(ospf_snmp_is_if_have_addr) Simplify logic using new CONNECTED_PREFIX
macro.
* ospf_vty.c: (show_ip_ospf_interface_sub) Use new CONNECTED_PEER macro
instead of testing the IFF_POINTOPOINT flag.
* ospfd.c: (ospf_network_match_iface) Use new CONNECTED_PEER macro
instead of testing with if_is_pointopoint. And add commented-out
code to implement alternative (in my opinion) more elegant behavior
that has no special-case treatment for PtP addresses.
(ospf_network_run) Use new CONNECTED_ID macro to simplify logic.
* rip_interface.c: (rip_interface_multicast_set) Use new CONNECTED_ID
macro to simplify logic.
(rip_request_interface_send) Fix minor bug: ipv4_broadcast_addr does
not give a useful result if prefixlen is 32 (we require a peer
address in such cases).
* ripd.c: (rip_update_interface) Fix same bug as above.
2006-12-12 20:18:21 +01:00
|
|
|
ifc->flags = flags;
|
zebra: set connected route metric based on the devaddr metric
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>
2019-01-15 00:45:33 +01:00
|
|
|
ifc->metric = metric;
|
2013-01-24 15:04:48 +01:00
|
|
|
/* If we get a notification from the kernel,
|
|
|
|
* we can safely assume the address is known to the kernel */
|
|
|
|
SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
|
2022-04-11 05:58:14 +02:00
|
|
|
if (!if_is_operative(ifp))
|
|
|
|
SET_FLAG(ifc->conf, ZEBRA_IFC_DOWN);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2002-12-13 21:15:29 +01:00
|
|
|
/* Allocate new connected address. */
|
|
|
|
p = prefix_ipv6_new();
|
|
|
|
p->family = AF_INET6;
|
|
|
|
IPV6_ADDR_COPY(&p->prefix, addr);
|
|
|
|
p->prefixlen = prefixlen;
|
|
|
|
ifc->address = (struct prefix *)p;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-02-10 19:58:41 +01:00
|
|
|
/* Add global ipv6 address to the RA prefix list */
|
|
|
|
if (!IN6_IS_ADDR_LINKLOCAL(&p->prefix))
|
|
|
|
rtadv_add_prefix(ifp->info, p);
|
|
|
|
|
2019-08-10 11:52:03 +02:00
|
|
|
if (dest) {
|
2018-04-15 16:57:19 +02:00
|
|
|
p = prefix_ipv6_new();
|
|
|
|
p->family = AF_INET6;
|
2019-08-10 11:52:03 +02:00
|
|
|
IPV6_ADDR_COPY(&p->prefix, dest);
|
2018-04-15 16:57:19 +02:00
|
|
|
p->prefixlen = prefixlen;
|
|
|
|
ifc->destination = (struct prefix *)p;
|
2018-04-16 17:17:52 +02:00
|
|
|
} else {
|
|
|
|
if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
|
2018-08-16 22:10:32 +02:00
|
|
|
zlog_debug(
|
2021-03-12 02:57:47 +01:00
|
|
|
"%s called for interface %s with peer flag set, but no peer address supplied",
|
2018-08-16 22:10:32 +02:00
|
|
|
__func__, ifp->name);
|
2018-04-16 17:17:52 +02:00
|
|
|
UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
|
|
|
|
}
|
2018-04-15 16:57:19 +02:00
|
|
|
}
|
|
|
|
|
2005-11-03 Paul Jakma <paul.jakma@sun.com>
* connected.{c,h}: Include memory.h
(connected_add_ipv4) Use MTYPE for ifc label.
(connected_add_ipv6) Also should accept label. Store it in ifp.
(connected_del_ipv4) Taking label as argument is pointless.
* rt_netlink.c: (netlink_interface_addr) update label usage
for connected_{add,delete} functions.
* if_ioctl.c: (if_getaddrs) NULL label for connected_add_ipv6.
* if_ioctl_solaris.c: (interface_list_ioctl) Pass LIFC_NOXMIT
so we also find out about NOXMIT interfaces like VNI.
Bit of hackery to turn interface names into the primary
interface name, later with routing socket messages we only
will about primary interfaces anyway, so we must normalise
the name.
(if_get_addr) take label as argument, so it can
be passed to connected_add.
If label is provided, then it is interface name to issue the
ioctl for address information on, not the ifp name.
(interface_list) List AF_UNSPEC too, just in case.
* if_proc.c: (ifaddr_proc_ipv6) label for connected_add_ipv6.
* interface.c: (if_addr_wakeup) Some very bogus code - sets
IFF_RUNNING - add comment.
(if_refresh)
(ip_address_install) Use MTYPE for ifc label.
* ioctl_solaris.c: (if_mangle_up) New function. Hackery to make
IFF_UP reflect whether any addresses are left on the
interface, as we get signalled for IFF_UP flags change on the
primary interface only. Logical interfaces dont generate
IFINFO, but we do get an RTM_DELADDR.
(if_get_flags) Call if_mangle_up before return.
* kernel_socket.c: (ifam_read) Fixup calls to
connected_{add,delete} to match above changes. Rename gate
variable to brd, less confusing.
Pass the interface name as a label, if it is not same name
as ifp->name.
2005-11-03 13:35:21 +01:00
|
|
|
/* Label of this address. */
|
|
|
|
if (label)
|
|
|
|
ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2013-01-24 15:04:49 +01:00
|
|
|
/* On Linux, we only get here when DAD is complete, therefore we can set
|
|
|
|
* ZEBRA_IFC_REAL.
|
|
|
|
*
|
|
|
|
* On BSD, there currently doesn't seem to be a way to check for
|
|
|
|
* completion of
|
|
|
|
* DAD, so we replicate the old behaviour and set ZEBRA_IFC_REAL,
|
|
|
|
* although DAD
|
|
|
|
* might still be running.
|
|
|
|
*/
|
|
|
|
SET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
|
2013-01-24 15:04:46 +01:00
|
|
|
connected_update(ifp, ifc);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
|
|
|
|
2021-07-08 16:10:14 +02:00
|
|
|
void connected_delete_ipv6(struct interface *ifp,
|
|
|
|
const struct in6_addr *address,
|
|
|
|
const struct in6_addr *dest, uint16_t prefixlen)
|
2002-12-13 21:15:29 +01:00
|
|
|
{
|
2018-04-15 16:57:19 +02:00
|
|
|
struct prefix p, d;
|
2002-12-13 21:15:29 +01:00
|
|
|
struct connected *ifc;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&p, 0, sizeof(p));
|
2002-12-13 21:15:29 +01:00
|
|
|
p.family = AF_INET6;
|
2017-08-31 00:34:48 +02:00
|
|
|
memcpy(&p.u.prefix6, address, sizeof(struct in6_addr));
|
2002-12-13 21:15:29 +01:00
|
|
|
p.prefixlen = prefixlen;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-02-10 19:58:41 +01:00
|
|
|
/* Delete global ipv6 address from RA prefix list */
|
|
|
|
if (!IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6))
|
|
|
|
rtadv_delete_prefix(ifp->info, &p);
|
|
|
|
|
2019-08-10 11:52:03 +02:00
|
|
|
if (dest) {
|
2022-05-11 12:16:44 +02:00
|
|
|
memset(&d, 0, sizeof(d));
|
2018-04-15 16:57:19 +02:00
|
|
|
d.family = AF_INET6;
|
2019-08-10 11:52:03 +02:00
|
|
|
IPV6_ADDR_COPY(&d.u.prefix6, dest);
|
2018-04-15 16:57:19 +02:00
|
|
|
d.prefixlen = prefixlen;
|
|
|
|
ifc = connected_check_ptp(ifp, &p, &d);
|
|
|
|
} else
|
|
|
|
ifc = connected_check_ptp(ifp, &p, NULL);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-08-31 00:34:48 +02:00
|
|
|
connected_delete_helper(ifc, &p);
|
2002-12-13 21:15:29 +01:00
|
|
|
}
|
2015-11-16 21:48:07 +01:00
|
|
|
|
|
|
|
int connected_is_unnumbered(struct interface *ifp)
|
|
|
|
{
|
|
|
|
struct connected *connected;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2023-11-22 19:05:41 +01:00
|
|
|
frr_each (if_connected, ifp->connected, connected) {
|
2015-11-16 21:48:07 +01:00
|
|
|
if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
|
|
|
|
&& connected->address->family == AF_INET)
|
|
|
|
return CHECK_FLAG(connected->flags,
|
|
|
|
ZEBRA_IFA_UNNUMBERED);
|
|
|
|
}
|
2020-03-06 22:09:10 +01:00
|
|
|
return 0;
|
2015-11-16 21:48:07 +01:00
|
|
|
}
|