summaryrefslogtreecommitdiff
path: root/trafgen_proto.h
blob: 29d68db1016d384bd1df2618a2dfe7f6267bb924 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#ifndef TRAFGEN_PROTO_H
#define TRAFGEN_PROTO_H

#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>

enum proto_id {
	PROTO_NONE = 0,
	PROTO_ETH,
	PROTO_PAUSE,
	PROTO_PFC,
	PROTO_VLAN,
	PROTO_ARP,
	PROTO_MPLS,
	PROTO_IP4,
	PROTO_ICMP4,
	PROTO_IP6,
	PROTO_ICMP6,
	PROTO_UDP,
	PROTO_TCP,
	__PROTO_MAX,
};

enum proto_layer {
	PROTO_L0, /* invalid layer */
	PROTO_L2,
	PROTO_L3,
	PROTO_L4,
};

struct proto_field;
struct proto_hdr;

struct proto_ops {
	enum proto_id id;
	enum proto_layer layer;

	void (*header_init)(struct proto_hdr *hdr);
	void (*header_finish)(struct proto_hdr *hdr);
	void (*field_changed)(struct proto_field *field);
	void (*packet_finish)(struct proto_hdr *hdr);
	void (*packet_update)(struct proto_hdr *hdr);
	void (*set_next_proto)(struct proto_hdr *hdr, enum proto_id pid);
};

struct proto_hdr {
	const struct proto_ops *ops;
	uint16_t pkt_offset;
	uint32_t pkt_id;
	uint32_t index;
	struct proto_field *fields;
	size_t fields_count;
	bool is_csum_valid;
	size_t len;
};

enum proto_field_func_t {
	PROTO_FIELD_FUNC_INC = 1 << 0,
	PROTO_FIELD_FUNC_MIN = 1 << 1,
	PROTO_FIELD_FUNC_RND = 1 << 2,
};

struct proto_field_func {
	enum proto_field_func_t type;
	uint32_t min;
	uint32_t max;
	int32_t inc;
	uint16_t offset;
	uint32_t val;
	size_t len;

	void (*update_field)(struct proto_field *field);
};

struct proto_field {
	uint32_t id;
	size_t len;
	uint32_t shift;
	uint32_t mask;
	/* might be negative (e.g. VLAN TPID field) */
	int16_t offset;

	struct proto_field_func func;
	bool is_set;
	uint16_t pkt_offset;
	struct proto_hdr *hdr;
};

extern void protos_init(const char *dev);
extern void proto_ops_register(const struct proto_ops *ops);

extern struct proto_hdr *proto_header_push(enum proto_id pid);
extern void proto_header_finish(struct proto_hdr *hdr);
extern void proto_packet_finish(void);
extern void proto_packet_update(uint32_t idx);

extern struct proto_hdr *proto_lower_default_add(struct proto_hdr *hdr,
						 enum proto_id pid);

extern struct proto_hdr *proto_lower_header(struct proto_hdr *hdr);
extern struct proto_hdr *proto_upper_header(struct proto_hdr *hdr);
extern uint8_t *proto_header_ptr(struct proto_hdr *hdr);

extern void proto_header_fields_add(struct proto_hdr *hdr,
				    const struct proto_field *fields,
				    size_t count);

extern bool proto_hdr_field_is_set(struct proto_hdr *hdr, uint32_t fid);
extern void proto_hdr_field_set_bytes(struct proto_hdr *hdr, uint32_t fid,
				  const uint8_t *bytes);
extern void proto_hdr_field_set_u8(struct proto_hdr *hdr, uint32_t fid, uint8_t val);
extern uint8_t proto_hdr_field_get_u8(struct proto_hdr *hdr, uint32_t fid);
extern void proto_hdr_field_set_u16(struct proto_hdr *hdr, uint32_t fid, uint16_t val);
extern uint16_t proto_hdr_field_get_u16(struct proto_hdr *hdr, uint32_t fid);
extern void proto_hdr_field_set_u32(struct proto_hdr *hdr, uint32_t fid, uint32_t val);
extern uint32_t proto_hdr_field_get_u32(struct proto_hdr *hdr, uint32_t fid);

extern void proto_hdr_field_set_default_bytes(struct proto_hdr *hdr, uint32_t fid,
					  const uint8_t *bytes);
extern void proto_hdr_field_set_default_u8(struct proto_hdr *hdr, uint32_t fid,
				       uint8_t val);
extern void proto_hdr_field_set_default_u16(struct proto_hdr *hdr, uint32_t fid,
				        uint16_t val);
extern void proto_hdr_field_set_default_u32(struct proto_hdr *hdr, uint32_t fid,
				        uint32_t val);

extern void proto_hdr_field_set_be16(struct proto_hdr *hdr, uint32_t fid, uint16_t val);
extern void proto_hdr_field_set_be32(struct proto_hdr *hdr, uint32_t fid, uint32_t val);

extern void proto_hdr_field_set_default_be16(struct proto_hdr *hdr, uint32_t fid,
					 uint16_t val);
extern void proto_hdr_field_set_default_be32(struct proto_hdr *hdr, uint32_t fid,
					 uint32_t val);

extern void proto_hdr_field_set_dev_mac(struct proto_hdr *hdr, uint32_t fid);
extern void proto_hdr_field_set_default_dev_mac(struct proto_hdr *hdr, uint32_t fid);

extern void proto_hdr_field_set_dev_ipv4(struct proto_hdr *hdr, uint32_t fid);
extern void proto_hdr_field_set_default_dev_ipv4(struct proto_hdr *hdr, uint32_t fid);

extern void proto_hdr_field_set_dev_ipv6(struct proto_hdr *hdr, uint32_t fid);
extern void proto_hdr_field_set_default_dev_ipv6(struct proto_hdr *hdr, uint32_t fid);

extern void proto_field_dyn_apply(struct proto_field *field);

extern struct proto_field *proto_hdr_field_by_id(struct proto_hdr *hdr, uint32_t fid);


extern void proto_field_set_u8(struct proto_field *field, uint8_t val);
extern uint8_t proto_field_get_u8(struct proto_field *field);
extern void proto_field_set_u16(struct proto_field *field, uint16_t val);
extern uint16_t proto_field_get_u16(struct proto_field *field);
extern void proto_field_set_u32(struct proto_field *field, uint32_t val);
extern uint32_t proto_field_get_u32(struct proto_field *field);
extern void proto_field_set_be16(struct proto_field *field, uint16_t val);
extern void proto_field_set_be32(struct proto_field *field, uint32_t val);

extern void proto_field_func_add(struct proto_field *field,
				 struct proto_field_func *func);

#endif /* TRAFGEN_PROTO_H */