P4C
The P4 Compiler
 
Loading...
Searching...
No Matches
pna.h
1/*
2Copyright (C) 2023 Intel Corporation
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing,
11software distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions
14and limitations under the License.
15*/
16
17#ifndef P4C_PNA_H
18#define P4C_PNA_H
19
20#include <stdbool.h>
21#include "crc32.h"
22
23// pna.p4 information
24
25typedef __u32 PortId_t;
26typedef __u64 Timestamp_t;
27typedef __u8 ClassOfService_t;
28typedef __u16 CloneSessionId_t;
29typedef __u32 MulticastGroup_t;
30typedef __u16 EgressInstance_t;
31typedef __u8 MirrorSlotId_t;
32typedef __u16 MirrorSessionId_t;
33
34// Instead of using enum we define ParserError_t as __u8 to save memory.
35typedef __u8 ParserError_t;
36static const ParserError_t NoError = 0; // No error.
37static const ParserError_t PacketTooShort = 1; // Not enough bits in packet for 'extract'.
38static const ParserError_t NoMatch = 2; // 'select' expression has no matches.
39static const ParserError_t StackOutOfBounds = 3; // Reference to invalid element of a header stack.
40static const ParserError_t HeaderTooShort = 4; // Extracting too many bits into a varbit field.
41static const ParserError_t ParserTimeout = 5; // Parser execution time limit exceeded.
42static const ParserError_t ParserInvalidArgument = 6; // Parser operation was called with a value
43 // not supported by the implementation
44
45enum PNA_Source_t { FROM_HOST, FROM_NET };
46
47enum PNA_MeterColor_t { RED, GREEN, YELLOW };
48
49enum MirrorType { NO_MIRROR, PRE_MODIFY, POST_MODIFY };
50
52 bool recirculated;
53 PortId_t input_port; // taken from xdp_md or __sk_buff
54} __attribute__((aligned(4)));
55
57 // All of these values are initialized by the architecture before
58 // the control block begins executing.
59 bool recirculated;
60 Timestamp_t timestamp; // taken from bpf helper
61 ParserError_t parser_error; // local to parser
62 ClassOfService_t class_of_service; // 0, set in control as global metadata
63 PortId_t input_port;
64} __attribute__((aligned(4)));;
65
67 // The comment after each field specifies its initial value when the
68 // control block begins executing.
69 ClassOfService_t class_of_service;
70} __attribute__((aligned(4)));
71
72/*
73 * Opaque struct to be used to share global PNA metadata fields.
74 * The size of this struct must be less than 32 bytes.
75 */
77 bool recirculated;
78 bool drop; // NOTE : no drop field in PNA metadata, so we keep drop state as internal metadata.
79 PortId_t egress_port;
80 enum MirrorType mirror_type;
81 MirrorSlotId_t mirror_slot_id;
82 ParserError_t parser_error;
83 MirrorSessionId_t mirror_session_id;
84 __u8 mark;
85 bool pass_to_kernel; // internal metadata, forces sending packet up to kernel stack
86} __attribute__((aligned(4)));
87
89 __u32 egress_port;
90 __u16 instance;
91 __u8 class_of_service;
92 __u8 truncate;
93 __u16 packet_length_bytes;
94} __attribute__((aligned(4)));
95
96#define send_to_port(x) (compiler_meta__->egress_port = x)
97#define drop_packet() (compiler_meta__->drop = true)
98
99// structures and functions for tc backend
100
102 u32 pipeid;
103 u32 tblid;
104} __attribute__((preserve_access_index));
105
106struct __attribute__((__packed__)) p4tc_table_entry_act_bpf {
107 u32 act_id;
108 u32 hit:1,
109 is_default_miss_act:1,
110 is_default_hit_act:1;
111 u8 params[124];
112};
113
115 u32 pipeid;
116 u32 tblid;
117 u32 profile_id;
118};
119extern struct p4tc_table_entry_act_bpf *bpf_p4tc_tbl_read(
120 struct __sk_buff *skb, struct p4tc_table_entry_act_bpf_params__local *params, void *key,
121 const u32 key__sz) __ksym;
122extern struct p4tc_table_entry_act_bpf *bpf_xdp_p4tc_tbl_lookup(
123 struct xdp_md *skb, struct p4tc_table_entry_act_bpf_params__local *params, void *key,
124 const u32 key__sz) __ksym;
125
126/* No mapping to PNA, but are useful utilities */
127extern int
128bpf_p4tc_entry_create(struct __sk_buff *skb_ctx,
130 void *key, const u32 key__sz,
131 struct p4tc_table_entry_act_bpf *act_bpf) __ksym;
132
133extern int
134xdp_p4tc_entry_create(struct xdp_md *xdp_ctx,
136 void *bpf_key_mask, u32 bpf_key_mask__sz,
137 struct p4tc_table_entry_act_bpf *act_bpf) __ksym;
138
139/* Equivalent to PNA add-on-miss */
140extern int
141bpf_p4tc_entry_create_on_miss(struct __sk_buff *skb_ctx,
143 void *key, const u32 key__sz,
144 struct p4tc_table_entry_act_bpf *act_bpf) __ksym;
145
146extern int
147xdp_p4tc_entry_create_on_miss(struct xdp_md *xdp_ctx,
149 void *key, const u32 key__sz,
150 struct p4tc_table_entry_act_bpf *act_bpf) __ksym;
151
152/* No mapping to PNA, but are useful utilities */
153extern int
154bpf_p4tc_entry_update(struct __sk_buff *skb_ctx,
156 void *key, const u32 key__sz,
157 struct p4tc_table_entry_act_bpf *act_bpf) __ksym;
158
159extern int
160xdp_p4tc_entry_update(struct xdp_md *xdp_ctx,
162 void *key, const u32 key__sz,
163 struct p4tc_table_entry_act_bpf *act_bpf) __ksym;
164
165/* No mapping to PNA, but are useful utilities */
166extern int
167bpf_p4tc_entry_delete(struct __sk_buff *skb_ctx,
169 void *key, const u32 key__sz) __ksym;
170
171extern int
172xdp_p4tc_entry_delete(struct xdp_md *xdp_ctx,
174 void *key, const u32 key__sz) __ksym;
175
176/* Start generic kfunc interface to any extern */
178 u32 ext_id;
179 u8 params[124]; // extern specific params if any
180};
181
182struct __attribute__((__packed__)) p4tc_ext_bpf_res {
183 u32 ext_id;
184 u8 params[124]; // extern specific values if any
185};
186
187/* Equivalent to PNA indirect counters */
188extern int
189bpf_p4tc_extern_indirect_count_pktsnbytes(struct __sk_buff *skb_ctx,
190 struct p4tc_ext_bpf_params *params,
191 struct p4tc_ext_bpf_res *res) __ksym;
192
193extern int
194bpf_p4tc_extern_indirect_count_pktsonly(struct __sk_buff *skb_ctx,
195 struct p4tc_ext_bpf_params *params,
196 struct p4tc_ext_bpf_res *res) __ksym;
197
198extern int
199bpf_p4tc_extern_indirect_count_bytesonly(struct __sk_buff *skb_ctx,
200 struct p4tc_ext_bpf_params *params,
201 struct p4tc_ext_bpf_res *res) __ksym;
202
203extern int
204xdp_p4tc_extern_indirect_count_pktsnbytes(struct xdp_md *xdp_ctx,
205 struct p4tc_ext_bpf_params *params,
206 struct p4tc_ext_bpf_res *res) __ksym;
207
208extern int
209xdp_p4tc_extern_indirect_count_pktsonly(struct xdp_md *xdp_ctx,
210 struct p4tc_ext_bpf_params *params,
211 struct p4tc_ext_bpf_res *res) __ksym;
212
213extern int
214xdp_p4tc_extern_indirect_count_bytesonly(struct xdp_md *xdp_ctx,
215 struct p4tc_ext_bpf_params *params,
216 struct p4tc_ext_bpf_res *res) __ksym;
217
218extern int bpf_p4tc_extern_meter_bytes_color(struct __sk_buff *skb_ctx,
219 struct p4tc_ext_bpf_params *params,
220 struct p4tc_ext_bpf_res *res,
221 u8 color) __ksym;
222
223extern int bpf_p4tc_extern_meter_bytes(struct __sk_buff *skb_ctx,
224 struct p4tc_ext_bpf_params *params,
225 struct p4tc_ext_bpf_res *res) __ksym;
226
227extern int bpf_p4tc_extern_meter_pkts_color(struct __sk_buff *skb_ctx,
228 struct p4tc_ext_bpf_params *params,
229 struct p4tc_ext_bpf_res *res,
230 u8 color) __ksym;
231
232extern int xdp_p4tc_extern_meter_pkts(struct xdp_md *xdp_ctx,
233 struct p4tc_ext_bpf_params *params,
234 struct p4tc_ext_bpf_res *res) __ksym;
235
236extern int xdp_p4tc_extern_meter_bytes_color(struct xdp_md *xdp_ctx,
237 struct p4tc_ext_bpf_params *params,
238 struct p4tc_ext_bpf_res *res,
239 u8 color) __ksym;
240
241extern int xdp_p4tc_extern_meter_bytes(struct xdp_md *xdp_ctx,
242 struct p4tc_ext_bpf_params *params,
243 struct p4tc_ext_bpf_res *res) __ksym;
244
245extern int xdp_p4tc_extern_meter_pkts_color(struct xdp_md *xdp_ctx,
246 struct p4tc_ext_bpf_params *params,
247 struct p4tc_ext_bpf_res *res,
248 u8 color) __ksym;
249
250extern int xdp_p4tc_extern_meter_pkts(struct xdp_md *xdp_ctx,
251 struct p4tc_ext_bpf_params *params,
252 struct p4tc_ext_bpf_res *res) __ksym;
253
254/* Start checksum related kfuncs */
256 __wsum csum;
257};
258
259/* Equivalent to PNA CRC16 checksum */
260/* Basic checksums are not implemented in DPDK */
261extern u16
262bpf_p4tc_ext_csum_crc16_add(struct p4tc_ext_csum_params *params,
263 const void *data, const u32 data__sz) __ksym;
264
265extern u16
266bpf_p4tc_ext_csum_crc16_get(struct p4tc_ext_csum_params *params) __ksym;
267
268extern void
269bpf_p4tc_ext_csum_crc16_clear(struct p4tc_ext_csum_params *params) __ksym;
270
271/* Equivalent to PNA CRC32 checksum */
272/* Basic checksums are not implemented in DPDK */
273extern u32
274bpf_p4tc_ext_csum_crc32_add(struct p4tc_ext_csum_params *params,
275 const void *data, const u32 data__sz) __ksym;
276
277extern u32
278bpf_p4tc_ext_csum_crc32_get(struct p4tc_ext_csum_params *params) __ksym;
279
280extern void
281bpf_p4tc_ext_csum_crc32_clear(struct p4tc_ext_csum_params *params) __ksym;
282
283extern u16
284bpf_p4tc_ext_csum_16bit_complement_get(struct p4tc_ext_csum_params *params) __ksym;
285
286/* Equivalent to PNA 16bit complement checksum (incremental checksum) */
287extern __wsum
288bpf_p4tc_ext_csum_16bit_complement_add(struct p4tc_ext_csum_params *params,
289 const void *data, int len) __ksym;
290
291extern int
292bpf_p4tc_ext_csum_16bit_complement_sub(struct p4tc_ext_csum_params *params,
293 const void *data, const u32 data__sz) __ksym;
294
295extern void
296bpf_p4tc_ext_csum_16bit_complement_clear(struct p4tc_ext_csum_params *params) __ksym;
297
298extern void
299bpf_p4tc_ext_csum_16bit_complement_set_state(struct p4tc_ext_csum_params *params,
300 u16 csum) __ksym;
301
302/* Equivalent to PNA crc16 hash */
303extern u16
304bpf_p4tc_ext_hash_crc16(const void *data, int len, u16 seed) __ksym;
305
306/* Equivalent to PNA crc16 hash base */
307static inline u16
308bpf_p4tc_ext_hash_base_crc16(const void *data, const u32 data__sz,
309 u32 base, u32 max, u16 seed) {
310 u16 hash = bpf_p4tc_ext_hash_crc16(data, data__sz, seed);
311
312 return (base + (hash % max));
313}
314
315/* Equivalent to PNA crc32 hash */
316extern u32
317bpf_p4tc_ext_hash_crc32(const void *data, const u32 data__sz, u32 seed) __ksym;
318
319/* Equivalent to PNA crc32 hash base */
320static inline u32
321bpf_p4tc_ext_hash_base_crc32(const void *data, const u32 data__sz,
322 u32 base, u32 max, u32 seed) {
323 u32 hash = bpf_p4tc_ext_hash_crc32(data, data__sz, seed);
324
325 return (base + (hash % max));
326}
327
328/* Equivalent to PNA 16-bit ones complement hash */
329extern u16
330bpf_p4tc_ext_hash_16bit_complement(const void *data, const u32 data__sz,
331 u16 seed) __ksym;
332
333/* Equivalent to PNA 16-bit ones complement hash base */
334static inline u16
335bpf_p4tc_ext_hash_base_16bit_complement(const void *data, const u32 data__sz,
336 u32 base, u32 max, u16 seed) {
337 u16 hash = bpf_p4tc_ext_hash_16bit_complement(data, data__sz, seed);
338
339 return (base + (hash % max));
340}
341
342// Generic api indirection for all externs which would hook into p4tc core code
343// or directly into kernel modules that could be written in C/RUST by user
344extern struct p4tc_ext_bpf_res *
345bpf_skb_p4tc_run_extern(struct __sk_buff *skb,
346 struct p4tc_ext_bpf_params *params) __ksym;
347extern struct p4tc_ext_bpf_res *
348bpf_xdp_p4tc_run_extern(struct xdp_md *skb,
349 struct p4tc_ext_bpf_params *params) __ksym;
350
351/* end generic kfunc interface to any extern */
352
353/* per extern specifics start */
354
355/* in this case it is PNA so we have these helpers like below
356 "is_net_port_skb" but for user specific externs the caller should
357 be doing similar flow:
358 a) populating p4tc_ext_bpf_params struct with their proper
359 parametrization of pipeline id, extern id, and extern specific params
360 b) receiving a response and retrieving their extern-specific data/return
361 codes from res->params
362*/
363
364#define EXTERN_IS_NET_PORT 1234
365#define EXTERN_IS_HOST_PORT 4567
366
367static bool is_net_port_skb(struct __sk_buff *skb, u32 ifindex)
368{
369 struct p4tc_ext_bpf_params param = {};
370 u32 *index = (u32 *)param.params;
371 struct p4tc_ext_bpf_res *res;
372 u32 *direction;
373
374 param.ext_id = EXTERN_IS_NET_PORT;
375 *index = ifindex;
376
377 res = bpf_skb_p4tc_run_extern(skb, &param);
378 /* NULL means if index wasn't found, and this will default to host */
379 if (!res)
380 return false;
381
382 direction = (u32 *)res->params;
383
384 return *direction == FROM_NET;
385}
386
387static bool is_host_port_skb(struct __sk_buff *skb, u32 ifindex)
388{
389 struct p4tc_ext_bpf_params param = {};
390 u32 *index = (u32 *)param.params;
391 struct p4tc_ext_bpf_res *res;
392 u32 *direction;
393
394 param.ext_id = EXTERN_IS_HOST_PORT;
395 *index = ifindex;
396
397 res = bpf_skb_p4tc_run_extern(skb, &param);
398 /* NULL means if index wasn't found, and this will default to host */
399 if (!res)
400 return true;
401
402 direction = (u32 *)res->params;
403
404 return *direction == FROM_HOST;
405}
406
407static bool is_net_port_xdp(struct xdp_md *skb, u32 ifindex)
408{
409 struct p4tc_ext_bpf_params param = {};
410 u32 *index = (u32 *)param.params;
411 struct p4tc_ext_bpf_res *res;
412 u32 *direction;
413
414 param.ext_id = EXTERN_IS_NET_PORT;
415 *index = ifindex;
416
417 res = bpf_xdp_p4tc_run_extern(skb, &param);
418 /* NULL means if index wasn't found, and this will default to host */
419 if (!res)
420 return false;
421
422 direction = (u32 *)res->params;
423
424 return *direction == FROM_NET;
425}
426
427static bool is_host_port_xdp(struct xdp_md *skb, u32 ifindex)
428{
429 struct p4tc_ext_bpf_params param = {};
430 u32 *index = (u32 *)param.params;
431 struct p4tc_ext_bpf_res *res;
432 u32 *direction;
433
434 param.ext_id = EXTERN_IS_HOST_PORT;
435 *index = ifindex;
436
437 res = bpf_xdp_p4tc_run_extern(skb, &param);
438 /* NULL means if index wasn't found, and this will default to host */
439 if (!res)
440 return true;
441
442 direction = (u32 *)res->params;
443
444 return *direction == FROM_HOST;
445}
446/* Extern control path read (for example, used for register read) */
447extern int bpf_p4tc_extern_md_read(struct __sk_buff *skb_ctx,
448 struct p4tc_ext_bpf_params *params,
449 struct p4tc_ext_bpf_res *res) __ksym;
450
451/* Extern control path write (for example, used for register write) */
452extern int bpf_p4tc_extern_md_write(struct __sk_buff *skb_ctx,
453 struct p4tc_ext_bpf_params *params,
454 struct p4tc_ext_bpf_res *res) __ksym;
455
456/* Extern control path read (for example, used for register read) for XDP */
457extern int xdp_p4tc_extern_md_read(struct xdp_md *xdp_ctx,
458 struct p4tc_ext_bpf_params *params,
459 struct p4tc_ext_bpf_res *res) __ksym;
460
461/* Extern control path read (for example, used for register write for XDP */
462extern int xdp_p4tc_extern_md_write(struct xdp_md *xdp_ctx,
463 struct p4tc_ext_bpf_params *params,
464 struct p4tc_ext_bpf_res *res) __ksym;
465
466/* Timestamp PNA extern */
467static inline u64 bpf_p4tc_extern_timestamp() {
468 return bpf_ktime_get_ns();
469}
470
471#define U32_MAX ((u32)~0U)
472
473/* Random PNA extern */
474static inline u32 bpf_p4tc_extern_random(u32 min, u32 max) {
475 if (max == U32_MAX)
476 return (min + bpf_get_prandom_u32());
477
478 return (min + bpf_get_prandom_u32()) % (max + 1);
479}
480#endif /* P4C_PNA_H */
Definition psa.h:125
Definition pna.h:177
Definition pna.h:255
Definition pna.h:101
Definition pna.h:114
Definition pna.h:76
Definition pna.h:56
Definition pna.h:66