zebra: netlink rtm tunnel msg parsing

'bridge vni add vni <id> dev <vxlan device>'
generates new RTM_NEWTUNNEL and RTM_DELTUNNEL
to add or remove vni to l3vxlan device.

Register new RTNLGRP_TUNNEL group to receive
new netlink notification.
Callback for the new RTM_xxxTUNNEL.

kernel patches:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/
linux.git/commit/?h=v5.18-rc7&id=7b8135f4df98b155b23754b6065c157861e268f1

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/
linux.git/commit/?h=v5.18-rc7&id=f9c4bb0b245cee35ef66f75bf409c9573d934cf9

Ticket:#3073812
Testing Done:

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
Signed-off-by: Chirag Shah <chirag@nvidia.com>
This commit is contained in:
Chirag Shah 2022-01-25 10:25:38 -08:00 committed by Donald Sharp
parent c315b87c4f
commit acc8e68720
3 changed files with 73 additions and 1 deletions

View File

@ -1182,6 +1182,14 @@ int interface_lookup_netlink(struct zebra_ns *zns)
if (ret < 0)
return ret;
ret = netlink_tunneldump_read(zns);
if (ret < 0)
return ret;
ret = netlink_parse_info(netlink_interface, netlink_cmd, &dp_info, 0,
true);
if (ret < 0)
return ret;
/* fixup linkages */
zebra_if_update_all_links(zns);
return 0;
@ -2274,4 +2282,62 @@ uint8_t if_netlink_get_frr_protodown_r_bit(void)
return frr_protodown_r_bit;
}
/**
* netlink_request_tunneldump() - Request all tunnels from the linux kernel
*
* @zns: Zebra namespace
* @family: AF_* netlink family
* @type: RTM_* (RTM_GETTUNNEL) route type
*
* Return: Result status
*/
static int netlink_request_tunneldump(struct zebra_ns *zns, int family,
int ifindex)
{
struct {
struct nlmsghdr n;
struct tunnel_msg tmsg;
char buf[256];
} req;
/* Form the request */
memset(&req, 0, sizeof(req));
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct tunnel_msg));
req.n.nlmsg_type = RTM_GETTUNNEL;
req.n.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
req.tmsg.family = family;
req.tmsg.ifindex = ifindex;
return netlink_request(&zns->netlink_cmd, &req);
}
/*
* Currently we only ask for vxlan l3svd vni information.
* In the future this can be expanded.
*/
int netlink_tunneldump_read(struct zebra_ns *zns)
{
int ret = 0;
struct zebra_dplane_info dp_info;
struct route_node *rn;
struct interface *tmp_if = NULL;
struct zebra_if *zif;
zebra_dplane_info_from_zns(&dp_info, zns, true /*is_cmd*/);
for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
tmp_if = (struct interface *)rn->info;
if (!tmp_if)
continue;
zif = tmp_if->info;
if (!zif || zif->zif_type != ZEBRA_IF_VXLAN)
continue;
ret = netlink_request_tunneldump(zns, PF_BRIDGE,
tmp_if->ifindex);
if (ret < 0)
return ret;
}
return 0;
}
#endif /* GNU_LINUX */

View File

@ -50,6 +50,7 @@ extern enum netlink_msg_status
netlink_put_address_update_msg(struct nl_batch *bth,
struct zebra_dplane_ctx *ctx);
extern int netlink_tunneldump_read(struct zebra_ns *zns);
extern enum netlink_msg_status
netlink_put_intf_update_msg(struct nl_batch *bth, struct zebra_dplane_ctx *ctx);

View File

@ -111,6 +111,9 @@ static const struct message nlmsg_str[] = {{RTM_NEWROUTE, "RTM_NEWROUTE"},
{RTM_GETNEXTHOP, "RTM_GETNEXTHOP"},
{RTM_NEWNETCONF, "RTM_NEWNETCONF"},
{RTM_DELNETCONF, "RTM_DELNETCONF"},
{RTM_NEWTUNNEL, "RTM_NEWTUNNEL"},
{RTM_DELTUNNEL, "RTM_DELTUNNEL"},
{RTM_GETTUNNEL, "RTM_GETTUNNEL"},
{0}};
static const struct message rtproto_str[] = {
@ -393,8 +396,10 @@ static int netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id,
case RTM_DELADDR:
case RTM_NEWNETCONF:
case RTM_DELNETCONF:
case RTM_NEWTUNNEL:
case RTM_DELTUNNEL:
case RTM_GETTUNNEL:
return 0;
default:
/*
* If we have received this message then