summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChirag Shah <chirag@nvidia.com>2022-01-25 10:25:38 -0800
committerDonald Sharp <sharpd@nvidia.com>2022-06-24 07:33:34 -0400
commitacc8e68720ecc320b6d008ebb21c921f404762b0 (patch)
tree7d66433769cf90ca0365eee21dbce1348d9c5b6a
parentc315b87c4f71c79508eb61e2f6cbd27b8df2ec87 (diff)
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>
-rw-r--r--zebra/if_netlink.c66
-rw-r--r--zebra/if_netlink.h1
-rw-r--r--zebra/kernel_netlink.c7
3 files changed, 73 insertions, 1 deletions
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index ffd52da8d8..7a4e1304bd 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -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 */
diff --git a/zebra/if_netlink.h b/zebra/if_netlink.h
index 46eac25377..21ae1713be 100644
--- a/zebra/if_netlink.h
+++ b/zebra/if_netlink.h
@@ -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);
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index 7e47822a2c..4bd0ac27f6 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -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