xref: /dragonfly/sys/net/ipfw3/ip_fw3.h (revision e98bdfd3)
1 /*
2  * Copyright (c) 1993 Daniel Boulet
3  * Copyright (c) 1994 Ugen J.S.Antsilevich
4  * Copyright (c) 2002 Luigi Rizzo, Universita` di Pisa
5  * Copyright (c) 2015 The DragonFly Project.  All rights reserved.
6  *
7  * This code is derived from software contributed to The DragonFly Project
8  * by Bill Yuan <bycn82@dragonflybsd.org>
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  *
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in
18  *    the documentation and/or other materials provided with the
19  *    distribution.
20  * 3. Neither the name of The DragonFly Project nor the names of its
21  *    contributors may be used to endorse or promote products derived
22  *    from this software without specific, prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
28  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
30  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
32  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
33  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
34  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  *
37  */
38 
39 #ifndef _IP_FW3_H_
40 #define _IP_FW3_H_
41 
42 #ifdef _KERNEL
43 #include <net/bpf.h>
44 #include <net/netisr2.h>
45 
46 int     ip_fw3_sockopt(struct sockopt *);
47 extern int ip_fw3_loaded;
48 
49 #else
50 #include <pcap/bpf.h>
51 #define PCAP_DONT_INCLUDE_PCAP_BPF_H
52 #endif
53 
54 #define	IPFW3_LOADED	(ip_fw3_loaded)
55 
56 /*
57  * _IPFW2_H is from ipfw/ip_fw2.h, both cannot be included past this
58  * point but we need both the IPFW2_LOADED and IPFW3_LOADED macros
59  */
60 #ifndef _IPFW2_H
61 #define _IPFW2_H
62 
63 #define		RESERVED_SIZE		12
64 #define		SIZE_OF_IPFWINSN	8
65 #define		LEN_OF_IPFWINSN		2
66 #define		IPFW_DEFAULT_RULE	65535	/* rulenum for the default rule */
67 #define		IPFW_DEFAULT_SET	31	/* set number for the default rule  */
68 
69 /*
70  * Template for instructions.
71  *
72  * ipfw_insn is used for all instructions which require no operands,
73  * a single 16-bit value (arg1), or a couple of 8-bit values.
74  *
75  * For other instructions which require different/larger arguments
76  * we have derived structures, ipfw_insn_*.
77  *
78  * The size of the instruction (in 32-bit words) is in the low
79  * 6 bits of "len". The 2 remaining bits are used to implement
80  * NOT and OR on individual instructions. Given a type, you can
81  * compute the length to be put in "len" using F_INSN_SIZE(t)
82  *
83  * F_NOT	negates the match result of the instruction.
84  *
85  * F_OR		is used to build or blocks. By default, instructions
86  *		are evaluated as part of a logical AND. An "or" block
87  *		{ X or Y or Z } contains F_OR set in all but the last
88  *		instruction of the block. A match will cause the code
89  *		to skip past the last instruction of the block.
90  *
91  * NOTA BENE: in a couple of places we assume that
92  *	sizeof(ipfw_insn) == sizeof(uint32_t)
93  * this needs to be fixed.
94  *
95  */
96 
97 #define	F_NOT		0x80
98 #define	F_OR		0x40
99 #define	F_LEN_MASK	0x3f
100 #define	F_LEN(cmd)	((cmd)->len & F_LEN_MASK)
101 
102 typedef struct	_ipfw_insn {	/* template for instructions */
103 	uint8_t		opcode;
104 	uint8_t		len;	/* numer of 32-byte words */
105 	uint16_t	arg1;
106 
107 	uint8_t		module;
108 	uint8_t		arg3;
109 	uint16_t	arg2;
110 } ipfw_insn;
111 
112 /*
113  * The F_INSN_SIZE(type) computes the size, in 4-byte words, of
114  * a given type.
115  */
116 #define	F_INSN_SIZE(t)	((sizeof (t))/sizeof(uint32_t))
117 
118 #define MTAG_IPFW	1148380143	/* IPFW-tagged cookie */
119 
120 /*
121  * This is used to store an array of 16-bit entries (ports etc.)
122  */
123 typedef struct	_ipfw_insn_u16 {
124 	ipfw_insn o;
125 	uint16_t ports[2];	/* there may be more */
126 } ipfw_insn_u16;
127 
128 /*
129  * This is used to store an array of 32-bit entries
130  * (uid, single IPv4 addresses etc.)
131  */
132 typedef struct	_ipfw_insn_u32 {
133 	ipfw_insn o;
134 	uint32_t d[1];	/* one or more */
135 } ipfw_insn_u32;
136 
137 /*
138  * This is used to store IP addr-mask pairs.
139  */
140 typedef struct	_ipfw_insn_ip {
141 	ipfw_insn o;
142 	struct in_addr	addr;
143 	struct in_addr	mask;
144 } ipfw_insn_ip;
145 
146 /*
147  * This is used to forward to a given address (ip)
148  */
149 typedef struct  _ipfw_insn_sa {
150 	ipfw_insn o;
151 	struct sockaddr_in sa;
152 } ipfw_insn_sa;
153 
154 /*
155  * This is used for MAC addr-mask pairs.
156  */
157 typedef struct	_ipfw_insn_mac {
158 	ipfw_insn o;
159 	u_char addr[12];	/* dst[6] + src[6] */
160 	u_char mask[12];	/* dst[6] + src[6] */
161 } ipfw_insn_mac;
162 
163 /*
164  * This is used for interface match rules (recv xx, xmit xx)
165  */
166 typedef struct	_ipfw_insn_if {
167 	ipfw_insn o;
168 	union {
169 		struct in_addr ip;
170 		int glob;
171 	} p;
172 	char name[IFNAMSIZ];
173 } ipfw_insn_if;
174 
175 /*
176  * This is used for pipe and queue actions, which need to store
177  * a single pointer (which can have different size on different
178  * architectures.
179  */
180 typedef struct	_ipfw_insn_pipe {
181 	ipfw_insn	o;
182 	void		*pipe_ptr;
183 } ipfw_insn_pipe;
184 
185 /*
186  * This is used for limit rules.
187  */
188 typedef struct	_ipfw_insn_limit {
189 	ipfw_insn o;
190 	uint8_t _pad;
191 	uint8_t limit_mask;	/* combination of DYN_* below	*/
192 #define	DYN_SRC_ADDR	0x1
193 #define	DYN_SRC_PORT	0x2
194 #define	DYN_DST_ADDR	0x4
195 #define	DYN_DST_PORT	0x8
196 
197 	uint16_t conn_limit;
198 } ipfw_insn_limit;
199 
200 /*
201  * This is used for bpf filtering.
202  */
203 typedef struct _ipfw_insn_bpf {
204 	ipfw_insn o;
205 	char bf_str[128];
206 	u_int bf_len;
207 	struct bpf_insn bf_insn[1];
208 } ipfw_insn_bpf;
209 
210 /*
211  * Here we have the structure representing an ipfw rule.
212  *
213  * It starts with a general area (with link fields and counters)
214  * followed by an array of one or more instructions, which the code
215  * accesses as an array of 32-bit values.
216  *
217  * Given a rule pointer  r:
218  *
219  *  r->cmd		is the start of the first instruction.
220  *  ACTION_PTR(r)	is the start of the first action (things to do
221  *			once a rule matched).
222  *
223  * When assembling instruction, remember the following:
224  *
225  *  + if a rule has a "keep-state" (or "limit") option, then the
226  *	first instruction (at r->cmd) MUST BE an O_PROBE_STATE
227  *  + if a rule has a "log" option, then the first action
228  *	(at ACTION_PTR(r)) MUST be O_LOG
229  *
230  * NOTE: we use a simple linked list of rules because we never need
231  * 	to delete a rule without scanning the list. We do not use
232  *	queue(3) macros for portability and readability.
233  */
234 
235 struct ip_fw {
236 	struct ip_fw	*next;		/* linked list of rules		*/
237 	struct ip_fw	*next_rule;	/* ptr to next [skipto] rule	*/
238 	uint16_t	act_ofs;	/* offset of action in 32-bit units */
239 	uint16_t	cmd_len;	/* # of 32-bit words in cmd	*/
240 	uint16_t	rulenum;	/* rule number			*/
241 	uint8_t		set;		/* rule set (0..31)		*/
242 	uint8_t		flags;		/* IPFW_USR_F_			*/
243 
244 	/* These fields are present in all rules.			*/
245 	uint64_t	pcnt;		/* Packet counter		*/
246 	uint64_t	bcnt;		/* Byte counter			*/
247 	uint32_t	timestamp;	/* tv_sec of last match		*/
248 
249 	struct ip_fw 	*sibling;	/* pointer to the rule in next CPU */
250 
251 	ipfw_insn	cmd[1];		/* storage for commands		*/
252 };
253 
254 
255 #define IPFW_RULE_F_INVALID	0x1
256 #define IPFW_RULE_F_STATE	0x2
257 
258 #define RULESIZE(rule) (sizeof(struct ip_fw) + (rule)->cmd_len * 4 - SIZE_OF_IPFWINSN)
259 
260 /*
261  * This structure is used as a flow mask and a flow id for various
262  * parts of the code.
263  */
264 struct ipfw_flow_id {
265 	uint32_t	dst_ip;
266 	uint32_t	src_ip;
267 	uint16_t	dst_port;
268 	uint16_t	src_port;
269 	uint8_t		proto;
270 	uint8_t		flags;	/* protocol-specific flags */
271 };
272 
273 struct ip_fw_state {
274 	struct ip_fw_state	*next;
275 	struct ipfw_flow_id	flow_id;
276 	struct ip_fw	*stub;
277 
278 	uint64_t	pcnt;	   /* packet match counter	 */
279 	uint64_t	bcnt;	   /* byte match counter	   */
280 
281 	uint16_t	lifetime;
282 	uint32_t	timestamp;
283 	uint32_t	expiry;
284 };
285 
286 
287 /* ipfw_chk/ip_fw_chk_ptr return values */
288 #define IP_FW_PASS	0
289 #define IP_FW_DENY	1
290 #define IP_FW_DIVERT	2
291 #define IP_FW_TEE	3
292 #define IP_FW_DUMMYNET	4
293 #define IP_FW_NAT	5
294 #define IP_FW_ROUTE	6
295 
296 /* ipfw_chk controller values */
297 #define IP_FW_CTL_NO		0
298 #define IP_FW_CTL_DONE		1
299 #define IP_FW_CTL_AGAIN		2
300 #define IP_FW_CTL_NEXT		3
301 #define IP_FW_CTL_NAT		4
302 #define IP_FW_CTL_LOOP		5
303 #define IP_FW_CTL_CHK_STATE	6
304 
305 #define IP_FW_NOT_MATCH		0
306 #define IP_FW_MATCH		1
307 
308 /*
309  * arguments for calling ipfw_chk() and dummynet_io(). We put them
310  * all into a structure because this way it is easier and more
311  * efficient to pass variables around and extend the interface.
312  */
313 struct ip_fw_args {
314 	struct mbuf	*m;		/* the mbuf chain		*/
315 	struct ifnet	*oif;		/* output interface		*/
316 	struct ip_fw	*rule;		/* matching rule		*/
317 	struct ether_header *eh;	/* for bridged packets		*/
318 
319 	struct ipfw_flow_id f_id;	/* grabbed from IP header	*/
320 
321 	/*
322 	 * Depend on the return value of ipfw_chk/ip_fw_chk_ptr
323 	 * 'cookie' field may save following information:
324 	 *
325 	 * IP_FW_TEE or IP_FW_DIVERT
326 	 *   The divert port number
327 	 *
328 	 * IP_FW_DUMMYNET
329 	 *   The pipe or queue number
330 	 */
331 	uint32_t	cookie;
332 };
333 
334 #ifdef _KERNEL
335 /*
336  * Function definitions.
337  */
338 int	ip_fw_sockopt(struct sockopt *);
339 int	ipfw_ctl_x(struct sockopt *sopt);
340 
341 /* Firewall hooks */
342 struct sockopt;
343 struct dn_flow_set;
344 
345 typedef int	ip_fw_chk_t(struct ip_fw_args *);
346 typedef int	ip_fw_ctl_t(struct sockopt *);
347 typedef int	ipfw_nat_cfg_t(struct sockopt *);
348 typedef void ip_fw_dn_io_t(struct mbuf *, int, int, struct ip_fw_args *);
349 
350 
351 extern ip_fw_chk_t	*ip_fw_chk_ptr;
352 extern ip_fw_ctl_t	*ip_fw_ctl_x_ptr;
353 extern ip_fw_dn_io_t	*ip_fw_dn_io_ptr;
354 
355 extern int fw3_one_pass;
356 extern int fw3_enable;
357 
358 
359 #define IPFW_CFGCPUID	0
360 #define IPFW_CFGPORT	netisr_cpuport(IPFW_CFGCPUID)
361 #define IPFW_ASSERT_CFGPORT(msgport)				\
362 	KASSERT((msgport) == IPFW_CFGPORT, ("not IPFW CFGPORT"))
363 
364 #define	IPFW_TABLES_MAX		32
365 
366 /* root of place holding all information, per-cpu */
367 struct ipfw_context {
368 	struct ip_fw	*ipfw_rule_chain;		/* list of rules*/
369 	struct ip_fw	*ipfw_default_rule;	 /* default rule */
370 	struct ipfw_state_context *state_ctx;
371 	struct ipfw_table_context *table_ctx;
372 	uint16_t		state_hash_size;
373 	uint32_t		ipfw_set_disable;
374 };
375 
376 /* place to hold the states */
377 struct ipfw_state_context {
378 	struct ip_fw_state *state;
379 	struct ip_fw_state *last;
380 	int	count;
381 };
382 
383 /* place to hold the nat conf */
384 struct ipfw_nat_context {
385 	LIST_HEAD(, cfg_nat) nat;		/* list of nat entries */
386 };
387 
388 typedef void (*filter_func)(int *cmd_ctl,int *cmd_val,struct ip_fw_args **args,
389 struct ip_fw **f,ipfw_insn *cmd,uint16_t ip_len);
390 void register_ipfw_filter_funcs(int module,int opcode,filter_func func);
391 void unregister_ipfw_filter_funcs(int module,filter_func func);
392 void register_ipfw_module(int module_id,char *module_name);
393 int unregister_ipfw_module(int module_id);
394 
395 #endif
396 
397 #define ACTION_PTR(rule)	\
398 	(ipfw_insn *)((uint32_t *)((rule)->cmd) + ((rule)->act_ofs))
399 
400 
401 
402 struct ipfw_ioc_rule {
403 	uint16_t	act_ofs;	/* offset of action in 32-bit units */
404 	uint16_t	cmd_len;	/* # of 32-bit words in cmd	*/
405 	uint16_t	rulenum;	/* rule number			*/
406 	uint8_t		set;		/* rule set (0..31)		*/
407 	uint8_t		usr_flags;	/* IPFW_USR_F_ 			*/
408 
409 	/* Rule set information */
410 	uint32_t	set_disable;	/* disabled rule sets		*/
411 	uint32_t	static_count;	/* # of static rules		*/
412 	uint32_t	static_len;	/* total length of static rules	*/
413 
414 	/* Statistics */
415 	uint64_t	pcnt;		/* Packet counter		*/
416 	uint64_t	bcnt;		/* Byte counter			*/
417 	uint32_t	timestamp;	/* tv_sec of last match		*/
418 
419 	uint8_t		reserved[RESERVED_SIZE];
420 
421 	ipfw_insn	cmd[1];		/* storage for commands		*/
422 };
423 
424 #define IPFW_USR_F_NORULE	0x01
425 
426 #define IPFW_RULE_SIZE_MAX	255	/* unit: uint32_t */
427 
428 #define IOC_RULESIZE(rule)	\
429 	(sizeof(struct ipfw_ioc_rule) + (rule)->cmd_len * 4 - SIZE_OF_IPFWINSN)
430 
431 struct ipfw_ioc_flowid {
432 	uint16_t	type;	/* ETHERTYPE_ */
433 	uint16_t	pad;
434 	union {
435 		struct {
436 			uint32_t dst_ip;
437 			uint32_t src_ip;
438 			uint16_t dst_port;
439 			uint16_t src_port;
440 			uint8_t proto;
441 		} ip;
442 		uint8_t pad[64];
443 	} u;
444 };
445 
446 struct ipfw_ioc_state {
447 	uint64_t	pcnt;		/* packet match counter		*/
448 	uint64_t	bcnt;		/* byte match counter		*/
449 	uint16_t 	lifetime;
450 	uint32_t	timestamp;	/* alive time				*/
451 	uint32_t	expiry;		/* expire time				*/
452 
453 	uint16_t	rulenum;
454 	uint16_t	cpuid;
455 	struct ipfw_flow_id 	flow_id;	/* proto +src/dst ip/port */
456 	uint8_t		reserved[16];
457 };
458 
459 /*
460  * Definitions for IP option names.
461  */
462 #define	IP_FW_IPOPT_LSRR	0x01
463 #define	IP_FW_IPOPT_SSRR	0x02
464 #define	IP_FW_IPOPT_RR		0x04
465 #define	IP_FW_IPOPT_TS		0x08
466 
467 /*
468  * Definitions for TCP option names.
469  */
470 #define	IP_FW_TCPOPT_MSS	0x01
471 #define	IP_FW_TCPOPT_WINDOW	0x02
472 #define	IP_FW_TCPOPT_SACK	0x04
473 #define	IP_FW_TCPOPT_TS		0x08
474 #define	IP_FW_TCPOPT_CC		0x10
475 
476 #define	ICMP_REJECT_RST		0x100	/* fake ICMP code (send a TCP RST) */
477 
478 struct ipfw_module{
479 	int type;
480 	int id;
481 	char name[20];
482 };
483 
484 /*
485  * type of the keyword, it indecates the position of the keyword in the rule
486  *      BEFORE ACTION FROM TO FILTER OTHER
487  */
488 #define NONE            0
489 #define BEFORE          1
490 #define ACTION          2
491 #define PROTO           3
492 #define FROM            4
493 #define TO              5
494 #define FILTER          6
495 #define AFTER           7
496 
497 #define NOT_IN_USE      0
498 #define IN_USE          1
499 
500 
501 #define NEED1(msg)  {if (ac < 1) errx(EX_USAGE, msg);}
502 #define NEED2(msg)  {if (ac < 2) errx(EX_USAGE, msg);}
503 #define NEED(c, n, msg) {if (c < n) errx(EX_USAGE, msg);}
504 
505 #define NEXT_ARG	ac--; if(ac > 0){av++;}
506 #define NEXT_ARG1 	(*ac)--; if(*ac > 0){(*av)++;}
507 
508 #define MATCH_REVERSE	0
509 #define MATCH_FORWARD	1
510 #define MATCH_NONE	2
511 #define MATCH_UNKNOWN	3
512 
513 #define BOTH_SYN	(TH_SYN | (TH_SYN << 8))
514 #define BOTH_FIN	(TH_FIN | (TH_FIN << 8))
515 
516 #define TIME_LEQ(a, b)  ((int)((a) - (b)) <= 0)
517 #define L3HDR(T, ip) ((T *)((uint32_t *)(ip) + (ip)->ip_hl))
518 
519 /* IP_FW_X header/opcodes */
520 typedef struct _ip_fw_x_header {
521 	uint16_t opcode;	/* Operation opcode */
522 	uint16_t _pad;   	/* Opcode version */
523 } ip_fw_x_header;
524 
525 typedef void ipfw_basic_delete_state_t(struct ip_fw *);
526 typedef void ipfw_basic_append_state_t(struct ipfw_ioc_state *);
527 typedef void ipfw_sync_send_state_t(struct ip_fw_state *, int cpu, int hash);
528 
529 /* IP_FW3 opcodes */
530 
531 #define IP_FW_ADD		50   /* add a firewall rule to chain */
532 #define IP_FW_DEL		51   /* delete a firewall rule from chain */
533 #define IP_FW_FLUSH		52   /* flush firewall rule chain */
534 #define IP_FW_ZERO		53   /* clear single/all firewall counter(s) */
535 #define IP_FW_GET		54   /* get entire firewall rule chain */
536 #define IP_FW_RESETLOG		55   /* reset logging counters */
537 
538 #define IP_DUMMYNET_CONFIGURE	60   /* add/configure a dummynet pipe */
539 #define IP_DUMMYNET_DEL		61   /* delete a dummynet pipe from chain */
540 #define IP_DUMMYNET_FLUSH	62   /* flush dummynet */
541 #define IP_DUMMYNET_GET		64   /* get entire dummynet pipes */
542 
543 #define IP_FW_MODULE		67  /* get modules names */
544 
545 #define IP_FW_NAT_CFG		68   /* add/config a nat rule */
546 #define IP_FW_NAT_DEL		69   /* delete a nat rule */
547 #define IP_FW_NAT_FLUSH		70   /* get configuration of a nat rule */
548 #define IP_FW_NAT_GET		71   /* get config of a nat rule */
549 #define IP_FW_NAT_LOG		72   /* get nat record of a nat rule */
550 
551 #define IP_FW_STATE_ADD		56   /* add one state */
552 #define IP_FW_STATE_DEL		57   /* delete states of one rulenum */
553 #define IP_FW_STATE_FLUSH	58   /* flush all states */
554 
555 #define IP_FW_TABLE_CREATE	73	/* table_create 	*/
556 #define IP_FW_TABLE_DELETE	74	/* table_delete 	*/
557 #define IP_FW_TABLE_APPEND	75	/* table_append 	*/
558 #define IP_FW_TABLE_REMOVE	76	/* table_remove 	*/
559 #define IP_FW_TABLE_LIST	77	/* table_list 		*/
560 #define IP_FW_TABLE_FLUSH	78	/* table_flush 		*/
561 #define IP_FW_TABLE_SHOW	79	/* table_show 		*/
562 #define IP_FW_TABLE_TEST	80	/* table_test 		*/
563 #define IP_FW_TABLE_RENAME	81	/* rename a table 	*/
564 
565 /* opcodes for ipfw3sync */
566 #define IP_FW_SYNC_SHOW_CONF	82	/* show sync config */
567 #define IP_FW_SYNC_SHOW_STATUS	83	/* show edge & centre running status */
568 
569 #define IP_FW_SYNC_EDGE_CONF	84	/* config sync edge */
570 #define IP_FW_SYNC_EDGE_START	85	/* start the edge */
571 #define IP_FW_SYNC_EDGE_STOP	86	/* stop the edge */
572 #define IP_FW_SYNC_EDGE_TEST	87	/* test sync edge */
573 #define IP_FW_SYNC_EDGE_CLEAR	88	/* stop and clear the edge */
574 
575 #define IP_FW_SYNC_CENTRE_CONF	89	/* config sync centre */
576 #define IP_FW_SYNC_CENTRE_START	90	/* start the centre */
577 #define IP_FW_SYNC_CENTRE_STOP	91	/* stop the centre */
578 #define IP_FW_SYNC_CENTRE_TEST	92	/* test sync centre */
579 #define IP_FW_SYNC_CENTRE_CLEAR	93	/* stop and clear the centre */
580 #endif
581 
582 #endif /* _IP_FW3_H_ */
583