summaryrefslogtreecommitdiffstats
path: root/include/datatype.h
blob: cf1151582245d92ea580626b179af58e84d68532 (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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
#ifndef NFTABLES_DATATYPE_H
#define NFTABLES_DATATYPE_H

#include <json.h>

/**
 * enum datatypes
 *
 * @TYPE_INVALID:	uninitialized
 * @TYPE_VERDICT:	nftables verdict
 * @TYPE_NFPROTO:	netfilter protocol (integer subtype)
 * @TYPE_BITMASK:	bitmask
 * @TYPE_INTEGER:	integer
 * @TYPE_STRING:	string
 * @TYPE_LLADDR:	link layer address (integer subtype)
 * @TYPE_IPADDR:	IPv4 address (integer subtype)
 * @TYPE_IP6ADDR:	IPv6 address (integer subtype)
 * @TYPE_ETHERADDR:	Ethernet address (lladdr subtype)
 * @TYPE_ETHERTYPE:	EtherType (integer subtype)
 * @TYPE_ARPOP:		ARP operation (integer subtype)
 * @TYPE_INET_PROTOCOL:	internet protocol (integer subtype)
 * @TYPE_INET_SERVICE:	internet service (integer subtype)
 * @TYPE_ICMP_TYPE:	ICMP type codes (integer subtype)
 * @TYPE_TCP_FLAG:	TCP flag (bitmask subtype)
 * @TCPE_DCCP_PKTTYPE:	DCCP packet type (integer subtype)
 * @TYPE_MH_TYPE:	Mobility Header type (integer subtype)
 * @TYPE_TIME:		relative time
 * @TYPE_MARK:		packet mark (integer subtype)
 * @TYPE_IFINDEX:	interface index (integer subtype)
 * @TYPE_ARPHRD:	interface type (integer subtype)
 * @TYPE_REALM:		routing realm (integer subtype)
 * @TYPE_CLASSID:	TC classid (integer subtype)
 * @TYPE_UID:		user ID (integer subtype)
 * @TYPE_GID:		group ID (integer subtype)
 * @TYPE_CT_STATE:	conntrack state (bitmask subtype)
 * @TYPE_CT_DIR:	conntrack direction
 * @TYPE_CT_STATUS:	conntrack status (bitmask subtype)
 * @TYPE_ICMP6_TYPE:	ICMPv6 type codes (integer subtype)
 * @TYPE_CT_LABEL:	Conntrack Label (bitmask subtype)
 * @TYPE_PKTTYPE:	packet type (integer subtype)
 * @TYPE_ICMP_CODE:	icmp code (integer subtype)
 * @TYPE_ICMPV6_CODE:	icmpv6 code (integer subtype)
 * @TYPE_ICMPX_CODE:	icmpx code (integer subtype)
 * @TYPE_DEVGROUP:	devgroup code (integer subtype)
 * @TYPE_DSCP:		Differentiated Services Code Point (integer subtype)
 * @TYPE_IFNAME:	interface name (string subtype)
 * @TYPE_IGMP:		IGMP type (integer subtype)
 */
enum datatypes {
	TYPE_INVALID,
	TYPE_VERDICT,
	TYPE_NFPROTO,
	TYPE_BITMASK,
	TYPE_INTEGER,
	TYPE_STRING,
	TYPE_LLADDR,
	TYPE_IPADDR,
	TYPE_IP6ADDR,
	TYPE_ETHERADDR,
	TYPE_ETHERTYPE,
	TYPE_ARPOP,
	TYPE_INET_PROTOCOL,
	TYPE_INET_SERVICE,
	TYPE_ICMP_TYPE,
	TYPE_TCP_FLAG,
	TYPE_DCCP_PKTTYPE,
	TYPE_MH_TYPE,
	TYPE_TIME,
	TYPE_MARK,
	TYPE_IFINDEX,
	TYPE_ARPHRD,
	TYPE_REALM,
	TYPE_CLASSID,
	TYPE_UID,
	TYPE_GID,
	TYPE_CT_STATE,
	TYPE_CT_DIR,
	TYPE_CT_STATUS,
	TYPE_ICMP6_TYPE,
	TYPE_CT_LABEL,
	TYPE_PKTTYPE,
	TYPE_ICMP_CODE,
	TYPE_ICMPV6_CODE,
	TYPE_ICMPX_CODE,
	TYPE_DEVGROUP,
	TYPE_DSCP,
	TYPE_ECN,
	TYPE_FIB_ADDR,
	TYPE_BOOLEAN,
	TYPE_CT_EVENTBIT,
	TYPE_IFNAME,
	TYPE_IGMP_TYPE,
	__TYPE_MAX
};
#define TYPE_MAX		(__TYPE_MAX - 1)

#define TYPE_BITS		6
#define TYPE_MASK		((1 << TYPE_BITS) - 1)

/**
 * enum byteorder
 *
 * @BYTEORDER_INVALID:		uninitialized/unknown
 * @BYTEORDER_HOST_ENDIAN:	host endian
 * @BYTEORDER_BIG_ENDIAN:	big endian
 */
enum byteorder {
	BYTEORDER_INVALID,
	BYTEORDER_HOST_ENDIAN,
	BYTEORDER_BIG_ENDIAN,
};

struct expr;

/**
 * enum datatype_flags
 *
 * @DTYPE_F_ALLOC:		datatype is dynamically allocated
 * @DTYPE_F_PREFIX:		preferred representation for ranges is a prefix
 */
enum datatype_flags {
	DTYPE_F_ALLOC		= (1 << 0),
	DTYPE_F_PREFIX		= (1 << 1),
};

struct parse_ctx;
/**
 * struct datatype
 *
 * @type:	numeric identifier
 * @byteorder:	byteorder of type (non-basetypes only)
 * @flags:	flags
 * @size:	type size (fixed sized non-basetypes only)
 * @subtypes:	number of subtypes (concat type)
 * @name:	type name
 * @desc:	type description
 * @basetype:	basetype for subtypes, determines type compatibility
 * @basefmt:	format string for basetype
 * @print:	function to print a constant of this type
 * @parse:	function to parse a symbol and return an expression
 * @sym_tbl:	symbol table for this type
 * @refcnt:	reference counter (only for DTYPE_F_ALLOC)
 */
struct datatype {
	uint32_t			type;
	enum byteorder			byteorder;
	unsigned int			flags;
	unsigned int			size;
	unsigned int			subtypes;
	const char			*name;
	const char			*desc;
	const struct datatype		*basetype;
	const char			*basefmt;
	void				(*print)(const struct expr *expr,
						 struct output_ctx *octx);
	json_t				*(*json)(const struct expr *expr,
						 struct output_ctx *octx);
	struct error_record		*(*parse)(struct parse_ctx *ctx,
						  const struct expr *sym,
						  struct expr **res);
	const struct symbol_table	*sym_tbl;
	unsigned int			refcnt;
};

extern const struct datatype *datatype_lookup(enum datatypes type);
extern const struct datatype *datatype_lookup_byname(const char *name);
extern struct datatype *datatype_get(const struct datatype *dtype);
extern void datatype_set(struct expr *expr, const struct datatype *dtype);
extern void datatype_free(const struct datatype *dtype);

struct parse_ctx {
	struct symbol_tables	*tbl;
};

extern struct error_record *symbol_parse(struct parse_ctx *ctx,
					 const struct expr *sym,
					 struct expr **res);
extern void datatype_print(const struct expr *expr, struct output_ctx *octx);

static inline bool datatype_equal(const struct datatype *d1,
				  const struct datatype *d2)
{
	return d1->type == d2->type;
}

static inline const struct datatype *
datatype_basetype(const struct datatype *dtype)
{
	return dtype->basetype ? dtype->basetype : dtype;
}

/**
 * struct symbolic_constant - symbol <-> constant mapping
 *
 * @identifier:	symbol
 * @value:	symbolic value
 */
struct symbolic_constant {
	const char			*identifier;
	uint64_t			value;
};

#define SYMBOL(id, v)	{ .identifier = (id), .value = (v) }
#define SYMBOL_LIST_END	(struct symbolic_constant) { }

/**
 * enum base - indicate how to display symbol table values
 *
 * @BASE_HEXADECIMAL:	hexadecimal
 * @BASE_DECIMAL:	decimal
 */
enum base {
	BASE_HEXADECIMAL,
	BASE_DECIMAL,
};

/**
 * struct symbol_table - type construction from symbolic values
 *
 * @base:	base of symbols representation
 * @symbols:	the symbols
 */
struct symbol_table {
	enum base 			base;
	struct symbolic_constant	symbols[];
};

extern struct error_record *symbolic_constant_parse(struct parse_ctx *ctx,
						    const struct expr *sym,
						    const struct symbol_table *tbl,
						    struct expr **res);
extern void symbolic_constant_print(const struct symbol_table *tbl,
				    const struct expr *expr, bool quotes,
				    struct output_ctx *octx);
extern void symbol_table_print(const struct symbol_table *tbl,
			       const struct datatype *dtype,
			       enum byteorder byteorder,
			       struct output_ctx *octx);

extern struct symbol_table *rt_symbol_table_init(const char *filename);
extern void rt_symbol_table_free(const struct symbol_table *tbl);

extern const struct datatype invalid_type;
extern const struct datatype verdict_type;
extern const struct datatype nfproto_type;
extern const struct datatype bitmask_type;
extern const struct datatype integer_type;
extern const struct datatype string_type;
extern const struct datatype lladdr_type;
extern const struct datatype ipaddr_type;
extern const struct datatype ip6addr_type;
extern const struct datatype etheraddr_type;
extern const struct datatype ethertype_type;
extern const struct datatype arphrd_type;
extern const struct datatype inet_protocol_type;
extern const struct datatype inet_service_type;
extern const struct datatype mark_type;
extern const struct datatype icmp_type_type;
extern const struct datatype icmp_code_type;
extern const struct datatype icmpv6_code_type;
extern const struct datatype icmpx_code_type;
extern const struct datatype igmp_type_type;
extern const struct datatype time_type;
extern const struct datatype boolean_type;

void inet_service_type_print(const struct expr *expr, struct output_ctx *octx);

extern const struct datatype *concat_type_alloc(uint32_t type);

static inline uint32_t concat_subtype_add(uint32_t type, uint32_t subtype)
{
	return type << TYPE_BITS | subtype;
}

static inline uint32_t concat_subtype_id(uint32_t type, unsigned int n)
{
	return (type >> TYPE_BITS * n) & TYPE_MASK;
}

static inline const struct datatype *
concat_subtype_lookup(uint32_t type, unsigned int n)
{
	return datatype_lookup(concat_subtype_id(type, n));
}

extern const struct datatype *
set_datatype_alloc(const struct datatype *orig_dtype, unsigned int byteorder);
extern void set_datatype_destroy(const struct datatype *dtype);

extern void time_print(uint64_t msec, struct output_ctx *octx);
extern struct error_record *time_parse(const struct location *loc,
				       const char *c, uint64_t *res);

extern struct error_record *rate_parse(const struct location *loc,
				       const char *str, uint64_t *rate,
				       uint64_t *unit);

extern struct error_record *data_unit_parse(const struct location *loc,
					    const char *str, uint64_t *rate);

#endif /* NFTABLES_DATATYPE_H */