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>
2023-02-01 11:24:17 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
|
|
|
|
|
|
|
#include <linux/netdevice.h>
|
|
|
|
#include <linux/notifier.h>
|
|
|
|
#include <linux/rtnetlink.h>
|
2024-09-10 17:14:47 +00:00
|
|
|
#include <net/busy_poll.h>
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
#include <net/net_namespace.h>
|
2024-09-10 17:14:47 +00:00
|
|
|
#include <net/netdev_queues.h>
|
|
|
|
#include <net/netdev_rx_queue.h>
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
#include <net/sock.h>
|
2023-09-13 10:13:49 -07:00
|
|
|
#include <net/xdp.h>
|
2023-11-27 11:03:08 -08:00
|
|
|
#include <net/xdp_sock.h>
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
|
2023-12-01 15:28:56 -08:00
|
|
|
#include "dev.h"
|
2024-09-10 17:14:47 +00:00
|
|
|
#include "devmem.h"
|
|
|
|
#include "netdev-genl-gen.h"
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
|
2023-12-01 15:28:46 -08:00
|
|
|
struct netdev_nl_dump_ctx {
|
|
|
|
unsigned long ifindex;
|
|
|
|
unsigned int rxq_idx;
|
|
|
|
unsigned int txq_idx;
|
2023-12-01 15:28:56 -08:00
|
|
|
unsigned int napi_id;
|
2023-12-01 15:28:46 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
static struct netdev_nl_dump_ctx *netdev_dump_ctx(struct netlink_callback *cb)
|
|
|
|
{
|
2024-10-09 10:09:47 +02:00
|
|
|
NL_ASSERT_CTX_FITS(struct netdev_nl_dump_ctx);
|
2023-12-01 15:28:46 -08:00
|
|
|
|
|
|
|
return (struct netdev_nl_dump_ctx *)cb->ctx;
|
|
|
|
}
|
|
|
|
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
static int
|
|
|
|
netdev_nl_dev_fill(struct net_device *netdev, struct sk_buff *rsp,
|
2023-08-14 14:47:21 -07:00
|
|
|
const struct genl_info *info)
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
{
|
2023-11-27 11:03:08 -08:00
|
|
|
u64 xsk_features = 0;
|
2023-09-13 10:13:49 -07:00
|
|
|
u64 xdp_rx_meta = 0;
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
void *hdr;
|
|
|
|
|
2023-08-14 14:47:21 -07:00
|
|
|
hdr = genlmsg_iput(rsp, info);
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
if (!hdr)
|
|
|
|
return -EMSGSIZE;
|
|
|
|
|
2023-09-13 10:13:49 -07:00
|
|
|
#define XDP_METADATA_KFUNC(_, flag, __, xmo) \
|
|
|
|
if (netdev->xdp_metadata_ops && netdev->xdp_metadata_ops->xmo) \
|
|
|
|
xdp_rx_meta |= flag;
|
|
|
|
XDP_METADATA_KFUNC_xxx
|
|
|
|
#undef XDP_METADATA_KFUNC
|
|
|
|
|
2023-11-27 11:03:08 -08:00
|
|
|
if (netdev->xsk_tx_metadata_ops) {
|
|
|
|
if (netdev->xsk_tx_metadata_ops->tmo_fill_timestamp)
|
|
|
|
xsk_features |= NETDEV_XSK_FLAGS_TX_TIMESTAMP;
|
|
|
|
if (netdev->xsk_tx_metadata_ops->tmo_request_checksum)
|
|
|
|
xsk_features |= NETDEV_XSK_FLAGS_TX_CHECKSUM;
|
|
|
|
}
|
|
|
|
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
if (nla_put_u32(rsp, NETDEV_A_DEV_IFINDEX, netdev->ifindex) ||
|
|
|
|
nla_put_u64_64bit(rsp, NETDEV_A_DEV_XDP_FEATURES,
|
2023-09-13 10:13:49 -07:00
|
|
|
netdev->xdp_features, NETDEV_A_DEV_PAD) ||
|
|
|
|
nla_put_u64_64bit(rsp, NETDEV_A_DEV_XDP_RX_METADATA_FEATURES,
|
2023-11-27 11:03:08 -08:00
|
|
|
xdp_rx_meta, NETDEV_A_DEV_PAD) ||
|
|
|
|
nla_put_u64_64bit(rsp, NETDEV_A_DEV_XSK_FEATURES,
|
2024-06-13 14:30:44 -07:00
|
|
|
xsk_features, NETDEV_A_DEV_PAD))
|
|
|
|
goto err_cancel_msg;
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
|
2023-07-19 15:24:07 +02:00
|
|
|
if (netdev->xdp_features & NETDEV_XDP_ACT_XSK_ZEROCOPY) {
|
|
|
|
if (nla_put_u32(rsp, NETDEV_A_DEV_XDP_ZC_MAX_SEGS,
|
2024-06-13 14:30:44 -07:00
|
|
|
netdev->xdp_zc_max_segs))
|
|
|
|
goto err_cancel_msg;
|
2023-07-19 15:24:07 +02:00
|
|
|
}
|
|
|
|
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
genlmsg_end(rsp, hdr);
|
|
|
|
|
|
|
|
return 0;
|
2024-06-13 14:30:44 -07:00
|
|
|
|
|
|
|
err_cancel_msg:
|
|
|
|
genlmsg_cancel(rsp, hdr);
|
|
|
|
return -EMSGSIZE;
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
netdev_genl_dev_notify(struct net_device *netdev, int cmd)
|
|
|
|
{
|
2023-08-14 14:47:21 -07:00
|
|
|
struct genl_info info;
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
struct sk_buff *ntf;
|
|
|
|
|
|
|
|
if (!genl_has_listeners(&netdev_nl_family, dev_net(netdev),
|
|
|
|
NETDEV_NLGRP_MGMT))
|
|
|
|
return;
|
|
|
|
|
2023-08-14 14:47:21 -07:00
|
|
|
genl_info_init_ntf(&info, &netdev_nl_family, cmd);
|
|
|
|
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
ntf = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
|
|
|
if (!ntf)
|
|
|
|
return;
|
|
|
|
|
2023-08-14 14:47:21 -07:00
|
|
|
if (netdev_nl_dev_fill(netdev, ntf, &info)) {
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
nlmsg_free(ntf);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
genlmsg_multicast_netns(&netdev_nl_family, dev_net(netdev), ntf,
|
|
|
|
0, NETDEV_NLGRP_MGMT, GFP_KERNEL);
|
|
|
|
}
|
|
|
|
|
|
|
|
int netdev_nl_dev_get_doit(struct sk_buff *skb, struct genl_info *info)
|
|
|
|
{
|
|
|
|
struct net_device *netdev;
|
|
|
|
struct sk_buff *rsp;
|
|
|
|
u32 ifindex;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_DEV_IFINDEX))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
ifindex = nla_get_u32(info->attrs[NETDEV_A_DEV_IFINDEX]);
|
|
|
|
|
|
|
|
rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
|
|
|
if (!rsp)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
rtnl_lock();
|
|
|
|
|
|
|
|
netdev = __dev_get_by_index(genl_info_net(info), ifindex);
|
|
|
|
if (netdev)
|
2023-08-14 14:47:21 -07:00
|
|
|
err = netdev_nl_dev_fill(netdev, rsp, info);
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
else
|
|
|
|
err = -ENODEV;
|
|
|
|
|
|
|
|
rtnl_unlock();
|
|
|
|
|
|
|
|
if (err)
|
|
|
|
goto err_free_msg;
|
|
|
|
|
|
|
|
return genlmsg_reply(rsp, info);
|
|
|
|
|
|
|
|
err_free_msg:
|
|
|
|
nlmsg_free(rsp);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
int netdev_nl_dev_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
|
|
|
|
{
|
2023-12-01 15:28:46 -08:00
|
|
|
struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb);
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
struct net *net = sock_net(skb->sk);
|
|
|
|
struct net_device *netdev;
|
2023-07-26 11:55:30 -07:00
|
|
|
int err = 0;
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
|
|
|
|
rtnl_lock();
|
2023-12-01 15:28:46 -08:00
|
|
|
for_each_netdev_dump(net, netdev, ctx->ifindex) {
|
2023-08-14 14:47:21 -07:00
|
|
|
err = netdev_nl_dev_fill(netdev, skb, genl_info_dump(cb));
|
2023-07-26 11:55:30 -07:00
|
|
|
if (err < 0)
|
|
|
|
break;
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
}
|
|
|
|
rtnl_unlock();
|
|
|
|
|
2024-03-02 21:24:07 -08:00
|
|
|
return err;
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
}
|
|
|
|
|
2023-12-01 15:28:56 -08:00
|
|
|
static int
|
|
|
|
netdev_nl_napi_fill_one(struct sk_buff *rsp, struct napi_struct *napi,
|
|
|
|
const struct genl_info *info)
|
|
|
|
{
|
2024-11-09 05:02:31 +00:00
|
|
|
unsigned long irq_suspend_timeout;
|
2024-10-11 18:44:59 +00:00
|
|
|
unsigned long gro_flush_timeout;
|
2024-10-11 18:44:57 +00:00
|
|
|
u32 napi_defer_hard_irqs;
|
2023-12-01 15:28:56 -08:00
|
|
|
void *hdr;
|
2023-12-01 15:29:18 -08:00
|
|
|
pid_t pid;
|
2023-12-01 15:28:56 -08:00
|
|
|
|
|
|
|
if (!(napi->dev->flags & IFF_UP))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
hdr = genlmsg_iput(rsp, info);
|
|
|
|
if (!hdr)
|
|
|
|
return -EMSGSIZE;
|
|
|
|
|
2025-01-03 10:32:07 -08:00
|
|
|
if (nla_put_u32(rsp, NETDEV_A_NAPI_ID, napi->napi_id))
|
2023-12-01 15:28:56 -08:00
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
|
|
if (nla_put_u32(rsp, NETDEV_A_NAPI_IFINDEX, napi->dev->ifindex))
|
|
|
|
goto nla_put_failure;
|
|
|
|
|
2023-12-01 15:29:07 -08:00
|
|
|
if (napi->irq >= 0 && nla_put_u32(rsp, NETDEV_A_NAPI_IRQ, napi->irq))
|
|
|
|
goto nla_put_failure;
|
|
|
|
|
2023-12-01 15:29:18 -08:00
|
|
|
if (napi->thread) {
|
|
|
|
pid = task_pid_nr(napi->thread);
|
|
|
|
if (nla_put_u32(rsp, NETDEV_A_NAPI_PID, pid))
|
|
|
|
goto nla_put_failure;
|
|
|
|
}
|
|
|
|
|
2024-10-11 18:44:57 +00:00
|
|
|
napi_defer_hard_irqs = napi_get_defer_hard_irqs(napi);
|
|
|
|
if (nla_put_s32(rsp, NETDEV_A_NAPI_DEFER_HARD_IRQS,
|
|
|
|
napi_defer_hard_irqs))
|
|
|
|
goto nla_put_failure;
|
|
|
|
|
2024-11-09 05:02:31 +00:00
|
|
|
irq_suspend_timeout = napi_get_irq_suspend_timeout(napi);
|
|
|
|
if (nla_put_uint(rsp, NETDEV_A_NAPI_IRQ_SUSPEND_TIMEOUT,
|
|
|
|
irq_suspend_timeout))
|
|
|
|
goto nla_put_failure;
|
|
|
|
|
2024-10-11 18:44:59 +00:00
|
|
|
gro_flush_timeout = napi_get_gro_flush_timeout(napi);
|
|
|
|
if (nla_put_uint(rsp, NETDEV_A_NAPI_GRO_FLUSH_TIMEOUT,
|
|
|
|
gro_flush_timeout))
|
|
|
|
goto nla_put_failure;
|
|
|
|
|
2023-12-01 15:28:56 -08:00
|
|
|
genlmsg_end(rsp, hdr);
|
2023-12-01 15:29:07 -08:00
|
|
|
|
2023-12-01 15:28:56 -08:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
nla_put_failure:
|
|
|
|
genlmsg_cancel(rsp, hdr);
|
|
|
|
return -EMSGSIZE;
|
|
|
|
}
|
|
|
|
|
2023-12-01 15:28:51 -08:00
|
|
|
int netdev_nl_napi_get_doit(struct sk_buff *skb, struct genl_info *info)
|
|
|
|
{
|
2023-12-01 15:28:56 -08:00
|
|
|
struct napi_struct *napi;
|
|
|
|
struct sk_buff *rsp;
|
|
|
|
u32 napi_id;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_NAPI_ID))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
napi_id = nla_get_u32(info->attrs[NETDEV_A_NAPI_ID]);
|
|
|
|
|
|
|
|
rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
|
|
|
if (!rsp)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
rtnl_lock();
|
2024-11-14 17:51:56 +00:00
|
|
|
rcu_read_lock();
|
2023-12-01 15:28:56 -08:00
|
|
|
|
2025-01-06 10:01:36 -08:00
|
|
|
napi = netdev_napi_by_id(genl_info_net(info), napi_id);
|
2024-08-31 12:17:04 +00:00
|
|
|
if (napi) {
|
2023-12-01 15:28:56 -08:00
|
|
|
err = netdev_nl_napi_fill_one(rsp, napi, info);
|
2024-08-31 12:17:04 +00:00
|
|
|
} else {
|
|
|
|
NL_SET_BAD_ATTR(info->extack, info->attrs[NETDEV_A_NAPI_ID]);
|
|
|
|
err = -ENOENT;
|
|
|
|
}
|
2023-12-01 15:28:56 -08:00
|
|
|
|
2024-11-14 17:51:56 +00:00
|
|
|
rcu_read_unlock();
|
2023-12-01 15:28:56 -08:00
|
|
|
rtnl_unlock();
|
|
|
|
|
2024-12-18 19:28:32 -08:00
|
|
|
if (err) {
|
|
|
|
goto err_free_msg;
|
|
|
|
} else if (!rsp->len) {
|
|
|
|
err = -ENOENT;
|
2023-12-01 15:28:56 -08:00
|
|
|
goto err_free_msg;
|
2024-12-18 19:28:32 -08:00
|
|
|
}
|
2023-12-01 15:28:56 -08:00
|
|
|
|
|
|
|
return genlmsg_reply(rsp, info);
|
|
|
|
|
|
|
|
err_free_msg:
|
|
|
|
nlmsg_free(rsp);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
netdev_nl_napi_dump_one(struct net_device *netdev, struct sk_buff *rsp,
|
|
|
|
const struct genl_info *info,
|
|
|
|
struct netdev_nl_dump_ctx *ctx)
|
|
|
|
{
|
|
|
|
struct napi_struct *napi;
|
2025-01-09 16:45:04 -08:00
|
|
|
unsigned int prev_id;
|
2023-12-01 15:28:56 -08:00
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
if (!(netdev->flags & IFF_UP))
|
|
|
|
return err;
|
|
|
|
|
2025-01-09 16:45:04 -08:00
|
|
|
prev_id = UINT_MAX;
|
2023-12-01 15:28:56 -08:00
|
|
|
list_for_each_entry(napi, &netdev->napi_list, dev_list) {
|
2025-01-03 10:32:07 -08:00
|
|
|
if (napi->napi_id < MIN_NAPI_ID)
|
|
|
|
continue;
|
2025-01-09 16:45:04 -08:00
|
|
|
|
|
|
|
/* Dump continuation below depends on the list being sorted */
|
|
|
|
WARN_ON_ONCE(napi->napi_id >= prev_id);
|
|
|
|
prev_id = napi->napi_id;
|
|
|
|
|
2023-12-01 15:28:56 -08:00
|
|
|
if (ctx->napi_id && napi->napi_id >= ctx->napi_id)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
err = netdev_nl_napi_fill_one(rsp, napi, info);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
ctx->napi_id = napi->napi_id;
|
|
|
|
}
|
|
|
|
return err;
|
2023-12-01 15:28:51 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
int netdev_nl_napi_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
|
|
|
|
{
|
2023-12-01 15:28:56 -08:00
|
|
|
struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb);
|
|
|
|
const struct genl_info *info = genl_info_dump(cb);
|
|
|
|
struct net *net = sock_net(skb->sk);
|
|
|
|
struct net_device *netdev;
|
|
|
|
u32 ifindex = 0;
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
if (info->attrs[NETDEV_A_NAPI_IFINDEX])
|
|
|
|
ifindex = nla_get_u32(info->attrs[NETDEV_A_NAPI_IFINDEX]);
|
|
|
|
|
|
|
|
rtnl_lock();
|
|
|
|
if (ifindex) {
|
|
|
|
netdev = __dev_get_by_index(net, ifindex);
|
|
|
|
if (netdev)
|
|
|
|
err = netdev_nl_napi_dump_one(netdev, skb, info, ctx);
|
|
|
|
else
|
|
|
|
err = -ENODEV;
|
|
|
|
} else {
|
|
|
|
for_each_netdev_dump(net, netdev, ctx->ifindex) {
|
|
|
|
err = netdev_nl_napi_dump_one(netdev, skb, info, ctx);
|
|
|
|
if (err < 0)
|
|
|
|
break;
|
|
|
|
ctx->napi_id = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
rtnl_unlock();
|
|
|
|
|
2024-03-02 21:24:07 -08:00
|
|
|
return err;
|
2023-12-01 15:28:51 -08:00
|
|
|
}
|
|
|
|
|
2024-10-11 18:45:01 +00:00
|
|
|
static int
|
|
|
|
netdev_nl_napi_set_config(struct napi_struct *napi, struct genl_info *info)
|
|
|
|
{
|
2024-11-09 05:02:31 +00:00
|
|
|
u64 irq_suspend_timeout = 0;
|
2024-10-11 18:45:01 +00:00
|
|
|
u64 gro_flush_timeout = 0;
|
|
|
|
u32 defer = 0;
|
|
|
|
|
|
|
|
if (info->attrs[NETDEV_A_NAPI_DEFER_HARD_IRQS]) {
|
|
|
|
defer = nla_get_u32(info->attrs[NETDEV_A_NAPI_DEFER_HARD_IRQS]);
|
|
|
|
napi_set_defer_hard_irqs(napi, defer);
|
|
|
|
}
|
|
|
|
|
2024-11-09 05:02:31 +00:00
|
|
|
if (info->attrs[NETDEV_A_NAPI_IRQ_SUSPEND_TIMEOUT]) {
|
|
|
|
irq_suspend_timeout = nla_get_uint(info->attrs[NETDEV_A_NAPI_IRQ_SUSPEND_TIMEOUT]);
|
|
|
|
napi_set_irq_suspend_timeout(napi, irq_suspend_timeout);
|
|
|
|
}
|
|
|
|
|
2024-10-11 18:45:01 +00:00
|
|
|
if (info->attrs[NETDEV_A_NAPI_GRO_FLUSH_TIMEOUT]) {
|
|
|
|
gro_flush_timeout = nla_get_uint(info->attrs[NETDEV_A_NAPI_GRO_FLUSH_TIMEOUT]);
|
|
|
|
napi_set_gro_flush_timeout(napi, gro_flush_timeout);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int netdev_nl_napi_set_doit(struct sk_buff *skb, struct genl_info *info)
|
|
|
|
{
|
|
|
|
struct napi_struct *napi;
|
|
|
|
unsigned int napi_id;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_NAPI_ID))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
napi_id = nla_get_u32(info->attrs[NETDEV_A_NAPI_ID]);
|
|
|
|
|
|
|
|
rtnl_lock();
|
2024-11-14 17:55:59 +00:00
|
|
|
rcu_read_lock();
|
2024-10-11 18:45:01 +00:00
|
|
|
|
2025-01-06 10:01:36 -08:00
|
|
|
napi = netdev_napi_by_id(genl_info_net(info), napi_id);
|
2024-10-11 18:45:01 +00:00
|
|
|
if (napi) {
|
|
|
|
err = netdev_nl_napi_set_config(napi, info);
|
|
|
|
} else {
|
|
|
|
NL_SET_BAD_ATTR(info->extack, info->attrs[NETDEV_A_NAPI_ID]);
|
|
|
|
err = -ENOENT;
|
|
|
|
}
|
|
|
|
|
2024-11-14 17:55:59 +00:00
|
|
|
rcu_read_unlock();
|
2024-10-11 18:45:01 +00:00
|
|
|
rtnl_unlock();
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2023-12-01 15:28:46 -08:00
|
|
|
static int
|
|
|
|
netdev_nl_queue_fill_one(struct sk_buff *rsp, struct net_device *netdev,
|
|
|
|
u32 q_idx, u32 q_type, const struct genl_info *info)
|
|
|
|
{
|
netdev: add dmabuf introspection
Add dmabuf information to page_pool stats:
$ ./cli.py --spec ../netlink/specs/netdev.yaml --dump page-pool-get
...
{'dmabuf': 10,
'id': 456,
'ifindex': 3,
'inflight': 1023,
'inflight-mem': 4190208},
{'dmabuf': 10,
'id': 455,
'ifindex': 3,
'inflight': 1023,
'inflight-mem': 4190208},
{'dmabuf': 10,
'id': 454,
'ifindex': 3,
'inflight': 1023,
'inflight-mem': 4190208},
{'dmabuf': 10,
'id': 453,
'ifindex': 3,
'inflight': 1023,
'inflight-mem': 4190208},
{'dmabuf': 10,
'id': 452,
'ifindex': 3,
'inflight': 1023,
'inflight-mem': 4190208},
{'dmabuf': 10,
'id': 451,
'ifindex': 3,
'inflight': 1023,
'inflight-mem': 4190208},
{'dmabuf': 10,
'id': 450,
'ifindex': 3,
'inflight': 1023,
'inflight-mem': 4190208},
{'dmabuf': 10,
'id': 449,
'ifindex': 3,
'inflight': 1023,
'inflight-mem': 4190208},
And queue stats:
$ ./cli.py --spec ../netlink/specs/netdev.yaml --dump queue-get
...
{'dmabuf': 10, 'id': 8, 'ifindex': 3, 'type': 'rx'},
{'dmabuf': 10, 'id': 9, 'ifindex': 3, 'type': 'rx'},
{'dmabuf': 10, 'id': 10, 'ifindex': 3, 'type': 'rx'},
{'dmabuf': 10, 'id': 11, 'ifindex': 3, 'type': 'rx'},
{'dmabuf': 10, 'id': 12, 'ifindex': 3, 'type': 'rx'},
{'dmabuf': 10, 'id': 13, 'ifindex': 3, 'type': 'rx'},
{'dmabuf': 10, 'id': 14, 'ifindex': 3, 'type': 'rx'},
{'dmabuf': 10, 'id': 15, 'ifindex': 3, 'type': 'rx'},
Suggested-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Mina Almasry <almasrymina@google.com>
Reviewed-by: Jakub Kicinski <kuba@kernel.org>
Link: https://patch.msgid.link/20240910171458.219195-14-almasrymina@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2024-09-10 17:14:57 +00:00
|
|
|
struct net_devmem_dmabuf_binding *binding;
|
2023-12-01 15:28:46 -08:00
|
|
|
struct netdev_rx_queue *rxq;
|
|
|
|
struct netdev_queue *txq;
|
|
|
|
void *hdr;
|
|
|
|
|
|
|
|
hdr = genlmsg_iput(rsp, info);
|
|
|
|
if (!hdr)
|
|
|
|
return -EMSGSIZE;
|
|
|
|
|
|
|
|
if (nla_put_u32(rsp, NETDEV_A_QUEUE_ID, q_idx) ||
|
|
|
|
nla_put_u32(rsp, NETDEV_A_QUEUE_TYPE, q_type) ||
|
|
|
|
nla_put_u32(rsp, NETDEV_A_QUEUE_IFINDEX, netdev->ifindex))
|
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
|
|
switch (q_type) {
|
|
|
|
case NETDEV_QUEUE_TYPE_RX:
|
|
|
|
rxq = __netif_get_rx_queue(netdev, q_idx);
|
|
|
|
if (rxq->napi && nla_put_u32(rsp, NETDEV_A_QUEUE_NAPI_ID,
|
|
|
|
rxq->napi->napi_id))
|
|
|
|
goto nla_put_failure;
|
netdev: add dmabuf introspection
Add dmabuf information to page_pool stats:
$ ./cli.py --spec ../netlink/specs/netdev.yaml --dump page-pool-get
...
{'dmabuf': 10,
'id': 456,
'ifindex': 3,
'inflight': 1023,
'inflight-mem': 4190208},
{'dmabuf': 10,
'id': 455,
'ifindex': 3,
'inflight': 1023,
'inflight-mem': 4190208},
{'dmabuf': 10,
'id': 454,
'ifindex': 3,
'inflight': 1023,
'inflight-mem': 4190208},
{'dmabuf': 10,
'id': 453,
'ifindex': 3,
'inflight': 1023,
'inflight-mem': 4190208},
{'dmabuf': 10,
'id': 452,
'ifindex': 3,
'inflight': 1023,
'inflight-mem': 4190208},
{'dmabuf': 10,
'id': 451,
'ifindex': 3,
'inflight': 1023,
'inflight-mem': 4190208},
{'dmabuf': 10,
'id': 450,
'ifindex': 3,
'inflight': 1023,
'inflight-mem': 4190208},
{'dmabuf': 10,
'id': 449,
'ifindex': 3,
'inflight': 1023,
'inflight-mem': 4190208},
And queue stats:
$ ./cli.py --spec ../netlink/specs/netdev.yaml --dump queue-get
...
{'dmabuf': 10, 'id': 8, 'ifindex': 3, 'type': 'rx'},
{'dmabuf': 10, 'id': 9, 'ifindex': 3, 'type': 'rx'},
{'dmabuf': 10, 'id': 10, 'ifindex': 3, 'type': 'rx'},
{'dmabuf': 10, 'id': 11, 'ifindex': 3, 'type': 'rx'},
{'dmabuf': 10, 'id': 12, 'ifindex': 3, 'type': 'rx'},
{'dmabuf': 10, 'id': 13, 'ifindex': 3, 'type': 'rx'},
{'dmabuf': 10, 'id': 14, 'ifindex': 3, 'type': 'rx'},
{'dmabuf': 10, 'id': 15, 'ifindex': 3, 'type': 'rx'},
Suggested-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Mina Almasry <almasrymina@google.com>
Reviewed-by: Jakub Kicinski <kuba@kernel.org>
Link: https://patch.msgid.link/20240910171458.219195-14-almasrymina@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2024-09-10 17:14:57 +00:00
|
|
|
|
|
|
|
binding = rxq->mp_params.mp_priv;
|
|
|
|
if (binding &&
|
|
|
|
nla_put_u32(rsp, NETDEV_A_QUEUE_DMABUF, binding->id))
|
|
|
|
goto nla_put_failure;
|
|
|
|
|
2023-12-01 15:28:46 -08:00
|
|
|
break;
|
|
|
|
case NETDEV_QUEUE_TYPE_TX:
|
|
|
|
txq = netdev_get_tx_queue(netdev, q_idx);
|
|
|
|
if (txq->napi && nla_put_u32(rsp, NETDEV_A_QUEUE_NAPI_ID,
|
|
|
|
txq->napi->napi_id))
|
|
|
|
goto nla_put_failure;
|
|
|
|
}
|
|
|
|
|
|
|
|
genlmsg_end(rsp, hdr);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
nla_put_failure:
|
|
|
|
genlmsg_cancel(rsp, hdr);
|
|
|
|
return -EMSGSIZE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int netdev_nl_queue_validate(struct net_device *netdev, u32 q_id,
|
|
|
|
u32 q_type)
|
|
|
|
{
|
|
|
|
switch (q_type) {
|
|
|
|
case NETDEV_QUEUE_TYPE_RX:
|
|
|
|
if (q_id >= netdev->real_num_rx_queues)
|
|
|
|
return -EINVAL;
|
|
|
|
return 0;
|
|
|
|
case NETDEV_QUEUE_TYPE_TX:
|
|
|
|
if (q_id >= netdev->real_num_tx_queues)
|
|
|
|
return -EINVAL;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
netdev_nl_queue_fill(struct sk_buff *rsp, struct net_device *netdev, u32 q_idx,
|
|
|
|
u32 q_type, const struct genl_info *info)
|
|
|
|
{
|
2024-12-17 18:25:08 -08:00
|
|
|
int err;
|
2023-12-01 15:28:46 -08:00
|
|
|
|
|
|
|
if (!(netdev->flags & IFF_UP))
|
2024-12-17 18:25:08 -08:00
|
|
|
return -ENOENT;
|
2023-12-01 15:28:46 -08:00
|
|
|
|
|
|
|
err = netdev_nl_queue_validate(netdev, q_idx, q_type);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
return netdev_nl_queue_fill_one(rsp, netdev, q_idx, q_type, info);
|
|
|
|
}
|
|
|
|
|
2023-12-01 15:28:29 -08:00
|
|
|
int netdev_nl_queue_get_doit(struct sk_buff *skb, struct genl_info *info)
|
|
|
|
{
|
2023-12-01 15:28:46 -08:00
|
|
|
u32 q_id, q_type, ifindex;
|
|
|
|
struct net_device *netdev;
|
|
|
|
struct sk_buff *rsp;
|
|
|
|
int err;
|
|
|
|
|
|
|
|
if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_QUEUE_ID) ||
|
|
|
|
GENL_REQ_ATTR_CHECK(info, NETDEV_A_QUEUE_TYPE) ||
|
|
|
|
GENL_REQ_ATTR_CHECK(info, NETDEV_A_QUEUE_IFINDEX))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
q_id = nla_get_u32(info->attrs[NETDEV_A_QUEUE_ID]);
|
|
|
|
q_type = nla_get_u32(info->attrs[NETDEV_A_QUEUE_TYPE]);
|
|
|
|
ifindex = nla_get_u32(info->attrs[NETDEV_A_QUEUE_IFINDEX]);
|
|
|
|
|
|
|
|
rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
|
|
|
if (!rsp)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
rtnl_lock();
|
|
|
|
|
|
|
|
netdev = __dev_get_by_index(genl_info_net(info), ifindex);
|
|
|
|
if (netdev)
|
|
|
|
err = netdev_nl_queue_fill(rsp, netdev, q_id, q_type, info);
|
|
|
|
else
|
|
|
|
err = -ENODEV;
|
|
|
|
|
|
|
|
rtnl_unlock();
|
|
|
|
|
|
|
|
if (err)
|
|
|
|
goto err_free_msg;
|
|
|
|
|
|
|
|
return genlmsg_reply(rsp, info);
|
|
|
|
|
|
|
|
err_free_msg:
|
|
|
|
nlmsg_free(rsp);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
netdev_nl_queue_dump_one(struct net_device *netdev, struct sk_buff *rsp,
|
|
|
|
const struct genl_info *info,
|
|
|
|
struct netdev_nl_dump_ctx *ctx)
|
|
|
|
{
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
if (!(netdev->flags & IFF_UP))
|
|
|
|
return err;
|
|
|
|
|
2024-12-13 07:22:40 -08:00
|
|
|
for (; ctx->rxq_idx < netdev->real_num_rx_queues; ctx->rxq_idx++) {
|
|
|
|
err = netdev_nl_queue_fill_one(rsp, netdev, ctx->rxq_idx,
|
2023-12-01 15:28:46 -08:00
|
|
|
NETDEV_QUEUE_TYPE_RX, info);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
}
|
2024-12-13 07:22:40 -08:00
|
|
|
for (; ctx->txq_idx < netdev->real_num_tx_queues; ctx->txq_idx++) {
|
|
|
|
err = netdev_nl_queue_fill_one(rsp, netdev, ctx->txq_idx,
|
2023-12-01 15:28:46 -08:00
|
|
|
NETDEV_QUEUE_TYPE_TX, info);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
return err;
|
2023-12-01 15:28:29 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
int netdev_nl_queue_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
|
|
|
|
{
|
2023-12-01 15:28:46 -08:00
|
|
|
struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb);
|
|
|
|
const struct genl_info *info = genl_info_dump(cb);
|
|
|
|
struct net *net = sock_net(skb->sk);
|
|
|
|
struct net_device *netdev;
|
|
|
|
u32 ifindex = 0;
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
if (info->attrs[NETDEV_A_QUEUE_IFINDEX])
|
|
|
|
ifindex = nla_get_u32(info->attrs[NETDEV_A_QUEUE_IFINDEX]);
|
|
|
|
|
|
|
|
rtnl_lock();
|
|
|
|
if (ifindex) {
|
|
|
|
netdev = __dev_get_by_index(net, ifindex);
|
|
|
|
if (netdev)
|
|
|
|
err = netdev_nl_queue_dump_one(netdev, skb, info, ctx);
|
|
|
|
else
|
|
|
|
err = -ENODEV;
|
|
|
|
} else {
|
|
|
|
for_each_netdev_dump(net, netdev, ctx->ifindex) {
|
|
|
|
err = netdev_nl_queue_dump_one(netdev, skb, info, ctx);
|
|
|
|
if (err < 0)
|
|
|
|
break;
|
|
|
|
ctx->rxq_idx = 0;
|
|
|
|
ctx->txq_idx = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
rtnl_unlock();
|
|
|
|
|
2024-03-02 21:24:07 -08:00
|
|
|
return err;
|
2023-12-01 15:28:29 -08:00
|
|
|
}
|
|
|
|
|
2024-03-06 11:55:07 -08:00
|
|
|
#define NETDEV_STAT_NOT_SET (~0ULL)
|
|
|
|
|
|
|
|
static void netdev_nl_stats_add(void *_sum, const void *_add, size_t size)
|
|
|
|
{
|
|
|
|
const u64 *add = _add;
|
|
|
|
u64 *sum = _sum;
|
|
|
|
|
|
|
|
while (size) {
|
|
|
|
if (*add != NETDEV_STAT_NOT_SET && *sum != NETDEV_STAT_NOT_SET)
|
|
|
|
*sum += *add;
|
|
|
|
sum++;
|
|
|
|
add++;
|
|
|
|
size -= 8;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int netdev_stat_put(struct sk_buff *rsp, unsigned int attr_id, u64 value)
|
|
|
|
{
|
|
|
|
if (value == NETDEV_STAT_NOT_SET)
|
|
|
|
return 0;
|
|
|
|
return nla_put_uint(rsp, attr_id, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
netdev_nl_stats_write_rx(struct sk_buff *rsp, struct netdev_queue_stats_rx *rx)
|
|
|
|
{
|
|
|
|
if (netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_PACKETS, rx->packets) ||
|
2024-03-06 11:55:08 -08:00
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_BYTES, rx->bytes) ||
|
2024-04-26 11:39:27 +08:00
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_ALLOC_FAIL, rx->alloc_fail) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_HW_DROPS, rx->hw_drops) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_HW_DROP_OVERRUNS, rx->hw_drop_overruns) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_CSUM_UNNECESSARY, rx->csum_unnecessary) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_CSUM_NONE, rx->csum_none) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_CSUM_BAD, rx->csum_bad) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_HW_GRO_PACKETS, rx->hw_gro_packets) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_HW_GRO_BYTES, rx->hw_gro_bytes) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_HW_GRO_WIRE_PACKETS, rx->hw_gro_wire_packets) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_HW_GRO_WIRE_BYTES, rx->hw_gro_wire_bytes) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_RX_HW_DROP_RATELIMITS, rx->hw_drop_ratelimits))
|
2024-03-06 11:55:07 -08:00
|
|
|
return -EMSGSIZE;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
netdev_nl_stats_write_tx(struct sk_buff *rsp, struct netdev_queue_stats_tx *tx)
|
|
|
|
{
|
|
|
|
if (netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_PACKETS, tx->packets) ||
|
2024-04-26 11:39:27 +08:00
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_BYTES, tx->bytes) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_HW_DROPS, tx->hw_drops) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_HW_DROP_ERRORS, tx->hw_drop_errors) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_CSUM_NONE, tx->csum_none) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_NEEDS_CSUM, tx->needs_csum) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_HW_GSO_PACKETS, tx->hw_gso_packets) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_HW_GSO_BYTES, tx->hw_gso_bytes) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_HW_GSO_WIRE_PACKETS, tx->hw_gso_wire_packets) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_HW_GSO_WIRE_BYTES, tx->hw_gso_wire_bytes) ||
|
2024-05-10 23:19:26 +03:00
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_HW_DROP_RATELIMITS, tx->hw_drop_ratelimits) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_STOP, tx->stop) ||
|
|
|
|
netdev_stat_put(rsp, NETDEV_A_QSTATS_TX_WAKE, tx->wake))
|
2024-03-06 11:55:07 -08:00
|
|
|
return -EMSGSIZE;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
netdev_nl_stats_queue(struct net_device *netdev, struct sk_buff *rsp,
|
|
|
|
u32 q_type, int i, const struct genl_info *info)
|
|
|
|
{
|
|
|
|
const struct netdev_stat_ops *ops = netdev->stat_ops;
|
|
|
|
struct netdev_queue_stats_rx rx;
|
|
|
|
struct netdev_queue_stats_tx tx;
|
|
|
|
void *hdr;
|
|
|
|
|
|
|
|
hdr = genlmsg_iput(rsp, info);
|
|
|
|
if (!hdr)
|
|
|
|
return -EMSGSIZE;
|
|
|
|
if (nla_put_u32(rsp, NETDEV_A_QSTATS_IFINDEX, netdev->ifindex) ||
|
|
|
|
nla_put_u32(rsp, NETDEV_A_QSTATS_QUEUE_TYPE, q_type) ||
|
|
|
|
nla_put_u32(rsp, NETDEV_A_QSTATS_QUEUE_ID, i))
|
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
|
|
switch (q_type) {
|
|
|
|
case NETDEV_QUEUE_TYPE_RX:
|
|
|
|
memset(&rx, 0xff, sizeof(rx));
|
|
|
|
ops->get_queue_stats_rx(netdev, i, &rx);
|
|
|
|
if (!memchr_inv(&rx, 0xff, sizeof(rx)))
|
|
|
|
goto nla_cancel;
|
|
|
|
if (netdev_nl_stats_write_rx(rsp, &rx))
|
|
|
|
goto nla_put_failure;
|
|
|
|
break;
|
|
|
|
case NETDEV_QUEUE_TYPE_TX:
|
|
|
|
memset(&tx, 0xff, sizeof(tx));
|
|
|
|
ops->get_queue_stats_tx(netdev, i, &tx);
|
|
|
|
if (!memchr_inv(&tx, 0xff, sizeof(tx)))
|
|
|
|
goto nla_cancel;
|
|
|
|
if (netdev_nl_stats_write_tx(rsp, &tx))
|
|
|
|
goto nla_put_failure;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
genlmsg_end(rsp, hdr);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
nla_cancel:
|
|
|
|
genlmsg_cancel(rsp, hdr);
|
|
|
|
return 0;
|
|
|
|
nla_put_failure:
|
|
|
|
genlmsg_cancel(rsp, hdr);
|
|
|
|
return -EMSGSIZE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
netdev_nl_stats_by_queue(struct net_device *netdev, struct sk_buff *rsp,
|
|
|
|
const struct genl_info *info,
|
|
|
|
struct netdev_nl_dump_ctx *ctx)
|
|
|
|
{
|
|
|
|
const struct netdev_stat_ops *ops = netdev->stat_ops;
|
|
|
|
int i, err;
|
|
|
|
|
|
|
|
if (!(netdev->flags & IFF_UP))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
i = ctx->rxq_idx;
|
|
|
|
while (ops->get_queue_stats_rx && i < netdev->real_num_rx_queues) {
|
|
|
|
err = netdev_nl_stats_queue(netdev, rsp, NETDEV_QUEUE_TYPE_RX,
|
|
|
|
i, info);
|
|
|
|
if (err)
|
|
|
|
return err;
|
netdev: fix repeated netlink messages in queue stats
The context is supposed to record the next queue to dump,
not last dumped. If the dump doesn't fit we will restart
from the already-dumped queue, duplicating the message.
Before this fix and with the selftest improvements later
in this series we see:
# ./run_kselftest.sh -t drivers/net:stats.py
timeout set to 45
selftests: drivers/net: stats.py
KTAP version 1
1..5
ok 1 stats.check_pause
ok 2 stats.check_fec
ok 3 stats.pkt_byte_sum
# Check| At /root/ksft-net-drv/drivers/net/./stats.py, line 125, in qstat_by_ifindex:
# Check| ksft_eq(len(queues[qtype]), len(set(queues[qtype])),
# Check failed 45 != 44 repeated queue keys
# Check| At /root/ksft-net-drv/drivers/net/./stats.py, line 127, in qstat_by_ifindex:
# Check| ksft_eq(len(queues[qtype]), max(queues[qtype]) + 1,
# Check failed 45 != 44 missing queue keys
# Check| At /root/ksft-net-drv/drivers/net/./stats.py, line 125, in qstat_by_ifindex:
# Check| ksft_eq(len(queues[qtype]), len(set(queues[qtype])),
# Check failed 45 != 44 repeated queue keys
# Check| At /root/ksft-net-drv/drivers/net/./stats.py, line 127, in qstat_by_ifindex:
# Check| ksft_eq(len(queues[qtype]), max(queues[qtype]) + 1,
# Check failed 45 != 44 missing queue keys
# Check| At /root/ksft-net-drv/drivers/net/./stats.py, line 125, in qstat_by_ifindex:
# Check| ksft_eq(len(queues[qtype]), len(set(queues[qtype])),
# Check failed 103 != 100 repeated queue keys
# Check| At /root/ksft-net-drv/drivers/net/./stats.py, line 127, in qstat_by_ifindex:
# Check| ksft_eq(len(queues[qtype]), max(queues[qtype]) + 1,
# Check failed 103 != 100 missing queue keys
# Check| At /root/ksft-net-drv/drivers/net/./stats.py, line 125, in qstat_by_ifindex:
# Check| ksft_eq(len(queues[qtype]), len(set(queues[qtype])),
# Check failed 102 != 100 repeated queue keys
# Check| At /root/ksft-net-drv/drivers/net/./stats.py, line 127, in qstat_by_ifindex:
# Check| ksft_eq(len(queues[qtype]), max(queues[qtype]) + 1,
# Check failed 102 != 100 missing queue keys
not ok 4 stats.qstat_by_ifindex
ok 5 stats.check_down
# Totals: pass:4 fail:1 xfail:0 xpass:0 skip:0 error:0
With the fix:
# ./ksft-net-drv/run_kselftest.sh -t drivers/net:stats.py
timeout set to 45
selftests: drivers/net: stats.py
KTAP version 1
1..5
ok 1 stats.check_pause
ok 2 stats.check_fec
ok 3 stats.pkt_byte_sum
ok 4 stats.qstat_by_ifindex
ok 5 stats.check_down
# Totals: pass:5 fail:0 xfail:0 xpass:0 skip:0 error:0
Fixes: ab63a2387cb9 ("netdev: add per-queue statistics")
Reviewed-by: Joe Damato <jdamato@fastly.com>
Link: https://patch.msgid.link/20241213152244.3080955-3-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2024-12-13 07:22:41 -08:00
|
|
|
ctx->rxq_idx = ++i;
|
2024-03-06 11:55:07 -08:00
|
|
|
}
|
|
|
|
i = ctx->txq_idx;
|
|
|
|
while (ops->get_queue_stats_tx && i < netdev->real_num_tx_queues) {
|
|
|
|
err = netdev_nl_stats_queue(netdev, rsp, NETDEV_QUEUE_TYPE_TX,
|
|
|
|
i, info);
|
|
|
|
if (err)
|
|
|
|
return err;
|
netdev: fix repeated netlink messages in queue stats
The context is supposed to record the next queue to dump,
not last dumped. If the dump doesn't fit we will restart
from the already-dumped queue, duplicating the message.
Before this fix and with the selftest improvements later
in this series we see:
# ./run_kselftest.sh -t drivers/net:stats.py
timeout set to 45
selftests: drivers/net: stats.py
KTAP version 1
1..5
ok 1 stats.check_pause
ok 2 stats.check_fec
ok 3 stats.pkt_byte_sum
# Check| At /root/ksft-net-drv/drivers/net/./stats.py, line 125, in qstat_by_ifindex:
# Check| ksft_eq(len(queues[qtype]), len(set(queues[qtype])),
# Check failed 45 != 44 repeated queue keys
# Check| At /root/ksft-net-drv/drivers/net/./stats.py, line 127, in qstat_by_ifindex:
# Check| ksft_eq(len(queues[qtype]), max(queues[qtype]) + 1,
# Check failed 45 != 44 missing queue keys
# Check| At /root/ksft-net-drv/drivers/net/./stats.py, line 125, in qstat_by_ifindex:
# Check| ksft_eq(len(queues[qtype]), len(set(queues[qtype])),
# Check failed 45 != 44 repeated queue keys
# Check| At /root/ksft-net-drv/drivers/net/./stats.py, line 127, in qstat_by_ifindex:
# Check| ksft_eq(len(queues[qtype]), max(queues[qtype]) + 1,
# Check failed 45 != 44 missing queue keys
# Check| At /root/ksft-net-drv/drivers/net/./stats.py, line 125, in qstat_by_ifindex:
# Check| ksft_eq(len(queues[qtype]), len(set(queues[qtype])),
# Check failed 103 != 100 repeated queue keys
# Check| At /root/ksft-net-drv/drivers/net/./stats.py, line 127, in qstat_by_ifindex:
# Check| ksft_eq(len(queues[qtype]), max(queues[qtype]) + 1,
# Check failed 103 != 100 missing queue keys
# Check| At /root/ksft-net-drv/drivers/net/./stats.py, line 125, in qstat_by_ifindex:
# Check| ksft_eq(len(queues[qtype]), len(set(queues[qtype])),
# Check failed 102 != 100 repeated queue keys
# Check| At /root/ksft-net-drv/drivers/net/./stats.py, line 127, in qstat_by_ifindex:
# Check| ksft_eq(len(queues[qtype]), max(queues[qtype]) + 1,
# Check failed 102 != 100 missing queue keys
not ok 4 stats.qstat_by_ifindex
ok 5 stats.check_down
# Totals: pass:4 fail:1 xfail:0 xpass:0 skip:0 error:0
With the fix:
# ./ksft-net-drv/run_kselftest.sh -t drivers/net:stats.py
timeout set to 45
selftests: drivers/net: stats.py
KTAP version 1
1..5
ok 1 stats.check_pause
ok 2 stats.check_fec
ok 3 stats.pkt_byte_sum
ok 4 stats.qstat_by_ifindex
ok 5 stats.check_down
# Totals: pass:5 fail:0 xfail:0 xpass:0 skip:0 error:0
Fixes: ab63a2387cb9 ("netdev: add per-queue statistics")
Reviewed-by: Joe Damato <jdamato@fastly.com>
Link: https://patch.msgid.link/20241213152244.3080955-3-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2024-12-13 07:22:41 -08:00
|
|
|
ctx->txq_idx = ++i;
|
2024-03-06 11:55:07 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
ctx->rxq_idx = 0;
|
|
|
|
ctx->txq_idx = 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
netdev_nl_stats_by_netdev(struct net_device *netdev, struct sk_buff *rsp,
|
|
|
|
const struct genl_info *info)
|
|
|
|
{
|
|
|
|
struct netdev_queue_stats_rx rx_sum, rx;
|
|
|
|
struct netdev_queue_stats_tx tx_sum, tx;
|
|
|
|
const struct netdev_stat_ops *ops;
|
|
|
|
void *hdr;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
ops = netdev->stat_ops;
|
|
|
|
/* Netdev can't guarantee any complete counters */
|
|
|
|
if (!ops->get_base_stats)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
memset(&rx_sum, 0xff, sizeof(rx_sum));
|
|
|
|
memset(&tx_sum, 0xff, sizeof(tx_sum));
|
|
|
|
|
|
|
|
ops->get_base_stats(netdev, &rx_sum, &tx_sum);
|
|
|
|
|
|
|
|
/* The op was there, but nothing reported, don't bother */
|
|
|
|
if (!memchr_inv(&rx_sum, 0xff, sizeof(rx_sum)) &&
|
|
|
|
!memchr_inv(&tx_sum, 0xff, sizeof(tx_sum)))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
hdr = genlmsg_iput(rsp, info);
|
|
|
|
if (!hdr)
|
|
|
|
return -EMSGSIZE;
|
|
|
|
if (nla_put_u32(rsp, NETDEV_A_QSTATS_IFINDEX, netdev->ifindex))
|
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
|
|
for (i = 0; i < netdev->real_num_rx_queues; i++) {
|
|
|
|
memset(&rx, 0xff, sizeof(rx));
|
|
|
|
if (ops->get_queue_stats_rx)
|
|
|
|
ops->get_queue_stats_rx(netdev, i, &rx);
|
|
|
|
netdev_nl_stats_add(&rx_sum, &rx, sizeof(rx));
|
|
|
|
}
|
|
|
|
for (i = 0; i < netdev->real_num_tx_queues; i++) {
|
|
|
|
memset(&tx, 0xff, sizeof(tx));
|
|
|
|
if (ops->get_queue_stats_tx)
|
|
|
|
ops->get_queue_stats_tx(netdev, i, &tx);
|
|
|
|
netdev_nl_stats_add(&tx_sum, &tx, sizeof(tx));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (netdev_nl_stats_write_rx(rsp, &rx_sum) ||
|
|
|
|
netdev_nl_stats_write_tx(rsp, &tx_sum))
|
|
|
|
goto nla_put_failure;
|
|
|
|
|
|
|
|
genlmsg_end(rsp, hdr);
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
nla_put_failure:
|
|
|
|
genlmsg_cancel(rsp, hdr);
|
|
|
|
return -EMSGSIZE;
|
|
|
|
}
|
|
|
|
|
2024-04-19 19:35:39 -07:00
|
|
|
static int
|
|
|
|
netdev_nl_qstats_get_dump_one(struct net_device *netdev, unsigned int scope,
|
|
|
|
struct sk_buff *skb, const struct genl_info *info,
|
|
|
|
struct netdev_nl_dump_ctx *ctx)
|
|
|
|
{
|
|
|
|
if (!netdev->stat_ops)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
switch (scope) {
|
|
|
|
case 0:
|
|
|
|
return netdev_nl_stats_by_netdev(netdev, skb, info);
|
|
|
|
case NETDEV_QSTATS_SCOPE_QUEUE:
|
|
|
|
return netdev_nl_stats_by_queue(netdev, skb, info, ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
return -EINVAL; /* Should not happen, per netlink policy */
|
|
|
|
}
|
|
|
|
|
2024-03-06 11:55:07 -08:00
|
|
|
int netdev_nl_qstats_get_dumpit(struct sk_buff *skb,
|
|
|
|
struct netlink_callback *cb)
|
|
|
|
{
|
|
|
|
struct netdev_nl_dump_ctx *ctx = netdev_dump_ctx(cb);
|
|
|
|
const struct genl_info *info = genl_info_dump(cb);
|
|
|
|
struct net *net = sock_net(skb->sk);
|
|
|
|
struct net_device *netdev;
|
2024-04-19 19:35:39 -07:00
|
|
|
unsigned int ifindex;
|
2024-03-06 11:55:07 -08:00
|
|
|
unsigned int scope;
|
|
|
|
int err = 0;
|
|
|
|
|
|
|
|
scope = 0;
|
|
|
|
if (info->attrs[NETDEV_A_QSTATS_SCOPE])
|
|
|
|
scope = nla_get_uint(info->attrs[NETDEV_A_QSTATS_SCOPE]);
|
|
|
|
|
2024-04-19 19:35:39 -07:00
|
|
|
ifindex = 0;
|
|
|
|
if (info->attrs[NETDEV_A_QSTATS_IFINDEX])
|
|
|
|
ifindex = nla_get_u32(info->attrs[NETDEV_A_QSTATS_IFINDEX]);
|
2024-03-06 11:55:07 -08:00
|
|
|
|
2024-04-19 19:35:39 -07:00
|
|
|
rtnl_lock();
|
|
|
|
if (ifindex) {
|
|
|
|
netdev = __dev_get_by_index(net, ifindex);
|
|
|
|
if (netdev && netdev->stat_ops) {
|
|
|
|
err = netdev_nl_qstats_get_dump_one(netdev, scope, skb,
|
|
|
|
info, ctx);
|
|
|
|
} else {
|
|
|
|
NL_SET_BAD_ATTR(info->extack,
|
|
|
|
info->attrs[NETDEV_A_QSTATS_IFINDEX]);
|
|
|
|
err = netdev ? -EOPNOTSUPP : -ENODEV;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for_each_netdev_dump(net, netdev, ctx->ifindex) {
|
|
|
|
err = netdev_nl_qstats_get_dump_one(netdev, scope, skb,
|
|
|
|
info, ctx);
|
|
|
|
if (err < 0)
|
|
|
|
break;
|
2024-03-06 11:55:07 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
rtnl_unlock();
|
|
|
|
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
2024-09-10 17:14:46 +00:00
|
|
|
int netdev_nl_bind_rx_doit(struct sk_buff *skb, struct genl_info *info)
|
|
|
|
{
|
2024-09-10 17:14:47 +00:00
|
|
|
struct nlattr *tb[ARRAY_SIZE(netdev_queue_id_nl_policy)];
|
|
|
|
struct net_devmem_dmabuf_binding *binding;
|
|
|
|
struct list_head *sock_binding_list;
|
|
|
|
u32 ifindex, dmabuf_fd, rxq_idx;
|
|
|
|
struct net_device *netdev;
|
|
|
|
struct sk_buff *rsp;
|
|
|
|
struct nlattr *attr;
|
|
|
|
int rem, err = 0;
|
|
|
|
void *hdr;
|
|
|
|
|
|
|
|
if (GENL_REQ_ATTR_CHECK(info, NETDEV_A_DEV_IFINDEX) ||
|
|
|
|
GENL_REQ_ATTR_CHECK(info, NETDEV_A_DMABUF_FD) ||
|
|
|
|
GENL_REQ_ATTR_CHECK(info, NETDEV_A_DMABUF_QUEUES))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
ifindex = nla_get_u32(info->attrs[NETDEV_A_DEV_IFINDEX]);
|
|
|
|
dmabuf_fd = nla_get_u32(info->attrs[NETDEV_A_DMABUF_FD]);
|
|
|
|
|
|
|
|
sock_binding_list = genl_sk_priv_get(&netdev_nl_family,
|
|
|
|
NETLINK_CB(skb).sk);
|
|
|
|
if (IS_ERR(sock_binding_list))
|
|
|
|
return PTR_ERR(sock_binding_list);
|
|
|
|
|
|
|
|
rsp = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
|
|
|
|
if (!rsp)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
hdr = genlmsg_iput(rsp, info);
|
|
|
|
if (!hdr) {
|
|
|
|
err = -EMSGSIZE;
|
|
|
|
goto err_genlmsg_free;
|
|
|
|
}
|
|
|
|
|
|
|
|
rtnl_lock();
|
|
|
|
|
|
|
|
netdev = __dev_get_by_index(genl_info_net(info), ifindex);
|
|
|
|
if (!netdev || !netif_device_present(netdev)) {
|
|
|
|
err = -ENODEV;
|
|
|
|
goto err_unlock;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dev_xdp_prog_count(netdev)) {
|
|
|
|
NL_SET_ERR_MSG(info->extack, "unable to bind dmabuf to device with XDP program attached");
|
|
|
|
err = -EEXIST;
|
|
|
|
goto err_unlock;
|
|
|
|
}
|
|
|
|
|
|
|
|
binding = net_devmem_bind_dmabuf(netdev, dmabuf_fd, info->extack);
|
|
|
|
if (IS_ERR(binding)) {
|
|
|
|
err = PTR_ERR(binding);
|
|
|
|
goto err_unlock;
|
|
|
|
}
|
|
|
|
|
|
|
|
nla_for_each_attr_type(attr, NETDEV_A_DMABUF_QUEUES,
|
|
|
|
genlmsg_data(info->genlhdr),
|
|
|
|
genlmsg_len(info->genlhdr), rem) {
|
|
|
|
err = nla_parse_nested(
|
|
|
|
tb, ARRAY_SIZE(netdev_queue_id_nl_policy) - 1, attr,
|
|
|
|
netdev_queue_id_nl_policy, info->extack);
|
|
|
|
if (err < 0)
|
|
|
|
goto err_unbind;
|
|
|
|
|
|
|
|
if (NL_REQ_ATTR_CHECK(info->extack, attr, tb, NETDEV_A_QUEUE_ID) ||
|
|
|
|
NL_REQ_ATTR_CHECK(info->extack, attr, tb, NETDEV_A_QUEUE_TYPE)) {
|
|
|
|
err = -EINVAL;
|
|
|
|
goto err_unbind;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nla_get_u32(tb[NETDEV_A_QUEUE_TYPE]) != NETDEV_QUEUE_TYPE_RX) {
|
|
|
|
NL_SET_BAD_ATTR(info->extack, tb[NETDEV_A_QUEUE_TYPE]);
|
|
|
|
err = -EINVAL;
|
|
|
|
goto err_unbind;
|
|
|
|
}
|
|
|
|
|
|
|
|
rxq_idx = nla_get_u32(tb[NETDEV_A_QUEUE_ID]);
|
|
|
|
|
|
|
|
err = net_devmem_bind_dmabuf_to_queue(netdev, rxq_idx, binding,
|
|
|
|
info->extack);
|
|
|
|
if (err)
|
|
|
|
goto err_unbind;
|
|
|
|
}
|
|
|
|
|
|
|
|
list_add(&binding->list, sock_binding_list);
|
|
|
|
|
|
|
|
nla_put_u32(rsp, NETDEV_A_DMABUF_ID, binding->id);
|
|
|
|
genlmsg_end(rsp, hdr);
|
|
|
|
|
|
|
|
err = genlmsg_reply(rsp, info);
|
|
|
|
if (err)
|
|
|
|
goto err_unbind;
|
|
|
|
|
|
|
|
rtnl_unlock();
|
|
|
|
|
2024-09-10 17:14:46 +00:00
|
|
|
return 0;
|
2024-09-10 17:14:47 +00:00
|
|
|
|
|
|
|
err_unbind:
|
|
|
|
net_devmem_unbind_dmabuf(binding);
|
|
|
|
err_unlock:
|
|
|
|
rtnl_unlock();
|
|
|
|
err_genlmsg_free:
|
|
|
|
nlmsg_free(rsp);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
void netdev_nl_sock_priv_init(struct list_head *priv)
|
|
|
|
{
|
|
|
|
INIT_LIST_HEAD(priv);
|
|
|
|
}
|
|
|
|
|
|
|
|
void netdev_nl_sock_priv_destroy(struct list_head *priv)
|
|
|
|
{
|
|
|
|
struct net_devmem_dmabuf_binding *binding;
|
|
|
|
struct net_devmem_dmabuf_binding *temp;
|
|
|
|
|
|
|
|
list_for_each_entry_safe(binding, temp, priv, list) {
|
|
|
|
rtnl_lock();
|
|
|
|
net_devmem_unbind_dmabuf(binding);
|
|
|
|
rtnl_unlock();
|
|
|
|
}
|
2024-09-10 17:14:46 +00:00
|
|
|
}
|
|
|
|
|
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>
2023-02-01 11:24:17 +01:00
|
|
|
static int netdev_genl_netdevice_event(struct notifier_block *nb,
|
|
|
|
unsigned long event, void *ptr)
|
|
|
|
{
|
|
|
|
struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
|
|
|
|
|
|
|
|
switch (event) {
|
|
|
|
case NETDEV_REGISTER:
|
|
|
|
netdev_genl_dev_notify(netdev, NETDEV_CMD_DEV_ADD_NTF);
|
|
|
|
break;
|
|
|
|
case NETDEV_UNREGISTER:
|
|
|
|
netdev_genl_dev_notify(netdev, NETDEV_CMD_DEV_DEL_NTF);
|
|
|
|
break;
|
|
|
|
case NETDEV_XDP_FEAT_CHANGE:
|
|
|
|
netdev_genl_dev_notify(netdev, NETDEV_CMD_DEV_CHANGE_NTF);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NOTIFY_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct notifier_block netdev_genl_nb = {
|
|
|
|
.notifier_call = netdev_genl_netdevice_event,
|
|
|
|
};
|
|
|
|
|
|
|
|
static int __init netdev_genl_init(void)
|
|
|
|
{
|
|
|
|
int err;
|
|
|
|
|
|
|
|
err = register_netdevice_notifier(&netdev_genl_nb);
|
|
|
|
if (err)
|
|
|
|
return err;
|
|
|
|
|
|
|
|
err = genl_register_family(&netdev_nl_family);
|
|
|
|
if (err)
|
|
|
|
goto err_unreg_ntf;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
err_unreg_ntf:
|
|
|
|
unregister_netdevice_notifier(&netdev_genl_nb);
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
subsys_initcall(netdev_genl_init);
|