Skip to content

Commit f2f7cfa

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. Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
1 parent d3f5c6a commit f2f7cfa

File tree

3 files changed

+400
-0
lines changed

3 files changed

+400
-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: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/* SPDX-License-Identifier: GPL-2.0
2+
*
3+
* modify it under the terms of version 2 of the GNU General Public
4+
* License as published by the Free Software Foundation.
5+
*
6+
* This program is distributed in the hope that it will be useful, but
7+
* WITHOUT ANY WARRANTY; without even the implied warranty of
8+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9+
* General Public License for more details.
10+
*/
11+
#define KBUILD_MODNAME "foo"
12+
#include <uapi/linux/bpf.h>
13+
#include <linux/in.h>
14+
#include <linux/if_ether.h>
15+
#include <linux/ip.h>
16+
#include <linux/ipv6.h>
17+
#include <bpf/bpf_helpers.h>
18+
19+
struct {
20+
__uint(type, BPF_MAP_TYPE_DEVMAP_HASH);
21+
__uint(key_size, sizeof(int));
22+
__uint(value_size, sizeof(int));
23+
__uint(max_entries, 32);
24+
} forward_map_general SEC(".maps");
25+
26+
struct {
27+
__uint(type, BPF_MAP_TYPE_DEVMAP_HASH);
28+
__uint(key_size, sizeof(int));
29+
__uint(value_size, sizeof(struct bpf_devmap_val));
30+
__uint(max_entries, 32);
31+
} forward_map_native SEC(".maps");
32+
33+
struct {
34+
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
35+
__type(key, u32);
36+
__type(value, long);
37+
__uint(max_entries, 1);
38+
} rxcnt SEC(".maps");
39+
40+
/* map to stroe egress interfaces mac addresses, set the
41+
* max_entries to 1 and extend it in user sapce prog.
42+
*/
43+
struct {
44+
__uint(type, BPF_MAP_TYPE_ARRAY);
45+
__type(key, u32);
46+
__type(value, __be64);
47+
__uint(max_entries, 1);
48+
} mac_map SEC(".maps");
49+
50+
static int xdp_redirect_map(struct xdp_md *ctx, void *forward_map)
51+
{
52+
long *value;
53+
u32 key = 0;
54+
55+
/* count packet in global counter */
56+
value = bpf_map_lookup_elem(&rxcnt, &key);
57+
if (value)
58+
*value += 1;
59+
60+
return bpf_redirect_map_multi(forward_map, NULL, BPF_F_EXCLUDE_INGRESS);
61+
}
62+
63+
SEC("xdp_redirect_general")
64+
int xdp_redirect_map_general(struct xdp_md *ctx)
65+
{
66+
return xdp_redirect_map(ctx, &forward_map_general);
67+
}
68+
69+
SEC("xdp_redirect_native")
70+
int xdp_redirect_map_native(struct xdp_md *ctx)
71+
{
72+
return xdp_redirect_map(ctx, &forward_map_native);
73+
}
74+
75+
SEC("xdp_devmap/map_prog")
76+
int xdp_devmap_prog(struct xdp_md *ctx)
77+
{
78+
void *data_end = (void *)(long)ctx->data_end;
79+
void *data = (void *)(long)ctx->data;
80+
u32 key = ctx->egress_ifindex;
81+
struct ethhdr *eth = data;
82+
__be64 *mac;
83+
u64 nh_off;
84+
85+
nh_off = sizeof(*eth);
86+
if (data + nh_off > data_end)
87+
return XDP_DROP;
88+
89+
mac = bpf_map_lookup_elem(&mac_map, &key);
90+
if (mac)
91+
__builtin_memcpy(eth->h_source, mac, ETH_ALEN);
92+
93+
return XDP_PASS;
94+
}
95+
96+
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)