diff options
| author | Mark Stapp <mstapp@nvidia.com> | 2021-10-28 11:23:31 -0400 |
|---|---|---|
| committer | Mark Stapp <mstapp@nvidia.com> | 2022-02-25 10:18:32 -0500 |
| commit | cd787a8a45ea3c94a689d5ff01ddf62467373550 (patch) | |
| tree | 6d33a836729d423443dd004ca2eda91933c44ea6 /zebra/netconf_netlink.c | |
| parent | 728f2017ae285aea6f7e8bda369eaae7a3083899 (diff) | |
zebra: use dataplane to read interface NETCONF info
Use the dataplane to query and read interface NETCONF data;
add netconf-oriented data to the dplane context object, and
add accessors for it. Add handler for incoming update
processing.
Signed-off-by: Mark Stapp <mstapp@nvidia.com>
Diffstat (limited to 'zebra/netconf_netlink.c')
| -rw-r--r-- | zebra/netconf_netlink.c | 104 |
1 files changed, 70 insertions, 34 deletions
diff --git a/zebra/netconf_netlink.c b/zebra/netconf_netlink.c index e43685b794..587f6c749e 100644 --- a/zebra/netconf_netlink.c +++ b/zebra/netconf_netlink.c @@ -37,25 +37,53 @@ static struct rtattr *netconf_rta(struct netconfmsg *ncm) { - return (struct rtattr *)((char *)ncm - + NLMSG_ALIGN(sizeof(struct netconfmsg))); + return (struct rtattr *)((char *)ncm + + NLMSG_ALIGN(sizeof(struct netconfmsg))); } +/* + * Handle netconf update about a single interface: create dplane + * context, and enqueue for processing in the main zebra pthread. + */ +static int netlink_netconf_dplane_update(ns_id_t ns_id, ifindex_t ifindex, + enum dplane_netconf_status_e mpls_on, + enum dplane_netconf_status_e mcast_on) +{ + struct zebra_dplane_ctx *ctx; + + ctx = dplane_ctx_alloc(); + dplane_ctx_set_op(ctx, DPLANE_OP_INTF_NETCONFIG); + dplane_ctx_set_netconf_ns_id(ctx, ns_id); + dplane_ctx_set_netconf_ifindex(ctx, ifindex); + + dplane_ctx_set_netconf_mpls(ctx, mpls_on); + dplane_ctx_set_netconf_mcast(ctx, mcast_on); + + /* Enqueue ctx for main pthread to process */ + dplane_provider_enqueue_to_zebra(ctx); + + return 0; +} + +/* + * Parse and process an incoming netlink netconf update. + */ int netlink_netconf_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) { struct netconfmsg *ncm; struct rtattr *tb[NETCONFA_MAX + 1] = {}; int len; ifindex_t ifindex; - bool mpls_on = false; - bool mc_on = false; + uint32_t ival; + enum dplane_netconf_status_e mpls_on = DPLANE_NETCONF_STATUS_UNKNOWN; + enum dplane_netconf_status_e mcast_on = DPLANE_NETCONF_STATUS_UNKNOWN; if (h->nlmsg_type != RTM_NEWNETCONF && h->nlmsg_type != RTM_DELNETCONF) return 0; len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct netconfmsg)); if (len < 0) { - zlog_err("%s: Message received from netlink is of a broken size: %d %zu", + zlog_err("%s: Message received from netlink is of a broken size: %d, min %zu", __func__, h->nlmsg_len, (size_t)NLMSG_LENGTH(sizeof(struct netconfmsg))); return -1; @@ -66,8 +94,7 @@ int netlink_netconf_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) netlink_parse_rtattr(tb, NETCONFA_MAX, netconf_rta(ncm), len); if (!tb[NETCONFA_IFINDEX]) { - zlog_err("%s: Message received from netlink that we expected to receive an interface on", - __func__); + zlog_err("NETCONF message received from netlink without an ifindex"); return 0; } @@ -81,59 +108,68 @@ int netlink_netconf_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) * for all and default interfaces. I am not 100% sure * what that is yet, or where we would store it. */ + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("%s: Ignoring global ifindex %d", + __func__, ifindex); + return 0; default: break; } + if (tb[NETCONFA_INPUT]) { - mpls_on = *(bool *)RTA_DATA(tb[NETCONFA_INPUT]); - /* Create a context and pass it up for processing */ + ival = *(uint32_t *)RTA_DATA(tb[NETCONFA_INPUT]); + if (ival != 0) + mpls_on = DPLANE_NETCONF_STATUS_ENABLED; + else + mpls_on = DPLANE_NETCONF_STATUS_DISABLED; } if (tb[NETCONFA_MC_FORWARDING]) { - mc_on = *(bool *)RTA_DATA(tb[NETCONFA_MC_FORWARDING]); - /* Create a context and pass it up for processing */ + ival = *(uint32_t *)RTA_DATA(tb[NETCONFA_MC_FORWARDING]); + if (ival != 0) + mcast_on = DPLANE_NETCONF_STATUS_ENABLED; + else + mcast_on = DPLANE_NETCONF_STATUS_DISABLED; } if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("Interface %u is mpls on: %d multicast on: %d", - ifindex, mpls_on, mc_on); + zlog_debug("%s: interface %u is mpls on: %d multicast on: %d", + __func__, ifindex, mpls_on, mcast_on); + + /* Create a dplane context and pass it along for processing */ + netlink_netconf_dplane_update(ns_id, ifindex, mpls_on, mcast_on); return 0; } -static int netlink_request_netconf(struct nlsock *netlink_cmd) +/* + * Request info from the host OS. This only sends the request; any replies + * are processed asynchronously. + */ +int netlink_request_netconf(int sockfd) { + struct nlsock *nls; struct { struct nlmsghdr n; struct netconfmsg ncm; char buf[1024]; - } req; + } req = {}; + + nls = kernel_netlink_nlsock_lookup(sockfd); + + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("%s: nlsock %s", __func__, nls ? nls->name : "NULL"); + + if (nls == NULL) + return -1; - memset(&req, 0, sizeof(req)); req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct netconfmsg)); req.n.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST; req.n.nlmsg_type = RTM_GETNETCONF; req.ncm.ncm_family = AF_UNSPEC; - return netlink_request(netlink_cmd, &req); -} - -int netconf_lookup_netlink(struct zebra_ns *zns) -{ - int ret; - struct zebra_dplane_info dp_info; - struct nlsock *netlink_cmd = &zns->netlink_cmd; - - zebra_dplane_info_from_zns(&dp_info, zns, true); - - ret = netlink_request_netconf(netlink_cmd); - if (ret < 0) - return ret; - - ret = netlink_parse_info(netlink_netconf_change, netlink_cmd, &dp_info, - 0, 1); - return ret; + return netlink_request(nls, &req); } #endif /* HAVE_NETLINK */ |
