Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

netdev-genl: create a simple family for netdev stuff

Add a Netlink spec-compatible family for netdevs.
This is a very simple implementation without much
thought going into it.

It allows us to reap all the benefits of Netlink specs,
one can use the generic client to issue the commands:

$ ./cli.py --spec netdev.yaml --dump dev_get
[{'ifindex': 1, 'xdp-features': set()},
{'ifindex': 2, 'xdp-features': {'basic', 'ndo-xmit', 'redirect'}},
{'ifindex': 3, 'xdp-features': {'rx-sg'}}]

the generic python library does not have flags-by-name
support, yet, but we also don't have to carry strings
in the messages, as user space can get the names from
the spec.

Acked-by: Jesper Dangaard Brouer <brouer@redhat.com>
Co-developed-by: Lorenzo Bianconi <lorenzo@kernel.org>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Co-developed-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Co-developed-by: Marek Majtyka <alardam@gmail.com>
Signed-off-by: Marek Majtyka <alardam@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Link: https://lore.kernel.org/r/327ad9c9868becbe1e601b580c962549c8cd81f2.1675245258.git.lorenzo@kernel.org
Signed-off-by: Alexei Starovoitov <ast@kernel.org>

authored by

Jakub Kicinski and committed by
Alexei Starovoitov
d3d854fd 15080908

+477 -1
+100
Documentation/netlink/specs/netdev.yaml
··· 1 + name: netdev 2 + 3 + doc: 4 + netdev configuration over generic netlink. 5 + 6 + definitions: 7 + - 8 + type: flags 9 + name: xdp-act 10 + entries: 11 + - 12 + name: basic 13 + doc: 14 + XDP feautues set supported by all drivers 15 + (XDP_ABORTED, XDP_DROP, XDP_PASS, XDP_TX) 16 + - 17 + name: redirect 18 + doc: 19 + The netdev supports XDP_REDIRECT 20 + - 21 + name: ndo-xmit 22 + doc: 23 + This feature informs if netdev implements ndo_xdp_xmit callback. 24 + - 25 + name: xsk-zerocopy 26 + doc: 27 + This feature informs if netdev supports AF_XDP in zero copy mode. 28 + - 29 + name: hw-offload 30 + doc: 31 + This feature informs if netdev supports XDP hw oflloading. 32 + - 33 + name: rx-sg 34 + doc: 35 + This feature informs if netdev implements non-linear XDP buffer 36 + support in the driver napi callback. 37 + - 38 + name: ndo-xmit-sg 39 + doc: 40 + This feature informs if netdev implements non-linear XDP buffer 41 + support in ndo_xdp_xmit callback. 42 + 43 + attribute-sets: 44 + - 45 + name: dev 46 + attributes: 47 + - 48 + name: ifindex 49 + doc: netdev ifindex 50 + type: u32 51 + value: 1 52 + checks: 53 + min: 1 54 + - 55 + name: pad 56 + type: pad 57 + - 58 + name: xdp-features 59 + doc: Bitmask of enabled xdp-features. 60 + type: u64 61 + enum: xdp-act 62 + enum-as-flags: true 63 + 64 + operations: 65 + list: 66 + - 67 + name: dev-get 68 + doc: Get / dump information about a netdev. 69 + value: 1 70 + attribute-set: dev 71 + do: 72 + request: 73 + attributes: 74 + - ifindex 75 + reply: &dev-all 76 + attributes: 77 + - ifindex 78 + - xdp-features 79 + dump: 80 + reply: *dev-all 81 + - 82 + name: dev-add-ntf 83 + doc: Notification about device appearing. 84 + notify: dev-get 85 + mcgrp: mgmt 86 + - 87 + name: dev-del-ntf 88 + doc: Notification about device disappearing. 89 + notify: dev-get 90 + mcgrp: mgmt 91 + - 92 + name: dev-change-ntf 93 + doc: Notification about device configuration being changed. 94 + notify: dev-get 95 + mcgrp: mgmt 96 + 97 + mcast-groups: 98 + list: 99 + - 100 + name: mgmt
+3
include/linux/netdevice.h
··· 47 47 #include <uapi/linux/netdevice.h> 48 48 #include <uapi/linux/if_bonding.h> 49 49 #include <uapi/linux/pkt_cls.h> 50 + #include <uapi/linux/netdev.h> 50 51 #include <linux/hashtable.h> 51 52 #include <linux/rbtree.h> 52 53 #include <net/net_trackers.h> ··· 2056 2055 2057 2056 /* Read-mostly cache-line for fast-path access */ 2058 2057 unsigned int flags; 2058 + xdp_features_t xdp_features; 2059 2059 unsigned long long priv_flags; 2060 2060 const struct net_device_ops *netdev_ops; 2061 2061 const struct xdp_metadata_ops *xdp_metadata_ops; ··· 2841 2839 NETDEV_OFFLOAD_XSTATS_DISABLE, 2842 2840 NETDEV_OFFLOAD_XSTATS_REPORT_USED, 2843 2841 NETDEV_OFFLOAD_XSTATS_REPORT_DELTA, 2842 + NETDEV_XDP_FEAT_CHANGE, 2844 2843 }; 2845 2844 const char *netdev_cmd_to_name(enum netdev_cmd cmd); 2846 2845
+3
include/net/xdp.h
··· 7 7 #define __LINUX_NET_XDP_H__ 8 8 9 9 #include <linux/skbuff.h> /* skb_shared_info */ 10 + #include <uapi/linux/netdev.h> 10 11 11 12 /** 12 13 * DOC: XDP RX-queue information ··· 43 42 MEM_TYPE_XSK_BUFF_POOL, 44 43 MEM_TYPE_MAX, 45 44 }; 45 + 46 + typedef u32 xdp_features_t; 46 47 47 48 /* XDP flags for ndo_xdp_xmit */ 48 49 #define XDP_XMIT_FLUSH (1U << 0) /* doorbell signal consumer */
+59
include/uapi/linux/netdev.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 + /* Do not edit directly, auto-generated from: */ 3 + /* Documentation/netlink/specs/netdev.yaml */ 4 + /* YNL-GEN uapi header */ 5 + 6 + #ifndef _UAPI_LINUX_NETDEV_H 7 + #define _UAPI_LINUX_NETDEV_H 8 + 9 + #define NETDEV_FAMILY_NAME "netdev" 10 + #define NETDEV_FAMILY_VERSION 1 11 + 12 + /** 13 + * enum netdev_xdp_act 14 + * @NETDEV_XDP_ACT_BASIC: XDP feautues set supported by all drivers 15 + * (XDP_ABORTED, XDP_DROP, XDP_PASS, XDP_TX) 16 + * @NETDEV_XDP_ACT_REDIRECT: The netdev supports XDP_REDIRECT 17 + * @NETDEV_XDP_ACT_NDO_XMIT: This feature informs if netdev implements 18 + * ndo_xdp_xmit callback. 19 + * @NETDEV_XDP_ACT_XSK_ZEROCOPY: This feature informs if netdev supports AF_XDP 20 + * in zero copy mode. 21 + * @NETDEV_XDP_ACT_HW_OFFLOAD: This feature informs if netdev supports XDP hw 22 + * oflloading. 23 + * @NETDEV_XDP_ACT_RX_SG: This feature informs if netdev implements non-linear 24 + * XDP buffer support in the driver napi callback. 25 + * @NETDEV_XDP_ACT_NDO_XMIT_SG: This feature informs if netdev implements 26 + * non-linear XDP buffer support in ndo_xdp_xmit callback. 27 + */ 28 + enum netdev_xdp_act { 29 + NETDEV_XDP_ACT_BASIC = 1, 30 + NETDEV_XDP_ACT_REDIRECT = 2, 31 + NETDEV_XDP_ACT_NDO_XMIT = 4, 32 + NETDEV_XDP_ACT_XSK_ZEROCOPY = 8, 33 + NETDEV_XDP_ACT_HW_OFFLOAD = 16, 34 + NETDEV_XDP_ACT_RX_SG = 32, 35 + NETDEV_XDP_ACT_NDO_XMIT_SG = 64, 36 + }; 37 + 38 + enum { 39 + NETDEV_A_DEV_IFINDEX = 1, 40 + NETDEV_A_DEV_PAD, 41 + NETDEV_A_DEV_XDP_FEATURES, 42 + 43 + __NETDEV_A_DEV_MAX, 44 + NETDEV_A_DEV_MAX = (__NETDEV_A_DEV_MAX - 1) 45 + }; 46 + 47 + enum { 48 + NETDEV_CMD_DEV_GET = 1, 49 + NETDEV_CMD_DEV_ADD_NTF, 50 + NETDEV_CMD_DEV_DEL_NTF, 51 + NETDEV_CMD_DEV_CHANGE_NTF, 52 + 53 + __NETDEV_CMD_MAX, 54 + NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1) 55 + }; 56 + 57 + #define NETDEV_MCGRP_MGMT "mgmt" 58 + 59 + #endif /* _UAPI_LINUX_NETDEV_H */
+2 -1
net/core/Makefile
··· 12 12 obj-y += dev.o dev_addr_lists.o dst.o netevent.o \ 13 13 neighbour.o rtnetlink.o utils.o link_watch.o filter.o \ 14 14 sock_diag.o dev_ioctl.o tso.o sock_reuseport.o \ 15 - fib_notifier.o xdp.o flow_offload.o gro.o 15 + fib_notifier.o xdp.o flow_offload.o gro.o \ 16 + netdev-genl.o netdev-genl-gen.o 16 17 17 18 obj-$(CONFIG_NETDEV_ADDR_LIST_TEST) += dev_addr_lists_test.o 18 19
+1
net/core/dev.c
··· 1614 1614 N(SVLAN_FILTER_PUSH_INFO) N(SVLAN_FILTER_DROP_INFO) 1615 1615 N(PRE_CHANGEADDR) N(OFFLOAD_XSTATS_ENABLE) N(OFFLOAD_XSTATS_DISABLE) 1616 1616 N(OFFLOAD_XSTATS_REPORT_USED) N(OFFLOAD_XSTATS_REPORT_DELTA) 1617 + N(XDP_FEAT_CHANGE) 1617 1618 } 1618 1619 #undef N 1619 1620 return "UNKNOWN_NETDEV_EVENT";
+48
net/core/netdev-genl-gen.c
··· 1 + // SPDX-License-Identifier: BSD-3-Clause 2 + /* Do not edit directly, auto-generated from: */ 3 + /* Documentation/netlink/specs/netdev.yaml */ 4 + /* YNL-GEN kernel source */ 5 + 6 + #include <net/netlink.h> 7 + #include <net/genetlink.h> 8 + 9 + #include "netdev-genl-gen.h" 10 + 11 + #include <linux/netdev.h> 12 + 13 + /* NETDEV_CMD_DEV_GET - do */ 14 + static const struct nla_policy netdev_dev_get_nl_policy[NETDEV_A_DEV_IFINDEX + 1] = { 15 + [NETDEV_A_DEV_IFINDEX] = NLA_POLICY_MIN(NLA_U32, 1), 16 + }; 17 + 18 + /* Ops table for netdev */ 19 + static const struct genl_split_ops netdev_nl_ops[2] = { 20 + { 21 + .cmd = NETDEV_CMD_DEV_GET, 22 + .doit = netdev_nl_dev_get_doit, 23 + .policy = netdev_dev_get_nl_policy, 24 + .maxattr = NETDEV_A_DEV_IFINDEX, 25 + .flags = GENL_CMD_CAP_DO, 26 + }, 27 + { 28 + .cmd = NETDEV_CMD_DEV_GET, 29 + .dumpit = netdev_nl_dev_get_dumpit, 30 + .flags = GENL_CMD_CAP_DUMP, 31 + }, 32 + }; 33 + 34 + static const struct genl_multicast_group netdev_nl_mcgrps[] = { 35 + [NETDEV_NLGRP_MGMT] = { "mgmt", }, 36 + }; 37 + 38 + struct genl_family netdev_nl_family __ro_after_init = { 39 + .name = NETDEV_FAMILY_NAME, 40 + .version = NETDEV_FAMILY_VERSION, 41 + .netnsok = true, 42 + .parallel_ops = true, 43 + .module = THIS_MODULE, 44 + .split_ops = netdev_nl_ops, 45 + .n_split_ops = ARRAY_SIZE(netdev_nl_ops), 46 + .mcgrps = netdev_nl_mcgrps, 47 + .n_mcgrps = ARRAY_SIZE(netdev_nl_mcgrps), 48 + };
+23
net/core/netdev-genl-gen.h
··· 1 + /* SPDX-License-Identifier: BSD-3-Clause */ 2 + /* Do not edit directly, auto-generated from: */ 3 + /* Documentation/netlink/specs/netdev.yaml */ 4 + /* YNL-GEN kernel header */ 5 + 6 + #ifndef _LINUX_NETDEV_GEN_H 7 + #define _LINUX_NETDEV_GEN_H 8 + 9 + #include <net/netlink.h> 10 + #include <net/genetlink.h> 11 + 12 + #include <linux/netdev.h> 13 + 14 + int netdev_nl_dev_get_doit(struct sk_buff *skb, struct genl_info *info); 15 + int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb); 16 + 17 + enum { 18 + NETDEV_NLGRP_MGMT, 19 + }; 20 + 21 + extern struct genl_family netdev_nl_family; 22 + 23 + #endif /* _LINUX_NETDEV_GEN_H */
+179
net/core/netdev-genl.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + 3 + #include <linux/netdevice.h> 4 + #include <linux/notifier.h> 5 + #include <linux/rtnetlink.h> 6 + #include <net/net_namespace.h> 7 + #include <net/sock.h> 8 + 9 + #include "netdev-genl-gen.h" 10 + 11 + static int 12 + netdev_nl_dev_fill(struct net_device *netdev, struct sk_buff *rsp, 13 + u32 portid, u32 seq, int flags, u32 cmd) 14 + { 15 + void *hdr; 16 + 17 + hdr = genlmsg_put(rsp, portid, seq, &netdev_nl_family, flags, cmd); 18 + if (!hdr) 19 + return -EMSGSIZE; 20 + 21 + if (nla_put_u32(rsp, NETDEV_A_DEV_IFINDEX, netdev->ifindex) || 22 + nla_put_u64_64bit(rsp, NETDEV_A_DEV_XDP_FEATURES, 23 + netdev->xdp_features, NETDEV_A_DEV_PAD)) { 24 + genlmsg_cancel(rsp, hdr); 25 + return -EINVAL; 26 + } 27 + 28 + genlmsg_end(rsp, hdr); 29 + 30 + return 0; 31 + } 32 + 33 + static void 34 + netdev_genl_dev_notify(struct net_device *netdev, int cmd) 35 + { 36 + struct sk_buff *ntf; 37 + 38 + if (!genl_has_listeners(&netdev_nl_family, dev_net(netdev), 39 + NETDEV_NLGRP_MGMT)) 40 + return; 41 + 42 + ntf = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 43 + if (!ntf) 44 + return; 45 + 46 + if (netdev_nl_dev_fill(netdev, ntf, 0, 0, 0, cmd)) { 47 + nlmsg_free(ntf); 48 + return; 49 + } 50 + 51 + genlmsg_multicast_netns(&netdev_nl_family, dev_net(netdev), ntf, 52 + 0, NETDEV_NLGRP_MGMT, GFP_KERNEL); 53 + } 54 + 55 + int netdev_nl_dev_get_doit(struct sk_buff *skb, struct genl_info *info) 56 + { 57 + struct net_device *netdev; 58 + struct sk_buff *rsp; 59 + u32 ifindex; 60 + int err; 61 + 62 + if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_DEV_IFINDEX)) 63 + return -EINVAL; 64 + 65 + ifindex = nla_get_u32(info->attrs[NETDEV_A_DEV_IFINDEX]); 66 + 67 + rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL); 68 + if (!rsp) 69 + return -ENOMEM; 70 + 71 + rtnl_lock(); 72 + 73 + netdev = __dev_get_by_index(genl_info_net(info), ifindex); 74 + if (netdev) 75 + err = netdev_nl_dev_fill(netdev, rsp, info->snd_portid, 76 + info->snd_seq, 0, info->genlhdr->cmd); 77 + else 78 + err = -ENODEV; 79 + 80 + rtnl_unlock(); 81 + 82 + if (err) 83 + goto err_free_msg; 84 + 85 + return genlmsg_reply(rsp, info); 86 + 87 + err_free_msg: 88 + nlmsg_free(rsp); 89 + return err; 90 + } 91 + 92 + int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb) 93 + { 94 + struct net *net = sock_net(skb->sk); 95 + struct net_device *netdev; 96 + int idx = 0, s_idx; 97 + int h, s_h; 98 + int err; 99 + 100 + s_h = cb->args[0]; 101 + s_idx = cb->args[1]; 102 + 103 + rtnl_lock(); 104 + 105 + for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { 106 + struct hlist_head *head; 107 + 108 + idx = 0; 109 + head = &net->dev_index_head[h]; 110 + hlist_for_each_entry(netdev, head, index_hlist) { 111 + if (idx < s_idx) 112 + goto cont; 113 + err = netdev_nl_dev_fill(netdev, skb, 114 + NETLINK_CB(cb->skb).portid, 115 + cb->nlh->nlmsg_seq, 0, 116 + NETDEV_CMD_DEV_GET); 117 + if (err < 0) 118 + break; 119 + cont: 120 + idx++; 121 + } 122 + } 123 + 124 + rtnl_unlock(); 125 + 126 + if (err != -EMSGSIZE) 127 + return err; 128 + 129 + cb->args[1] = idx; 130 + cb->args[0] = h; 131 + cb->seq = net->dev_base_seq; 132 + 133 + return skb->len; 134 + } 135 + 136 + static int netdev_genl_netdevice_event(struct notifier_block *nb, 137 + unsigned long event, void *ptr) 138 + { 139 + struct net_device *netdev = netdev_notifier_info_to_dev(ptr); 140 + 141 + switch (event) { 142 + case NETDEV_REGISTER: 143 + netdev_genl_dev_notify(netdev, NETDEV_CMD_DEV_ADD_NTF); 144 + break; 145 + case NETDEV_UNREGISTER: 146 + netdev_genl_dev_notify(netdev, NETDEV_CMD_DEV_DEL_NTF); 147 + break; 148 + case NETDEV_XDP_FEAT_CHANGE: 149 + netdev_genl_dev_notify(netdev, NETDEV_CMD_DEV_CHANGE_NTF); 150 + break; 151 + } 152 + 153 + return NOTIFY_OK; 154 + } 155 + 156 + static struct notifier_block netdev_genl_nb = { 157 + .notifier_call = netdev_genl_netdevice_event, 158 + }; 159 + 160 + static int __init netdev_genl_init(void) 161 + { 162 + int err; 163 + 164 + err = register_netdevice_notifier(&netdev_genl_nb); 165 + if (err) 166 + return err; 167 + 168 + err = genl_register_family(&netdev_nl_family); 169 + if (err) 170 + goto err_unreg_ntf; 171 + 172 + return 0; 173 + 174 + err_unreg_ntf: 175 + unregister_netdevice_notifier(&netdev_genl_nb); 176 + return err; 177 + } 178 + 179 + subsys_initcall(netdev_genl_init);
+59
tools/include/uapi/linux/netdev.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 + /* Do not edit directly, auto-generated from: */ 3 + /* Documentation/netlink/specs/netdev.yaml */ 4 + /* YNL-GEN uapi header */ 5 + 6 + #ifndef _UAPI_LINUX_NETDEV_H 7 + #define _UAPI_LINUX_NETDEV_H 8 + 9 + #define NETDEV_FAMILY_NAME "netdev" 10 + #define NETDEV_FAMILY_VERSION 1 11 + 12 + /** 13 + * enum netdev_xdp_act 14 + * @NETDEV_XDP_ACT_BASIC: XDP feautues set supported by all drivers 15 + * (XDP_ABORTED, XDP_DROP, XDP_PASS, XDP_TX) 16 + * @NETDEV_XDP_ACT_REDIRECT: The netdev supports XDP_REDIRECT 17 + * @NETDEV_XDP_ACT_NDO_XMIT: This feature informs if netdev implements 18 + * ndo_xdp_xmit callback. 19 + * @NETDEV_XDP_ACT_XSK_ZEROCOPY: This feature informs if netdev supports AF_XDP 20 + * in zero copy mode. 21 + * @NETDEV_XDP_ACT_HW_OFFLOAD: This feature informs if netdev supports XDP hw 22 + * oflloading. 23 + * @NETDEV_XDP_ACT_RX_SG: This feature informs if netdev implements non-linear 24 + * XDP buffer support in the driver napi callback. 25 + * @NETDEV_XDP_ACT_NDO_XMIT_SG: This feature informs if netdev implements 26 + * non-linear XDP buffer support in ndo_xdp_xmit callback. 27 + */ 28 + enum netdev_xdp_act { 29 + NETDEV_XDP_ACT_BASIC = 1, 30 + NETDEV_XDP_ACT_REDIRECT = 2, 31 + NETDEV_XDP_ACT_NDO_XMIT = 4, 32 + NETDEV_XDP_ACT_XSK_ZEROCOPY = 8, 33 + NETDEV_XDP_ACT_HW_OFFLOAD = 16, 34 + NETDEV_XDP_ACT_RX_SG = 32, 35 + NETDEV_XDP_ACT_NDO_XMIT_SG = 64, 36 + }; 37 + 38 + enum { 39 + NETDEV_A_DEV_IFINDEX = 1, 40 + NETDEV_A_DEV_PAD, 41 + NETDEV_A_DEV_XDP_FEATURES, 42 + 43 + __NETDEV_A_DEV_MAX, 44 + NETDEV_A_DEV_MAX = (__NETDEV_A_DEV_MAX - 1) 45 + }; 46 + 47 + enum { 48 + NETDEV_CMD_DEV_GET = 1, 49 + NETDEV_CMD_DEV_ADD_NTF, 50 + NETDEV_CMD_DEV_DEL_NTF, 51 + NETDEV_CMD_DEV_CHANGE_NTF, 52 + 53 + __NETDEV_CMD_MAX, 54 + NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1) 55 + }; 56 + 57 + #define NETDEV_MCGRP_MGMT "mgmt" 58 + 59 + #endif /* _UAPI_LINUX_NETDEV_H */