]>
Commit | Line | Data |
---|---|---|
9d6e0052 JF |
1 | /* Copyright (c) 2017 Covalent IO, Inc. http://covalent.io |
2 | * | |
3 | * This program is free software; you can redistribute it and/or | |
4 | * modify it under the terms of version 2 of the GNU General Public | |
5 | * License as published by the Free Software Foundation. | |
6 | * | |
7 | * This program is distributed in the hope that it will be useful, but | |
8 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
10 | * General Public License for more details. | |
11 | */ | |
12 | #define KBUILD_MODNAME "foo" | |
13 | #include <uapi/linux/bpf.h> | |
14 | #include <linux/in.h> | |
15 | #include <linux/if_ether.h> | |
16 | #include <linux/if_packet.h> | |
17 | #include <linux/if_vlan.h> | |
18 | #include <linux/ip.h> | |
19 | #include <linux/ipv6.h> | |
20 | #include "bpf_helpers.h" | |
21 | ||
22 | struct bpf_map_def SEC("maps") tx_port = { | |
23 | .type = BPF_MAP_TYPE_DEVMAP, | |
24 | .key_size = sizeof(int), | |
25 | .value_size = sizeof(int), | |
26 | .max_entries = 100, | |
27 | }; | |
28 | ||
306da4e6 JDB |
29 | /* Count RX packets, as XDP bpf_prog doesn't get direct TX-success |
30 | * feedback. Redirect TX errors can be caught via a tracepoint. | |
31 | */ | |
9d6e0052 JF |
32 | struct bpf_map_def SEC("maps") rxcnt = { |
33 | .type = BPF_MAP_TYPE_PERCPU_ARRAY, | |
34 | .key_size = sizeof(u32), | |
35 | .value_size = sizeof(long), | |
36 | .max_entries = 1, | |
37 | }; | |
38 | ||
9d6e0052 JF |
39 | static void swap_src_dst_mac(void *data) |
40 | { | |
41 | unsigned short *p = data; | |
42 | unsigned short dst[3]; | |
43 | ||
44 | dst[0] = p[0]; | |
45 | dst[1] = p[1]; | |
46 | dst[2] = p[2]; | |
47 | p[0] = p[3]; | |
48 | p[1] = p[4]; | |
49 | p[2] = p[5]; | |
50 | p[3] = dst[0]; | |
51 | p[4] = dst[1]; | |
52 | p[5] = dst[2]; | |
53 | } | |
54 | ||
55 | SEC("xdp_redirect_map") | |
56 | int xdp_redirect_map_prog(struct xdp_md *ctx) | |
57 | { | |
58 | void *data_end = (void *)(long)ctx->data_end; | |
59 | void *data = (void *)(long)ctx->data; | |
60 | struct ethhdr *eth = data; | |
61 | int rc = XDP_DROP; | |
62 | int vport, port = 0, m = 0; | |
63 | long *value; | |
64 | u32 key = 0; | |
65 | u64 nh_off; | |
66 | ||
67 | nh_off = sizeof(*eth); | |
68 | if (data + nh_off > data_end) | |
69 | return rc; | |
70 | ||
71 | /* constant virtual port */ | |
72 | vport = 0; | |
73 | ||
74 | /* count packet in global counter */ | |
75 | value = bpf_map_lookup_elem(&rxcnt, &key); | |
76 | if (value) | |
77 | *value += 1; | |
78 | ||
79 | swap_src_dst_mac(data); | |
80 | ||
81 | /* send packet out physical port */ | |
82 | return bpf_redirect_map(&tx_port, vport, 0); | |
83 | } | |
84 | ||
306da4e6 JDB |
85 | /* Redirect require an XDP bpf_prog loaded on the TX device */ |
86 | SEC("xdp_redirect_dummy") | |
3edcf18e | 87 | int xdp_redirect_dummy_prog(struct xdp_md *ctx) |
306da4e6 JDB |
88 | { |
89 | return XDP_PASS; | |
90 | } | |
91 | ||
9d6e0052 | 92 | char _license[] SEC("license") = "GPL"; |