From acc8e68720ecc320b6d008ebb21c921f404762b0 Mon Sep 17 00:00:00 2001 From: Chirag Shah Date: Tue, 25 Jan 2022 10:25:38 -0800 Subject: [PATCH] zebra: netlink rtm tunnel msg parsing 'bridge vni add vni dev ' 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 Signed-off-by: Chirag Shah --- zebra/if_netlink.c | 66 ++++++++++++++++++++++++++++++++++++++++++ zebra/if_netlink.h | 1 + zebra/kernel_netlink.c | 7 ++++- 3 files changed, 73 insertions(+), 1 deletion(-) 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 -- 2.39.5