aboutsummaryrefslogtreecommitdiffstats
path: root/sys/linux/netfilter_bridge.txt
blob: 44184a65dd9afd9b5684a0d12e9377d5511dd90b (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
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
# Copyright 2018 syzkaller project authors. All rights reserved.
# Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.

include <linux/socket.h>
include <uapi/linux/netfilter/x_tables.h>
include <uapi/linux/netfilter_bridge.h>
include <uapi/linux/netfilter_bridge/ebtables.h>
include <uapi/linux/netfilter_bridge/ebt_802_3.h>
include <uapi/linux/netfilter_bridge/ebt_among.h>
include <uapi/linux/netfilter_bridge/ebt_arp.h>
include <uapi/linux/netfilter_bridge/ebt_ip.h>
include <uapi/linux/netfilter_bridge/ebt_ip6.h>
include <uapi/linux/netfilter_bridge/ebt_limit.h>
include <uapi/linux/netfilter_bridge/ebt_mark_m.h>
include <uapi/linux/netfilter_bridge/ebt_pkttype.h>
include <uapi/linux/netfilter_bridge/ebt_stp.h>
include <uapi/linux/netfilter_bridge/ebt_vlan.h>
include <uapi/linux/netfilter_bridge/ebt_arpreply.h>
include <uapi/linux/netfilter_bridge/ebt_nat.h>
include <uapi/linux/netfilter_bridge/ebt_log.h>
include <uapi/linux/netfilter_bridge/ebt_mark_t.h>
include <uapi/linux/netfilter_bridge/ebt_nflog.h>
include <uapi/linux/netfilter_bridge/ebt_redirect.h>

setsockopt$EBT_SO_SET_ENTRIES(fd sock_in, level const[SOL_IP], opt const[EBT_SO_SET_ENTRIES], val ptr[in, ebt_replace], len const[0])
setsockopt$EBT_SO_SET_COUNTERS(fd sock_in, level const[SOL_IP], opt const[EBT_SO_SET_COUNTERS], val ptr[in, ebt_counters_info], len len[val])
getsockopt$EBT_SO_GET_INFO(fd sock_in, level const[SOL_IP], opt const[EBT_SO_GET_INFO], val ptr[in, ebt_getinfo], len ptr[in, len[val, int32]])
getsockopt$EBT_SO_GET_INIT_INFO(fd sock_in, level const[SOL_IP], opt const[EBT_SO_GET_INIT_INFO], val ptr[in, ebt_getinfo], len ptr[in, len[val, int32]])
getsockopt$EBT_SO_GET_ENTRIES(fd sock_in, level const[SOL_IP], opt const[EBT_SO_GET_ENTRIES], val ptr[in, ebt_get_entries], len ptr[in, len[val, int32]])
getsockopt$EBT_SO_GET_INIT_ENTRIES(fd sock_in, level const[SOL_IP], opt const[EBT_SO_GET_INIT_ENTRIES], val ptr[in, ebt_get_entries], len ptr[in, len[val, int32]])

ebt_replace [
	filter	ebt_replace_t["filter", EBT_FILTER_VALID_HOOKS, ebt_filter_targets]
	nat	ebt_replace_t["nat", EBT_NAT_VALID_HOOKS, ebt_nat_targets]
	broute	ebt_replace_t["broute", EBT_BROUTE_VALID_HOOKS, ebt_broute_targets]
] [varlen]

define NF_BR_PRE_ROUTING_BIT	1 << NF_BR_PRE_ROUTING
define NF_BR_LOCAL_IN_BIT	1 << NF_BR_LOCAL_IN
define NF_BR_FORWARD_BIT	1 << NF_BR_FORWARD
define NF_BR_LOCAL_OUT_BIT	1 << NF_BR_LOCAL_OUT
define NF_BR_POST_ROUTING_BIT	1 << NF_BR_POST_ROUTING
define NF_BR_BROUTING_BIT	1 << NF_BR_BROUTING

define EBT_FILTER_VALID_HOOKS	NF_BR_LOCAL_IN_BIT | NF_BR_FORWARD_BIT | NF_BR_LOCAL_OUT_BIT
define EBT_NAT_VALID_HOOKS	NF_BR_PRE_ROUTING_BIT | NF_BR_LOCAL_OUT_BIT | NF_BR_POST_ROUTING_BIT
define EBT_BROUTE_VALID_HOOKS	NF_BR_BROUTING_BIT

type ebt_replace_t[NAME, HOOKS, TARGETS] {
	name		string[NAME, XT_TABLE_MAXNAMELEN]
	valid_hooks	const[HOOKS, int32]
	nentries	const[0, int32]
	entries_size	bytesize[entries, int32]
	hook_entry	array[intptr, NF_BR_NUMHOOKS]
	num_counters	const[0, int32]
	counters	ptr[out, array[xt_counters, 1]]
	entries		ptr[in, array[ebt_entries[TARGETS], 3:4]]
}

type ebt_entries[TARGETS] {
	distinguisher	const[0, int32]
	name		string["", EBT_CHAIN_MAXNAMELEN]
	counter_offset	const[0, int32]
	policy		flags[ebt_entries_policy, int32]
	nentries	len[entries, int32]
	entries		array[ebt_entry[TARGETS], 0:2]
}

ebt_entries_policy = EBT_DROP, EBT_ACCEPT, EBT_RETURN
ebt_verdicts = EBT_DROP, EBT_ACCEPT, EBT_RETURN, EBT_CONTINUE

type ebt_entry[TARGETS] {
	bitmask		flags[ebt_entry_bitmask, int32]
	invflags	flags[ebt_entry_invflags, int32]
	ethproto	flags[ether_types, int16be]
	in		devname
	logical_in	devname
	out		devname
	logical_out	devname
	sourcemac	mac_addr
	sourcemsk	mac_addr_mask
	destmac		mac_addr
	destmsk		mac_addr_mask
	watchers_offset	offsetof[watchers, int32]
	target_offset	offsetof[target, int32]
	next_offset	bytesize[parent, int32]
	matches		array[ebt_matches, 0:2]
	watchers	array[TARGETS, 0:2]
	target		TARGETS
} [packed]

ebt_entry_bitmask = EBT_NOPROTO_F, EBT_802_3_F, EBT_SOURCEMAC_F, EBT_DESTMAC_F
ebt_entry_invflags = EBT_IPROTO, EBT_IIN, EBT_IOUT, EBT_ISOURCE, EBT_IDEST, EBT_ILOGICALIN, EBT_ILOGICALOUT

define EBT_NOPROTO_F	EBT_ENTRY_OR_ENTRIES | EBT_NOPROTO
define EBT_802_3_F	EBT_ENTRY_OR_ENTRIES | EBT_802_3
define EBT_SOURCEMAC_F	EBT_ENTRY_OR_ENTRIES | EBT_SOURCEMAC
define EBT_DESTMAC_F	EBT_ENTRY_OR_ENTRIES | EBT_DESTMAC

ebt_tables = "filter", "nat", "broute"

ebt_counters_info {
	name		string[ebt_tables, XT_TABLE_MAXNAMELEN]
	valid_hooks	const[0, int32]
	nentries	const[0, int32]
	entries_size	const[0, int32]
	hook_entry	array[intptr, NF_BR_NUMHOOKS]
	num_counters	len[counters1, int32]
	counters	ptr[out, array[xt_counters]]
	entries		const[0, intptr]
	counters1	array[xt_counters]
}

ebt_getinfo {
	name		string[ebt_tables, XT_TABLE_MAXNAMELEN]
	valid_hooks	const[0, int32]
	nentries	const[0, int32]
	entries_size	const[0, int32]
	hook_entry	array[intptr, NF_BR_NUMHOOKS]
	num_counters	const[0, int32]
	counters	const[0, intptr]
	entries		const[0, intptr]
}

ebt_get_entries {
	name		string[ebt_tables, XT_TABLE_MAXNAMELEN]
	valid_hooks	const[0, int32]
	nentries	int32[3:4]
	entries_size	bytesize[entries, int32]
	hook_entry	array[intptr, NF_BR_NUMHOOKS]
	num_counters	len[counters, int32]
	counters	ptr[out, array[xt_counters]]
	entries		ptr[out, array[int8]]
}

# MATCHES:

type ebt_entry_match[NAME] {
	name		string[NAME, EBT_EXTENSION_MAXNAMELEN]
	revision	const[0, int8]
	match_size	bytesize[ebt_entry_match_t:data, int32]
} [align[PTR_SIZE]]

type ebt_entry_match_t[NAME, DATA] {
	header	ebt_entry_match[NAME]
	data	xt_padded[DATA]
}

type xt_padded[TYPE] {
	data	TYPE
} [align[PTR_SIZE]]

ebt_matches [
	m802_3		ebt_entry_match_t["802_3", ebt_802_3_info]
	among		ebt_entry_match_t["among", ebt_among_info]
	arp		ebt_entry_match_t["arp", ebt_arp_info]
	ip		ebt_entry_match_t["ip", ebt_ip_info]
	ip6		ebt_entry_match_t["ip6", ebt_ip6_info]
	limit		ebt_entry_match_t["limit", ebt_limit_info]
	mark_m		ebt_entry_match_t["mark_m", ebt_mark_m_info]
	pkttype		ebt_entry_match_t["pkttype", ebt_pkttype_info]
	stp		ebt_entry_match_t["stp", ebt_stp_info]
	vlan		ebt_entry_match_t["vlan", ebt_vlan_info]
# AF_UNSPEC matches (only version 0 and not overriden by AF_BRIDGE).
	cgroup0		ebt_entry_match_t["cgroup", xt_cgroup_info_v0]
	helper		ebt_entry_match_t["helper", xt_helper_info]
	rateest		ebt_entry_match_t["rateest", xt_rateest_match_info]
	time		ebt_entry_match_t["time", xt_time_info]
	bpf0		ebt_entry_match_t["bpf", xt_bpf_info]
	realm		ebt_entry_match_t["realm", xt_realm_info]
	connbytes	ebt_entry_match_t["connbytes", xt_connbytes_info]
	quota		ebt_entry_match_t["quota", xt_quota_info]
	ipvs		ebt_entry_match_t["ipvs", xt_ipvs_mtinfo]
	nfacct		ebt_entry_match_t["nfacct", xt_nfacct_match_info]
	mac		ebt_entry_match_t["mac", xt_mac_info]
	comment		ebt_entry_match_t["comment", xt_comment_info]
	statistic	ebt_entry_match_t["statistic", xt_statistic_info]
	physdev		ebt_entry_match_t["physdev", xt_physdev_info]
	connlabel	ebt_entry_match_t["connlabel", xt_connlabel_mtinfo]
	devgroup	ebt_entry_match_t["devgroup", xt_devgroup_info]
	cluster		ebt_entry_match_t["cluster", xt_cluster_match_info]
	owner		ebt_entry_match_t["owner", xt_owner_match_info]
	u32		ebt_entry_match_t["u32", xt_u32]
	cpu		ebt_entry_match_t["cpu", xt_cpu_info]
	state		ebt_entry_match_t["state", xt_state_info]
] [varlen]

ebt_802_3_info {
	sap		flags[sap_values, int8]
	type		int16be
	bitmask		flags[ebt_802_3_flags, int8]
	invflags	flags[ebt_802_3_flags, int8]
}

ebt_802_3_flags = EBT_802_3_SAP, EBT_802_3_TYPE, EBT_802_3

ebt_among_info {
	wh_dst_ofs	ebt_among_info_offset[dst]
	wh_src_ofs	ebt_among_info_offset[src]
	bitmask		flags[ebt_among_flags, int32]
	dst		ebt_mac_wormhash
	src		ebt_mac_wormhash
} [packed]

type ebt_among_info_offset[FIELD] [
	offset	offsetof[ebt_among_info:FIELD, int32]
	zero	const[0, int32]
]

ebt_mac_wormhash {
	table		array[int32, 257]
	poolsize	len[pool, int32]
	pool		array[ebt_mac_wormhash_tuple]
}

ebt_mac_wormhash_tuple {
	cmp	array[int32, 2]
	ip	ipv4_addr
}

ebt_among_flags = EBT_AMONG_DST_NEG, EBT_AMONG_SRC_NEG

ebt_arp_info {
	htype		flags[arp_htypes, int16be]
	ptype		flags[ether_types, int16be]
	op		flags[arp_ops, int16be]
	saddr		ipv4_addr
	smsk		ipv4_addr_mask
	daddr		ipv4_addr
	dmsk		ipv4_addr_mask
	smaddr		mac_addr
	smmsk		mac_addr_mask
	dmaddr		mac_addr
	dmmsk		mac_addr_mask
	bitmask		flags[ebt_arp_flags, int8]
	invflags	flags[ebt_arp_flags, int8]
}

ebt_arp_flags = EBT_ARP_OPCODE, EBT_ARP_HTYPE, EBT_ARP_PTYPE, EBT_ARP_SRC_IP, EBT_ARP_DST_IP, EBT_ARP_SRC_MAC, EBT_ARP_DST_MAC, EBT_ARP_GRAT

ebt_ip_info {
	saddr		ipv4_addr
	daddr		ipv4_addr
	smsk		ipv4_addr_mask
	dmsk		ipv4_addr_mask
	tos		int8
	protocol	flags[ipv4_types, int8]
	bitmask		flags[ebt_ip_flags, int8]
	invflags	flags[ebt_ip_flags, int8]
	sport_min	sock_port
	sport_max	sock_port
	dport_min	sock_port
	dport_max	sock_port
}

ebt_ip_flags = EBT_IP_SOURCE, EBT_IP_DEST, EBT_IP_TOS, EBT_IP_PROTO, EBT_IP_SPORT, EBT_IP_DPORT

ebt_ip6_info {
	saddr		ipv6_addr
	daddr		ipv6_addr
	smsk		ipv6_addr_mask
	dmsk		ipv6_addr_mask
	tclass		int8
	protocol	flags[ipv6_types, int8]
	bitmask		flags[ebt_ip6_flags, int8]
	invflags	flags[ebt_ip6_flags, int8]
	sport_min	sock_port
	sport_max	sock_port
	dport_min	sock_port
	dport_max	sock_port
}

ebt_ip6_flags = EBT_IP6_SOURCE, EBT_IP6_DEST, EBT_IP6_TCLASS, EBT_IP6_PROTO, EBT_IP6_SPORT, EBT_IP6_DPORT, EBT_IP6_ICMP6

ebt_limit_info {
	avg		int32
	burst		int32
	prev		intptr
	credit		int32
	credit_cap	int32
	cost		int32
}

ebt_mark_m_info {
	mark	intptr
	mask	intptr
	invert	flags[ebt_mark_m_flags, int8]
	bitmask	flags[ebt_mark_m_flags, int8]
}

ebt_mark_m_flags = EBT_MARK_AND, EBT_MARK_OR

ebt_pkttype_info {
	pkt_type	int8[0:7]
	invert		bool8
}

ebt_stp_info {
	type		int8
	config		ebt_stp_config_info
	bitmask		flags[ebt_stp_flags, int16]
	invflags	flags[ebt_stp_flags, int16]
}

ebt_stp_config_info {
	flags		int8
	root_priol	int16
	root_priou	int16
	root_addr	mac_addr
	root_addrmsk	mac_addr_mask
	root_costl	int32
	root_costu	int32
	sender_priol	int16
	sender_priou	int16
	sender_addr	mac_addr
	sender_addrmsk	mac_addr_mask
	portl		sock_port
	portu		sock_port
	msg_agel	int16
	msg_ageu	int16
	max_agel	int16
	max_ageu	int16
	hello_timel	int16
	hello_timeu	int16
	forward_delayl	int16
	forward_delayu	int16
}

ebt_stp_flags = EBT_STP_TYPE, EBT_STP_FLAGS, EBT_STP_ROOTPRIO, EBT_STP_ROOTADDR, EBT_STP_ROOTCOST, EBT_STP_SENDERPRIO, EBT_STP_SENDERADDR, EBT_STP_PORT, EBT_STP_MSGAGE, EBT_STP_MAXAGE, EBT_STP_HELLOTIME, EBT_STP_FWDD

ebt_vlan_info {
	id		int16[0:4]
	prio		int8[0:7]
	encap		flags[ether_types, int16be]
	bitmask		flags[ebt_vlan_flags, int8]
	invflags	flags[ebt_vlan_flags, int8]
}

ebt_vlan_flags = EBT_VLAN_ID, EBT_VLAN_PRIO, EBT_VLAN_ENCAP

# TARGETS:

type ebt_entry_target[NAME, DATA] {
	name		string[NAME, EBT_FUNCTION_MAXNAMELEN]
	target_size	bytesize[data, int32]
	data		xt_padded[DATA]
}

ebt_targets [
	dnat		ebt_entry_target["dnat", ebt_nat_info]
	log		ebt_entry_target["log", ebt_log_info]
	mark		ebt_entry_target["mark", ebt_mark_t_info]
	nflog		ebt_entry_target["nflog", ebt_nflog_info]
	redirect	ebt_entry_target["redirect", ebt_redirect_info]
# AF_UNSPEC targets (only version 0).
	STANDARD	ebt_entry_target["", flags[nf_verdicts, int32]]
	ERROR		ebt_entry_target["ERROR", array[int8, XT_FUNCTION_MAXNAMELEN]]
	LED		ebt_entry_target["LED", xt_led_info]
	RATEEST		ebt_entry_target["RATEEST", xt_rateest_target_info]
	NFQUEUE0	ebt_entry_target["NFQUEUE", xt_NFQ_info]
	CLASSIFY	ebt_entry_target["CLASSIFY", xt_classify_target_info]
	IDLETIMER	ebt_entry_target["IDLETIMER", idletimer_tg_info]
	AUDIT		ebt_entry_target["AUDIT", xt_audit_info]
	CONNSECMARK	ebt_entry_target["CONNSECMARK", xt_connsecmark_target_info]
	SECMARK		ebt_entry_target["SECMARK", xt_secmark_target_info]
	NFLOG		ebt_entry_target["NFLOG", xt_nflog_info]
] [varlen]

ebt_filter_targets [
	common	ebt_targets
] [varlen]

ebt_nat_targets [
	common		ebt_targets
	arpreply	ebt_entry_target["arpreply", ebt_arpreply_info]
	snat		ebt_entry_target["snat", ebt_nat_info]
] [varlen]

ebt_broute_targets [
	common	ebt_targets
] [varlen]

ebt_arpreply_info {
	mac	mac_addr
# TODO: can also be jump target
	target	flags[ebt_verdicts, int32]
}

ebt_nat_info {
	mac	mac_addr
# TODO: can also be jump target
	target	flags[ebt_nat_verdicts, int32]
}

ebt_nat_verdicts = NAT_ARP_BIT, ebt_verdicts

ebt_log_info {
	loglevel	int8
	prefix		array[int8, EBT_LOG_PREFIX_SIZE]
	bitmask		flags[ebt_log_bitmask, int32]
}

ebt_log_bitmask = EBT_LOG_IP, EBT_LOG_ARP, EBT_LOG_NFLOG, EBT_LOG_IP6

ebt_mark_t_info {
	mark	flags[ebt_mark_marks, intptr]
# TODO: can also be jump target
	target	flags[ebt_verdicts, int32]
}

ebt_mark_marks = MARK_SET_VALUE, MARK_OR_VALUE, MARK_AND_VALUE, MARK_XOR_VALUE

ebt_nflog_info {
	len		int32
	group		int16
	threshold	int16
	flags		const[0, int16]
	pad		const[0, int16]
	prefix		array[int8, EBT_NFLOG_PREFIX_SIZE]
}

ebt_redirect_info {
# TODO: can also be jump target
	target	flags[ebt_verdicts, int32]
}