@@ -99,8 +99,8 @@ xdp_tx_iptunnel-objs := xdp_tx_iptunnel_user.o
test_map_in_map-objs := test_map_in_map_user.o
per_socket_stats_example-objs := cookie_uid_helper_example.o
xdp_redirect-objs := xdp_redirect_user.o
-xdp_redirect_map-objs := xdp_redirect_map_user.o
xdp_redirect_map_multi-objs := xdp_redirect_map_multi_user.o
+xdp_redirect_map-objs := xdp_redirect_map_user.o xdp_sample_user.o
xdp_redirect_cpu-objs := xdp_redirect_cpu_user.o xdp_sample_user.o
xdp_monitor-objs := xdp_monitor_user.o
xdp_rxq_info-objs := xdp_rxq_info_user.o
@@ -19,6 +19,8 @@
#include <linux/ipv6.h>
#include <bpf/bpf_helpers.h>
+#include "xdp_sample_kern.h"
+
/* The 2nd xdp prog on egress does not support skb mode, so we define two
* maps, tx_port_general and tx_port_native.
*/
@@ -36,16 +38,6 @@ struct {
__uint(max_entries, 100);
} tx_port_native SEC(".maps");
-/* Count RX packets, as XDP bpf_prog doesn't get direct TX-success
- * feedback. Redirect TX errors can be caught via a tracepoint.
- */
-struct {
- __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
- __type(key, u32);
- __type(value, long);
- __uint(max_entries, 1);
-} rxcnt SEC(".maps");
-
/* map to store egress interface mac address */
struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
@@ -75,7 +67,7 @@ static __always_inline int xdp_redirect_map(struct xdp_md *ctx, void *redirect_m
void *data_end = (void *)(long)ctx->data_end;
void *data = (void *)(long)ctx->data;
struct ethhdr *eth = data;
- int rc = XDP_DROP;
+ struct datarec *rec;
long *value;
u32 key = 0;
u64 nh_off;
@@ -83,15 +75,16 @@ static __always_inline int xdp_redirect_map(struct xdp_md *ctx, void *redirect_m
nh_off = sizeof(*eth);
if (data + nh_off > data_end)
- return rc;
+ return XDP_DROP;
/* constant virtual port */
vport = 0;
/* count packet in global counter */
- value = bpf_map_lookup_elem(&rxcnt, &key);
- if (value)
- *value += 1;
+ rec = bpf_map_lookup_elem(&rx_cnt, &key);
+ if (!rec)
+ return XDP_ABORTED;
+ rec->processed++;
swap_src_dst_mac(data);
@@ -13,15 +13,11 @@
#include <net/if.h>
#include <unistd.h>
#include <libgen.h>
-#include <sys/resource.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
#include "bpf_util.h"
#include <bpf/bpf.h>
#include <bpf/libbpf.h>
+#include "xdp_sample_user.h"
static int ifindex_in;
static int ifindex_out;
@@ -31,7 +27,6 @@ static __u32 prog_id;
static __u32 dummy_prog_id;
static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
-static int rxcnt_map_fd;
static void int_exit(int sig)
{
@@ -62,56 +57,8 @@ static void int_exit(int sig)
else
printf("program on iface OUT changed, not removing\n");
}
- exit(0);
-}
-static void poll_stats(int interval, int ifindex)
-{
- unsigned int nr_cpus = bpf_num_possible_cpus();
- __u64 values[nr_cpus], prev[nr_cpus];
-
- memset(prev, 0, sizeof(prev));
-
- while (1) {
- __u64 sum = 0;
- __u32 key = 0;
- int i;
-
- sleep(interval);
- assert(bpf_map_lookup_elem(rxcnt_map_fd, &key, values) == 0);
- for (i = 0; i < nr_cpus; i++)
- sum += (values[i] - prev[i]);
- if (sum)
- printf("ifindex %i: %10llu pkt/s\n",
- ifindex, sum / interval);
- memcpy(prev, values, sizeof(values));
- }
-}
-
-static int get_mac_addr(unsigned int ifindex_out, void *mac_addr)
-{
- char ifname[IF_NAMESIZE];
- struct ifreq ifr;
- int fd, ret = -1;
-
- fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (fd < 0)
- return ret;
-
- if (!if_indextoname(ifindex_out, ifname))
- goto err_out;
-
- strcpy(ifr.ifr_name, ifname);
-
- if (ioctl(fd, SIOCGIFHWADDR, &ifr) != 0)
- goto err_out;
-
- memcpy(mac_addr, ifr.ifr_hwaddr.sa_data, 6 * sizeof(char));
- ret = 0;
-
-err_out:
- close(fd);
- return ret;
+ sample_exit(EXIT_OK);
}
static void usage(const char *prog)
@@ -128,6 +75,8 @@ static void usage(const char *prog)
int main(int argc, char **argv)
{
+ int mask = SAMPLE_RX_CNT | SAMPLE_REDIRECT_ERR_CNT |
+ SAMPLE_EXCEPTION_CNT;
struct bpf_prog_load_attr prog_load_attr = {
.prog_type = BPF_PROG_TYPE_UNSPEC,
};
@@ -136,8 +85,11 @@ int main(int argc, char **argv)
int tx_port_map_fd, tx_mac_map_fd;
struct bpf_devmap_val devmap_val;
struct bpf_prog_info info = {};
+ char str[2 * IF_NAMESIZE + 1];
__u32 info_len = sizeof(info);
+ char ifname_out[IF_NAMESIZE];
const char *optstr = "FSNX";
+ char ifname_in[IF_NAMESIZE];
struct bpf_object *obj;
int ret, opt, key = 0;
char filename[256];
@@ -182,14 +134,17 @@ int main(int argc, char **argv)
if (!ifindex_out)
ifindex_out = strtoul(argv[optind + 1], NULL, 0);
- printf("input: %d output: %d\n", ifindex_in, ifindex_out);
-
snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
prog_load_attr.file = filename;
if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd))
return 1;
+ if (sample_init(obj) < 0) {
+ fprintf(stderr, "Failed to initialize sample\n");
+ return 1;
+ }
+
if (xdp_flags & XDP_FLAGS_SKB_MODE) {
prog = bpf_object__find_program_by_name(obj, "xdp_redirect_map_general");
tx_port_map_fd = bpf_object__find_map_fd_by_name(obj, "tx_port_general");
@@ -210,8 +165,7 @@ int main(int argc, char **argv)
}
tx_mac_map_fd = bpf_object__find_map_fd_by_name(obj, "tx_mac");
- rxcnt_map_fd = bpf_object__find_map_fd_by_name(obj, "rxcnt");
- if (tx_mac_map_fd < 0 || rxcnt_map_fd < 0) {
+ if (tx_mac_map_fd < 0) {
printf("bpf_object__find_map_fd_by_name failed\n");
return 1;
}
@@ -281,8 +235,28 @@ int main(int argc, char **argv)
goto out;
}
- poll_stats(2, ifindex_out);
+ if (!if_indextoname(ifindex_in, ifname_in)) {
+ perror("if_nametoindex");
+ goto out;
+ }
+
+ if (!if_indextoname(ifindex_out, ifname_out)) {
+ perror("if_nametoindex");
+ goto out;
+ }
+
+ strncpy(str, get_driver_name(ifindex_in) ?: "(err)", sizeof(str));
+
+ printf("Redirecting from %s (ifindex %d; driver %s) to %s (ifindex %d; driver %s)\n",
+ ifname_in, ifindex_in, str, ifname_out, ifindex_out,
+ get_driver_name(ifindex_out) ?: "(err)");
+
+ snprintf(str, sizeof(str), "%s->%s", ifname_in, ifname_out);
+
+ sample_stats_poll(1, mask, str, true);
-out:
return 0;
+
+out:
+ return 1;
}
This uses the xdp_sample_* reorg we did in the past commits to report more statistics than just the per second packet count. Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> --- samples/bpf/Makefile | 2 +- samples/bpf/xdp_redirect_map_kern.c | 23 +++---- samples/bpf/xdp_redirect_map_user.c | 96 +++++++++++------------------ 3 files changed, 44 insertions(+), 77 deletions(-)