P4C
The P4 Compiler
Loading...
Searching...
No Matches
xdpHelpProgram.h
1/*
2 * SPDX-FileCopyrightText: 2022 Open Networking Foundation
3 * SPDX-FileCopyrightText: 2022 Orange
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7#ifndef BACKENDS_EBPF_PSA_XDPHELPPROGRAM_H_
8#define BACKENDS_EBPF_PSA_XDPHELPPROGRAM_H_
9
10#include "backends/ebpf/ebpfProgram.h"
11
12namespace P4::EBPF {
13
14class XDPHelpProgram : public EBPFProgram {
15 const char *XDPProgUsingMetaForXDP2TC =
16 " void *data_end = (void *)(long)skb->data_end;\n"
17 " struct ethhdr *eth = (struct ethhdr *)(long)skb->data;\n"
18 " if ((void *)((struct ethhdr *) eth + 1) > data_end) {\n"
19 " return XDP_ABORTED;\n"
20 " }\n"
21 " if (eth->h_proto == bpf_htons(0x0800) || eth->h_proto == bpf_htons(0x86DD)) {\n"
22 " return XDP_PASS;\n"
23 " }\n"
24 "\n"
25 " struct internal_metadata *meta;\n"
26 " int ret = bpf_xdp_adjust_meta(skb, -(int)sizeof(*meta));\n"
27 " if (ret < 0) {\n"
28 " return XDP_ABORTED;\n"
29 " }\n"
30 " meta = (struct internal_metadata *)(unsigned long)skb->data_meta;\n"
31 " eth = (void *)(long)skb->data;\n"
32 " data_end = (void *)(long)skb->data_end;\n"
33 " if ((void *) ((struct internal_metadata *) meta + 1) > (void *)(long)skb->data)\n"
34 " return XDP_ABORTED;\n"
35 " if ((void *)((struct ethhdr *) eth + 1) > data_end) {\n"
36 " return XDP_ABORTED;\n"
37 " }\n"
38 " meta->pkt_ether_type = eth->h_proto;\n"
39 " eth->h_proto = bpf_htons(0x0800);\n"
40 "\n"
41 " return XDP_PASS;";
42
43 const char *XDPProgUsingHeadForXDP2TC =
44 " void *data = (void *)(long)skb->data;\n"
45 " void *data_end = (void *)(long)skb->data_end;\n"
46 " struct ethhdr *eth = data;\n"
47 " if ((void *)((struct ethhdr *) eth + 1) > data_end) {\n"
48 " return XDP_ABORTED;\n"
49 " }\n"
50 " __u16 orig_ethtype = eth->h_proto;\n"
51 " int ret = bpf_xdp_adjust_head(skb, -2);\n"
52 " if (ret < 0) {\n"
53 " return XDP_ABORTED;\n"
54 " }\n"
55 "\n"
56 " data = (void *)(long)skb->data;\n"
57 " data_end = (void *)(long)skb->data_end;\n"
58 "\n"
59 " if ((void *)(data + 16) > data_end) {\n"
60 " return XDP_ABORTED;\n"
61 " }\n"
62 " __builtin_memmove(data, data + 2, 14);\n"
63 " eth = data;\n"
64 " if ((void *)((struct ethhdr *) eth + 1) > data_end) {\n"
65 " return XDP_ABORTED;\n"
66 " }\n"
67 " eth->h_proto = bpf_htons(0x0800);\n"
68 " __builtin_memcpy((char *)data + 14, &orig_ethtype, 2);\n"
69 " "
70 "\n"
71 " return XDP_PASS;";
72
73 const char *XDPProgUsingCPUMAPForXDP2TC =
74 " void *data = (void *)(long)skb->data;\n"
75 " void *data_end = (void *)(long)skb->data_end;\n"
76 " struct ethhdr *eth = data;\n"
77 " if ((void *)((struct ethhdr *) eth + 1) > data_end) {\n"
78 " return XDP_ABORTED;\n"
79 " }\n"
80 " u16 orig_ethtype = eth->h_proto;\n"
81 " eth->h_proto = bpf_htons(0x0800);\n"
82 " u32 zero = 0;\n"
83 " BPF_MAP_UPDATE_ELEM(xdp2tc_cpumap, &zero, &orig_ethtype, BPF_ANY);\n"
84 " return XDP_PASS;";
85
86 public:
87 cstring sectionName;
88 explicit XDPHelpProgram(const EbpfOptions &options)
89 : EBPFProgram(options, nullptr, nullptr, nullptr, nullptr) {
90 sectionName = "xdp/xdp-ingress"_cs;
91 functionName = "xdp_func"_cs;
92 }
93
94 void emit(CodeBuilder *builder) {
95 builder->target->emitCodeSection(builder, sectionName);
96 builder->emitIndent();
97 builder->appendFormat("int %v(struct xdp_md *%s)", functionName, model.CPacketName.str());
98 builder->spc();
99 builder->blockStart();
100 builder->emitIndent();
101 // This is static program, so we can just paste a piece of code.
102 if (options.xdp2tcMode == XDP2TC_META) {
103 builder->appendLine(XDPProgUsingMetaForXDP2TC);
104 } else if (options.xdp2tcMode == XDP2TC_HEAD) {
105 builder->appendLine(XDPProgUsingHeadForXDP2TC);
106 } else if (options.xdp2tcMode == XDP2TC_CPUMAP) {
107 builder->appendLine(XDPProgUsingCPUMAPForXDP2TC);
108 }
109 builder->blockEnd(true);
110 }
111};
112
113} // namespace P4::EBPF
114
115#endif /* BACKENDS_EBPF_PSA_XDPHELPPROGRAM_H_ */
Definition ebpf/codeGen.h:33
EBPFProgram(const EbpfOptions &options, const IR::P4Program *program, P4::ReferenceMap *refMap, P4::TypeMap *typeMap, const IR::ToplevelBlock *toplevel)
return 'true' on success
Definition ebpfProgram.h:56
Definition ebpfOptions.h:26
Definition cstring.h:85
Definition codeGen.cpp:25