|
15 | 15 | #include <arpa/inet.h> |
16 | 16 | #include <asm/barrier.h> |
17 | 17 | #include <linux/compiler.h> |
18 | | -#include <linux/ethtool.h> |
19 | 18 | #include <linux/filter.h> |
20 | 19 | #include <linux/if_ether.h> |
21 | 20 | #include <linux/if_link.h> |
|
31 | 30 | #include <sys/types.h> |
32 | 31 |
|
33 | 32 | #include "bpf.h" |
| 33 | +#include "ethtool.h" |
34 | 34 | #include "libbpf.h" |
35 | 35 | #include "libbpf_internal.h" |
36 | 36 | #include "xsk.h" |
@@ -931,3 +931,52 @@ void xsk_socket__delete(struct xsk_socket *xsk) |
931 | 931 | close(xsk->fd); |
932 | 932 | free(xsk); |
933 | 933 | } |
| 934 | + |
| 935 | +int xsk_socket__get_caps(const char *ifname, __u32 *xdp_caps, __u16 *bind_caps) |
| 936 | +{ |
| 937 | + struct ethnl_params param; |
| 938 | + int ret; |
| 939 | + |
| 940 | + if (!xdp_caps || !bind_caps || !ifname || |
| 941 | + (strnlen(ifname, IFNAMSIZ) >= IFNAMSIZ)) |
| 942 | + return -EINVAL; |
| 943 | + |
| 944 | + param.nl_family = ETHTOOL_GENL_NAME; |
| 945 | + param.xdp_zc_flags = 0; |
| 946 | + param.ifname = ifname; |
| 947 | + param.xdp_flags = 0; |
| 948 | + |
| 949 | + /* First, get the netlink family id */ |
| 950 | + ret = libbpf_ethnl_get_ethtool_family_id(¶m); |
| 951 | + if (ret) |
| 952 | + return ret; |
| 953 | + |
| 954 | + /* Second, get number of features */ |
| 955 | + param.features = 0; |
| 956 | + ret = libbpf_ethnl_get_netdev_features(¶m); |
| 957 | + if (ret) |
| 958 | + return ret; |
| 959 | + |
| 960 | + /* Third, get the features description */ |
| 961 | + ret = libbpf_ethnl_get_netdev_features(¶m); |
| 962 | + if (ret) |
| 963 | + return ret; |
| 964 | + |
| 965 | + *xdp_caps = XDP_FLAGS_SKB_MODE; |
| 966 | + *bind_caps = XDP_COPY; |
| 967 | + |
| 968 | + if (param.xdp_idx == -1 || param.xdp_zc_idx == -1) |
| 969 | + return 0; |
| 970 | + |
| 971 | + /* Finally, get features flags and process it */ |
| 972 | + ret = libbpf_ethnl_get_active_bits(¶m); |
| 973 | + if (!ret) { |
| 974 | + if (param.xdp_flags) { |
| 975 | + *xdp_caps |= XDP_FLAGS_DRV_MODE; |
| 976 | + if (param.xdp_zc_flags) |
| 977 | + *bind_caps |= XDP_ZEROCOPY; |
| 978 | + } |
| 979 | + } |
| 980 | + |
| 981 | + return ret; |
| 982 | +} |
0 commit comments