2012-11-13 23:48:59 +01:00
|
|
|
/*
|
|
|
|
* Code for encoding/decoding FPM messages that are in netlink format.
|
|
|
|
*
|
|
|
|
* Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
|
|
|
|
* Copyright (C) 2012 by Open Source Routing.
|
|
|
|
* Copyright (C) 2012 by Internet Systems Consortium, Inc. ("ISC")
|
|
|
|
*
|
|
|
|
* This file is part of GNU Zebra.
|
|
|
|
*
|
|
|
|
* GNU Zebra is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by the
|
|
|
|
* Free Software Foundation; either version 2, or (at your option) any
|
|
|
|
* later version.
|
|
|
|
*
|
|
|
|
* GNU Zebra is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* General Public License for more details.
|
|
|
|
*
|
2017-05-13 10:25:29 +02:00
|
|
|
* You should have received a copy of the GNU General Public License along
|
|
|
|
* with this program; see the file COPYING; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
2012-11-13 23:48:59 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <zebra.h>
|
|
|
|
|
2017-07-26 19:49:15 +02:00
|
|
|
#ifdef HAVE_NETLINK
|
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
#include "log.h"
|
|
|
|
#include "rib.h"
|
2016-10-06 21:56:13 +02:00
|
|
|
#include "vty.h"
|
2016-08-11 02:04:20 +02:00
|
|
|
#include "prefix.h"
|
2012-11-13 23:48:59 +01:00
|
|
|
|
2016-10-17 21:39:55 +02:00
|
|
|
#include "zebra/zserv.h"
|
2019-02-13 20:58:29 +01:00
|
|
|
#include "zebra/zebra_router.h"
|
2018-09-12 20:59:57 +02:00
|
|
|
#include "zebra/zebra_dplane.h"
|
2016-10-17 21:39:55 +02:00
|
|
|
#include "zebra/zebra_ns.h"
|
|
|
|
#include "zebra/zebra_vrf.h"
|
|
|
|
#include "zebra/kernel_netlink.h"
|
|
|
|
#include "zebra/rt_netlink.h"
|
2015-05-20 02:40:34 +02:00
|
|
|
#include "nexthop.h"
|
2012-11-13 23:48:59 +01:00
|
|
|
|
2016-10-17 21:39:55 +02:00
|
|
|
#include "zebra/zebra_fpm_private.h"
|
2019-05-17 03:38:03 +02:00
|
|
|
#include "zebra/zebra_vxlan_private.h"
|
2021-01-11 20:08:43 +01:00
|
|
|
#include "zebra/interface.h"
|
2012-11-13 23:48:59 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* af_addr_size
|
|
|
|
*
|
|
|
|
* The size of an address in a given address family.
|
|
|
|
*/
|
2018-03-27 21:13:34 +02:00
|
|
|
static size_t af_addr_size(uint8_t af)
|
2012-11-13 23:48:59 +01:00
|
|
|
{
|
|
|
|
switch (af) {
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
case AF_INET:
|
|
|
|
return 4;
|
|
|
|
case AF_INET6:
|
|
|
|
return 16;
|
|
|
|
default:
|
|
|
|
assert(0);
|
|
|
|
return 16;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-17 03:38:03 +02:00
|
|
|
/*
|
|
|
|
* We plan to use RTA_ENCAP_TYPE attribute for VxLAN encap as well.
|
|
|
|
* Currently, values 0 to 8 for this attribute are used by lwtunnel_encap_types
|
|
|
|
* So, we cannot use these values for VxLAN encap.
|
|
|
|
*/
|
|
|
|
enum fpm_nh_encap_type_t {
|
|
|
|
FPM_NH_ENCAP_NONE = 0,
|
|
|
|
FPM_NH_ENCAP_VXLAN = 100,
|
|
|
|
FPM_NH_ENCAP_MAX,
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* fpm_nh_encap_type_to_str
|
|
|
|
*/
|
|
|
|
static const char *fpm_nh_encap_type_to_str(enum fpm_nh_encap_type_t encap_type)
|
|
|
|
{
|
|
|
|
switch (encap_type) {
|
|
|
|
case FPM_NH_ENCAP_NONE:
|
|
|
|
return "none";
|
|
|
|
|
|
|
|
case FPM_NH_ENCAP_VXLAN:
|
|
|
|
return "VxLAN";
|
|
|
|
|
|
|
|
case FPM_NH_ENCAP_MAX:
|
|
|
|
return "invalid";
|
|
|
|
}
|
|
|
|
|
|
|
|
return "invalid";
|
|
|
|
}
|
|
|
|
|
|
|
|
struct vxlan_encap_info_t {
|
|
|
|
vni_t vni;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum vxlan_encap_info_type_t {
|
|
|
|
VXLAN_VNI = 0,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct fpm_nh_encap_info_t {
|
|
|
|
enum fpm_nh_encap_type_t encap_type;
|
|
|
|
union {
|
|
|
|
struct vxlan_encap_info_t vxlan_encap;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
/*
|
2020-05-07 14:50:04 +02:00
|
|
|
* netlink_nh_info
|
2012-11-13 23:48:59 +01:00
|
|
|
*
|
|
|
|
* Holds information about a single nexthop for netlink. These info
|
|
|
|
* structures are transient and may contain pointers into rib
|
|
|
|
* data structures for convenience.
|
|
|
|
*/
|
2020-05-07 14:50:04 +02:00
|
|
|
struct netlink_nh_info {
|
2022-02-10 16:47:20 +01:00
|
|
|
/* Weight of the nexthop ( for unequal cost ECMP ) */
|
|
|
|
uint8_t weight;
|
2012-11-13 23:48:59 +01:00
|
|
|
uint32_t if_index;
|
|
|
|
union g_addr *gateway;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
/*
|
|
|
|
* Information from the struct nexthop from which this nh was
|
|
|
|
* derived. For debug purposes only.
|
|
|
|
*/
|
|
|
|
int recursive;
|
|
|
|
enum nexthop_types_t type;
|
2019-05-17 03:38:03 +02:00
|
|
|
struct fpm_nh_encap_info_t encap_info;
|
2020-05-07 14:50:04 +02:00
|
|
|
};
|
2012-11-13 23:48:59 +01:00
|
|
|
|
|
|
|
/*
|
2020-05-07 14:52:38 +02:00
|
|
|
* netlink_route_info
|
2012-11-13 23:48:59 +01:00
|
|
|
*
|
|
|
|
* A structure for holding information for a netlink route message.
|
|
|
|
*/
|
2020-05-07 14:52:38 +02:00
|
|
|
struct netlink_route_info {
|
2021-01-15 17:06:17 +01:00
|
|
|
uint32_t nlmsg_pid;
|
2012-11-13 23:48:59 +01:00
|
|
|
uint16_t nlmsg_type;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t rtm_type;
|
2012-11-13 23:48:59 +01:00
|
|
|
uint32_t rtm_table;
|
2018-03-27 21:13:34 +02:00
|
|
|
uint8_t rtm_protocol;
|
|
|
|
uint8_t af;
|
2012-11-13 23:48:59 +01:00
|
|
|
struct prefix *prefix;
|
|
|
|
uint32_t *metric;
|
2016-11-04 00:59:19 +01:00
|
|
|
unsigned int num_nhs;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
/*
|
2015-11-17 17:13:23 +01:00
|
|
|
* Nexthop structures
|
2012-11-13 23:48:59 +01:00
|
|
|
*/
|
2020-05-07 14:50:04 +02:00
|
|
|
struct netlink_nh_info nhs[MULTIPATH_NUM];
|
2012-11-13 23:48:59 +01:00
|
|
|
union g_addr *pref_src;
|
2020-05-07 14:52:38 +02:00
|
|
|
};
|
2012-11-13 23:48:59 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
* netlink_route_info_add_nh
|
|
|
|
*
|
|
|
|
* Add information about the given nexthop to the given route info
|
|
|
|
* structure.
|
|
|
|
*
|
2019-07-01 19:26:05 +02:00
|
|
|
* Returns true if a nexthop was added, false otherwise.
|
2012-11-13 23:48:59 +01:00
|
|
|
*/
|
2020-05-07 14:52:38 +02:00
|
|
|
static int netlink_route_info_add_nh(struct netlink_route_info *ri,
|
2019-05-17 03:38:03 +02:00
|
|
|
struct nexthop *nexthop,
|
|
|
|
struct route_entry *re)
|
2012-11-13 23:48:59 +01:00
|
|
|
{
|
2020-05-07 14:50:04 +02:00
|
|
|
struct netlink_nh_info nhi;
|
2012-11-13 23:48:59 +01:00
|
|
|
union g_addr *src;
|
2021-01-11 20:08:43 +01:00
|
|
|
struct zebra_vrf *zvrf = NULL;
|
|
|
|
struct interface *ifp = NULL, *link_if = NULL;
|
|
|
|
struct zebra_if *zif = NULL;
|
|
|
|
vni_t vni = 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
memset(&nhi, 0, sizeof(nhi));
|
|
|
|
src = NULL;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2019-03-23 14:53:58 +01:00
|
|
|
if (ri->num_nhs >= (int)array_size(ri->nhs))
|
2012-11-13 23:48:59 +01:00
|
|
|
return 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-07-10 21:19:11 +02:00
|
|
|
nhi.recursive = nexthop->rparent ? 1 : 0;
|
2012-11-13 23:48:59 +01:00
|
|
|
nhi.type = nexthop->type;
|
2012-11-13 23:49:01 +01:00
|
|
|
nhi.if_index = nexthop->ifindex;
|
2022-02-10 16:47:20 +01:00
|
|
|
nhi.weight = nexthop->weight;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
if (nexthop->type == NEXTHOP_TYPE_IPV4
|
|
|
|
|| nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX) {
|
|
|
|
nhi.gateway = &nexthop->gate;
|
2020-02-06 07:49:02 +01:00
|
|
|
if (nexthop->src.ipv4.s_addr != INADDR_ANY)
|
2012-11-13 23:48:59 +01:00
|
|
|
src = &nexthop->src;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
if (nexthop->type == NEXTHOP_TYPE_IPV6
|
|
|
|
|| nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) {
|
zebra: Fix IPv4 routes with IPv6 link local next hops install in FPM
Description: Currently IPv4 routes with IPv6 link local next hops are
not properly installed in FPM.
Reason is the netlink decoding truncates the ipv6 LL address to 4 byte
ipv4 address.
Ex : fe80:: is directly converted to ipv4 and it results in 254.128.0.0
as next hop for below routes
show ip route
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
B>* 2.1.0.0/16 [200/0] via fe80::268a:7ff:fed0:d40, Ethernet0, weight 1,
02:22:26
B>* 5.1.0.0/16 [200/0] via fe80::268a:7ff:fed0:d40, Ethernet0, weight 1,
02:22:26
B>* 10.1.0.2/32 [200/0] via fe80::268a:7ff:fed0:d40, Ethernet0, weight
1, 02:22:26
Hence this fix converts the ipv6-LL address to ipv4-LL (169.254.0.1)
address before sending it to FPM. This is inline with how these types of
routes are currently programmed into kernel.
Signed-off-by: Nikhil Kelapure <nikhil.kelapure@broadcom.com>
2021-09-12 21:25:00 +02:00
|
|
|
/* Special handling for IPv4 route with IPv6 Link Local next hop
|
|
|
|
*/
|
|
|
|
if (ri->af == AF_INET)
|
|
|
|
nhi.gateway = &ipv4ll_gateway;
|
|
|
|
else
|
|
|
|
nhi.gateway = &nexthop->gate;
|
2012-11-13 23:48:59 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2015-12-04 18:52:49 +01:00
|
|
|
if (nexthop->type == NEXTHOP_TYPE_IFINDEX) {
|
2020-02-06 07:49:02 +01:00
|
|
|
if (nexthop->src.ipv4.s_addr != INADDR_ANY)
|
2012-11-13 23:48:59 +01:00
|
|
|
src = &nexthop->src;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
if (!nhi.gateway && nhi.if_index == 0)
|
|
|
|
return 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2022-02-22 10:22:45 +01:00
|
|
|
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_EVPN)) {
|
2019-05-17 03:38:03 +02:00
|
|
|
nhi.encap_info.encap_type = FPM_NH_ENCAP_VXLAN;
|
|
|
|
|
2021-01-11 20:08:43 +01:00
|
|
|
/* Extract VNI id for the nexthop SVI interface */
|
|
|
|
zvrf = zebra_vrf_lookup_by_id(nexthop->vrf_id);
|
|
|
|
if (zvrf) {
|
|
|
|
ifp = if_lookup_by_index_per_ns(zvrf->zns,
|
|
|
|
nexthop->ifindex);
|
|
|
|
if (ifp) {
|
|
|
|
zif = (struct zebra_if *)ifp->info;
|
|
|
|
if (zif) {
|
|
|
|
if (IS_ZEBRA_IF_BRIDGE(ifp))
|
|
|
|
link_if = ifp;
|
|
|
|
else if (IS_ZEBRA_IF_VLAN(ifp))
|
|
|
|
link_if =
|
|
|
|
if_lookup_by_index_per_ns(
|
|
|
|
zvrf->zns,
|
|
|
|
zif->link_ifindex);
|
|
|
|
if (link_if)
|
|
|
|
vni = vni_id_from_svi(ifp,
|
|
|
|
link_if);
|
|
|
|
}
|
|
|
|
}
|
2019-05-17 03:38:03 +02:00
|
|
|
}
|
2021-01-11 20:08:43 +01:00
|
|
|
|
|
|
|
nhi.encap_info.vxlan_encap.vni = vni;
|
2019-05-17 03:38:03 +02:00
|
|
|
}
|
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
/*
|
|
|
|
* We have a valid nhi. Copy the structure over to the route_info.
|
|
|
|
*/
|
|
|
|
ri->nhs[ri->num_nhs] = nhi;
|
|
|
|
ri->num_nhs++;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
if (src && !ri->pref_src)
|
|
|
|
ri->pref_src = src;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* netlink_proto_from_route_type
|
|
|
|
*/
|
2018-03-27 21:13:34 +02:00
|
|
|
static uint8_t netlink_proto_from_route_type(int type)
|
2012-11-13 23:48:59 +01:00
|
|
|
{
|
zebra_fpm: Add support for other protocols in fpm:netlink
fpm:netlink format doesn't indicate the protocol information
in routes of BGP, OSPF and other protocols. Routes of those
protocols just indicate protocol as zebra.
The below route is actually BGP route but 'proto': 11
indicates that it is zebra.
{'attrs': [('RTA_DST', 'dummy'),
('RTA_PRIORITY', 0),
('RTA_GATEWAY', 'dummy'),
('RTA_OIF', 2)],
'dst_len': 32,
'family': 2,
'flags': 0,
'header': {'flags': 1025,
'length': 60,
'pid': 3160253895,
'sequence_number': 0,
'type': 24},
'proto': 11,
'scope': 0,
'src_len': 0,
'table': 254,
'tos': 0,
'type': 1}
with this change it is now seen with 'proto': 186
indicates that it is BGP.
{'attrs': [('RTA_DST', 'dummy'),
('RTA_PRIORITY', 0),
('RTA_GATEWAY', 'dummy'),
('RTA_OIF', 2)],
'dst_len': 32,
'family': 2,
'flags': 0,
'header': {'flags': 1025,
'length': 60,
'pid': 3160253895,
'sequence_number': 0,
'type': 24},
'proto': 186,
'scope': 0,
'src_len': 0,
'table': 254,
'tos': 0,
'type': 1}
Signed-off-by: Spoorthi K <spk@redhat.com>
2023-01-23 04:34:04 +01:00
|
|
|
return zebra2proto(type);
|
2012-11-13 23:48:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* netlink_route_info_fill
|
|
|
|
*
|
|
|
|
* Fill out the route information object from the given route.
|
|
|
|
*
|
2019-07-01 19:26:05 +02:00
|
|
|
* Returns true on success and false on failure.
|
2012-11-13 23:48:59 +01:00
|
|
|
*/
|
2020-05-07 14:52:38 +02:00
|
|
|
static int netlink_route_info_fill(struct netlink_route_info *ri, int cmd,
|
2017-06-01 13:26:25 +02:00
|
|
|
rib_dest_t *dest, struct route_entry *re)
|
2012-11-13 23:48:59 +01:00
|
|
|
{
|
2017-06-27 12:49:49 +02:00
|
|
|
struct nexthop *nexthop;
|
2021-01-15 17:06:17 +01:00
|
|
|
struct rib_table_info *table_info =
|
|
|
|
rib_table_info(rib_dest_table(dest));
|
|
|
|
struct zebra_vrf *zvrf = table_info->zvrf;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
memset(ri, 0, sizeof(*ri));
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
ri->prefix = rib_dest_prefix(dest);
|
|
|
|
ri->af = rib_dest_af(dest);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-01-15 17:06:17 +01:00
|
|
|
if (zvrf && zvrf->zns)
|
2021-07-01 20:29:41 +02:00
|
|
|
ri->nlmsg_pid = zvrf->zns->netlink_dplane_out.snl.nl_pid;
|
2021-01-15 17:06:17 +01:00
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
ri->nlmsg_type = cmd;
|
2021-01-15 17:06:17 +01:00
|
|
|
ri->rtm_table = table_info->table_id;
|
2012-11-13 23:48:59 +01:00
|
|
|
ri->rtm_protocol = RTPROT_UNSPEC;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
/*
|
|
|
|
* An RTM_DELROUTE need not be accompanied by any nexthops,
|
|
|
|
* particularly in our communication with the FPM.
|
|
|
|
*/
|
2017-06-01 13:26:25 +02:00
|
|
|
if (cmd == RTM_DELROUTE && !re)
|
2016-11-13 04:12:13 +01:00
|
|
|
return 1;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
if (!re) {
|
2020-03-06 15:23:22 +01:00
|
|
|
zfpm_debug("%s: Expected non-NULL re pointer", __func__);
|
2016-11-13 04:12:13 +01:00
|
|
|
return 0;
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
ri->rtm_protocol = netlink_proto_from_route_type(re->type);
|
2010-02-05 04:31:56 +01:00
|
|
|
ri->rtm_type = RTN_UNICAST;
|
2017-06-01 13:26:25 +02:00
|
|
|
ri->metric = &re->metric;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-02-25 14:29:46 +01:00
|
|
|
for (ALL_NEXTHOPS(re->nhe->nhg, nexthop)) {
|
2019-02-13 20:58:29 +01:00
|
|
|
if (ri->num_nhs >= zrouter.multipath_num)
|
2013-07-05 17:35:37 +02:00
|
|
|
break;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2013-07-05 17:35:37 +02:00
|
|
|
if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
|
|
|
|
continue;
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2010-02-05 04:31:56 +01:00
|
|
|
if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE) {
|
|
|
|
switch (nexthop->bh_type) {
|
|
|
|
case BLACKHOLE_ADMINPROHIB:
|
|
|
|
ri->rtm_type = RTN_PROHIBIT;
|
|
|
|
break;
|
|
|
|
case BLACKHOLE_REJECT:
|
|
|
|
ri->rtm_type = RTN_UNREACHABLE;
|
|
|
|
break;
|
|
|
|
case BLACKHOLE_NULL:
|
|
|
|
default:
|
|
|
|
ri->rtm_type = RTN_BLACKHOLE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-07-05 17:35:37 +02:00
|
|
|
if ((cmd == RTM_NEWROUTE
|
|
|
|
&& CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE))
|
|
|
|
|| (cmd == RTM_DELROUTE
|
2019-01-14 22:37:53 +01:00
|
|
|
&& CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED))) {
|
2019-05-17 03:38:03 +02:00
|
|
|
netlink_route_info_add_nh(ri, nexthop, re);
|
2012-11-13 23:48:59 +01:00
|
|
|
}
|
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-09-28 13:51:19 +02:00
|
|
|
if (ri->num_nhs == 0) {
|
|
|
|
switch (ri->rtm_type) {
|
|
|
|
case RTN_PROHIBIT:
|
|
|
|
case RTN_UNREACHABLE:
|
|
|
|
case RTN_BLACKHOLE:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
/* If there is no useful nexthop then return. */
|
|
|
|
zfpm_debug(
|
|
|
|
"netlink_encode_route(): No useful nexthop.");
|
|
|
|
return 0;
|
|
|
|
}
|
2012-11-13 23:48:59 +01:00
|
|
|
}
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* netlink_route_info_encode
|
|
|
|
*
|
|
|
|
* Returns the number of bytes written to the buffer. 0 or a negative
|
|
|
|
* value indicates an error.
|
|
|
|
*/
|
2020-05-07 14:52:38 +02:00
|
|
|
static int netlink_route_info_encode(struct netlink_route_info *ri,
|
|
|
|
char *in_buf, size_t in_buf_len)
|
2012-11-13 23:48:59 +01:00
|
|
|
{
|
2016-10-11 18:17:28 +02:00
|
|
|
size_t bytelen;
|
2016-11-04 00:59:19 +01:00
|
|
|
unsigned int nexthop_num = 0;
|
2012-11-13 23:48:59 +01:00
|
|
|
size_t buf_offset;
|
2020-05-07 14:50:04 +02:00
|
|
|
struct netlink_nh_info *nhi;
|
2019-05-17 03:38:03 +02:00
|
|
|
enum fpm_nh_encap_type_t encap;
|
2020-06-08 23:37:26 +02:00
|
|
|
struct rtattr *nest, *inner_nest;
|
|
|
|
struct rtnexthop *rtnh;
|
2019-05-17 03:38:03 +02:00
|
|
|
struct vxlan_encap_info_t *vxlan;
|
2020-07-29 17:48:57 +02:00
|
|
|
struct in6_addr ipv6;
|
2012-11-13 23:48:59 +01:00
|
|
|
|
|
|
|
struct {
|
|
|
|
struct nlmsghdr n;
|
|
|
|
struct rtmsg r;
|
|
|
|
char buf[1];
|
|
|
|
} * req;
|
|
|
|
|
|
|
|
req = (void *)in_buf;
|
|
|
|
|
|
|
|
buf_offset = ((char *)req->buf) - ((char *)req);
|
|
|
|
|
|
|
|
if (in_buf_len < buf_offset) {
|
|
|
|
assert(0);
|
|
|
|
return 0;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2012-11-13 23:48:59 +01:00
|
|
|
|
|
|
|
memset(req, 0, buf_offset);
|
|
|
|
|
|
|
|
bytelen = af_addr_size(ri->af);
|
|
|
|
|
|
|
|
req->n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
|
|
|
|
req->n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
|
2021-01-15 17:06:17 +01:00
|
|
|
req->n.nlmsg_pid = ri->nlmsg_pid;
|
2012-11-13 23:48:59 +01:00
|
|
|
req->n.nlmsg_type = ri->nlmsg_type;
|
|
|
|
req->r.rtm_family = ri->af;
|
2019-05-17 21:47:57 +02:00
|
|
|
|
|
|
|
/*
|
2022-04-19 14:29:58 +02:00
|
|
|
* rtm_table field is a uchar field which can accommodate table_id less
|
2019-05-17 21:47:57 +02:00
|
|
|
* than 256.
|
|
|
|
* To support table id greater than 255, if the table_id is greater than
|
|
|
|
* 255, set rtm_table to RT_TABLE_UNSPEC and add RTA_TABLE attribute
|
|
|
|
* with 32 bit value as the table_id.
|
|
|
|
*/
|
|
|
|
if (ri->rtm_table < 256)
|
|
|
|
req->r.rtm_table = ri->rtm_table;
|
|
|
|
else {
|
|
|
|
req->r.rtm_table = RT_TABLE_UNSPEC;
|
2020-06-08 23:37:26 +02:00
|
|
|
nl_attr_put32(&req->n, in_buf_len, RTA_TABLE, ri->rtm_table);
|
2019-05-17 21:47:57 +02:00
|
|
|
}
|
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
req->r.rtm_dst_len = ri->prefix->prefixlen;
|
|
|
|
req->r.rtm_protocol = ri->rtm_protocol;
|
|
|
|
req->r.rtm_scope = RT_SCOPE_UNIVERSE;
|
|
|
|
|
2020-06-08 23:37:26 +02:00
|
|
|
nl_attr_put(&req->n, in_buf_len, RTA_DST, &ri->prefix->u.prefix,
|
|
|
|
bytelen);
|
2012-11-13 23:48:59 +01:00
|
|
|
|
|
|
|
req->r.rtm_type = ri->rtm_type;
|
|
|
|
|
|
|
|
/* Metric. */
|
|
|
|
if (ri->metric)
|
2020-06-08 23:37:26 +02:00
|
|
|
nl_attr_put32(&req->n, in_buf_len, RTA_PRIORITY, *ri->metric);
|
2012-11-13 23:48:59 +01:00
|
|
|
|
|
|
|
if (ri->num_nhs == 0)
|
|
|
|
goto done;
|
|
|
|
|
|
|
|
if (ri->num_nhs == 1) {
|
|
|
|
nhi = &ri->nhs[0];
|
|
|
|
|
|
|
|
if (nhi->gateway) {
|
2020-07-29 17:48:57 +02:00
|
|
|
if (nhi->type == NEXTHOP_TYPE_IPV4_IFINDEX
|
|
|
|
&& ri->af == AF_INET6) {
|
|
|
|
ipv4_to_ipv4_mapped_ipv6(&ipv6,
|
|
|
|
nhi->gateway->ipv4);
|
|
|
|
nl_attr_put(&req->n, in_buf_len, RTA_GATEWAY,
|
|
|
|
&ipv6, bytelen);
|
|
|
|
} else
|
|
|
|
nl_attr_put(&req->n, in_buf_len, RTA_GATEWAY,
|
|
|
|
nhi->gateway, bytelen);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2012-11-13 23:48:59 +01:00
|
|
|
|
|
|
|
if (nhi->if_index) {
|
2020-06-08 23:37:26 +02:00
|
|
|
nl_attr_put32(&req->n, in_buf_len, RTA_OIF,
|
|
|
|
nhi->if_index);
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
2012-11-13 23:48:59 +01:00
|
|
|
|
2019-05-17 03:38:03 +02:00
|
|
|
encap = nhi->encap_info.encap_type;
|
2020-04-21 13:50:27 +02:00
|
|
|
switch (encap) {
|
|
|
|
case FPM_NH_ENCAP_NONE:
|
|
|
|
case FPM_NH_ENCAP_MAX:
|
|
|
|
break;
|
|
|
|
case FPM_NH_ENCAP_VXLAN:
|
2020-06-08 23:37:26 +02:00
|
|
|
nl_attr_put16(&req->n, in_buf_len, RTA_ENCAP_TYPE,
|
|
|
|
encap);
|
2020-04-21 13:50:27 +02:00
|
|
|
vxlan = &nhi->encap_info.vxlan_encap;
|
2020-06-08 23:37:26 +02:00
|
|
|
nest = nl_attr_nest(&req->n, in_buf_len, RTA_ENCAP);
|
|
|
|
nl_attr_put32(&req->n, in_buf_len, VXLAN_VNI,
|
|
|
|
vxlan->vni);
|
|
|
|
nl_attr_nest_end(&req->n, nest);
|
2020-04-21 13:50:27 +02:00
|
|
|
break;
|
2019-05-17 03:38:03 +02:00
|
|
|
}
|
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
2017-07-17 14:03:14 +02:00
|
|
|
/*
|
2012-11-13 23:48:59 +01:00
|
|
|
* Multipath case.
|
2017-07-17 14:03:14 +02:00
|
|
|
*/
|
2020-06-08 23:37:26 +02:00
|
|
|
nest = nl_attr_nest(&req->n, in_buf_len, RTA_MULTIPATH);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
for (nexthop_num = 0; nexthop_num < ri->num_nhs; nexthop_num++) {
|
2020-06-08 23:37:26 +02:00
|
|
|
rtnh = nl_attr_rtnh(&req->n, in_buf_len);
|
2012-11-13 23:48:59 +01:00
|
|
|
nhi = &ri->nhs[nexthop_num];
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2020-06-08 23:37:26 +02:00
|
|
|
if (nhi->gateway)
|
|
|
|
nl_attr_put(&req->n, in_buf_len, RTA_GATEWAY,
|
|
|
|
nhi->gateway, bytelen);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
if (nhi->if_index) {
|
|
|
|
rtnh->rtnh_ifindex = nhi->if_index;
|
2017-07-17 14:03:14 +02:00
|
|
|
}
|
|
|
|
|
2022-02-10 16:47:20 +01:00
|
|
|
rtnh->rtnh_hops = nhi->weight;
|
|
|
|
|
2019-05-17 03:38:03 +02:00
|
|
|
encap = nhi->encap_info.encap_type;
|
2020-04-21 13:50:27 +02:00
|
|
|
switch (encap) {
|
|
|
|
case FPM_NH_ENCAP_NONE:
|
|
|
|
case FPM_NH_ENCAP_MAX:
|
|
|
|
break;
|
|
|
|
case FPM_NH_ENCAP_VXLAN:
|
2020-06-08 23:37:26 +02:00
|
|
|
nl_attr_put16(&req->n, in_buf_len, RTA_ENCAP_TYPE,
|
|
|
|
encap);
|
2020-04-21 13:50:27 +02:00
|
|
|
vxlan = &nhi->encap_info.vxlan_encap;
|
2020-06-08 23:37:26 +02:00
|
|
|
inner_nest =
|
|
|
|
nl_attr_nest(&req->n, in_buf_len, RTA_ENCAP);
|
|
|
|
nl_attr_put32(&req->n, in_buf_len, VXLAN_VNI,
|
|
|
|
vxlan->vni);
|
|
|
|
nl_attr_nest_end(&req->n, inner_nest);
|
2020-04-21 13:50:27 +02:00
|
|
|
break;
|
2019-05-17 03:38:03 +02:00
|
|
|
}
|
|
|
|
|
2020-06-08 23:37:26 +02:00
|
|
|
nl_attr_rtnh_end(&req->n, rtnh);
|
2012-11-13 23:48:59 +01:00
|
|
|
}
|
|
|
|
|
2020-06-08 23:37:26 +02:00
|
|
|
nl_attr_nest_end(&req->n, nest);
|
|
|
|
assert(nest->rta_len > RTA_LENGTH(0));
|
2012-11-13 23:48:59 +01:00
|
|
|
|
|
|
|
done:
|
|
|
|
|
|
|
|
if (ri->pref_src) {
|
2023-01-18 19:53:10 +01:00
|
|
|
nl_attr_put(&req->n, in_buf_len, RTA_PREFSRC, ri->pref_src,
|
2020-06-08 23:37:26 +02:00
|
|
|
bytelen);
|
2012-11-13 23:48:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
assert(req->n.nlmsg_len < in_buf_len);
|
|
|
|
return req->n.nlmsg_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* zfpm_log_route_info
|
|
|
|
*
|
|
|
|
* Helper function to log the information in a route_info structure.
|
|
|
|
*/
|
2020-05-07 14:52:38 +02:00
|
|
|
static void zfpm_log_route_info(struct netlink_route_info *ri,
|
|
|
|
const char *label)
|
2012-11-13 23:48:59 +01:00
|
|
|
{
|
2020-05-07 14:50:04 +02:00
|
|
|
struct netlink_nh_info *nhi;
|
2016-11-04 00:59:19 +01:00
|
|
|
unsigned int i;
|
2020-10-21 19:57:06 +02:00
|
|
|
char buf[PREFIX_STRLEN];
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2021-03-12 02:01:08 +01:00
|
|
|
zfpm_debug("%s : %s %pFX, Proto: %s, Metric: %u", label,
|
|
|
|
nl_msg_type_to_str(ri->nlmsg_type), ri->prefix,
|
2012-11-13 23:48:59 +01:00
|
|
|
nl_rtproto_to_str(ri->rtm_protocol),
|
|
|
|
ri->metric ? *ri->metric : 0);
|
2017-07-17 14:03:14 +02:00
|
|
|
|
2012-11-13 23:48:59 +01:00
|
|
|
for (i = 0; i < ri->num_nhs; i++) {
|
|
|
|
nhi = &ri->nhs[i];
|
2020-10-21 19:57:06 +02:00
|
|
|
|
2022-12-17 09:25:56 +01:00
|
|
|
if (nhi->gateway) {
|
|
|
|
if (ri->af == AF_INET)
|
|
|
|
inet_ntop(AF_INET, nhi->gateway, buf,
|
|
|
|
sizeof(buf));
|
|
|
|
else
|
|
|
|
inet_ntop(AF_INET6, nhi->gateway, buf,
|
|
|
|
sizeof(buf));
|
|
|
|
} else
|
|
|
|
strlcpy(buf, "none", sizeof(buf));
|
2020-10-21 19:57:06 +02:00
|
|
|
|
2019-05-17 03:38:03 +02:00
|
|
|
zfpm_debug(" Intf: %u, Gateway: %s, Recursive: %s, Type: %s, Encap type: %s",
|
2020-10-21 19:57:06 +02:00
|
|
|
nhi->if_index, buf, nhi->recursive ? "yes" : "no",
|
2019-05-17 03:38:03 +02:00
|
|
|
nexthop_type_to_str(nhi->type),
|
|
|
|
fpm_nh_encap_type_to_str(nhi->encap_info.encap_type)
|
|
|
|
);
|
2012-11-13 23:48:59 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* zfpm_netlink_encode_route
|
|
|
|
*
|
|
|
|
* Create a netlink message corresponding to the given route in the
|
|
|
|
* given buffer space.
|
|
|
|
*
|
|
|
|
* Returns the number of bytes written to the buffer. 0 or a negative
|
|
|
|
* value indicates an error.
|
|
|
|
*/
|
2017-06-01 13:26:25 +02:00
|
|
|
int zfpm_netlink_encode_route(int cmd, rib_dest_t *dest, struct route_entry *re,
|
2012-11-13 23:48:59 +01:00
|
|
|
char *in_buf, size_t in_buf_len)
|
|
|
|
{
|
2020-05-07 14:52:38 +02:00
|
|
|
struct netlink_route_info ri_space, *ri;
|
2012-11-13 23:48:59 +01:00
|
|
|
|
|
|
|
ri = &ri_space;
|
|
|
|
|
2017-06-01 13:26:25 +02:00
|
|
|
if (!netlink_route_info_fill(ri, cmd, dest, re))
|
2012-11-13 23:48:59 +01:00
|
|
|
return 0;
|
|
|
|
|
2020-03-05 19:17:54 +01:00
|
|
|
zfpm_log_route_info(ri, __func__);
|
2012-11-13 23:48:59 +01:00
|
|
|
|
|
|
|
return netlink_route_info_encode(ri, in_buf, in_buf_len);
|
|
|
|
}
|
2017-07-26 19:49:15 +02:00
|
|
|
|
Zebra: Build nelink message for RMAC updates
- Function "zfpm_netlink_encode_mac()" builds a netlink message for RMAC updates.
- To build a netlink message for RMAC updates, we use "ndmsg" in rtlink.
- FPM Message structure is:
FPM header -> nlmsg header -> ndmsg fields -> ndmsg attributes
- Netlink message will look like:
{'ndm_type': 0, 'family': 7, '__pad': (), 'header': {'flags': 1281,
'length':64, 'type': 28, 'pid': 0, 'sequence_number': 0}, 'state': 2,
'flags': 22, 'attrs': [('NDA_LLADDR', 'b2:66:eb:b9:5b:d3'),
('NDA_DST', '10.100.0.2'), ('NDA_MASTER', 11), ('NDA_VNI', 1000)],
'ifindex': 18}
- Message details:
nlmsghdr.nlmsg_type = RTM_NEWNEIGH(28) or RTM_DELNEIGH(29)
nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE for "add" ,
"NLM_F_REQUEST" for delete.
ndmsg.ndm_family = AF_BRIDGE
ndmsg.ndm_ifindex = vxlan_if (ifindex)
ndmsg.ndm_state = NUD_REACHABLE
ndmsg.ndm_flags |= NTF_SELF | NTF_MASTER | NTF_EXT_LEARNED
Attribute "NDA_LLADDR" for MAC address
Attribute "NDA_DST" for remote vtep ip
Attribute "NDA_MASTER" for bridge interface ifindex.
Attribute "NDA_VNI" for VNI id.
Signed-off-by: Ameya Dharkar <adharkar@vmware.com>
2019-05-17 02:29:08 +02:00
|
|
|
/*
|
|
|
|
* zfpm_netlink_encode_mac
|
|
|
|
*
|
|
|
|
* Create a netlink message corresponding to the given MAC.
|
|
|
|
*
|
|
|
|
* Returns the number of bytes written to the buffer. 0 or a negative
|
|
|
|
* value indicates an error.
|
|
|
|
*/
|
|
|
|
int zfpm_netlink_encode_mac(struct fpm_mac_info_t *mac, char *in_buf,
|
|
|
|
size_t in_buf_len)
|
|
|
|
{
|
|
|
|
size_t buf_offset;
|
|
|
|
|
2019-06-17 21:03:41 +02:00
|
|
|
struct macmsg {
|
Zebra: Build nelink message for RMAC updates
- Function "zfpm_netlink_encode_mac()" builds a netlink message for RMAC updates.
- To build a netlink message for RMAC updates, we use "ndmsg" in rtlink.
- FPM Message structure is:
FPM header -> nlmsg header -> ndmsg fields -> ndmsg attributes
- Netlink message will look like:
{'ndm_type': 0, 'family': 7, '__pad': (), 'header': {'flags': 1281,
'length':64, 'type': 28, 'pid': 0, 'sequence_number': 0}, 'state': 2,
'flags': 22, 'attrs': [('NDA_LLADDR', 'b2:66:eb:b9:5b:d3'),
('NDA_DST', '10.100.0.2'), ('NDA_MASTER', 11), ('NDA_VNI', 1000)],
'ifindex': 18}
- Message details:
nlmsghdr.nlmsg_type = RTM_NEWNEIGH(28) or RTM_DELNEIGH(29)
nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE for "add" ,
"NLM_F_REQUEST" for delete.
ndmsg.ndm_family = AF_BRIDGE
ndmsg.ndm_ifindex = vxlan_if (ifindex)
ndmsg.ndm_state = NUD_REACHABLE
ndmsg.ndm_flags |= NTF_SELF | NTF_MASTER | NTF_EXT_LEARNED
Attribute "NDA_LLADDR" for MAC address
Attribute "NDA_DST" for remote vtep ip
Attribute "NDA_MASTER" for bridge interface ifindex.
Attribute "NDA_VNI" for VNI id.
Signed-off-by: Ameya Dharkar <adharkar@vmware.com>
2019-05-17 02:29:08 +02:00
|
|
|
struct nlmsghdr hdr;
|
|
|
|
struct ndmsg ndm;
|
|
|
|
char buf[0];
|
|
|
|
} *req;
|
|
|
|
req = (void *)in_buf;
|
|
|
|
|
2019-06-17 21:03:41 +02:00
|
|
|
buf_offset = offsetof(struct macmsg, buf);
|
Zebra: Build nelink message for RMAC updates
- Function "zfpm_netlink_encode_mac()" builds a netlink message for RMAC updates.
- To build a netlink message for RMAC updates, we use "ndmsg" in rtlink.
- FPM Message structure is:
FPM header -> nlmsg header -> ndmsg fields -> ndmsg attributes
- Netlink message will look like:
{'ndm_type': 0, 'family': 7, '__pad': (), 'header': {'flags': 1281,
'length':64, 'type': 28, 'pid': 0, 'sequence_number': 0}, 'state': 2,
'flags': 22, 'attrs': [('NDA_LLADDR', 'b2:66:eb:b9:5b:d3'),
('NDA_DST', '10.100.0.2'), ('NDA_MASTER', 11), ('NDA_VNI', 1000)],
'ifindex': 18}
- Message details:
nlmsghdr.nlmsg_type = RTM_NEWNEIGH(28) or RTM_DELNEIGH(29)
nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE for "add" ,
"NLM_F_REQUEST" for delete.
ndmsg.ndm_family = AF_BRIDGE
ndmsg.ndm_ifindex = vxlan_if (ifindex)
ndmsg.ndm_state = NUD_REACHABLE
ndmsg.ndm_flags |= NTF_SELF | NTF_MASTER | NTF_EXT_LEARNED
Attribute "NDA_LLADDR" for MAC address
Attribute "NDA_DST" for remote vtep ip
Attribute "NDA_MASTER" for bridge interface ifindex.
Attribute "NDA_VNI" for VNI id.
Signed-off-by: Ameya Dharkar <adharkar@vmware.com>
2019-05-17 02:29:08 +02:00
|
|
|
if (in_buf_len < buf_offset)
|
|
|
|
return 0;
|
|
|
|
memset(req, 0, buf_offset);
|
|
|
|
|
|
|
|
/* Construct nlmsg header */
|
|
|
|
req->hdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg));
|
|
|
|
req->hdr.nlmsg_type = CHECK_FLAG(mac->fpm_flags, ZEBRA_MAC_DELETE_FPM) ?
|
|
|
|
RTM_DELNEIGH : RTM_NEWNEIGH;
|
|
|
|
req->hdr.nlmsg_flags = NLM_F_REQUEST;
|
|
|
|
if (req->hdr.nlmsg_type == RTM_NEWNEIGH)
|
|
|
|
req->hdr.nlmsg_flags |= (NLM_F_CREATE | NLM_F_REPLACE);
|
|
|
|
|
|
|
|
/* Construct ndmsg */
|
|
|
|
req->ndm.ndm_family = AF_BRIDGE;
|
|
|
|
req->ndm.ndm_ifindex = mac->vxlan_if;
|
|
|
|
|
|
|
|
req->ndm.ndm_state = NUD_REACHABLE;
|
|
|
|
req->ndm.ndm_flags |= NTF_SELF | NTF_MASTER;
|
|
|
|
if (CHECK_FLAG(mac->zebra_flags,
|
|
|
|
(ZEBRA_MAC_STICKY | ZEBRA_MAC_REMOTE_DEF_GW)))
|
|
|
|
req->ndm.ndm_state |= NUD_NOARP;
|
|
|
|
else
|
|
|
|
req->ndm.ndm_flags |= NTF_EXT_LEARNED;
|
|
|
|
|
|
|
|
/* Add attributes */
|
2020-06-08 23:37:26 +02:00
|
|
|
nl_attr_put(&req->hdr, in_buf_len, NDA_LLADDR, &mac->macaddr, 6);
|
|
|
|
nl_attr_put(&req->hdr, in_buf_len, NDA_DST, &mac->r_vtep_ip, 4);
|
|
|
|
nl_attr_put32(&req->hdr, in_buf_len, NDA_MASTER, mac->svi_if);
|
|
|
|
nl_attr_put32(&req->hdr, in_buf_len, NDA_VNI, mac->vni);
|
Zebra: Build nelink message for RMAC updates
- Function "zfpm_netlink_encode_mac()" builds a netlink message for RMAC updates.
- To build a netlink message for RMAC updates, we use "ndmsg" in rtlink.
- FPM Message structure is:
FPM header -> nlmsg header -> ndmsg fields -> ndmsg attributes
- Netlink message will look like:
{'ndm_type': 0, 'family': 7, '__pad': (), 'header': {'flags': 1281,
'length':64, 'type': 28, 'pid': 0, 'sequence_number': 0}, 'state': 2,
'flags': 22, 'attrs': [('NDA_LLADDR', 'b2:66:eb:b9:5b:d3'),
('NDA_DST', '10.100.0.2'), ('NDA_MASTER', 11), ('NDA_VNI', 1000)],
'ifindex': 18}
- Message details:
nlmsghdr.nlmsg_type = RTM_NEWNEIGH(28) or RTM_DELNEIGH(29)
nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE for "add" ,
"NLM_F_REQUEST" for delete.
ndmsg.ndm_family = AF_BRIDGE
ndmsg.ndm_ifindex = vxlan_if (ifindex)
ndmsg.ndm_state = NUD_REACHABLE
ndmsg.ndm_flags |= NTF_SELF | NTF_MASTER | NTF_EXT_LEARNED
Attribute "NDA_LLADDR" for MAC address
Attribute "NDA_DST" for remote vtep ip
Attribute "NDA_MASTER" for bridge interface ifindex.
Attribute "NDA_VNI" for VNI id.
Signed-off-by: Ameya Dharkar <adharkar@vmware.com>
2019-05-17 02:29:08 +02:00
|
|
|
|
|
|
|
assert(req->hdr.nlmsg_len < in_buf_len);
|
|
|
|
|
2021-03-12 02:01:08 +01:00
|
|
|
zfpm_debug("Tx %s family %s ifindex %u MAC %pEA DEST %pI4",
|
Zebra: Build nelink message for RMAC updates
- Function "zfpm_netlink_encode_mac()" builds a netlink message for RMAC updates.
- To build a netlink message for RMAC updates, we use "ndmsg" in rtlink.
- FPM Message structure is:
FPM header -> nlmsg header -> ndmsg fields -> ndmsg attributes
- Netlink message will look like:
{'ndm_type': 0, 'family': 7, '__pad': (), 'header': {'flags': 1281,
'length':64, 'type': 28, 'pid': 0, 'sequence_number': 0}, 'state': 2,
'flags': 22, 'attrs': [('NDA_LLADDR', 'b2:66:eb:b9:5b:d3'),
('NDA_DST', '10.100.0.2'), ('NDA_MASTER', 11), ('NDA_VNI', 1000)],
'ifindex': 18}
- Message details:
nlmsghdr.nlmsg_type = RTM_NEWNEIGH(28) or RTM_DELNEIGH(29)
nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE for "add" ,
"NLM_F_REQUEST" for delete.
ndmsg.ndm_family = AF_BRIDGE
ndmsg.ndm_ifindex = vxlan_if (ifindex)
ndmsg.ndm_state = NUD_REACHABLE
ndmsg.ndm_flags |= NTF_SELF | NTF_MASTER | NTF_EXT_LEARNED
Attribute "NDA_LLADDR" for MAC address
Attribute "NDA_DST" for remote vtep ip
Attribute "NDA_MASTER" for bridge interface ifindex.
Attribute "NDA_VNI" for VNI id.
Signed-off-by: Ameya Dharkar <adharkar@vmware.com>
2019-05-17 02:29:08 +02:00
|
|
|
nl_msg_type_to_str(req->hdr.nlmsg_type),
|
|
|
|
nl_family_to_str(req->ndm.ndm_family), req->ndm.ndm_ifindex,
|
2021-03-12 02:01:08 +01:00
|
|
|
&mac->macaddr, &mac->r_vtep_ip);
|
Zebra: Build nelink message for RMAC updates
- Function "zfpm_netlink_encode_mac()" builds a netlink message for RMAC updates.
- To build a netlink message for RMAC updates, we use "ndmsg" in rtlink.
- FPM Message structure is:
FPM header -> nlmsg header -> ndmsg fields -> ndmsg attributes
- Netlink message will look like:
{'ndm_type': 0, 'family': 7, '__pad': (), 'header': {'flags': 1281,
'length':64, 'type': 28, 'pid': 0, 'sequence_number': 0}, 'state': 2,
'flags': 22, 'attrs': [('NDA_LLADDR', 'b2:66:eb:b9:5b:d3'),
('NDA_DST', '10.100.0.2'), ('NDA_MASTER', 11), ('NDA_VNI', 1000)],
'ifindex': 18}
- Message details:
nlmsghdr.nlmsg_type = RTM_NEWNEIGH(28) or RTM_DELNEIGH(29)
nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE for "add" ,
"NLM_F_REQUEST" for delete.
ndmsg.ndm_family = AF_BRIDGE
ndmsg.ndm_ifindex = vxlan_if (ifindex)
ndmsg.ndm_state = NUD_REACHABLE
ndmsg.ndm_flags |= NTF_SELF | NTF_MASTER | NTF_EXT_LEARNED
Attribute "NDA_LLADDR" for MAC address
Attribute "NDA_DST" for remote vtep ip
Attribute "NDA_MASTER" for bridge interface ifindex.
Attribute "NDA_VNI" for VNI id.
Signed-off-by: Ameya Dharkar <adharkar@vmware.com>
2019-05-17 02:29:08 +02:00
|
|
|
|
|
|
|
return req->hdr.nlmsg_len;
|
|
|
|
}
|
|
|
|
|
2017-07-26 19:49:15 +02:00
|
|
|
#endif /* HAVE_NETLINK */
|