Skip to content

Commit d0756e6

Browse files
liuhangbinkernel-patches-bot
authored andcommitted
sample/bpf: add xdp_redirect_map_multicast test
This is a sample for xdp multicast. In the sample we could forward all packets between given interfaces. There is also an option -X that could enable 2nd xdp_prog on egress interface. Acked-by: Toke Høiland-Jørgensen <toke@redhat.com> Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
1 parent 1a828f7 commit d0756e6

File tree

3 files changed

+392
-0
lines changed

3 files changed

+392
-0
lines changed

samples/bpf/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ tprogs-y += test_map_in_map
4141
tprogs-y += per_socket_stats_example
4242
tprogs-y += xdp_redirect
4343
tprogs-y += xdp_redirect_map
44+
tprogs-y += xdp_redirect_map_multi
4445
tprogs-y += xdp_redirect_cpu
4546
tprogs-y += xdp_monitor
4647
tprogs-y += xdp_rxq_info
@@ -99,6 +100,7 @@ test_map_in_map-objs := test_map_in_map_user.o
99100
per_socket_stats_example-objs := cookie_uid_helper_example.o
100101
xdp_redirect-objs := xdp_redirect_user.o
101102
xdp_redirect_map-objs := xdp_redirect_map_user.o
103+
xdp_redirect_map_multi-objs := xdp_redirect_map_multi_user.o
102104
xdp_redirect_cpu-objs := xdp_redirect_cpu_user.o
103105
xdp_monitor-objs := xdp_monitor_user.o
104106
xdp_rxq_info-objs := xdp_rxq_info_user.o
@@ -160,6 +162,7 @@ always-y += tcp_tos_reflect_kern.o
160162
always-y += tcp_dumpstats_kern.o
161163
always-y += xdp_redirect_kern.o
162164
always-y += xdp_redirect_map_kern.o
165+
always-y += xdp_redirect_map_multi_kern.o
163166
always-y += xdp_redirect_cpu_kern.o
164167
always-y += xdp_monitor_kern.o
165168
always-y += xdp_rxq_info_kern.o
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
#define KBUILD_MODNAME "foo"
3+
#include <uapi/linux/bpf.h>
4+
#include <linux/in.h>
5+
#include <linux/if_ether.h>
6+
#include <linux/ip.h>
7+
#include <linux/ipv6.h>
8+
#include <bpf/bpf_helpers.h>
9+
10+
struct {
11+
__uint(type, BPF_MAP_TYPE_DEVMAP_HASH);
12+
__uint(key_size, sizeof(int));
13+
__uint(value_size, sizeof(int));
14+
__uint(max_entries, 32);
15+
} forward_map_general SEC(".maps");
16+
17+
struct {
18+
__uint(type, BPF_MAP_TYPE_DEVMAP_HASH);
19+
__uint(key_size, sizeof(int));
20+
__uint(value_size, sizeof(struct bpf_devmap_val));
21+
__uint(max_entries, 32);
22+
} forward_map_native SEC(".maps");
23+
24+
struct {
25+
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
26+
__type(key, u32);
27+
__type(value, long);
28+
__uint(max_entries, 1);
29+
} rxcnt SEC(".maps");
30+
31+
/* map to store egress interfaces mac addresses, set the
32+
* max_entries to 1 and extend it in user sapce prog.
33+
*/
34+
struct {
35+
__uint(type, BPF_MAP_TYPE_ARRAY);
36+
__type(key, u32);
37+
__type(value, __be64);
38+
__uint(max_entries, 1);
39+
} mac_map SEC(".maps");
40+
41+
static int xdp_redirect_map(struct xdp_md *ctx, void *forward_map)
42+
{
43+
long *value;
44+
u32 key = 0;
45+
46+
/* count packet in global counter */
47+
value = bpf_map_lookup_elem(&rxcnt, &key);
48+
if (value)
49+
*value += 1;
50+
51+
return bpf_redirect_map_multi(forward_map, NULL, BPF_F_EXCLUDE_INGRESS);
52+
}
53+
54+
SEC("xdp_redirect_general")
55+
int xdp_redirect_map_general(struct xdp_md *ctx)
56+
{
57+
return xdp_redirect_map(ctx, &forward_map_general);
58+
}
59+
60+
SEC("xdp_redirect_native")
61+
int xdp_redirect_map_native(struct xdp_md *ctx)
62+
{
63+
return xdp_redirect_map(ctx, &forward_map_native);
64+
}
65+
66+
SEC("xdp_devmap/map_prog")
67+
int xdp_devmap_prog(struct xdp_md *ctx)
68+
{
69+
void *data_end = (void *)(long)ctx->data_end;
70+
void *data = (void *)(long)ctx->data;
71+
u32 key = ctx->egress_ifindex;
72+
struct ethhdr *eth = data;
73+
__be64 *mac;
74+
u64 nh_off;
75+
76+
nh_off = sizeof(*eth);
77+
if (data + nh_off > data_end)
78+
return XDP_DROP;
79+
80+
mac = bpf_map_lookup_elem(&mac_map, &key);
81+
if (mac)
82+
__builtin_memcpy(eth->h_source, mac, ETH_ALEN);
83+
84+
return XDP_PASS;
85+
}
86+
87+
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)