2 * Copyright (c) 2002 Luigi Rizzo, Universita` di Pisa
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * $FreeBSD: src/sys/netinet/ip_fw2.c,v 1.6.2.12 2003/04/08 10:42:32 maxim Exp $
29 * Implement IP packet firewall (new version)
35 #error IPFIREWALL requires INET.
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/malloc.h>
42 #include <sys/kernel.h>
44 #include <sys/socket.h>
45 #include <sys/socketvar.h>
46 #include <sys/sysctl.h>
47 #include <sys/syslog.h>
48 #include <sys/ucred.h>
49 #include <sys/in_cksum.h>
50 #include <sys/limits.h>
55 #include <net/route.h>
57 #include <net/dummynet/ip_dummynet.h>
59 #include <sys/thread2.h>
60 #include <sys/mplock2.h>
61 #include <net/netmsg2.h>
63 #include <netinet/in.h>
64 #include <netinet/in_systm.h>
65 #include <netinet/in_var.h>
66 #include <netinet/in_pcb.h>
67 #include <netinet/ip.h>
68 #include <netinet/ip_var.h>
69 #include <netinet/ip_icmp.h>
70 #include <netinet/tcp.h>
71 #include <netinet/tcp_seq.h>
72 #include <netinet/tcp_timer.h>
73 #include <netinet/tcp_var.h>
74 #include <netinet/tcpip.h>
75 #include <netinet/udp.h>
76 #include <netinet/udp_var.h>
77 #include <netinet/ip_divert.h>
78 #include <netinet/if_ether.h> /* XXX for ETHERTYPE_IP */
80 #include <net/ipfw/ip_fw2.h>
82 #ifdef IPFIREWALL_DEBUG
83 #define DPRINTF(fmt, ...) \
86 kprintf(fmt, __VA_ARGS__); \
89 #define DPRINTF(fmt, ...) ((void)0)
93 * Description about per-CPU rule duplication:
95 * Module loading/unloading and all ioctl operations are serialized
96 * by netisr0, so we don't have any ordering or locking problems.
98 * Following graph shows how operation on per-CPU rule list is
99 * performed [2 CPU case]:
103 * netisr0 <------------------------------------+
109 * forwardmsg---------->netisr1 |
114 * replymsg--------------+
118 * Rule structure [2 CPU case]
122 * layer3_chain layer3_chain
125 * +-------+ sibling +-------+ sibling
126 * | rule1 |--------->| rule1 |--------->NULL
127 * +-------+ +-------+
131 * +-------+ sibling +-------+ sibling
132 * | rule2 |--------->| rule2 |--------->NULL
133 * +-------+ +-------+
136 * 1) Ease statistics calculation during IP_FW_GET. We only need to
137 * iterate layer3_chain in netisr0; the current rule's duplication
138 * to the other CPUs could safely be read-only accessed through
140 * 2) Accelerate rule insertion and deletion, e.g. rule insertion:
141 * a) In netisr0 rule3 is determined to be inserted between rule1
142 * and rule2. To make this decision we need to iterate the
143 * layer3_chain in netisr0. The netmsg, which is used to insert
144 * the rule, will contain rule1 in netisr0 as prev_rule and rule2
145 * in netisr0 as next_rule.
146 * b) After the insertion in netisr0 is done, we will move on to
147 * netisr1. But instead of relocating the rule3's position in
148 * netisr1 by iterating the layer3_chain in netisr1, we set the
149 * netmsg's prev_rule to rule1->sibling and next_rule to
150 * rule2->sibling before the netmsg is forwarded to netisr1 from
155 * Description of states and tracks.
157 * Both states and tracks are stored in per-cpu RB trees instead of
158 * per-cpu hash tables to avoid the worst case hash degeneration.
160 * The lifetimes of states and tracks are regulated by dyn_*_lifetime,
161 * measured in seconds and depending on the flags.
163 * When a packet is received, its address fields are first masked with
164 * the mask defined for the rule, then matched against the entries in
165 * the per-cpu state RB tree. States are generated by 'keep-state'
166 * and 'limit' options.
168 * The max number of states is ipfw_state_max. When we reach the
169 * maximum number of states we do not create anymore. This is done to
170 * avoid consuming too much memory, but also too much time when
171 * searching on each packet.
173 * Each state holds a pointer to the parent ipfw rule of the current
174 * CPU so we know what action to perform. States are removed when the
175 * parent rule is deleted. XXX we should make them survive.
177 * There are some limitations with states -- we do not obey the
178 * 'randomized match', and we do not do multiple passes through the
179 * firewall. XXX check the latter!!!
181 * States grow independently on each CPU, e.g. 2 CPU case:
184 * ................... ...................
185 * : state RB tree : : state RB tree :
187 * : state1 state2 : : state3 :
189 * :.....|....|......: :........|........:
194 * +-------+ +-------+
195 * | rule1 | | rule1 |
196 * +-------+ +-------+
198 * Tracks are used to enforce limits on the number of sessions. Tracks
199 * are generated by 'limit' option.
201 * The max number of tracks is ipfw_track_max. When we reach the
202 * maximum number of tracks we do not create anymore. This is done to
203 * avoid consuming too much memory.
205 * Tracks are organized into two layers, track counter RB tree is
206 * shared between CPUs, track RB tree is per-cpu. States generated by
207 * 'limit' option are linked to the track in addition to the per-cpu
208 * state RB tree; mainly to ease expiration. e.g. 2 CPU case:
210 * ..............................
211 * : track counter RB tree :
216 * : +--->counter<----+ :
218 * : | +-----------+ | :
219 * :......|................|....:
222 * ................. |t_count | .................
223 * : track RB tree : | | : track RB tree :
225 * : +-->track1-------+ +--------track2 :
228 * :.|.....|.......: :...............:
229 * | +----------------+
230 * | .................... |
231 * | : state RB tree : |st_track
233 * +---state1 state2---+
235 * :.....|.......|....:
244 #define IPFW_AUTOINC_STEP_MIN 1
245 #define IPFW_AUTOINC_STEP_MAX 1000
246 #define IPFW_AUTOINC_STEP_DEF 100
248 #define IPFW_TABLE_MAX_DEF 64
250 #define IPFW_DEFAULT_RULE 65535 /* rulenum for the default rule */
251 #define IPFW_DEFAULT_SET 31 /* set number for the default rule */
253 #define MATCH_REVERSE 0
254 #define MATCH_FORWARD 1
256 #define MATCH_UNKNOWN 3
258 #define IPFW_STATE_TCPFLAGS (TH_SYN | TH_FIN | TH_RST)
259 #define IPFW_STATE_TCPSTATES (IPFW_STATE_TCPFLAGS | \
260 (IPFW_STATE_TCPFLAGS << 8))
262 #define BOTH_SYN (TH_SYN | (TH_SYN << 8))
263 #define BOTH_FIN (TH_FIN | (TH_FIN << 8))
264 #define BOTH_RST (TH_RST | (TH_RST << 8))
265 /* TH_ACK here means FIN was ACKed. */
266 #define BOTH_FINACK (TH_ACK | (TH_ACK << 8))
268 #define IPFW_STATE_TCPCLOSED(s) ((s)->st_proto == IPPROTO_TCP && \
269 (((s)->st_state & BOTH_RST) || \
270 ((s)->st_state & BOTH_FINACK) == BOTH_FINACK))
272 #define O_ANCHOR O_NOP
275 struct netmsg_base base
;
276 const struct ipfw_ioc_rule
*ioc_rule
;
277 struct ip_fw
*next_rule
;
278 struct ip_fw
*prev_rule
;
279 struct ip_fw
*sibling
;
281 struct ip_fw
**cross_rules
;
285 struct netmsg_base base
;
286 struct ip_fw
*start_rule
;
287 struct ip_fw
*prev_rule
;
294 struct netmsg_base base
;
295 struct ip_fw
*start_rule
;
300 struct netmsg_cpstate
{
301 struct netmsg_base base
;
302 struct ipfw_ioc_state
*ioc_state
;
307 struct netmsg_tblent
{
308 struct netmsg_base base
;
309 struct sockaddr
*key
;
310 struct sockaddr
*netmask
;
311 struct ipfw_tblent
*sibling
;
315 struct netmsg_tblflush
{
316 struct netmsg_base base
;
321 struct netmsg_tblexp
{
322 struct netmsg_base base
;
327 struct radix_node_head
*rnh
;
330 struct ipfw_table_cp
{
331 struct ipfw_ioc_tblent
*te
;
338 * offset The offset of a fragment. offset != 0 means that
339 * we have a fragment at this offset of an IPv4 packet.
340 * offset == 0 means that (if this is an IPv4 packet)
341 * this is the first or only fragment.
346 * Local copies of addresses. They are only valid if we have
349 * proto The protocol. Set to 0 for non-ip packets,
350 * or to the protocol read from the packet otherwise.
351 * proto != 0 means that we have an IPv4 packet.
353 * src_port, dst_port port numbers, in HOST format. Only
354 * valid for TCP and UDP packets.
356 * src_ip, dst_ip ip addresses, in NETWORK format.
357 * Only valid for IPv4 packets.
360 uint16_t src_port
; /* NOTE: host format */
361 uint16_t dst_port
; /* NOTE: host format */
362 struct in_addr src_ip
; /* NOTE: network format */
363 struct in_addr dst_ip
; /* NOTE: network format */
379 struct ipfw_addrs addrs
;
383 struct ipfw_ports ports
;
387 uint8_t swap
; /* IPFW_KEY_SWAP_ */
391 #define IPFW_KEY_SWAP_ADDRS 0x1
392 #define IPFW_KEY_SWAP_PORTS 0x2
393 #define IPFW_KEY_SWAP_ALL (IPFW_KEY_SWAP_ADDRS | IPFW_KEY_SWAP_PORTS)
396 RB_ENTRY(ipfw_trkcnt
) tc_rblink
;
397 struct ipfw_key tc_key
;
401 time_t tc_expire
; /* userland get-only */
402 uint16_t tc_rulenum
; /* userland get-only */
405 #define tc_addrs tc_key.addr_u.value
406 #define tc_ports tc_key.port_u.value
407 #define tc_proto tc_key.proto
408 #define tc_saddr tc_key.addr_u.addrs.addr1
409 #define tc_daddr tc_key.addr_u.addrs.addr2
410 #define tc_sport tc_key.port_u.ports.port1
411 #define tc_dport tc_key.port_u.ports.port2
413 RB_HEAD(ipfw_trkcnt_tree
, ipfw_trkcnt
);
418 RB_ENTRY(ipfw_track
) t_rblink
;
419 struct ipfw_key t_key
;
420 struct ip_fw
*t_rule
;
422 LIST_HEAD(, ipfw_state
) t_state_list
;
424 volatile int *t_count
;
425 struct ipfw_trkcnt
*t_trkcnt
;
426 TAILQ_ENTRY(ipfw_track
) t_link
;
429 #define t_addrs t_key.addr_u.value
430 #define t_ports t_key.port_u.value
431 #define t_proto t_key.proto
432 #define t_saddr t_key.addr_u.addrs.addr1
433 #define t_daddr t_key.addr_u.addrs.addr2
434 #define t_sport t_key.port_u.ports.port1
435 #define t_dport t_key.port_u.ports.port2
437 RB_HEAD(ipfw_track_tree
, ipfw_track
);
438 TAILQ_HEAD(ipfw_track_list
, ipfw_track
);
441 RB_ENTRY(ipfw_state
) st_rblink
;
442 struct ipfw_key st_key
;
444 time_t st_expire
; /* expire time */
445 struct ip_fw
*st_rule
;
447 uint64_t st_pcnt
; /* packets */
448 uint64_t st_bcnt
; /* bytes */
452 * State of this rule, typically a combination of TCP flags.
454 * st_ack_fwd/st_ack_rev:
455 * Most recent ACKs in forward and reverse direction. They
456 * are used to generate keepalives.
464 uint16_t st_flags
; /* IPFW_STATE_F_ */
465 uint16_t st_type
; /* O_KEEP_STATE/O_LIMIT */
466 struct ipfw_track
*st_track
;
468 LIST_ENTRY(ipfw_state
) st_trklink
;
469 TAILQ_ENTRY(ipfw_state
) st_link
;
472 #define st_addrs st_key.addr_u.value
473 #define st_ports st_key.port_u.value
474 #define st_proto st_key.proto
475 #define st_swap st_key.swap
477 #define IPFW_STATE_F_ACKFWD 0x0001
478 #define IPFW_STATE_F_SEQFWD 0x0002
479 #define IPFW_STATE_F_ACKREV 0x0004
480 #define IPFW_STATE_F_SEQREV 0x0008
482 TAILQ_HEAD(ipfw_state_list
, ipfw_state
);
483 RB_HEAD(ipfw_state_tree
, ipfw_state
);
486 struct radix_node te_nodes
[2];
487 struct sockaddr_in te_key
;
490 struct ipfw_tblent
*te_sibling
;
491 volatile int te_expired
;
494 struct ipfw_context
{
495 struct ip_fw
*ipfw_layer3_chain
; /* rules for layer3 */
496 struct ip_fw
*ipfw_default_rule
; /* default rule */
497 uint64_t ipfw_norule_counter
; /* ipfw_log(NULL) stat*/
500 * ipfw_set_disable contains one bit per set value (0..31).
501 * If the bit is set, all rules with the corresponding set
502 * are disabled. Set IPDW_DEFAULT_SET is reserved for the
503 * default rule and CANNOT be disabled.
505 uint32_t ipfw_set_disable
;
507 uint8_t ipfw_flags
; /* IPFW_FLAG_ */
509 struct ip_fw
*ipfw_cont_rule
;
511 struct ipfw_state_tree ipfw_state_tree
;
512 struct ipfw_state_list ipfw_state_list
;
513 int ipfw_state_loosecnt
;
517 struct ipfw_state state
;
518 struct ipfw_track track
;
519 struct ipfw_trkcnt trkcnt
;
522 struct ipfw_track_tree ipfw_track_tree
;
523 struct ipfw_track_list ipfw_track_list
;
524 struct ipfw_trkcnt
*ipfw_trkcnt_spare
;
526 struct callout ipfw_stateto_ch
;
527 time_t ipfw_state_lastexp
;
528 struct netmsg_base ipfw_stateexp_nm
;
529 struct netmsg_base ipfw_stateexp_more
;
530 struct ipfw_state ipfw_stateexp_anch
;
532 struct callout ipfw_trackto_ch
;
533 time_t ipfw_track_lastexp
;
534 struct netmsg_base ipfw_trackexp_nm
;
535 struct netmsg_base ipfw_trackexp_more
;
536 struct ipfw_track ipfw_trackexp_anch
;
538 struct callout ipfw_keepalive_ch
;
539 struct netmsg_base ipfw_keepalive_nm
;
540 struct netmsg_base ipfw_keepalive_more
;
541 struct ipfw_state ipfw_keepalive_anch
;
546 u_long ipfw_sts_reap
;
547 u_long ipfw_sts_reapfailed
;
548 u_long ipfw_sts_overflow
;
549 u_long ipfw_sts_nomem
;
550 u_long ipfw_sts_tcprecycled
;
552 u_long ipfw_tks_nomem
;
553 u_long ipfw_tks_reap
;
554 u_long ipfw_tks_reapfailed
;
555 u_long ipfw_tks_overflow
;
556 u_long ipfw_tks_cntnomem
;
559 u_long ipfw_defraged
;
560 u_long ipfw_defrag_remote
;
563 struct radix_node_head
*ipfw_tables
[];
566 #define IPFW_FLAG_KEEPALIVE 0x01
567 #define IPFW_FLAG_STATEEXP 0x02
568 #define IPFW_FLAG_TRACKEXP 0x04
569 #define IPFW_FLAG_STATEREAP 0x08
570 #define IPFW_FLAG_TRACKREAP 0x10
572 #define ipfw_state_tmpkey ipfw_tmpkey.state
573 #define ipfw_track_tmpkey ipfw_tmpkey.track
574 #define ipfw_trkcnt_tmpkey ipfw_tmpkey.trkcnt
577 int ipfw_state_loosecnt
; /* cache aligned */
578 time_t ipfw_state_globexp __cachealign
;
580 struct lwkt_token ipfw_trkcnt_token __cachealign
;
581 struct ipfw_trkcnt_tree ipfw_trkcnt_tree
;
583 time_t ipfw_track_globexp
;
585 /* Accessed in netisr0. */
586 struct ip_fw
*ipfw_crossref_free __cachealign
;
587 struct callout ipfw_crossref_ch
;
588 struct netmsg_base ipfw_crossref_nm
;
592 * Module can not be unloaded, if there are references to
593 * certains rules of ipfw(4), e.g. dummynet(4)
595 int ipfw_refcnt __cachealign
;
599 static struct ipfw_context
*ipfw_ctx
[MAXCPU
];
601 MALLOC_DEFINE(M_IPFW
, "IpFw/IpAcct", "IpFw/IpAcct chain's");
604 * Following two global variables are accessed and updated only
607 static uint32_t static_count
; /* # of static rules */
608 static uint32_t static_ioc_len
; /* bytes of static rules */
611 * If 1, then ipfw static rules are being flushed,
612 * ipfw_chk() will skip to the default rule.
614 static int ipfw_flushing
;
616 static int fw_verbose
;
617 static int verbose_limit
;
620 static int autoinc_step
= IPFW_AUTOINC_STEP_DEF
;
622 static int ipfw_table_max
= IPFW_TABLE_MAX_DEF
;
624 static int ipfw_sysctl_enable(SYSCTL_HANDLER_ARGS
);
625 static int ipfw_sysctl_autoinc_step(SYSCTL_HANDLER_ARGS
);
627 TUNABLE_INT("net.inet.ip.fw.table_max", &ipfw_table_max
);
629 SYSCTL_NODE(_net_inet_ip
, OID_AUTO
, fw
, CTLFLAG_RW
, 0, "Firewall");
630 SYSCTL_NODE(_net_inet_ip_fw
, OID_AUTO
, stats
, CTLFLAG_RW
, 0,
631 "Firewall statistics");
633 SYSCTL_PROC(_net_inet_ip_fw
, OID_AUTO
, enable
, CTLTYPE_INT
| CTLFLAG_RW
,
634 &fw_enable
, 0, ipfw_sysctl_enable
, "I", "Enable ipfw");
635 SYSCTL_PROC(_net_inet_ip_fw
, OID_AUTO
, autoinc_step
, CTLTYPE_INT
| CTLFLAG_RW
,
636 &autoinc_step
, 0, ipfw_sysctl_autoinc_step
, "I",
637 "Rule number autincrement step");
638 SYSCTL_INT(_net_inet_ip_fw
, OID_AUTO
,one_pass
,CTLFLAG_RW
,
640 "Only do a single pass through ipfw when using dummynet(4)");
641 SYSCTL_INT(_net_inet_ip_fw
, OID_AUTO
, debug
, CTLFLAG_RW
,
642 &fw_debug
, 0, "Enable printing of debug ip_fw statements");
643 SYSCTL_INT(_net_inet_ip_fw
, OID_AUTO
, verbose
, CTLFLAG_RW
,
644 &fw_verbose
, 0, "Log matches to ipfw rules");
645 SYSCTL_INT(_net_inet_ip_fw
, OID_AUTO
, verbose_limit
, CTLFLAG_RW
,
646 &verbose_limit
, 0, "Set upper limit of matches of ipfw rules logged");
647 SYSCTL_INT(_net_inet_ip_fw
, OID_AUTO
, table_max
, CTLFLAG_RD
,
648 &ipfw_table_max
, 0, "Max # of tables");
650 static int ipfw_sysctl_dyncnt(SYSCTL_HANDLER_ARGS
);
651 static int ipfw_sysctl_dynmax(SYSCTL_HANDLER_ARGS
);
652 static int ipfw_sysctl_statecnt(SYSCTL_HANDLER_ARGS
);
653 static int ipfw_sysctl_statemax(SYSCTL_HANDLER_ARGS
);
654 static int ipfw_sysctl_scancnt(SYSCTL_HANDLER_ARGS
);
655 static int ipfw_sysctl_stat(SYSCTL_HANDLER_ARGS
);
658 * Timeouts for various events in handing states.
662 * 2 == 1~2 second(s).
664 * We use 2 seconds for FIN lifetime, so that the states will not be
665 * ripped prematurely.
667 static uint32_t dyn_ack_lifetime
= 300;
668 static uint32_t dyn_syn_lifetime
= 20;
669 static uint32_t dyn_finwait_lifetime
= 20;
670 static uint32_t dyn_fin_lifetime
= 2;
671 static uint32_t dyn_rst_lifetime
= 2;
672 static uint32_t dyn_udp_lifetime
= 10;
673 static uint32_t dyn_short_lifetime
= 5; /* used by tracks too */
676 * Keepalives are sent if dyn_keepalive is set. They are sent every
677 * dyn_keepalive_period seconds, in the last dyn_keepalive_interval
678 * seconds of lifetime of a rule.
680 static uint32_t dyn_keepalive_interval
= 20;
681 static uint32_t dyn_keepalive_period
= 5;
682 static uint32_t dyn_keepalive
= 1; /* do send keepalives */
684 static struct ipfw_global ipfw_gd
;
685 static int ipfw_state_loosecnt_updthr
;
686 static int ipfw_state_max
= 4096; /* max # of states */
687 static int ipfw_track_max
= 4096; /* max # of tracks */
689 static int ipfw_state_headroom
; /* setup at module load time */
690 static int ipfw_state_reap_min
= 8;
691 static int ipfw_state_expire_max
= 32;
692 static int ipfw_state_scan_max
= 256;
693 static int ipfw_keepalive_max
= 8;
694 static int ipfw_track_reap_max
= 4;
695 static int ipfw_track_expire_max
= 16;
696 static int ipfw_track_scan_max
= 128;
698 static eventhandler_tag ipfw_ifaddr_event
;
701 SYSCTL_PROC(_net_inet_ip_fw
, OID_AUTO
, dyn_count
,
702 CTLTYPE_INT
| CTLFLAG_RD
, NULL
, 0, ipfw_sysctl_dyncnt
, "I",
703 "Number of states and tracks");
704 SYSCTL_PROC(_net_inet_ip_fw
, OID_AUTO
, dyn_max
,
705 CTLTYPE_INT
| CTLFLAG_RW
, NULL
, 0, ipfw_sysctl_dynmax
, "I",
706 "Max number of states and tracks");
708 SYSCTL_PROC(_net_inet_ip_fw
, OID_AUTO
, state_cnt
,
709 CTLTYPE_INT
| CTLFLAG_RD
, NULL
, 0, ipfw_sysctl_statecnt
, "I",
711 SYSCTL_PROC(_net_inet_ip_fw
, OID_AUTO
, state_max
,
712 CTLTYPE_INT
| CTLFLAG_RW
, NULL
, 0, ipfw_sysctl_statemax
, "I",
713 "Max number of states");
714 SYSCTL_INT(_net_inet_ip_fw
, OID_AUTO
, state_headroom
, CTLFLAG_RW
,
715 &ipfw_state_headroom
, 0, "headroom for state reap");
716 SYSCTL_INT(_net_inet_ip_fw
, OID_AUTO
, track_cnt
, CTLFLAG_RD
,
717 &ipfw_gd
.ipfw_trkcnt_cnt
, 0, "Number of tracks");
718 SYSCTL_INT(_net_inet_ip_fw
, OID_AUTO
, track_max
, CTLFLAG_RW
,
719 &ipfw_track_max
, 0, "Max number of tracks");
720 SYSCTL_INT(_net_inet_ip_fw
, OID_AUTO
, static_count
, CTLFLAG_RD
,
721 &static_count
, 0, "Number of static rules");
722 SYSCTL_INT(_net_inet_ip_fw
, OID_AUTO
, dyn_ack_lifetime
, CTLFLAG_RW
,
723 &dyn_ack_lifetime
, 0, "Lifetime of dyn. rules for acks");
724 SYSCTL_INT(_net_inet_ip_fw
, OID_AUTO
, dyn_syn_lifetime
, CTLFLAG_RW
,
725 &dyn_syn_lifetime
, 0, "Lifetime of dyn. rules for syn");
726 SYSCTL_INT(_net_inet_ip_fw
, OID_AUTO
, dyn_fin_lifetime
, CTLFLAG_RW
,
727 &dyn_fin_lifetime
, 0, "Lifetime of dyn. rules for fin");
728 SYSCTL_INT(_net_inet_ip_fw
, OID_AUTO
, dyn_finwait_lifetime
, CTLFLAG_RW
,
729 &dyn_finwait_lifetime
, 0, "Lifetime of dyn. rules for fin wait");
730 SYSCTL_INT(_net_inet_ip_fw
, OID_AUTO
, dyn_rst_lifetime
, CTLFLAG_RW
,
731 &dyn_rst_lifetime
, 0, "Lifetime of dyn. rules for rst");
732 SYSCTL_INT(_net_inet_ip_fw
, OID_AUTO
, dyn_udp_lifetime
, CTLFLAG_RW
,
733 &dyn_udp_lifetime
, 0, "Lifetime of dyn. rules for UDP");
734 SYSCTL_INT(_net_inet_ip_fw
, OID_AUTO
, dyn_short_lifetime
, CTLFLAG_RW
,
735 &dyn_short_lifetime
, 0, "Lifetime of dyn. rules for other situations");
736 SYSCTL_INT(_net_inet_ip_fw
, OID_AUTO
, dyn_keepalive
, CTLFLAG_RW
,
737 &dyn_keepalive
, 0, "Enable keepalives for dyn. rules");
738 SYSCTL_PROC(_net_inet_ip_fw
, OID_AUTO
, state_scan_max
,
739 CTLTYPE_INT
| CTLFLAG_RW
, &ipfw_state_scan_max
, 0, ipfw_sysctl_scancnt
,
740 "I", "# of states to scan for each expire iteration");
741 SYSCTL_PROC(_net_inet_ip_fw
, OID_AUTO
, state_expire_max
,
742 CTLTYPE_INT
| CTLFLAG_RW
, &ipfw_state_expire_max
, 0, ipfw_sysctl_scancnt
,
743 "I", "# of states to expire for each expire iteration");
744 SYSCTL_PROC(_net_inet_ip_fw
, OID_AUTO
, keepalive_max
,
745 CTLTYPE_INT
| CTLFLAG_RW
, &ipfw_keepalive_max
, 0, ipfw_sysctl_scancnt
,
746 "I", "# of states to expire for each expire iteration");
747 SYSCTL_PROC(_net_inet_ip_fw
, OID_AUTO
, state_reap_min
,
748 CTLTYPE_INT
| CTLFLAG_RW
, &ipfw_state_reap_min
, 0, ipfw_sysctl_scancnt
,
749 "I", "# of states to reap for state shortage");
750 SYSCTL_PROC(_net_inet_ip_fw
, OID_AUTO
, track_scan_max
,
751 CTLTYPE_INT
| CTLFLAG_RW
, &ipfw_track_scan_max
, 0, ipfw_sysctl_scancnt
,
752 "I", "# of tracks to scan for each expire iteration");
753 SYSCTL_PROC(_net_inet_ip_fw
, OID_AUTO
, track_expire_max
,
754 CTLTYPE_INT
| CTLFLAG_RW
, &ipfw_track_expire_max
, 0, ipfw_sysctl_scancnt
,
755 "I", "# of tracks to expire for each expire iteration");
756 SYSCTL_PROC(_net_inet_ip_fw
, OID_AUTO
, track_reap_max
,
757 CTLTYPE_INT
| CTLFLAG_RW
, &ipfw_track_reap_max
, 0, ipfw_sysctl_scancnt
,
758 "I", "# of tracks to reap for track shortage");
760 SYSCTL_PROC(_net_inet_ip_fw_stats
, OID_AUTO
, state_reap
,
761 CTLTYPE_ULONG
| CTLFLAG_RW
, NULL
,
762 __offsetof(struct ipfw_context
, ipfw_sts_reap
), ipfw_sysctl_stat
,
763 "LU", "# of state reaps due to states shortage");
764 SYSCTL_PROC(_net_inet_ip_fw_stats
, OID_AUTO
, state_reapfailed
,
765 CTLTYPE_ULONG
| CTLFLAG_RW
, NULL
,
766 __offsetof(struct ipfw_context
, ipfw_sts_reapfailed
), ipfw_sysctl_stat
,
767 "LU", "# of state reap failure");
768 SYSCTL_PROC(_net_inet_ip_fw_stats
, OID_AUTO
, state_overflow
,
769 CTLTYPE_ULONG
| CTLFLAG_RW
, NULL
,
770 __offsetof(struct ipfw_context
, ipfw_sts_overflow
), ipfw_sysctl_stat
,
771 "LU", "# of state overflow");
772 SYSCTL_PROC(_net_inet_ip_fw_stats
, OID_AUTO
, state_nomem
,
773 CTLTYPE_ULONG
| CTLFLAG_RW
, NULL
,
774 __offsetof(struct ipfw_context
, ipfw_sts_nomem
), ipfw_sysctl_stat
,
775 "LU", "# of state allocation failure");
776 SYSCTL_PROC(_net_inet_ip_fw_stats
, OID_AUTO
, state_tcprecycled
,
777 CTLTYPE_ULONG
| CTLFLAG_RW
, NULL
,
778 __offsetof(struct ipfw_context
, ipfw_sts_tcprecycled
), ipfw_sysctl_stat
,
779 "LU", "# of state deleted due to fast TCP port recycling");
781 SYSCTL_PROC(_net_inet_ip_fw_stats
, OID_AUTO
, track_nomem
,
782 CTLTYPE_ULONG
| CTLFLAG_RW
, NULL
,
783 __offsetof(struct ipfw_context
, ipfw_tks_nomem
), ipfw_sysctl_stat
,
784 "LU", "# of track allocation failure");
785 SYSCTL_PROC(_net_inet_ip_fw_stats
, OID_AUTO
, track_reap
,
786 CTLTYPE_ULONG
| CTLFLAG_RW
, NULL
,
787 __offsetof(struct ipfw_context
, ipfw_tks_reap
), ipfw_sysctl_stat
,
788 "LU", "# of track reap due to tracks shortage");
789 SYSCTL_PROC(_net_inet_ip_fw_stats
, OID_AUTO
, track_reapfailed
,
790 CTLTYPE_ULONG
| CTLFLAG_RW
, NULL
,
791 __offsetof(struct ipfw_context
, ipfw_tks_reapfailed
), ipfw_sysctl_stat
,
792 "LU", "# of track reap failure");
793 SYSCTL_PROC(_net_inet_ip_fw_stats
, OID_AUTO
, track_overflow
,
794 CTLTYPE_ULONG
| CTLFLAG_RW
, NULL
,
795 __offsetof(struct ipfw_context
, ipfw_tks_overflow
), ipfw_sysctl_stat
,
796 "LU", "# of track overflow");
797 SYSCTL_PROC(_net_inet_ip_fw_stats
, OID_AUTO
, track_cntnomem
,
798 CTLTYPE_ULONG
| CTLFLAG_RW
, NULL
,
799 __offsetof(struct ipfw_context
, ipfw_tks_cntnomem
), ipfw_sysctl_stat
,
800 "LU", "# of track counter allocation failure");
801 SYSCTL_PROC(_net_inet_ip_fw_stats
, OID_AUTO
, frags
,
802 CTLTYPE_ULONG
| CTLFLAG_RW
, NULL
,
803 __offsetof(struct ipfw_context
, ipfw_frags
), ipfw_sysctl_stat
,
804 "LU", "# of IP fragements defraged");
805 SYSCTL_PROC(_net_inet_ip_fw_stats
, OID_AUTO
, defraged
,
806 CTLTYPE_ULONG
| CTLFLAG_RW
, NULL
,
807 __offsetof(struct ipfw_context
, ipfw_defraged
), ipfw_sysctl_stat
,
808 "LU", "# of IP packets after defrag");
809 SYSCTL_PROC(_net_inet_ip_fw_stats
, OID_AUTO
, defrag_remote
,
810 CTLTYPE_ULONG
| CTLFLAG_RW
, NULL
,
811 __offsetof(struct ipfw_context
, ipfw_defrag_remote
), ipfw_sysctl_stat
,
812 "LU", "# of IP packets after defrag dispatched to remote cpus");
814 static int ipfw_state_cmp(struct ipfw_state
*,
815 struct ipfw_state
*);
816 static int ipfw_trkcnt_cmp(struct ipfw_trkcnt
*,
817 struct ipfw_trkcnt
*);
818 static int ipfw_track_cmp(struct ipfw_track
*,
819 struct ipfw_track
*);
821 RB_PROTOTYPE(ipfw_state_tree
, ipfw_state
, st_rblink
, ipfw_state_cmp
);
822 RB_GENERATE(ipfw_state_tree
, ipfw_state
, st_rblink
, ipfw_state_cmp
);
824 RB_PROTOTYPE(ipfw_trkcnt_tree
, ipfw_trkcnt
, tc_rblink
, ipfw_trkcnt_cmp
);
825 RB_GENERATE(ipfw_trkcnt_tree
, ipfw_trkcnt
, tc_rblink
, ipfw_trkcnt_cmp
);
827 RB_PROTOTYPE(ipfw_track_tree
, ipfw_track
, t_rblink
, ipfw_track_cmp
);
828 RB_GENERATE(ipfw_track_tree
, ipfw_track
, t_rblink
, ipfw_track_cmp
);
830 static ip_fw_chk_t ipfw_chk
;
831 static void ipfw_track_expire_ipifunc(void *);
832 static void ipfw_state_expire_ipifunc(void *);
833 static void ipfw_keepalive(void *);
834 static int ipfw_state_expire_start(struct ipfw_context
*,
836 static void ipfw_crossref_timeo(void *);
838 #define IPFW_TRKCNT_TOKGET lwkt_gettoken(&ipfw_gd.ipfw_trkcnt_token)
839 #define IPFW_TRKCNT_TOKREL lwkt_reltoken(&ipfw_gd.ipfw_trkcnt_token)
840 #define IPFW_TRKCNT_TOKINIT \
841 lwkt_token_init(&ipfw_gd.ipfw_trkcnt_token, "ipfw_trkcnt");
844 sa_maskedcopy(const struct sockaddr
*src
, struct sockaddr
*dst
,
845 const struct sockaddr
*netmask
)
847 const u_char
*cp1
= (const u_char
*)src
;
848 u_char
*cp2
= (u_char
*)dst
;
849 const u_char
*cp3
= (const u_char
*)netmask
;
850 u_char
*cplim
= cp2
+ *cp3
;
851 u_char
*cplim2
= cp2
+ *cp1
;
853 *cp2
++ = *cp1
++; *cp2
++ = *cp1
++; /* copies sa_len & sa_family */
858 *cp2
++ = *cp1
++ & *cp3
++;
860 bzero(cp2
, cplim2
- cp2
);
864 ipfw_key_build(struct ipfw_key
*key
, in_addr_t saddr
, uint16_t sport
,
865 in_addr_t daddr
, uint16_t dport
, uint8_t proto
)
872 key
->addr_u
.addrs
.addr1
= daddr
;
873 key
->addr_u
.addrs
.addr2
= saddr
;
874 key
->swap
|= IPFW_KEY_SWAP_ADDRS
;
876 key
->addr_u
.addrs
.addr1
= saddr
;
877 key
->addr_u
.addrs
.addr2
= daddr
;
881 key
->port_u
.ports
.port1
= dport
;
882 key
->port_u
.ports
.port2
= sport
;
883 key
->swap
|= IPFW_KEY_SWAP_PORTS
;
885 key
->port_u
.ports
.port1
= sport
;
886 key
->port_u
.ports
.port2
= dport
;
889 if (sport
== dport
&& (key
->swap
& IPFW_KEY_SWAP_ADDRS
))
890 key
->swap
|= IPFW_KEY_SWAP_PORTS
;
891 if (saddr
== daddr
&& (key
->swap
& IPFW_KEY_SWAP_PORTS
))
892 key
->swap
|= IPFW_KEY_SWAP_ADDRS
;
896 ipfw_key_4tuple(const struct ipfw_key
*key
, in_addr_t
*saddr
, uint16_t *sport
,
897 in_addr_t
*daddr
, uint16_t *dport
)
900 if (key
->swap
& IPFW_KEY_SWAP_ADDRS
) {
901 *saddr
= key
->addr_u
.addrs
.addr2
;
902 *daddr
= key
->addr_u
.addrs
.addr1
;
904 *saddr
= key
->addr_u
.addrs
.addr1
;
905 *daddr
= key
->addr_u
.addrs
.addr2
;
908 if (key
->swap
& IPFW_KEY_SWAP_PORTS
) {
909 *sport
= key
->port_u
.ports
.port2
;
910 *dport
= key
->port_u
.ports
.port1
;
912 *sport
= key
->port_u
.ports
.port1
;
913 *dport
= key
->port_u
.ports
.port2
;
918 ipfw_state_cmp(struct ipfw_state
*s1
, struct ipfw_state
*s2
)
921 if (s1
->st_proto
> s2
->st_proto
)
923 if (s1
->st_proto
< s2
->st_proto
)
926 if (s1
->st_addrs
> s2
->st_addrs
)
928 if (s1
->st_addrs
< s2
->st_addrs
)
931 if (s1
->st_ports
> s2
->st_ports
)
933 if (s1
->st_ports
< s2
->st_ports
)
936 if (s1
->st_swap
== s2
->st_swap
||
937 (s1
->st_swap
^ s2
->st_swap
) == IPFW_KEY_SWAP_ALL
)
940 if (s1
->st_swap
> s2
->st_swap
)
947 ipfw_trkcnt_cmp(struct ipfw_trkcnt
*t1
, struct ipfw_trkcnt
*t2
)
950 if (t1
->tc_proto
> t2
->tc_proto
)
952 if (t1
->tc_proto
< t2
->tc_proto
)
955 if (t1
->tc_addrs
> t2
->tc_addrs
)
957 if (t1
->tc_addrs
< t2
->tc_addrs
)
960 if (t1
->tc_ports
> t2
->tc_ports
)
962 if (t1
->tc_ports
< t2
->tc_ports
)
965 if (t1
->tc_ruleid
> t2
->tc_ruleid
)
967 if (t1
->tc_ruleid
< t2
->tc_ruleid
)
974 ipfw_track_cmp(struct ipfw_track
*t1
, struct ipfw_track
*t2
)
977 if (t1
->t_proto
> t2
->t_proto
)
979 if (t1
->t_proto
< t2
->t_proto
)
982 if (t1
->t_addrs
> t2
->t_addrs
)
984 if (t1
->t_addrs
< t2
->t_addrs
)
987 if (t1
->t_ports
> t2
->t_ports
)
989 if (t1
->t_ports
< t2
->t_ports
)
992 if ((uintptr_t)t1
->t_rule
> (uintptr_t)t2
->t_rule
)
994 if ((uintptr_t)t1
->t_rule
< (uintptr_t)t2
->t_rule
)
1001 ipfw_state_max_set(int state_max
)
1004 ipfw_state_max
= state_max
;
1005 /* Allow 5% states over-allocation. */
1006 ipfw_state_loosecnt_updthr
= (state_max
/ 20) / netisr_ncpus
;
1010 ipfw_state_cntcoll(void)
1012 int cpu
, state_cnt
= 0;
1014 for (cpu
= 0; cpu
< netisr_ncpus
; ++cpu
)
1015 state_cnt
+= ipfw_ctx
[cpu
]->ipfw_state_cnt
;
1020 ipfw_state_cntsync(void)
1024 state_cnt
= ipfw_state_cntcoll();
1025 ipfw_gd
.ipfw_state_loosecnt
= state_cnt
;
1030 ipfw_free_rule(struct ip_fw
*rule
)
1032 KASSERT(rule
->cpuid
== mycpuid
, ("rule freed on cpu%d", mycpuid
));
1033 KASSERT(rule
->refcnt
> 0, ("invalid refcnt %u", rule
->refcnt
));
1035 if (rule
->refcnt
== 0) {
1036 if (rule
->cross_rules
!= NULL
)
1037 kfree(rule
->cross_rules
, M_IPFW
);
1038 kfree(rule
, M_IPFW
);
1045 ipfw_unref_rule(void *priv
)
1047 ipfw_free_rule(priv
);
1049 KASSERT(ipfw_gd
.ipfw_refcnt
> 0,
1050 ("invalid ipfw_refcnt %d", ipfw_gd
.ipfw_refcnt
));
1051 atomic_subtract_int(&ipfw_gd
.ipfw_refcnt
, 1);
1055 static __inline
void
1056 ipfw_ref_rule(struct ip_fw
*rule
)
1058 KASSERT(rule
->cpuid
== mycpuid
, ("rule used on cpu%d", mycpuid
));
1060 atomic_add_int(&ipfw_gd
.ipfw_refcnt
, 1);
1066 * This macro maps an ip pointer into a layer3 header pointer of type T
1068 #define L3HDR(T, ip) ((T *)((uint32_t *)(ip) + (ip)->ip_hl))
1071 icmptype_match(struct ip
*ip
, ipfw_insn_u32
*cmd
)
1073 int type
= L3HDR(struct icmp
,ip
)->icmp_type
;
1075 return (type
<= ICMP_MAXTYPE
&& (cmd
->d
[0] & (1 << type
)));
1078 #define TT ((1 << ICMP_ECHO) | \
1079 (1 << ICMP_ROUTERSOLICIT) | \
1080 (1 << ICMP_TSTAMP) | \
1081 (1 << ICMP_IREQ) | \
1082 (1 << ICMP_MASKREQ))
1085 is_icmp_query(struct ip
*ip
)
1087 int type
= L3HDR(struct icmp
, ip
)->icmp_type
;
1089 return (type
<= ICMP_MAXTYPE
&& (TT
& (1 << type
)));
1095 * The following checks use two arrays of 8 or 16 bits to store the
1096 * bits that we want set or clear, respectively. They are in the
1097 * low and high half of cmd->arg1 or cmd->d[0].
1099 * We scan options and store the bits we find set. We succeed if
1101 * (want_set & ~bits) == 0 && (want_clear & ~bits) == want_clear
1103 * The code is sometimes optimized not to store additional variables.
1106 flags_match(ipfw_insn
*cmd
, uint8_t bits
)
1111 if (((cmd
->arg1
& 0xff) & bits
) != 0)
1112 return 0; /* some bits we want set were clear */
1114 want_clear
= (cmd
->arg1
>> 8) & 0xff;
1115 if ((want_clear
& bits
) != want_clear
)
1116 return 0; /* some bits we want clear were set */
1121 ipopts_match(struct ip
*ip
, ipfw_insn
*cmd
)
1123 int optlen
, bits
= 0;
1124 u_char
*cp
= (u_char
*)(ip
+ 1);
1125 int x
= (ip
->ip_hl
<< 2) - sizeof(struct ip
);
1127 for (; x
> 0; x
-= optlen
, cp
+= optlen
) {
1128 int opt
= cp
[IPOPT_OPTVAL
];
1130 if (opt
== IPOPT_EOL
)
1133 if (opt
== IPOPT_NOP
) {
1136 optlen
= cp
[IPOPT_OLEN
];
1137 if (optlen
<= 0 || optlen
> x
)
1138 return 0; /* invalid or truncated */
1143 bits
|= IP_FW_IPOPT_LSRR
;
1147 bits
|= IP_FW_IPOPT_SSRR
;
1151 bits
|= IP_FW_IPOPT_RR
;
1155 bits
|= IP_FW_IPOPT_TS
;
1162 return (flags_match(cmd
, bits
));
1166 tcpopts_match(struct ip
*ip
, ipfw_insn
*cmd
)
1168 int optlen
, bits
= 0;
1169 struct tcphdr
*tcp
= L3HDR(struct tcphdr
,ip
);
1170 u_char
*cp
= (u_char
*)(tcp
+ 1);
1171 int x
= (tcp
->th_off
<< 2) - sizeof(struct tcphdr
);
1173 for (; x
> 0; x
-= optlen
, cp
+= optlen
) {
1176 if (opt
== TCPOPT_EOL
)
1179 if (opt
== TCPOPT_NOP
) {
1189 bits
|= IP_FW_TCPOPT_MSS
;
1193 bits
|= IP_FW_TCPOPT_WINDOW
;
1196 case TCPOPT_SACK_PERMITTED
:
1198 bits
|= IP_FW_TCPOPT_SACK
;
1201 case TCPOPT_TIMESTAMP
:
1202 bits
|= IP_FW_TCPOPT_TS
;
1208 bits
|= IP_FW_TCPOPT_CC
;
1215 return (flags_match(cmd
, bits
));
1219 iface_match(struct ifnet
*ifp
, ipfw_insn_if
*cmd
)
1221 if (ifp
== NULL
) /* no iface with this packet, match fails */
1224 /* Check by name or by IP address */
1225 if (cmd
->name
[0] != '\0') { /* match by name */
1228 if (kfnmatch(cmd
->name
, ifp
->if_xname
, 0) == 0)
1231 if (strncmp(ifp
->if_xname
, cmd
->name
, IFNAMSIZ
) == 0)
1235 struct ifaddr_container
*ifac
;
1237 TAILQ_FOREACH(ifac
, &ifp
->if_addrheads
[mycpuid
], ifa_link
) {
1238 struct ifaddr
*ia
= ifac
->ifa
;
1240 if (ia
->ifa_addr
== NULL
)
1242 if (ia
->ifa_addr
->sa_family
!= AF_INET
)
1244 if (cmd
->p
.ip
.s_addr
== ((struct sockaddr_in
*)
1245 (ia
->ifa_addr
))->sin_addr
.s_addr
)
1246 return(1); /* match */
1249 return(0); /* no match, fail ... */
1252 #define SNPARGS(buf, len) buf + len, sizeof(buf) > len ? sizeof(buf) - len : 0
1255 * We enter here when we have a rule with O_LOG.
1256 * XXX this function alone takes about 2Kbytes of code!
1259 ipfw_log(struct ipfw_context
*ctx
, struct ip_fw
*f
, u_int hlen
,
1260 struct ether_header
*eh
, struct mbuf
*m
, struct ifnet
*oif
)
1263 int limit_reached
= 0;
1264 char action2
[40], proto
[48], fragment
[28], abuf
[INET_ADDRSTRLEN
];
1269 if (f
== NULL
) { /* bogus pkt */
1270 if (verbose_limit
!= 0 &&
1271 ctx
->ipfw_norule_counter
>= verbose_limit
)
1273 ctx
->ipfw_norule_counter
++;
1274 if (ctx
->ipfw_norule_counter
== verbose_limit
)
1275 limit_reached
= verbose_limit
;
1277 } else { /* O_LOG is the first action, find the real one */
1278 ipfw_insn
*cmd
= ACTION_PTR(f
);
1279 ipfw_insn_log
*l
= (ipfw_insn_log
*)cmd
;
1281 if (l
->max_log
!= 0 && l
->log_left
== 0)
1284 if (l
->log_left
== 0)
1285 limit_reached
= l
->max_log
;
1286 cmd
+= F_LEN(cmd
); /* point to first action */
1287 if (cmd
->opcode
== O_PROB
)
1291 switch (cmd
->opcode
) {
1297 if (cmd
->arg1
==ICMP_REJECT_RST
) {
1299 } else if (cmd
->arg1
==ICMP_UNREACH_HOST
) {
1302 ksnprintf(SNPARGS(action2
, 0), "Unreach %d",
1316 ksnprintf(SNPARGS(action2
, 0), "Divert %d", cmd
->arg1
);
1320 ksnprintf(SNPARGS(action2
, 0), "Tee %d", cmd
->arg1
);
1324 ksnprintf(SNPARGS(action2
, 0), "SkipTo %d", cmd
->arg1
);
1328 ksnprintf(SNPARGS(action2
, 0), "Pipe %d", cmd
->arg1
);
1332 ksnprintf(SNPARGS(action2
, 0), "Queue %d", cmd
->arg1
);
1337 ipfw_insn_sa
*sa
= (ipfw_insn_sa
*)cmd
;
1340 len
= ksnprintf(SNPARGS(action2
, 0),
1342 kinet_ntoa(sa
->sa
.sin_addr
, abuf
));
1343 if (sa
->sa
.sin_port
) {
1344 ksnprintf(SNPARGS(action2
, len
), ":%d",
1356 if (hlen
== 0) { /* non-ip */
1357 ksnprintf(SNPARGS(proto
, 0), "MAC");
1359 struct ip
*ip
= mtod(m
, struct ip
*);
1360 /* these three are all aliases to the same thing */
1361 struct icmp
*const icmp
= L3HDR(struct icmp
, ip
);
1362 struct tcphdr
*const tcp
= (struct tcphdr
*)icmp
;
1363 struct udphdr
*const udp
= (struct udphdr
*)icmp
;
1365 int ip_off
, offset
, ip_len
;
1368 if (eh
!= NULL
) { /* layer 2 packets are as on the wire */
1369 ip_off
= ntohs(ip
->ip_off
);
1370 ip_len
= ntohs(ip
->ip_len
);
1372 ip_off
= ip
->ip_off
;
1373 ip_len
= ip
->ip_len
;
1375 offset
= ip_off
& IP_OFFMASK
;
1378 len
= ksnprintf(SNPARGS(proto
, 0), "TCP %s",
1379 kinet_ntoa(ip
->ip_src
, abuf
));
1381 ksnprintf(SNPARGS(proto
, len
), ":%d %s:%d",
1382 ntohs(tcp
->th_sport
),
1383 kinet_ntoa(ip
->ip_dst
, abuf
),
1384 ntohs(tcp
->th_dport
));
1386 ksnprintf(SNPARGS(proto
, len
), " %s",
1387 kinet_ntoa(ip
->ip_dst
, abuf
));
1392 len
= ksnprintf(SNPARGS(proto
, 0), "UDP %s",
1393 kinet_ntoa(ip
->ip_src
, abuf
));
1395 ksnprintf(SNPARGS(proto
, len
), ":%d %s:%d",
1396 ntohs(udp
->uh_sport
),
1397 kinet_ntoa(ip
->ip_dst
, abuf
),
1398 ntohs(udp
->uh_dport
));
1400 ksnprintf(SNPARGS(proto
, len
), " %s",
1401 kinet_ntoa(ip
->ip_dst
, abuf
));
1407 len
= ksnprintf(SNPARGS(proto
, 0),
1412 len
= ksnprintf(SNPARGS(proto
, 0), "ICMP ");
1414 len
+= ksnprintf(SNPARGS(proto
, len
), "%s",
1415 kinet_ntoa(ip
->ip_src
, abuf
));
1416 ksnprintf(SNPARGS(proto
, len
), " %s",
1417 kinet_ntoa(ip
->ip_dst
, abuf
));
1421 len
= ksnprintf(SNPARGS(proto
, 0), "P:%d %s", ip
->ip_p
,
1422 kinet_ntoa(ip
->ip_src
, abuf
));
1423 ksnprintf(SNPARGS(proto
, len
), " %s",
1424 kinet_ntoa(ip
->ip_dst
, abuf
));
1428 if (ip_off
& (IP_MF
| IP_OFFMASK
)) {
1429 ksnprintf(SNPARGS(fragment
, 0), " (frag %d:%d@%d%s)",
1430 ntohs(ip
->ip_id
), ip_len
- (ip
->ip_hl
<< 2),
1431 offset
<< 3, (ip_off
& IP_MF
) ? "+" : "");
1435 if (oif
|| m
->m_pkthdr
.rcvif
) {
1436 log(LOG_SECURITY
| LOG_INFO
,
1437 "ipfw: %d %s %s %s via %s%s\n",
1438 f
? f
->rulenum
: -1,
1439 action
, proto
, oif
? "out" : "in",
1440 oif
? oif
->if_xname
: m
->m_pkthdr
.rcvif
->if_xname
,
1443 log(LOG_SECURITY
| LOG_INFO
,
1444 "ipfw: %d %s %s [no if info]%s\n",
1445 f
? f
->rulenum
: -1,
1446 action
, proto
, fragment
);
1449 if (limit_reached
) {
1450 log(LOG_SECURITY
| LOG_NOTICE
,
1451 "ipfw: limit %d reached on entry %d\n",
1452 limit_reached
, f
? f
->rulenum
: -1);
1458 #define TIME_LEQ(a, b) ((a) - (b) <= 0)
1461 ipfw_state_del(struct ipfw_context
*ctx
, struct ipfw_state
*s
)
1464 KASSERT(s
->st_type
== O_KEEP_STATE
|| s
->st_type
== O_LIMIT
,
1465 ("invalid state type %u", s
->st_type
));
1466 KASSERT(ctx
->ipfw_state_cnt
> 0,
1467 ("invalid state count %d", ctx
->ipfw_state_cnt
));
1469 if (s
->st_track
!= NULL
) {
1470 struct ipfw_track
*t
= s
->st_track
;
1472 KASSERT(!LIST_EMPTY(&t
->t_state_list
),
1473 ("track state list is empty"));
1474 LIST_REMOVE(s
, st_trklink
);
1476 KASSERT(*t
->t_count
> 0,
1477 ("invalid track count %d", *t
->t_count
));
1478 atomic_subtract_int(t
->t_count
, 1);
1481 TAILQ_REMOVE(&ctx
->ipfw_state_list
, s
, st_link
);
1482 RB_REMOVE(ipfw_state_tree
, &ctx
->ipfw_state_tree
, s
);
1485 ctx
->ipfw_state_cnt
--;
1486 if (ctx
->ipfw_state_loosecnt
> 0)
1487 ctx
->ipfw_state_loosecnt
--;
1491 ipfw_state_reap(struct ipfw_context
*ctx
, int reap_max
)
1493 struct ipfw_state
*s
, *anchor
;
1496 if (reap_max
< ipfw_state_reap_min
)
1497 reap_max
= ipfw_state_reap_min
;
1499 if ((ctx
->ipfw_flags
& IPFW_FLAG_STATEEXP
) == 0) {
1501 * Kick start state expiring. Ignore scan limit,
1502 * we are short of states.
1504 ctx
->ipfw_flags
|= IPFW_FLAG_STATEREAP
;
1505 expired
= ipfw_state_expire_start(ctx
, INT_MAX
, reap_max
);
1506 ctx
->ipfw_flags
&= ~IPFW_FLAG_STATEREAP
;
1511 * States are being expired.
1514 if (ctx
->ipfw_state_cnt
== 0)
1518 anchor
= &ctx
->ipfw_stateexp_anch
;
1519 while ((s
= TAILQ_NEXT(anchor
, st_link
)) != NULL
) {
1521 * Ignore scan limit; we are short of states.
1524 TAILQ_REMOVE(&ctx
->ipfw_state_list
, anchor
, st_link
);
1525 TAILQ_INSERT_AFTER(&ctx
->ipfw_state_list
, s
, anchor
, st_link
);
1527 if (s
->st_type
== O_ANCHOR
)
1530 if (IPFW_STATE_TCPCLOSED(s
) ||
1531 TIME_LEQ(s
->st_expire
, time_uptime
)) {
1532 ipfw_state_del(ctx
, s
);
1533 if (++expired
>= reap_max
)
1535 if ((expired
& 0xff) == 0 &&
1536 ipfw_state_cntcoll() + ipfw_state_headroom
<=
1543 * Leave the anchor on the list, even if the end of the list has
1544 * been reached. ipfw_state_expire_more_dispatch() will handle
1551 ipfw_state_flush(struct ipfw_context
*ctx
, const struct ip_fw
*rule
)
1553 struct ipfw_state
*s
, *sn
;
1555 TAILQ_FOREACH_MUTABLE(s
, &ctx
->ipfw_state_list
, st_link
, sn
) {
1556 if (s
->st_type
== O_ANCHOR
)
1558 if (rule
!= NULL
&& s
->st_rule
!= rule
)
1560 ipfw_state_del(ctx
, s
);
1565 ipfw_state_expire_done(struct ipfw_context
*ctx
)
1568 KASSERT(ctx
->ipfw_flags
& IPFW_FLAG_STATEEXP
,
1569 ("stateexp is not in progress"));
1570 ctx
->ipfw_flags
&= ~IPFW_FLAG_STATEEXP
;
1571 callout_reset(&ctx
->ipfw_stateto_ch
, hz
,
1572 ipfw_state_expire_ipifunc
, NULL
);
1576 ipfw_state_expire_more(struct ipfw_context
*ctx
)
1578 struct netmsg_base
*nm
= &ctx
->ipfw_stateexp_more
;
1580 KASSERT(ctx
->ipfw_flags
& IPFW_FLAG_STATEEXP
,
1581 ("stateexp is not in progress"));
1582 KASSERT(nm
->lmsg
.ms_flags
& MSGF_DONE
,
1583 ("stateexp more did not finish"));
1584 netisr_sendmsg_oncpu(nm
);
1588 ipfw_state_expire_loop(struct ipfw_context
*ctx
, struct ipfw_state
*anchor
,
1589 int scan_max
, int expire_max
)
1591 struct ipfw_state
*s
;
1592 int scanned
= 0, expired
= 0;
1594 KASSERT(ctx
->ipfw_flags
& IPFW_FLAG_STATEEXP
,
1595 ("stateexp is not in progress"));
1597 while ((s
= TAILQ_NEXT(anchor
, st_link
)) != NULL
) {
1598 if (scanned
++ >= scan_max
) {
1599 ipfw_state_expire_more(ctx
);
1603 TAILQ_REMOVE(&ctx
->ipfw_state_list
, anchor
, st_link
);
1604 TAILQ_INSERT_AFTER(&ctx
->ipfw_state_list
, s
, anchor
, st_link
);
1606 if (s
->st_type
== O_ANCHOR
)
1609 if (TIME_LEQ(s
->st_expire
, time_uptime
) ||
1610 ((ctx
->ipfw_flags
& IPFW_FLAG_STATEREAP
) &&
1611 IPFW_STATE_TCPCLOSED(s
))) {
1612 ipfw_state_del(ctx
, s
);
1613 if (++expired
>= expire_max
) {
1614 ipfw_state_expire_more(ctx
);
1617 if ((ctx
->ipfw_flags
& IPFW_FLAG_STATEREAP
) &&
1618 (expired
& 0xff) == 0 &&
1619 ipfw_state_cntcoll() + ipfw_state_headroom
<=
1621 ipfw_state_expire_more(ctx
);
1626 TAILQ_REMOVE(&ctx
->ipfw_state_list
, anchor
, st_link
);
1627 ipfw_state_expire_done(ctx
);
1632 ipfw_state_expire_more_dispatch(netmsg_t nm
)
1634 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
1635 struct ipfw_state
*anchor
;
1637 ASSERT_NETISR_NCPUS(mycpuid
);
1638 KASSERT(ctx
->ipfw_flags
& IPFW_FLAG_STATEEXP
,
1639 ("statexp is not in progress"));
1642 netisr_replymsg(&nm
->base
, 0);
1644 anchor
= &ctx
->ipfw_stateexp_anch
;
1645 if (ctx
->ipfw_state_cnt
== 0) {
1646 TAILQ_REMOVE(&ctx
->ipfw_state_list
, anchor
, st_link
);
1647 ipfw_state_expire_done(ctx
);
1650 ipfw_state_expire_loop(ctx
, anchor
,
1651 ipfw_state_scan_max
, ipfw_state_expire_max
);
1655 ipfw_state_expire_start(struct ipfw_context
*ctx
, int scan_max
, int expire_max
)
1657 struct ipfw_state
*anchor
;
1659 KASSERT((ctx
->ipfw_flags
& IPFW_FLAG_STATEEXP
) == 0,
1660 ("stateexp is in progress"));
1661 ctx
->ipfw_flags
|= IPFW_FLAG_STATEEXP
;
1663 if (ctx
->ipfw_state_cnt
== 0) {
1664 ipfw_state_expire_done(ctx
);
1669 * Do not expire more than once per second, it is useless.
1671 if ((ctx
->ipfw_flags
& IPFW_FLAG_STATEREAP
) == 0 &&
1672 ctx
->ipfw_state_lastexp
== time_uptime
) {
1673 ipfw_state_expire_done(ctx
);
1676 ctx
->ipfw_state_lastexp
= time_uptime
;
1678 anchor
= &ctx
->ipfw_stateexp_anch
;
1679 TAILQ_INSERT_HEAD(&ctx
->ipfw_state_list
, anchor
, st_link
);
1680 return (ipfw_state_expire_loop(ctx
, anchor
, scan_max
, expire_max
));
1684 ipfw_state_expire_dispatch(netmsg_t nm
)
1686 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
1688 ASSERT_NETISR_NCPUS(mycpuid
);
1692 netisr_replymsg(&nm
->base
, 0);
1695 if (ctx
->ipfw_flags
& IPFW_FLAG_STATEEXP
) {
1696 /* Running; done. */
1699 ipfw_state_expire_start(ctx
,
1700 ipfw_state_scan_max
, ipfw_state_expire_max
);
1704 ipfw_state_expire_ipifunc(void *dummy __unused
)
1706 struct netmsg_base
*msg
;
1708 KKASSERT(mycpuid
< netisr_ncpus
);
1709 msg
= &ipfw_ctx
[mycpuid
]->ipfw_stateexp_nm
;
1712 if (msg
->lmsg
.ms_flags
& MSGF_DONE
)
1713 netisr_sendmsg_oncpu(msg
);
1718 ipfw_state_update_tcp(struct ipfw_state
*s
, int dir
, const struct tcphdr
*tcp
)
1720 uint32_t seq
= ntohl(tcp
->th_seq
);
1721 uint32_t ack
= ntohl(tcp
->th_ack
);
1723 if (tcp
->th_flags
& TH_RST
)
1726 if (dir
== MATCH_FORWARD
) {
1727 if ((s
->st_flags
& IPFW_STATE_F_SEQFWD
) == 0) {
1728 s
->st_flags
|= IPFW_STATE_F_SEQFWD
;
1729 s
->st_seq_fwd
= seq
;
1730 } else if (SEQ_GEQ(seq
, s
->st_seq_fwd
)) {
1731 s
->st_seq_fwd
= seq
;
1733 /* Out-of-sequence; done. */
1736 if (tcp
->th_flags
& TH_ACK
) {
1737 if ((s
->st_flags
& IPFW_STATE_F_ACKFWD
) == 0) {
1738 s
->st_flags
|= IPFW_STATE_F_ACKFWD
;
1739 s
->st_ack_fwd
= ack
;
1740 } else if (SEQ_GEQ(ack
, s
->st_ack_fwd
)) {
1741 s
->st_ack_fwd
= ack
;
1743 /* Out-of-sequence; done. */
1747 if ((s
->st_state
& ((TH_FIN
| TH_ACK
) << 8)) ==
1748 (TH_FIN
<< 8) && s
->st_ack_fwd
== s
->st_seq_rev
+ 1)
1749 s
->st_state
|= (TH_ACK
<< 8);
1752 if ((s
->st_flags
& IPFW_STATE_F_SEQREV
) == 0) {
1753 s
->st_flags
|= IPFW_STATE_F_SEQREV
;
1754 s
->st_seq_rev
= seq
;
1755 } else if (SEQ_GEQ(seq
, s
->st_seq_rev
)) {
1756 s
->st_seq_rev
= seq
;
1758 /* Out-of-sequence; done. */
1761 if (tcp
->th_flags
& TH_ACK
) {
1762 if ((s
->st_flags
& IPFW_STATE_F_ACKREV
) == 0) {
1763 s
->st_flags
|= IPFW_STATE_F_ACKREV
;
1765 } else if (SEQ_GEQ(ack
, s
->st_ack_rev
)) {
1766 s
->st_ack_rev
= ack
;
1768 /* Out-of-sequence; done. */
1772 if ((s
->st_state
& (TH_FIN
| TH_ACK
)) == TH_FIN
&&
1773 s
->st_ack_rev
== s
->st_seq_fwd
+ 1)
1774 s
->st_state
|= TH_ACK
;
1781 ipfw_state_update(const struct ipfw_flow_id
*pkt
, int dir
,
1782 const struct tcphdr
*tcp
, struct ipfw_state
*s
)
1785 if (pkt
->proto
== IPPROTO_TCP
) { /* update state according to flags */
1786 u_char flags
= pkt
->flags
& IPFW_STATE_TCPFLAGS
;
1788 if (tcp
!= NULL
&& !ipfw_state_update_tcp(s
, dir
, tcp
))
1791 s
->st_state
|= (dir
== MATCH_FORWARD
) ? flags
: (flags
<< 8);
1792 switch (s
->st_state
& IPFW_STATE_TCPSTATES
) {
1793 case TH_SYN
: /* opening */
1794 s
->st_expire
= time_uptime
+ dyn_syn_lifetime
;
1797 case BOTH_SYN
: /* move to established */
1798 case BOTH_SYN
| TH_FIN
: /* one side tries to close */
1799 case BOTH_SYN
| (TH_FIN
<< 8):
1800 s
->st_expire
= time_uptime
+ dyn_ack_lifetime
;
1803 case BOTH_SYN
| BOTH_FIN
: /* both sides closed */
1804 if ((s
->st_state
& BOTH_FINACK
) == BOTH_FINACK
) {
1805 /* And both FINs were ACKed. */
1806 s
->st_expire
= time_uptime
+ dyn_fin_lifetime
;
1808 s
->st_expire
= time_uptime
+
1809 dyn_finwait_lifetime
;
1816 * reset or some invalid combination, but can also
1817 * occur if we use keep-state the wrong way.
1819 if ((s
->st_state
& ((TH_RST
<< 8) | TH_RST
)) == 0)
1820 kprintf("invalid state: 0x%x\n", s
->st_state
);
1822 s
->st_expire
= time_uptime
+ dyn_rst_lifetime
;
1825 } else if (pkt
->proto
== IPPROTO_UDP
) {
1826 s
->st_expire
= time_uptime
+ dyn_udp_lifetime
;
1828 /* other protocols */
1829 s
->st_expire
= time_uptime
+ dyn_short_lifetime
;
1836 static struct ipfw_state
*
1837 ipfw_state_lookup(struct ipfw_context
*ctx
, const struct ipfw_flow_id
*pkt
,
1838 int *match_direction
, const struct tcphdr
*tcp
)
1840 struct ipfw_state
*key
, *s
;
1841 int dir
= MATCH_NONE
;
1843 key
= &ctx
->ipfw_state_tmpkey
;
1844 ipfw_key_build(&key
->st_key
, pkt
->src_ip
, pkt
->src_port
,
1845 pkt
->dst_ip
, pkt
->dst_port
, pkt
->proto
);
1846 s
= RB_FIND(ipfw_state_tree
, &ctx
->ipfw_state_tree
, key
);
1848 goto done
; /* not found. */
1849 if (TIME_LEQ(s
->st_expire
, time_uptime
)) {
1851 ipfw_state_del(ctx
, s
);
1855 if ((pkt
->flags
& TH_SYN
) && IPFW_STATE_TCPCLOSED(s
)) {
1856 /* TCP ports recycling is too fast. */
1857 ctx
->ipfw_sts_tcprecycled
++;
1858 ipfw_state_del(ctx
, s
);
1863 if (s
->st_swap
== key
->st_swap
) {
1864 dir
= MATCH_FORWARD
;
1866 KASSERT((s
->st_swap
& key
->st_swap
) == 0,
1867 ("found mismatch state"));
1868 dir
= MATCH_REVERSE
;
1871 /* Update this state. */
1872 ipfw_state_update(pkt
, dir
, tcp
, s
);
1874 if (s
->st_track
!= NULL
) {
1875 /* This track has been used. */
1876 s
->st_track
->t_expire
= time_uptime
+ dyn_short_lifetime
;
1879 if (match_direction
)
1880 *match_direction
= dir
;
1884 static __inline
struct ip_fw
*
1885 ipfw_state_lookup_rule(struct ipfw_context
*ctx
, const struct ipfw_flow_id
*pkt
,
1886 int *match_direction
, const struct tcphdr
*tcp
, uint16_t len
)
1888 struct ipfw_state
*s
;
1890 s
= ipfw_state_lookup(ctx
, pkt
, match_direction
, tcp
);
1894 KASSERT(s
->st_rule
->cpuid
== mycpuid
,
1895 ("rule %p (cpu%d) does not belong to the current cpu%d",
1896 s
->st_rule
, s
->st_rule
->cpuid
, mycpuid
));
1901 return (s
->st_rule
);
1904 static struct ipfw_state
*
1905 ipfw_state_add(struct ipfw_context
*ctx
, const struct ipfw_flow_id
*id
,
1906 uint16_t type
, struct ip_fw
*rule
, struct ipfw_track
*t
,
1907 const struct tcphdr
*tcp
)
1909 struct ipfw_state
*s
, *dup
;
1911 KASSERT(type
== O_KEEP_STATE
|| type
== O_LIMIT
,
1912 ("invalid state type %u", type
));
1914 s
= kmalloc(sizeof(*s
), M_IPFW
, M_INTWAIT
| M_NULLOK
| M_ZERO
);
1916 ctx
->ipfw_sts_nomem
++;
1920 ipfw_key_build(&s
->st_key
, id
->src_ip
, id
->src_port
,
1921 id
->dst_ip
, id
->dst_port
, id
->proto
);
1926 ctx
->ipfw_state_cnt
++;
1927 ctx
->ipfw_state_loosecnt
++;
1928 if (ctx
->ipfw_state_loosecnt
>= ipfw_state_loosecnt_updthr
) {
1929 ipfw_gd
.ipfw_state_loosecnt
+= ctx
->ipfw_state_loosecnt
;
1930 ctx
->ipfw_state_loosecnt
= 0;
1933 dup
= RB_INSERT(ipfw_state_tree
, &ctx
->ipfw_state_tree
, s
);
1935 panic("ipfw: state exists");
1936 TAILQ_INSERT_TAIL(&ctx
->ipfw_state_list
, s
, st_link
);
1939 * Update this state:
1940 * Set st_expire and st_state.
1942 ipfw_state_update(id
, MATCH_FORWARD
, tcp
, s
);
1945 /* Keep the track referenced. */
1946 LIST_INSERT_HEAD(&t
->t_state_list
, s
, st_trklink
);
1953 ipfw_track_free(struct ipfw_context
*ctx
, struct ipfw_track
*t
)
1955 struct ipfw_trkcnt
*trk
;
1956 boolean_t trk_freed
= FALSE
;
1958 KASSERT(t
->t_count
!= NULL
, ("track anchor"));
1959 KASSERT(LIST_EMPTY(&t
->t_state_list
),
1960 ("invalid track is still referenced"));
1963 KASSERT(trk
!= NULL
, ("track has no trkcnt"));
1965 RB_REMOVE(ipfw_track_tree
, &ctx
->ipfw_track_tree
, t
);
1966 TAILQ_REMOVE(&ctx
->ipfw_track_list
, t
, t_link
);
1970 * fdrop() style reference counting.
1971 * See kern/kern_descrip.c fdrop().
1974 int refs
= trk
->tc_refs
;
1977 KASSERT(refs
> 0, ("invalid trkcnt refs %d", refs
));
1980 if (atomic_cmpset_int(&trk
->tc_refs
, refs
, 0)) {
1981 KASSERT(trk
->tc_count
== 0,
1982 ("%d states reference this trkcnt",
1984 RB_REMOVE(ipfw_trkcnt_tree
,
1985 &ipfw_gd
.ipfw_trkcnt_tree
, trk
);
1987 KASSERT(ipfw_gd
.ipfw_trkcnt_cnt
> 0,
1988 ("invalid trkcnt cnt %d",
1989 ipfw_gd
.ipfw_trkcnt_cnt
));
1990 ipfw_gd
.ipfw_trkcnt_cnt
--;
1993 if (ctx
->ipfw_trkcnt_spare
== NULL
)
1994 ctx
->ipfw_trkcnt_spare
= trk
;
2002 } else if (atomic_cmpset_int(&trk
->tc_refs
, refs
, refs
- 1)) {
2011 ipfw_track_flush(struct ipfw_context
*ctx
, struct ip_fw
*rule
)
2013 struct ipfw_track
*t
, *tn
;
2015 TAILQ_FOREACH_MUTABLE(t
, &ctx
->ipfw_track_list
, t_link
, tn
) {
2016 if (t
->t_count
== NULL
) /* anchor */
2018 if (rule
!= NULL
&& t
->t_rule
!= rule
)
2020 ipfw_track_free(ctx
, t
);
2025 ipfw_track_state_expire(struct ipfw_context
*ctx
, struct ipfw_track
*t
,
2028 struct ipfw_state
*s
, *sn
;
2029 boolean_t ret
= FALSE
;
2031 KASSERT(t
->t_count
!= NULL
, ("track anchor"));
2033 if (LIST_EMPTY(&t
->t_state_list
))
2037 * Do not expire more than once per second, it is useless.
2039 if (t
->t_lastexp
== time_uptime
)
2041 t
->t_lastexp
= time_uptime
;
2043 LIST_FOREACH_MUTABLE(s
, &t
->t_state_list
, st_trklink
, sn
) {
2044 if (TIME_LEQ(s
->st_expire
, time_uptime
) ||
2045 (reap
&& IPFW_STATE_TCPCLOSED(s
))) {
2046 KASSERT(s
->st_track
== t
,
2047 ("state track %p does not match %p",
2049 ipfw_state_del(ctx
, s
);
2056 static __inline
struct ipfw_trkcnt
*
2057 ipfw_trkcnt_alloc(struct ipfw_context
*ctx
)
2059 struct ipfw_trkcnt
*trk
;
2061 if (ctx
->ipfw_trkcnt_spare
!= NULL
) {
2062 trk
= ctx
->ipfw_trkcnt_spare
;
2063 ctx
->ipfw_trkcnt_spare
= NULL
;
2065 trk
= kmalloc_cachealign(sizeof(*trk
), M_IPFW
,
2066 M_INTWAIT
| M_NULLOK
);
2072 ipfw_track_expire_done(struct ipfw_context
*ctx
)
2075 KASSERT(ctx
->ipfw_flags
& IPFW_FLAG_TRACKEXP
,
2076 ("trackexp is not in progress"));
2077 ctx
->ipfw_flags
&= ~IPFW_FLAG_TRACKEXP
;
2078 callout_reset(&ctx
->ipfw_trackto_ch
, hz
,
2079 ipfw_track_expire_ipifunc
, NULL
);
2083 ipfw_track_expire_more(struct ipfw_context
*ctx
)
2085 struct netmsg_base
*nm
= &ctx
->ipfw_trackexp_more
;
2087 KASSERT(ctx
->ipfw_flags
& IPFW_FLAG_TRACKEXP
,
2088 ("trackexp is not in progress"));
2089 KASSERT(nm
->lmsg
.ms_flags
& MSGF_DONE
,
2090 ("trackexp more did not finish"));
2091 netisr_sendmsg_oncpu(nm
);
2095 ipfw_track_expire_loop(struct ipfw_context
*ctx
, struct ipfw_track
*anchor
,
2096 int scan_max
, int expire_max
)
2098 struct ipfw_track
*t
;
2099 int scanned
= 0, expired
= 0;
2100 boolean_t reap
= FALSE
;
2102 KASSERT(ctx
->ipfw_flags
& IPFW_FLAG_TRACKEXP
,
2103 ("trackexp is not in progress"));
2105 if (ctx
->ipfw_flags
& IPFW_FLAG_TRACKREAP
)
2108 while ((t
= TAILQ_NEXT(anchor
, t_link
)) != NULL
) {
2109 if (scanned
++ >= scan_max
) {
2110 ipfw_track_expire_more(ctx
);
2114 TAILQ_REMOVE(&ctx
->ipfw_track_list
, anchor
, t_link
);
2115 TAILQ_INSERT_AFTER(&ctx
->ipfw_track_list
, t
, anchor
, t_link
);
2117 if (t
->t_count
== NULL
) /* anchor */
2120 ipfw_track_state_expire(ctx
, t
, reap
);
2121 if (!LIST_EMPTY(&t
->t_state_list
)) {
2122 /* There are states referencing this track. */
2126 if (TIME_LEQ(t
->t_expire
, time_uptime
) || reap
) {
2128 if (ipfw_track_free(ctx
, t
)) {
2129 if (++expired
>= expire_max
) {
2130 ipfw_track_expire_more(ctx
);
2136 TAILQ_REMOVE(&ctx
->ipfw_track_list
, anchor
, t_link
);
2137 ipfw_track_expire_done(ctx
);
2142 ipfw_track_expire_start(struct ipfw_context
*ctx
, int scan_max
, int expire_max
)
2144 struct ipfw_track
*anchor
;
2146 KASSERT((ctx
->ipfw_flags
& IPFW_FLAG_TRACKEXP
) == 0,
2147 ("trackexp is in progress"));
2148 ctx
->ipfw_flags
|= IPFW_FLAG_TRACKEXP
;
2150 if (RB_EMPTY(&ctx
->ipfw_track_tree
)) {
2151 ipfw_track_expire_done(ctx
);
2156 * Do not expire more than once per second, it is useless.
2158 if ((ctx
->ipfw_flags
& IPFW_FLAG_TRACKREAP
) == 0 &&
2159 ctx
->ipfw_track_lastexp
== time_uptime
) {
2160 ipfw_track_expire_done(ctx
);
2163 ctx
->ipfw_track_lastexp
= time_uptime
;
2165 anchor
= &ctx
->ipfw_trackexp_anch
;
2166 TAILQ_INSERT_HEAD(&ctx
->ipfw_track_list
, anchor
, t_link
);
2167 return (ipfw_track_expire_loop(ctx
, anchor
, scan_max
, expire_max
));
2171 ipfw_track_expire_more_dispatch(netmsg_t nm
)
2173 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
2174 struct ipfw_track
*anchor
;
2176 ASSERT_NETISR_NCPUS(mycpuid
);
2177 KASSERT(ctx
->ipfw_flags
& IPFW_FLAG_TRACKEXP
,
2178 ("trackexp is not in progress"));
2181 netisr_replymsg(&nm
->base
, 0);
2183 anchor
= &ctx
->ipfw_trackexp_anch
;
2184 if (RB_EMPTY(&ctx
->ipfw_track_tree
)) {
2185 TAILQ_REMOVE(&ctx
->ipfw_track_list
, anchor
, t_link
);
2186 ipfw_track_expire_done(ctx
);
2189 ipfw_track_expire_loop(ctx
, anchor
,
2190 ipfw_track_scan_max
, ipfw_track_expire_max
);
2194 ipfw_track_expire_dispatch(netmsg_t nm
)
2196 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
2198 ASSERT_NETISR_NCPUS(mycpuid
);
2202 netisr_replymsg(&nm
->base
, 0);
2205 if (ctx
->ipfw_flags
& IPFW_FLAG_TRACKEXP
) {
2206 /* Running; done. */
2209 ipfw_track_expire_start(ctx
,
2210 ipfw_track_scan_max
, ipfw_track_expire_max
);
2214 ipfw_track_expire_ipifunc(void *dummy __unused
)
2216 struct netmsg_base
*msg
;
2218 KKASSERT(mycpuid
< netisr_ncpus
);
2219 msg
= &ipfw_ctx
[mycpuid
]->ipfw_trackexp_nm
;
2222 if (msg
->lmsg
.ms_flags
& MSGF_DONE
)
2223 netisr_sendmsg_oncpu(msg
);
2228 ipfw_track_reap(struct ipfw_context
*ctx
)
2230 struct ipfw_track
*t
, *anchor
;
2233 if ((ctx
->ipfw_flags
& IPFW_FLAG_TRACKEXP
) == 0) {
2235 * Kick start track expiring. Ignore scan limit,
2236 * we are short of tracks.
2238 ctx
->ipfw_flags
|= IPFW_FLAG_TRACKREAP
;
2239 expired
= ipfw_track_expire_start(ctx
, INT_MAX
,
2240 ipfw_track_reap_max
);
2241 ctx
->ipfw_flags
&= ~IPFW_FLAG_TRACKREAP
;
2246 * Tracks are being expired.
2249 if (RB_EMPTY(&ctx
->ipfw_track_tree
))
2253 anchor
= &ctx
->ipfw_trackexp_anch
;
2254 while ((t
= TAILQ_NEXT(anchor
, t_link
)) != NULL
) {
2256 * Ignore scan limit; we are short of tracks.
2259 TAILQ_REMOVE(&ctx
->ipfw_track_list
, anchor
, t_link
);
2260 TAILQ_INSERT_AFTER(&ctx
->ipfw_track_list
, t
, anchor
, t_link
);
2262 if (t
->t_count
== NULL
) /* anchor */
2265 ipfw_track_state_expire(ctx
, t
, TRUE
);
2266 if (!LIST_EMPTY(&t
->t_state_list
)) {
2267 /* There are states referencing this track. */
2271 if (ipfw_track_free(ctx
, t
)) {
2272 if (++expired
>= ipfw_track_reap_max
) {
2273 ipfw_track_expire_more(ctx
);
2280 * Leave the anchor on the list, even if the end of the list has
2281 * been reached. ipfw_track_expire_more_dispatch() will handle
2287 static struct ipfw_track
*
2288 ipfw_track_alloc(struct ipfw_context
*ctx
, const struct ipfw_flow_id
*id
,
2289 uint16_t limit_mask
, struct ip_fw
*rule
)
2291 struct ipfw_track
*key
, *t
, *dup
;
2292 struct ipfw_trkcnt
*trk
, *ret
;
2293 boolean_t do_expire
= FALSE
;
2295 KASSERT(rule
->track_ruleid
!= 0,
2296 ("rule %u has no track ruleid", rule
->rulenum
));
2298 key
= &ctx
->ipfw_track_tmpkey
;
2299 key
->t_proto
= id
->proto
;
2303 if (limit_mask
& DYN_SRC_ADDR
)
2304 key
->t_saddr
= id
->src_ip
;
2305 if (limit_mask
& DYN_DST_ADDR
)
2306 key
->t_daddr
= id
->dst_ip
;
2307 if (limit_mask
& DYN_SRC_PORT
)
2308 key
->t_sport
= id
->src_port
;
2309 if (limit_mask
& DYN_DST_PORT
)
2310 key
->t_dport
= id
->dst_port
;
2312 t
= RB_FIND(ipfw_track_tree
, &ctx
->ipfw_track_tree
, key
);
2316 t
= kmalloc(sizeof(*t
), M_IPFW
, M_INTWAIT
| M_NULLOK
);
2318 ctx
->ipfw_tks_nomem
++;
2322 t
->t_key
= key
->t_key
;
2325 LIST_INIT(&t
->t_state_list
);
2327 if (ipfw_gd
.ipfw_trkcnt_cnt
>= ipfw_track_max
) {
2328 time_t globexp
, uptime
;
2334 * Do not expire globally more than once per second,
2337 uptime
= time_uptime
;
2338 globexp
= ipfw_gd
.ipfw_track_globexp
;
2339 if (globexp
!= uptime
&&
2340 atomic_cmpset_long(&ipfw_gd
.ipfw_track_globexp
,
2344 /* Expire tracks on other CPUs. */
2345 for (cpu
= 0; cpu
< netisr_ncpus
; ++cpu
) {
2348 lwkt_send_ipiq(globaldata_find(cpu
),
2349 ipfw_track_expire_ipifunc
, NULL
);
2353 trk
= ipfw_trkcnt_alloc(ctx
);
2356 struct ipfw_trkcnt
*tkey
;
2358 tkey
= &ctx
->ipfw_trkcnt_tmpkey
;
2359 key
= NULL
; /* tkey overlaps key */
2361 tkey
->tc_key
= t
->t_key
;
2362 tkey
->tc_ruleid
= rule
->track_ruleid
;
2365 trk
= RB_FIND(ipfw_trkcnt_tree
, &ipfw_gd
.ipfw_trkcnt_tree
,
2370 ctx
->ipfw_tks_reap
++;
2371 if (ipfw_track_reap(ctx
) > 0) {
2372 if (ipfw_gd
.ipfw_trkcnt_cnt
<
2374 trk
= ipfw_trkcnt_alloc(ctx
);
2377 ctx
->ipfw_tks_cntnomem
++;
2379 ctx
->ipfw_tks_overflow
++;
2382 ctx
->ipfw_tks_reapfailed
++;
2383 ctx
->ipfw_tks_overflow
++;
2386 ctx
->ipfw_tks_cntnomem
++;
2391 KASSERT(trk
->tc_refs
> 0 && trk
->tc_refs
< netisr_ncpus
,
2392 ("invalid trkcnt refs %d", trk
->tc_refs
));
2393 atomic_add_int(&trk
->tc_refs
, 1);
2397 trk
->tc_key
= t
->t_key
;
2398 trk
->tc_ruleid
= rule
->track_ruleid
;
2402 trk
->tc_rulenum
= rule
->rulenum
;
2405 ret
= RB_INSERT(ipfw_trkcnt_tree
, &ipfw_gd
.ipfw_trkcnt_tree
,
2408 KASSERT(ret
->tc_refs
> 0 &&
2409 ret
->tc_refs
< netisr_ncpus
,
2410 ("invalid trkcnt refs %d", ret
->tc_refs
));
2411 KASSERT(ctx
->ipfw_trkcnt_spare
== NULL
,
2412 ("trkcnt spare was installed"));
2413 ctx
->ipfw_trkcnt_spare
= trk
;
2416 ipfw_gd
.ipfw_trkcnt_cnt
++;
2418 atomic_add_int(&trk
->tc_refs
, 1);
2421 t
->t_count
= &trk
->tc_count
;
2424 dup
= RB_INSERT(ipfw_track_tree
, &ctx
->ipfw_track_tree
, t
);
2426 panic("ipfw: track exists");
2427 TAILQ_INSERT_TAIL(&ctx
->ipfw_track_list
, t
, t_link
);
2429 t
->t_expire
= time_uptime
+ dyn_short_lifetime
;
2434 * Install state for rule type cmd->o.opcode
2436 * Returns 1 (failure) if state is not installed because of errors or because
2437 * states limitations are enforced.
2440 ipfw_state_install(struct ipfw_context
*ctx
, struct ip_fw
*rule
,
2441 ipfw_insn_limit
*cmd
, struct ip_fw_args
*args
, const struct tcphdr
*tcp
)
2443 struct ipfw_state
*s
;
2444 struct ipfw_track
*t
;
2447 if (ipfw_gd
.ipfw_state_loosecnt
>= ipfw_state_max
&&
2448 (diff
= (ipfw_state_cntsync() - ipfw_state_max
)) >= 0) {
2449 boolean_t overflow
= TRUE
;
2451 ctx
->ipfw_sts_reap
++;
2452 if (ipfw_state_reap(ctx
, diff
) == 0)
2453 ctx
->ipfw_sts_reapfailed
++;
2454 if (ipfw_state_cntsync() < ipfw_state_max
)
2458 time_t globexp
, uptime
;
2462 * Do not expire globally more than once per second,
2465 uptime
= time_uptime
;
2466 globexp
= ipfw_gd
.ipfw_state_globexp
;
2467 if (globexp
== uptime
||
2468 !atomic_cmpset_long(&ipfw_gd
.ipfw_state_globexp
,
2470 ctx
->ipfw_sts_overflow
++;
2474 /* Expire states on other CPUs. */
2475 for (cpu
= 0; cpu
< netisr_ncpus
; ++cpu
) {
2478 lwkt_send_ipiq(globaldata_find(cpu
),
2479 ipfw_state_expire_ipifunc
, NULL
);
2481 ctx
->ipfw_sts_overflow
++;
2486 switch (cmd
->o
.opcode
) {
2487 case O_KEEP_STATE
: /* bidir rule */
2488 s
= ipfw_state_add(ctx
, &args
->f_id
, O_KEEP_STATE
, rule
, NULL
,
2494 case O_LIMIT
: /* limit number of sessions */
2495 t
= ipfw_track_alloc(ctx
, &args
->f_id
, cmd
->limit_mask
, rule
);
2499 if (*t
->t_count
>= cmd
->conn_limit
) {
2500 if (!ipfw_track_state_expire(ctx
, t
, TRUE
))
2504 count
= *t
->t_count
;
2505 if (count
>= cmd
->conn_limit
)
2507 if (atomic_cmpset_int(t
->t_count
, count
, count
+ 1))
2511 s
= ipfw_state_add(ctx
, &args
->f_id
, O_LIMIT
, rule
, t
, tcp
);
2514 atomic_subtract_int(t
->t_count
, 1);
2520 panic("unknown state type %u\n", cmd
->o
.opcode
);
2526 ipfw_table_lookup(struct ipfw_context
*ctx
, uint16_t tableid
,
2527 const struct in_addr
*in
)
2529 struct radix_node_head
*rnh
;
2530 struct sockaddr_in sin
;
2531 struct ipfw_tblent
*te
;
2533 KASSERT(tableid
< ipfw_table_max
, ("invalid tableid %u", tableid
));
2534 rnh
= ctx
->ipfw_tables
[tableid
];
2536 return (0); /* no match */
2538 memset(&sin
, 0, sizeof(sin
));
2539 sin
.sin_family
= AF_INET
;
2540 sin
.sin_len
= sizeof(sin
);
2543 te
= (struct ipfw_tblent
*)rnh
->rnh_matchaddr((char *)&sin
, rnh
);
2545 return (0); /* no match */
2548 te
->te_lastuse
= time_second
;
2549 return (1); /* match */
2553 * Transmit a TCP packet, containing either a RST or a keepalive.
2554 * When flags & TH_RST, we are sending a RST packet, because of a
2555 * "reset" action matched the packet.
2556 * Otherwise we are sending a keepalive, and flags & TH_
2558 * Only {src,dst}_{ip,port} of "id" are used.
2561 send_pkt(const struct ipfw_flow_id
*id
, uint32_t seq
, uint32_t ack
, int flags
)
2566 struct route sro
; /* fake route */
2568 MGETHDR(m
, M_NOWAIT
, MT_HEADER
);
2571 m
->m_pkthdr
.rcvif
= NULL
;
2572 m
->m_pkthdr
.len
= m
->m_len
= sizeof(struct ip
) + sizeof(struct tcphdr
);
2573 m
->m_data
+= max_linkhdr
;
2575 ip
= mtod(m
, struct ip
*);
2576 bzero(ip
, m
->m_len
);
2577 tcp
= (struct tcphdr
*)(ip
+ 1); /* no IP options */
2578 ip
->ip_p
= IPPROTO_TCP
;
2582 * Assume we are sending a RST (or a keepalive in the reverse
2583 * direction), swap src and destination addresses and ports.
2585 ip
->ip_src
.s_addr
= htonl(id
->dst_ip
);
2586 ip
->ip_dst
.s_addr
= htonl(id
->src_ip
);
2587 tcp
->th_sport
= htons(id
->dst_port
);
2588 tcp
->th_dport
= htons(id
->src_port
);
2589 if (flags
& TH_RST
) { /* we are sending a RST */
2590 if (flags
& TH_ACK
) {
2591 tcp
->th_seq
= htonl(ack
);
2592 tcp
->th_ack
= htonl(0);
2593 tcp
->th_flags
= TH_RST
;
2597 tcp
->th_seq
= htonl(0);
2598 tcp
->th_ack
= htonl(seq
);
2599 tcp
->th_flags
= TH_RST
| TH_ACK
;
2603 * We are sending a keepalive. flags & TH_SYN determines
2604 * the direction, forward if set, reverse if clear.
2605 * NOTE: seq and ack are always assumed to be correct
2606 * as set by the caller. This may be confusing...
2608 if (flags
& TH_SYN
) {
2610 * we have to rewrite the correct addresses!
2612 ip
->ip_dst
.s_addr
= htonl(id
->dst_ip
);
2613 ip
->ip_src
.s_addr
= htonl(id
->src_ip
);
2614 tcp
->th_dport
= htons(id
->dst_port
);
2615 tcp
->th_sport
= htons(id
->src_port
);
2617 tcp
->th_seq
= htonl(seq
);
2618 tcp
->th_ack
= htonl(ack
);
2619 tcp
->th_flags
= TH_ACK
;
2623 * set ip_len to the payload size so we can compute
2624 * the tcp checksum on the pseudoheader
2625 * XXX check this, could save a couple of words ?
2627 ip
->ip_len
= htons(sizeof(struct tcphdr
));
2628 tcp
->th_sum
= in_cksum(m
, m
->m_pkthdr
.len
);
2631 * now fill fields left out earlier
2633 ip
->ip_ttl
= ip_defttl
;
2634 ip
->ip_len
= m
->m_pkthdr
.len
;
2636 bzero(&sro
, sizeof(sro
));
2637 ip_rtaddr(ip
->ip_dst
, &sro
);
2639 m
->m_pkthdr
.fw_flags
|= IPFW_MBUF_GENERATED
;
2640 ip_output(m
, NULL
, &sro
, 0, NULL
, NULL
);
2646 * Send a reject message, consuming the mbuf passed as an argument.
2649 send_reject(struct ip_fw_args
*args
, int code
, int offset
, int ip_len
)
2651 if (code
!= ICMP_REJECT_RST
) { /* Send an ICMP unreach */
2652 /* We need the IP header in host order for icmp_error(). */
2653 if (args
->eh
!= NULL
) {
2654 struct ip
*ip
= mtod(args
->m
, struct ip
*);
2656 ip
->ip_len
= ntohs(ip
->ip_len
);
2657 ip
->ip_off
= ntohs(ip
->ip_off
);
2659 icmp_error(args
->m
, ICMP_UNREACH
, code
, 0L, 0);
2660 } else if (offset
== 0 && args
->f_id
.proto
== IPPROTO_TCP
) {
2661 struct tcphdr
*const tcp
=
2662 L3HDR(struct tcphdr
, mtod(args
->m
, struct ip
*));
2664 if ((tcp
->th_flags
& TH_RST
) == 0) {
2665 send_pkt(&args
->f_id
, ntohl(tcp
->th_seq
),
2666 ntohl(tcp
->th_ack
), tcp
->th_flags
| TH_RST
);
2676 * Given an ip_fw *, lookup_next_rule will return a pointer
2677 * to the next rule, which can be either the jump
2678 * target (for skipto instructions) or the next one in the list (in
2679 * all other cases including a missing jump target).
2680 * The result is also written in the "next_rule" field of the rule.
2681 * Backward jumps are not allowed, so start looking from the next
2684 * This never returns NULL -- in case we do not have an exact match,
2685 * the next rule is returned. When the ruleset is changed,
2686 * pointers are flushed so we are always correct.
2688 static struct ip_fw
*
2689 lookup_next_rule(struct ip_fw
*me
)
2691 struct ip_fw
*rule
= NULL
;
2694 /* look for action, in case it is a skipto */
2695 cmd
= ACTION_PTR(me
);
2696 if (cmd
->opcode
== O_LOG
)
2698 if (cmd
->opcode
== O_SKIPTO
) {
2699 for (rule
= me
->next
; rule
; rule
= rule
->next
) {
2700 if (rule
->rulenum
>= cmd
->arg1
)
2704 if (rule
== NULL
) /* failure or not a skipto */
2706 me
->next_rule
= rule
;
2711 ipfw_match_uid(const struct ipfw_flow_id
*fid
, struct ifnet
*oif
,
2712 enum ipfw_opcodes opcode
, uid_t uid
)
2714 struct in_addr src_ip
, dst_ip
;
2715 struct inpcbinfo
*pi
;
2719 if (fid
->proto
== IPPROTO_TCP
) {
2721 pi
= &tcbinfo
[mycpuid
];
2722 } else if (fid
->proto
== IPPROTO_UDP
) {
2724 pi
= &udbinfo
[mycpuid
];
2730 * Values in 'fid' are in host byte order
2732 dst_ip
.s_addr
= htonl(fid
->dst_ip
);
2733 src_ip
.s_addr
= htonl(fid
->src_ip
);
2735 pcb
= in_pcblookup_hash(pi
,
2736 dst_ip
, htons(fid
->dst_port
),
2737 src_ip
, htons(fid
->src_port
),
2740 pcb
= in_pcblookup_hash(pi
,
2741 src_ip
, htons(fid
->src_port
),
2742 dst_ip
, htons(fid
->dst_port
),
2745 if (pcb
== NULL
|| pcb
->inp_socket
== NULL
)
2748 if (opcode
== O_UID
) {
2749 #define socheckuid(a,b) ((a)->so_cred->cr_uid != (b))
2750 return !socheckuid(pcb
->inp_socket
, uid
);
2753 return groupmember(uid
, pcb
->inp_socket
->so_cred
);
2758 ipfw_match_ifip(ipfw_insn_ifip
*cmd
, const struct in_addr
*ip
)
2761 if (__predict_false((cmd
->o
.arg1
& IPFW_IFIP_VALID
) == 0)) {
2762 struct ifaddr_container
*ifac
;
2765 ifp
= ifunit_netisr(cmd
->ifname
);
2769 TAILQ_FOREACH(ifac
, &ifp
->if_addrheads
[mycpuid
], ifa_link
) {
2770 struct ifaddr
*ia
= ifac
->ifa
;
2772 if (ia
->ifa_addr
== NULL
)
2774 if (ia
->ifa_addr
->sa_family
!= AF_INET
)
2777 cmd
->mask
.s_addr
= INADDR_ANY
;
2778 if (cmd
->o
.arg1
& IPFW_IFIP_NET
) {
2779 cmd
->mask
= ((struct sockaddr_in
*)
2780 ia
->ifa_netmask
)->sin_addr
;
2782 if (cmd
->mask
.s_addr
== INADDR_ANY
)
2783 cmd
->mask
.s_addr
= INADDR_BROADCAST
;
2786 ((struct sockaddr_in
*)ia
->ifa_addr
)->sin_addr
;
2787 cmd
->addr
.s_addr
&= cmd
->mask
.s_addr
;
2789 cmd
->o
.arg1
|= IPFW_IFIP_VALID
;
2792 if ((cmd
->o
.arg1
& IPFW_IFIP_VALID
) == 0)
2795 return ((ip
->s_addr
& cmd
->mask
.s_addr
) == cmd
->addr
.s_addr
);
2798 static __inline
struct mbuf
*
2799 ipfw_setup_local(struct mbuf
*m
, const int hlen
, struct ip_fw_args
*args
,
2800 struct ip_fw_local
*local
, struct ip
**ip0
)
2802 struct ip
*ip
= mtod(m
, struct ip
*);
2807 * Collect parameters into local variables for faster matching.
2809 if (hlen
== 0) { /* do not grab addresses for non-ip pkts */
2810 local
->proto
= args
->f_id
.proto
= 0; /* mark f_id invalid */
2814 local
->proto
= args
->f_id
.proto
= ip
->ip_p
;
2815 local
->src_ip
= ip
->ip_src
;
2816 local
->dst_ip
= ip
->ip_dst
;
2817 if (args
->eh
!= NULL
) { /* layer 2 packets are as on the wire */
2818 local
->offset
= ntohs(ip
->ip_off
) & IP_OFFMASK
;
2819 local
->ip_len
= ntohs(ip
->ip_len
);
2821 local
->offset
= ip
->ip_off
& IP_OFFMASK
;
2822 local
->ip_len
= ip
->ip_len
;
2825 #define PULLUP_TO(len) \
2827 if (m->m_len < (len)) { \
2828 args->m = m = m_pullup(m, (len)); \
2833 ip = mtod(m, struct ip *); \
2837 if (local
->offset
== 0) {
2838 switch (local
->proto
) {
2840 PULLUP_TO(hlen
+ sizeof(struct tcphdr
));
2841 tcp
= L3HDR(struct tcphdr
, ip
);
2842 local
->dst_port
= tcp
->th_dport
;
2843 local
->src_port
= tcp
->th_sport
;
2844 args
->f_id
.flags
= tcp
->th_flags
;
2848 PULLUP_TO(hlen
+ sizeof(struct udphdr
));
2849 udp
= L3HDR(struct udphdr
, ip
);
2850 local
->dst_port
= udp
->uh_dport
;
2851 local
->src_port
= udp
->uh_sport
;
2855 PULLUP_TO(hlen
+ 4); /* type, code and checksum. */
2856 args
->f_id
.flags
= L3HDR(struct icmp
, ip
)->icmp_type
;
2866 args
->f_id
.src_ip
= ntohl(local
->src_ip
.s_addr
);
2867 args
->f_id
.dst_ip
= ntohl(local
->dst_ip
.s_addr
);
2868 args
->f_id
.src_port
= local
->src_port
= ntohs(local
->src_port
);
2869 args
->f_id
.dst_port
= local
->dst_port
= ntohs(local
->dst_port
);
2876 * The main check routine for the firewall.
2878 * All arguments are in args so we can modify them and return them
2879 * back to the caller.
2883 * args->m (in/out) The packet; we set to NULL when/if we nuke it.
2884 * Starts with the IP header.
2885 * args->eh (in) Mac header if present, or NULL for layer3 packet.
2886 * args->oif Outgoing interface, or NULL if packet is incoming.
2887 * The incoming interface is in the mbuf. (in)
2889 * args->rule Pointer to the last matching rule (in/out)
2890 * args->f_id Addresses grabbed from the packet (out)
2894 * If the packet was denied/rejected and has been dropped, *m is equal
2895 * to NULL upon return.
2897 * IP_FW_DENY the packet must be dropped.
2898 * IP_FW_PASS The packet is to be accepted and routed normally.
2899 * IP_FW_DIVERT Divert the packet to port (args->cookie)
2900 * IP_FW_TEE Tee the packet to port (args->cookie)
2901 * IP_FW_DUMMYNET Send the packet to pipe/queue (args->cookie)
2902 * IP_FW_CONTINUE Continue processing on another cpu.
2905 ipfw_chk(struct ip_fw_args
*args
)
2908 * Local variables hold state during the processing of a packet.
2910 * IMPORTANT NOTE: to speed up the processing of rules, there
2911 * are some assumption on the values of the variables, which
2912 * are documented here. Should you change them, please check
2913 * the implementation of the various instructions to make sure
2914 * that they still work.
2916 * args->eh The MAC header. It is non-null for a layer2
2917 * packet, it is NULL for a layer-3 packet.
2919 * m | args->m Pointer to the mbuf, as received from the caller.
2920 * It may change if ipfw_chk() does an m_pullup, or if it
2921 * consumes the packet because it calls send_reject().
2922 * XXX This has to change, so that ipfw_chk() never modifies
2923 * or consumes the buffer.
2924 * ip is simply an alias of the value of m, and it is kept
2925 * in sync with it (the packet is supposed to start with
2928 struct mbuf
*m
= args
->m
;
2929 struct ip
*ip
= mtod(m
, struct ip
*);
2932 * oif | args->oif If NULL, ipfw_chk has been called on the
2933 * inbound path (ether_input, ip_input).
2934 * If non-NULL, ipfw_chk has been called on the outbound path
2935 * (ether_output, ip_output).
2937 struct ifnet
*oif
= args
->oif
;
2939 struct ip_fw
*f
= NULL
; /* matching rule */
2940 int retval
= IP_FW_PASS
;
2942 struct divert_info
*divinfo
;
2945 * hlen The length of the IPv4 header.
2946 * hlen >0 means we have an IPv4 packet.
2948 u_int hlen
= 0; /* hlen >0 means we have an IP pkt */
2950 struct ip_fw_local lc
;
2953 * dyn_dir = MATCH_UNKNOWN when rules unchecked,
2954 * MATCH_NONE when checked and not matched (dyn_f = NULL),
2955 * MATCH_FORWARD or MATCH_REVERSE otherwise (dyn_f != NULL)
2957 int dyn_dir
= MATCH_UNKNOWN
;
2958 struct ip_fw
*dyn_f
= NULL
;
2959 int cpuid
= mycpuid
;
2960 struct ipfw_context
*ctx
;
2962 ASSERT_NETISR_NCPUS(cpuid
);
2963 ctx
= ipfw_ctx
[cpuid
];
2965 if (m
->m_pkthdr
.fw_flags
& IPFW_MBUF_GENERATED
)
2966 return IP_FW_PASS
; /* accept */
2968 if (args
->eh
== NULL
|| /* layer 3 packet */
2969 (m
->m_pkthdr
.len
>= sizeof(struct ip
) &&
2970 ntohs(args
->eh
->ether_type
) == ETHERTYPE_IP
))
2971 hlen
= ip
->ip_hl
<< 2;
2973 memset(&lc
, 0, sizeof(lc
));
2975 m
= ipfw_setup_local(m
, hlen
, args
, &lc
, &ip
);
2981 * Packet has already been tagged. Look for the next rule
2982 * to restart processing.
2984 * If fw_one_pass != 0 then just accept it.
2985 * XXX should not happen here, but optimized out in
2988 if (fw_one_pass
&& !args
->cont
)
2992 /* This rule is being/has been flushed */
2996 KASSERT(args
->rule
->cpuid
== cpuid
,
2997 ("rule used on cpu%d", cpuid
));
2999 /* This rule was deleted */
3000 if (args
->rule
->rule_flags
& IPFW_RULE_F_INVALID
)
3003 f
= args
->rule
->next_rule
;
3005 f
= lookup_next_rule(args
->rule
);
3008 * Find the starting rule. It can be either the first
3009 * one, or the one after divert_rule if asked so.
3013 KKASSERT(!args
->cont
);
3015 mtag
= m_tag_find(m
, PACKET_TAG_IPFW_DIVERT
, NULL
);
3017 divinfo
= m_tag_data(mtag
);
3018 skipto
= divinfo
->skipto
;
3023 f
= ctx
->ipfw_layer3_chain
;
3024 if (args
->eh
== NULL
&& skipto
!= 0) {
3025 /* No skipto during rule flushing */
3029 if (skipto
>= IPFW_DEFAULT_RULE
)
3030 return IP_FW_DENY
; /* invalid */
3032 while (f
&& f
->rulenum
<= skipto
)
3034 if (f
== NULL
) /* drop packet */
3036 } else if (ipfw_flushing
) {
3037 /* Rules are being flushed; skip to default rule */
3038 f
= ctx
->ipfw_default_rule
;
3041 if ((mtag
= m_tag_find(m
, PACKET_TAG_IPFW_DIVERT
, NULL
)) != NULL
)
3042 m_tag_delete(m
, mtag
);
3045 * Now scan the rules, and parse microinstructions for each rule.
3047 for (; f
; f
= f
->next
) {
3050 int skip_or
; /* skip rest of OR block */
3053 if (ctx
->ipfw_set_disable
& (1 << f
->set
))
3057 for (l
= f
->cmd_len
, cmd
= f
->cmd
; l
> 0;
3058 l
-= cmdlen
, cmd
+= cmdlen
) {
3062 * check_body is a jump target used when we find a
3063 * CHECK_STATE, and need to jump to the body of
3068 cmdlen
= F_LEN(cmd
);
3070 * An OR block (insn_1 || .. || insn_n) has the
3071 * F_OR bit set in all but the last instruction.
3072 * The first match will set "skip_or", and cause
3073 * the following instructions to be skipped until
3074 * past the one with the F_OR bit clear.
3076 if (skip_or
) { /* skip this instruction */
3077 if ((cmd
->len
& F_OR
) == 0)
3078 skip_or
= 0; /* next one is good */
3081 match
= 0; /* set to 1 if we succeed */
3083 switch (cmd
->opcode
) {
3085 * The first set of opcodes compares the packet's
3086 * fields with some pattern, setting 'match' if a
3087 * match is found. At the end of the loop there is
3088 * logic to deal with F_NOT and F_OR flags associated
3096 kprintf("ipfw: opcode %d unimplemented\n",
3103 * We only check offset == 0 && proto != 0,
3104 * as this ensures that we have an IPv4
3105 * packet with the ports info.
3110 match
= ipfw_match_uid(&args
->f_id
, oif
,
3112 (uid_t
)((ipfw_insn_u32
*)cmd
)->d
[0]);
3116 match
= iface_match(m
->m_pkthdr
.rcvif
,
3117 (ipfw_insn_if
*)cmd
);
3121 match
= iface_match(oif
, (ipfw_insn_if
*)cmd
);
3125 match
= iface_match(oif
? oif
:
3126 m
->m_pkthdr
.rcvif
, (ipfw_insn_if
*)cmd
);
3130 if (args
->eh
!= NULL
) { /* have MAC header */
3131 uint32_t *want
= (uint32_t *)
3132 ((ipfw_insn_mac
*)cmd
)->addr
;
3133 uint32_t *mask
= (uint32_t *)
3134 ((ipfw_insn_mac
*)cmd
)->mask
;
3135 uint32_t *hdr
= (uint32_t *)args
->eh
;
3138 (want
[0] == (hdr
[0] & mask
[0]) &&
3139 want
[1] == (hdr
[1] & mask
[1]) &&
3140 want
[2] == (hdr
[2] & mask
[2]));
3145 if (args
->eh
!= NULL
) {
3147 ntohs(args
->eh
->ether_type
);
3149 ((ipfw_insn_u16
*)cmd
)->ports
;
3152 /* Special vlan handling */
3153 if (m
->m_flags
& M_VLANTAG
)
3156 for (i
= cmdlen
- 1; !match
&& i
> 0;
3159 (t
>= p
[0] && t
<= p
[1]);
3165 match
= (hlen
> 0 && lc
.offset
!= 0);
3172 if (args
->eh
!= NULL
)
3173 off
= ntohs(ip
->ip_off
);
3176 if (off
& (IP_MF
| IP_OFFMASK
))
3181 case O_IN
: /* "out" is "not in" */
3182 match
= (oif
== NULL
);
3186 match
= (args
->eh
!= NULL
);
3191 * We do not allow an arg of 0 so the
3192 * check of "proto" only suffices.
3194 match
= (lc
.proto
== cmd
->arg1
);
3198 match
= (hlen
> 0 &&
3199 ((ipfw_insn_ip
*)cmd
)->addr
.s_addr
==
3204 match
= (hlen
> 0 &&
3205 ((ipfw_insn_ip
*)cmd
)->addr
.s_addr
==
3207 ((ipfw_insn_ip
*)cmd
)->mask
.s_addr
));
3214 tif
= INADDR_TO_IFP(&lc
.src_ip
);
3215 match
= (tif
!= NULL
);
3219 case O_IP_SRC_TABLE
:
3220 match
= ipfw_table_lookup(ctx
, cmd
->arg1
,
3225 match
= ipfw_match_ifip((ipfw_insn_ifip
*)cmd
,
3232 uint32_t *d
= (uint32_t *)(cmd
+ 1);
3234 cmd
->opcode
== O_IP_DST_SET
?
3240 addr
-= d
[0]; /* subtract base */
3242 (addr
< cmd
->arg1
) &&
3243 (d
[1 + (addr
>> 5)] &
3244 (1 << (addr
& 0x1f)));
3249 match
= (hlen
> 0 &&
3250 ((ipfw_insn_ip
*)cmd
)->addr
.s_addr
==
3255 match
= (hlen
> 0) &&
3256 (((ipfw_insn_ip
*)cmd
)->addr
.s_addr
==
3258 ((ipfw_insn_ip
*)cmd
)->mask
.s_addr
));
3265 tif
= INADDR_TO_IFP(&lc
.dst_ip
);
3266 match
= (tif
!= NULL
);
3270 case O_IP_DST_TABLE
:
3271 match
= ipfw_table_lookup(ctx
, cmd
->arg1
,
3276 match
= ipfw_match_ifip((ipfw_insn_ifip
*)cmd
,
3283 * offset == 0 && proto != 0 is enough
3284 * to guarantee that we have an IPv4
3285 * packet with port info.
3287 if ((lc
.proto
==IPPROTO_UDP
||
3288 lc
.proto
==IPPROTO_TCP
)
3289 && lc
.offset
== 0) {
3291 (cmd
->opcode
== O_IP_SRCPORT
) ?
3292 lc
.src_port
: lc
.dst_port
;
3294 ((ipfw_insn_u16
*)cmd
)->ports
;
3297 for (i
= cmdlen
- 1; !match
&& i
> 0;
3300 (x
>= p
[0] && x
<= p
[1]);
3306 match
= (lc
.offset
== 0 &&
3307 lc
.proto
==IPPROTO_ICMP
&&
3308 icmptype_match(ip
, (ipfw_insn_u32
*)cmd
));
3312 match
= (hlen
> 0 && ipopts_match(ip
, cmd
));
3316 match
= (hlen
> 0 && cmd
->arg1
== ip
->ip_v
);
3320 match
= (hlen
> 0 && cmd
->arg1
== ip
->ip_ttl
);
3324 match
= (hlen
> 0 &&
3325 cmd
->arg1
== ntohs(ip
->ip_id
));
3329 match
= (hlen
> 0 && cmd
->arg1
== lc
.ip_len
);
3332 case O_IPPRECEDENCE
:
3333 match
= (hlen
> 0 &&
3334 (cmd
->arg1
== (ip
->ip_tos
& 0xe0)));
3338 match
= (hlen
> 0 &&
3339 flags_match(cmd
, ip
->ip_tos
));
3343 match
= (lc
.proto
== IPPROTO_TCP
&&
3346 L3HDR(struct tcphdr
,ip
)->th_flags
));
3350 match
= (lc
.proto
== IPPROTO_TCP
&&
3351 lc
.offset
== 0 && tcpopts_match(ip
, cmd
));
3355 match
= (lc
.proto
== IPPROTO_TCP
&&
3357 ((ipfw_insn_u32
*)cmd
)->d
[0] ==
3358 L3HDR(struct tcphdr
,ip
)->th_seq
);
3362 match
= (lc
.proto
== IPPROTO_TCP
&&
3364 ((ipfw_insn_u32
*)cmd
)->d
[0] ==
3365 L3HDR(struct tcphdr
,ip
)->th_ack
);
3369 match
= (lc
.proto
== IPPROTO_TCP
&&
3372 L3HDR(struct tcphdr
,ip
)->th_win
);
3376 /* reject packets which have SYN only */
3377 /* XXX should i also check for TH_ACK ? */
3378 match
= (lc
.proto
== IPPROTO_TCP
&&
3380 (L3HDR(struct tcphdr
,ip
)->th_flags
&
3381 (TH_RST
| TH_ACK
| TH_SYN
)) != TH_SYN
);
3386 ipfw_log(ctx
, f
, hlen
, args
->eh
, m
,
3393 match
= (krandom() <
3394 ((ipfw_insn_u32
*)cmd
)->d
[0]);
3398 * The second set of opcodes represents 'actions',
3399 * i.e. the terminal part of a rule once the packet
3400 * matches all previous patterns.
3401 * Typically there is only one action for each rule,
3402 * and the opcode is stored at the end of the rule
3403 * (but there are exceptions -- see below).
3405 * In general, here we set retval and terminate the
3406 * outer loop (would be a 'break 3' in some language,
3407 * but we need to do a 'goto done').
3410 * O_COUNT and O_SKIPTO actions:
3411 * instead of terminating, we jump to the next rule
3412 * ('goto next_rule', equivalent to a 'break 2'),
3413 * or to the SKIPTO target ('goto again' after
3414 * having set f, cmd and l), respectively.
3416 * O_LIMIT and O_KEEP_STATE: these opcodes are
3417 * not real 'actions', and are stored right
3418 * before the 'action' part of the rule.
3419 * These opcodes try to install an entry in the
3420 * state tables; if successful, we continue with
3421 * the next opcode (match=1; break;), otherwise
3422 * the packet must be dropped ('goto done' after
3423 * setting retval). If static rules are changed
3424 * during the state installation, the packet will
3425 * be dropped and rule's stats will not beupdated
3426 * ('return IP_FW_DENY').
3428 * O_PROBE_STATE and O_CHECK_STATE: these opcodes
3429 * cause a lookup of the state table, and a jump
3430 * to the 'action' part of the parent rule
3431 * ('goto check_body') if an entry is found, or
3432 * (CHECK_STATE only) a jump to the next rule if
3433 * the entry is not found ('goto next_rule').
3434 * The result of the lookup is cached to make
3435 * further instances of these opcodes are
3436 * effectively NOPs. If static rules are changed
3437 * during the state looking up, the packet will
3438 * be dropped and rule's stats will not be updated
3439 * ('return IP_FW_DENY').
3443 if (ipfw_state_install(ctx
, f
,
3444 (ipfw_insn_limit
*)cmd
, args
,
3446 lc
.proto
== IPPROTO_TCP
) ?
3447 L3HDR(struct tcphdr
, ip
) : NULL
)) {
3448 retval
= IP_FW_DENY
;
3449 goto done
; /* error/limit violation */
3457 * States are checked at the first keep-state
3458 * check-state occurrence, with the result
3459 * being stored in dyn_dir. The compiler
3460 * introduces a PROBE_STATE instruction for
3461 * us when we have a KEEP_STATE/LIMIT (because
3462 * PROBE_STATE needs to be run first).
3464 if (dyn_dir
== MATCH_UNKNOWN
) {
3465 dyn_f
= ipfw_state_lookup_rule(ctx
,
3466 &args
->f_id
, &dyn_dir
,
3468 lc
.proto
== IPPROTO_TCP
) ?
3469 L3HDR(struct tcphdr
, ip
) : NULL
,
3471 if (dyn_f
!= NULL
) {
3473 * Found a rule from a state;
3474 * jump to the 'action' part
3478 cmd
= ACTION_PTR(f
);
3479 l
= f
->cmd_len
- f
->act_ofs
;
3484 * State not found. If CHECK_STATE, skip to
3485 * next rule, if PROBE_STATE just ignore and
3486 * continue with next opcode.
3488 if (cmd
->opcode
== O_CHECK_STATE
)
3494 retval
= IP_FW_PASS
; /* accept */
3498 if (f
->cross_rules
== NULL
) {
3500 * This rule was not completely setup;
3501 * move on to the next rule.
3507 * Don't defrag for l2 packets, output packets
3510 if (oif
!= NULL
|| args
->eh
!= NULL
||
3511 (ip
->ip_off
& (IP_MF
| IP_OFFMASK
)) == 0)
3518 retval
= IP_FW_PASS
;
3521 ctx
->ipfw_defraged
++;
3522 KASSERT((m
->m_flags
& M_HASH
) == 0,
3523 ("hash not cleared"));
3525 /* Update statistics */
3527 f
->bcnt
+= lc
.ip_len
;
3528 f
->timestamp
= time_second
;
3530 ip
= mtod(m
, struct ip
*);
3531 hlen
= ip
->ip_hl
<< 2;
3534 ip
->ip_len
= htons(ip
->ip_len
);
3535 ip
->ip_off
= htons(ip
->ip_off
);
3542 KASSERT(m
->m_flags
& M_HASH
, ("no hash"));
3543 cpuid
= netisr_hashcpu(m
->m_pkthdr
.hash
);
3544 if (cpuid
!= mycpuid
) {
3547 * ip_len/ip_off are in network byte
3550 ctx
->ipfw_defrag_remote
++;
3552 return (IP_FW_CONTINUE
);
3555 /* 'm' might be changed by ip_hashfn(). */
3556 ip
= mtod(m
, struct ip
*);
3557 ip
->ip_len
= ntohs(ip
->ip_len
);
3558 ip
->ip_off
= ntohs(ip
->ip_off
);
3560 m
= ipfw_setup_local(m
, hlen
, args
, &lc
, &ip
);
3569 args
->rule
= f
; /* report matching rule */
3570 args
->cookie
= cmd
->arg1
;
3571 retval
= IP_FW_DUMMYNET
;
3576 if (args
->eh
) /* not on layer 2 */
3579 mtag
= m_tag_get(PACKET_TAG_IPFW_DIVERT
,
3580 sizeof(*divinfo
), M_INTWAIT
| M_NULLOK
);
3582 retval
= IP_FW_DENY
;
3585 divinfo
= m_tag_data(mtag
);
3587 divinfo
->skipto
= f
->rulenum
;
3588 divinfo
->port
= cmd
->arg1
;
3589 divinfo
->tee
= (cmd
->opcode
== O_TEE
);
3590 m_tag_prepend(m
, mtag
);
3592 args
->cookie
= cmd
->arg1
;
3593 retval
= (cmd
->opcode
== O_DIVERT
) ?
3594 IP_FW_DIVERT
: IP_FW_TEE
;
3599 f
->pcnt
++; /* update stats */
3600 f
->bcnt
+= lc
.ip_len
;
3601 f
->timestamp
= time_second
;
3602 if (cmd
->opcode
== O_COUNT
)
3605 if (f
->next_rule
== NULL
)
3606 lookup_next_rule(f
);
3612 * Drop the packet and send a reject notice
3613 * if the packet is not ICMP (or is an ICMP
3614 * query), and it is not multicast/broadcast.
3617 (lc
.proto
!= IPPROTO_ICMP
||
3618 is_icmp_query(ip
)) &&
3619 !(m
->m_flags
& (M_BCAST
|M_MCAST
)) &&
3620 !IN_MULTICAST(ntohl(lc
.dst_ip
.s_addr
))) {
3621 send_reject(args
, cmd
->arg1
,
3622 lc
.offset
, lc
.ip_len
);
3623 retval
= IP_FW_DENY
;
3628 retval
= IP_FW_DENY
;
3632 if (args
->eh
) /* not valid on layer2 pkts */
3634 if (!dyn_f
|| dyn_dir
== MATCH_FORWARD
) {
3635 struct sockaddr_in
*sin
;
3637 mtag
= m_tag_get(PACKET_TAG_IPFORWARD
,
3638 sizeof(*sin
), M_INTWAIT
| M_NULLOK
);
3640 retval
= IP_FW_DENY
;
3643 sin
= m_tag_data(mtag
);
3645 /* Structure copy */
3646 *sin
= ((ipfw_insn_sa
*)cmd
)->sa
;
3648 m_tag_prepend(m
, mtag
);
3649 m
->m_pkthdr
.fw_flags
|=
3650 IPFORWARD_MBUF_TAGGED
;
3651 m
->m_pkthdr
.fw_flags
&=
3652 ~BRIDGE_MBUF_TAGGED
;
3654 retval
= IP_FW_PASS
;
3658 panic("-- unknown opcode %d", cmd
->opcode
);
3659 } /* end of switch() on opcodes */
3661 if (cmd
->len
& F_NOT
)
3665 if (cmd
->len
& F_OR
)
3668 if (!(cmd
->len
& F_OR
)) /* not an OR block, */
3669 break; /* try next rule */
3672 } /* end of inner for, scan opcodes */
3674 next_rule
:; /* try next rule */
3676 } /* end of outer for, scan rules */
3677 kprintf("+++ ipfw: ouch!, skip past end of rules, denying packet\n");
3681 /* Update statistics */
3683 f
->bcnt
+= lc
.ip_len
;
3684 f
->timestamp
= time_second
;
3689 kprintf("pullup failed\n");
3693 static struct mbuf
*
3694 ipfw_dummynet_io(struct mbuf
*m
, int pipe_nr
, int dir
, struct ip_fw_args
*fwa
)
3699 const struct ipfw_flow_id
*id
;
3700 struct dn_flow_id
*fid
;
3704 mtag
= m_tag_get(PACKET_TAG_DUMMYNET
, sizeof(*pkt
),
3705 M_INTWAIT
| M_NULLOK
);
3710 m_tag_prepend(m
, mtag
);
3712 pkt
= m_tag_data(mtag
);
3713 bzero(pkt
, sizeof(*pkt
));
3715 cmd
= fwa
->rule
->cmd
+ fwa
->rule
->act_ofs
;
3716 if (cmd
->opcode
== O_LOG
)
3718 KASSERT(cmd
->opcode
== O_PIPE
|| cmd
->opcode
== O_QUEUE
,
3719 ("Rule is not PIPE or QUEUE, opcode %d", cmd
->opcode
));
3722 pkt
->dn_flags
= (dir
& DN_FLAGS_DIR_MASK
);
3723 pkt
->ifp
= fwa
->oif
;
3724 pkt
->pipe_nr
= pipe_nr
;
3726 pkt
->cpuid
= mycpuid
;
3727 pkt
->msgport
= netisr_curport();
3731 fid
->fid_dst_ip
= id
->dst_ip
;
3732 fid
->fid_src_ip
= id
->src_ip
;
3733 fid
->fid_dst_port
= id
->dst_port
;
3734 fid
->fid_src_port
= id
->src_port
;
3735 fid
->fid_proto
= id
->proto
;
3736 fid
->fid_flags
= id
->flags
;
3738 ipfw_ref_rule(fwa
->rule
);
3739 pkt
->dn_priv
= fwa
->rule
;
3740 pkt
->dn_unref_priv
= ipfw_unref_rule
;
3742 if (cmd
->opcode
== O_PIPE
)
3743 pkt
->dn_flags
|= DN_FLAGS_IS_PIPE
;
3745 m
->m_pkthdr
.fw_flags
|= DUMMYNET_MBUF_TAGGED
;
3750 * When a rule is added/deleted, clear the next_rule pointers in all rules.
3751 * These will be reconstructed on the fly as packets are matched.
3754 ipfw_flush_rule_ptrs(struct ipfw_context
*ctx
)
3758 for (rule
= ctx
->ipfw_layer3_chain
; rule
; rule
= rule
->next
)
3759 rule
->next_rule
= NULL
;
3762 static __inline
void
3763 ipfw_inc_static_count(struct ip_fw
*rule
)
3765 /* Static rule's counts are updated only on CPU0 */
3766 KKASSERT(mycpuid
== 0);
3769 static_ioc_len
+= IOC_RULESIZE(rule
);
3772 static __inline
void
3773 ipfw_dec_static_count(struct ip_fw
*rule
)
3775 int l
= IOC_RULESIZE(rule
);
3777 /* Static rule's counts are updated only on CPU0 */
3778 KKASSERT(mycpuid
== 0);
3780 KASSERT(static_count
> 0, ("invalid static count %u", static_count
));
3783 KASSERT(static_ioc_len
>= l
,
3784 ("invalid static len %u", static_ioc_len
));
3785 static_ioc_len
-= l
;
3789 ipfw_link_sibling(struct netmsg_ipfw
*fwmsg
, struct ip_fw
*rule
)
3791 if (fwmsg
->sibling
!= NULL
) {
3792 KKASSERT(mycpuid
> 0 && fwmsg
->sibling
->cpuid
== mycpuid
- 1);
3793 fwmsg
->sibling
->sibling
= rule
;
3795 fwmsg
->sibling
= rule
;
3798 static struct ip_fw
*
3799 ipfw_create_rule(const struct ipfw_ioc_rule
*ioc_rule
, uint32_t rule_flags
)
3803 rule
= kmalloc(RULESIZE(ioc_rule
), M_IPFW
, M_WAITOK
| M_ZERO
);
3805 rule
->act_ofs
= ioc_rule
->act_ofs
;
3806 rule
->cmd_len
= ioc_rule
->cmd_len
;
3807 rule
->rulenum
= ioc_rule
->rulenum
;
3808 rule
->set
= ioc_rule
->set
;
3809 rule
->usr_flags
= ioc_rule
->usr_flags
;
3811 bcopy(ioc_rule
->cmd
, rule
->cmd
, rule
->cmd_len
* 4 /* XXX */);
3814 rule
->cpuid
= mycpuid
;
3815 rule
->rule_flags
= rule_flags
;
3821 ipfw_add_rule_dispatch(netmsg_t nmsg
)
3823 struct netmsg_ipfw
*fwmsg
= (struct netmsg_ipfw
*)nmsg
;
3824 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
3827 ASSERT_NETISR_NCPUS(mycpuid
);
3829 rule
= ipfw_create_rule(fwmsg
->ioc_rule
, fwmsg
->rule_flags
);
3832 * Insert rule into the pre-determined position
3834 if (fwmsg
->prev_rule
!= NULL
) {
3835 struct ip_fw
*prev
, *next
;
3837 prev
= fwmsg
->prev_rule
;
3838 KKASSERT(prev
->cpuid
== mycpuid
);
3840 next
= fwmsg
->next_rule
;
3841 KKASSERT(next
->cpuid
== mycpuid
);
3847 * Move to the position on the next CPU
3848 * before the msg is forwarded.
3850 fwmsg
->prev_rule
= prev
->sibling
;
3851 fwmsg
->next_rule
= next
->sibling
;
3853 KKASSERT(fwmsg
->next_rule
== NULL
);
3854 rule
->next
= ctx
->ipfw_layer3_chain
;
3855 ctx
->ipfw_layer3_chain
= rule
;
3858 /* Link rule CPU sibling */
3859 ipfw_link_sibling(fwmsg
, rule
);
3861 ipfw_flush_rule_ptrs(ctx
);
3864 /* Statistics only need to be updated once */
3865 ipfw_inc_static_count(rule
);
3867 /* Return the rule on CPU0 */
3868 nmsg
->lmsg
.u
.ms_resultp
= rule
;
3871 if (rule
->rule_flags
& IPFW_RULE_F_GENTRACK
)
3872 rule
->track_ruleid
= (uintptr_t)nmsg
->lmsg
.u
.ms_resultp
;
3874 if (fwmsg
->cross_rules
!= NULL
) {
3875 /* Save rules for later use. */
3876 fwmsg
->cross_rules
[mycpuid
] = rule
;
3879 netisr_forwardmsg(&nmsg
->base
, mycpuid
+ 1);
3883 ipfw_crossref_rule_dispatch(netmsg_t nmsg
)
3885 struct netmsg_ipfw
*fwmsg
= (struct netmsg_ipfw
*)nmsg
;
3886 struct ip_fw
*rule
= fwmsg
->sibling
;
3887 int sz
= sizeof(struct ip_fw
*) * netisr_ncpus
;
3889 ASSERT_NETISR_NCPUS(mycpuid
);
3890 KASSERT(rule
->rule_flags
& IPFW_RULE_F_CROSSREF
,
3891 ("not crossref rule"));
3893 rule
->cross_rules
= kmalloc(sz
, M_IPFW
, M_WAITOK
);
3894 memcpy(rule
->cross_rules
, fwmsg
->cross_rules
, sz
);
3896 fwmsg
->sibling
= rule
->sibling
;
3897 netisr_forwardmsg(&fwmsg
->base
, mycpuid
+ 1);
3901 * Add a new rule to the list. Copy the rule into a malloc'ed area,
3902 * then possibly create a rule number and add the rule to the list.
3903 * Update the rule_number in the input struct so the caller knows
3907 ipfw_add_rule(struct ipfw_ioc_rule
*ioc_rule
, uint32_t rule_flags
)
3909 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
3910 struct netmsg_ipfw fwmsg
;
3911 struct ip_fw
*f
, *prev
, *rule
;
3916 * If rulenum is 0, find highest numbered rule before the
3917 * default rule, and add rule number incremental step.
3919 if (ioc_rule
->rulenum
== 0) {
3920 int step
= autoinc_step
;
3922 KKASSERT(step
>= IPFW_AUTOINC_STEP_MIN
&&
3923 step
<= IPFW_AUTOINC_STEP_MAX
);
3926 * Locate the highest numbered rule before default
3928 for (f
= ctx
->ipfw_layer3_chain
; f
; f
= f
->next
) {
3929 if (f
->rulenum
== IPFW_DEFAULT_RULE
)
3931 ioc_rule
->rulenum
= f
->rulenum
;
3933 if (ioc_rule
->rulenum
< IPFW_DEFAULT_RULE
- step
)
3934 ioc_rule
->rulenum
+= step
;
3936 KASSERT(ioc_rule
->rulenum
!= IPFW_DEFAULT_RULE
&&
3937 ioc_rule
->rulenum
!= 0,
3938 ("invalid rule num %d", ioc_rule
->rulenum
));
3941 * Now find the right place for the new rule in the sorted list.
3943 for (prev
= NULL
, f
= ctx
->ipfw_layer3_chain
; f
;
3944 prev
= f
, f
= f
->next
) {
3945 if (f
->rulenum
> ioc_rule
->rulenum
) {
3946 /* Found the location */
3950 KASSERT(f
!= NULL
, ("no default rule?!"));
3953 * Duplicate the rule onto each CPU.
3954 * The rule duplicated on CPU0 will be returned.
3956 bzero(&fwmsg
, sizeof(fwmsg
));
3957 netmsg_init(&fwmsg
.base
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
3958 ipfw_add_rule_dispatch
);
3959 fwmsg
.ioc_rule
= ioc_rule
;
3960 fwmsg
.prev_rule
= prev
;
3961 fwmsg
.next_rule
= prev
== NULL
? NULL
: f
;
3962 fwmsg
.rule_flags
= rule_flags
;
3963 if (rule_flags
& IPFW_RULE_F_CROSSREF
) {
3964 fwmsg
.cross_rules
= kmalloc(
3965 sizeof(struct ip_fw
*) * netisr_ncpus
, M_TEMP
,
3969 netisr_domsg_global(&fwmsg
.base
);
3970 KKASSERT(fwmsg
.prev_rule
== NULL
&& fwmsg
.next_rule
== NULL
);
3972 rule
= fwmsg
.base
.lmsg
.u
.ms_resultp
;
3973 KKASSERT(rule
!= NULL
&& rule
->cpuid
== mycpuid
);
3975 if (fwmsg
.cross_rules
!= NULL
) {
3976 netmsg_init(&fwmsg
.base
, NULL
, &curthread
->td_msgport
,
3977 MSGF_PRIORITY
, ipfw_crossref_rule_dispatch
);
3978 fwmsg
.sibling
= rule
;
3979 netisr_domsg_global(&fwmsg
.base
);
3980 KKASSERT(fwmsg
.sibling
== NULL
);
3982 kfree(fwmsg
.cross_rules
, M_TEMP
);
3985 atomic_add_int(&ipfw_gd
.ipfw_refcnt
, 1);
3989 DPRINTF("++ installed rule %d, static count now %d\n",
3990 rule
->rulenum
, static_count
);
3994 * Free storage associated with a static rule (including derived
3996 * The caller is in charge of clearing rule pointers to avoid
3997 * dangling pointers.
3998 * @return a pointer to the next entry.
3999 * Arguments are not checked, so they better be correct.
4001 static struct ip_fw
*
4002 ipfw_delete_rule(struct ipfw_context
*ctx
,
4003 struct ip_fw
*prev
, struct ip_fw
*rule
)
4009 ctx
->ipfw_layer3_chain
= n
;
4013 /* Mark the rule as invalid */
4014 rule
->rule_flags
|= IPFW_RULE_F_INVALID
;
4015 rule
->next_rule
= NULL
;
4016 rule
->sibling
= NULL
;
4018 /* Don't reset cpuid here; keep various assertion working */
4022 /* Statistics only need to be updated once */
4024 ipfw_dec_static_count(rule
);
4026 if ((rule
->rule_flags
& IPFW_RULE_F_CROSSREF
) == 0) {
4027 /* Try to free this rule */
4028 ipfw_free_rule(rule
);
4030 /* TODO: check staging area. */
4032 rule
->next
= ipfw_gd
.ipfw_crossref_free
;
4033 ipfw_gd
.ipfw_crossref_free
= rule
;
4037 /* Return the next rule */
4042 ipfw_flush_dispatch(netmsg_t nmsg
)
4044 int kill_default
= nmsg
->lmsg
.u
.ms_result
;
4045 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
4048 ASSERT_NETISR_NCPUS(mycpuid
);
4053 ipfw_state_flush(ctx
, NULL
);
4054 KASSERT(ctx
->ipfw_state_cnt
== 0,
4055 ("%d pcpu states remain", ctx
->ipfw_state_cnt
));
4056 ctx
->ipfw_state_loosecnt
= 0;
4057 ctx
->ipfw_state_lastexp
= 0;
4062 ipfw_track_flush(ctx
, NULL
);
4063 ctx
->ipfw_track_lastexp
= 0;
4064 if (ctx
->ipfw_trkcnt_spare
!= NULL
) {
4065 kfree(ctx
->ipfw_trkcnt_spare
, M_IPFW
);
4066 ctx
->ipfw_trkcnt_spare
= NULL
;
4069 ipfw_flush_rule_ptrs(ctx
); /* more efficient to do outside the loop */
4071 while ((rule
= ctx
->ipfw_layer3_chain
) != NULL
&&
4072 (kill_default
|| rule
->rulenum
!= IPFW_DEFAULT_RULE
))
4073 ipfw_delete_rule(ctx
, NULL
, rule
);
4075 netisr_forwardmsg(&nmsg
->base
, mycpuid
+ 1);
4079 * Deletes all rules from a chain (including the default rule
4080 * if the second argument is set).
4083 ipfw_flush(int kill_default
)
4085 struct netmsg_base nmsg
;
4087 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
4094 * If 'kill_default' then caller has done the necessary
4095 * msgport syncing; unnecessary to do it again.
4097 if (!kill_default
) {
4099 * Let ipfw_chk() know the rules are going to
4100 * be flushed, so it could jump directly to
4104 /* XXX use priority sync */
4105 netmsg_service_sync();
4109 * Press the 'flush' button
4111 bzero(&nmsg
, sizeof(nmsg
));
4112 netmsg_init(&nmsg
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
4113 ipfw_flush_dispatch
);
4114 nmsg
.lmsg
.u
.ms_result
= kill_default
;
4115 netisr_domsg_global(&nmsg
);
4116 ipfw_gd
.ipfw_state_loosecnt
= 0;
4117 ipfw_gd
.ipfw_state_globexp
= 0;
4118 ipfw_gd
.ipfw_track_globexp
= 0;
4121 state_cnt
= ipfw_state_cntcoll();
4122 KASSERT(state_cnt
== 0, ("%d states remain", state_cnt
));
4124 KASSERT(ipfw_gd
.ipfw_trkcnt_cnt
== 0,
4125 ("%d trkcnts remain", ipfw_gd
.ipfw_trkcnt_cnt
));
4128 KASSERT(static_count
== 0,
4129 ("%u static rules remain", static_count
));
4130 KASSERT(static_ioc_len
== 0,
4131 ("%u bytes of static rules remain", static_ioc_len
));
4133 KASSERT(static_count
== 1,
4134 ("%u static rules remain", static_count
));
4135 KASSERT(static_ioc_len
== IOC_RULESIZE(ctx
->ipfw_default_rule
),
4136 ("%u bytes of static rules remain, should be %lu",
4138 (u_long
)IOC_RULESIZE(ctx
->ipfw_default_rule
)));
4147 ipfw_alt_delete_rule_dispatch(netmsg_t nmsg
)
4149 struct netmsg_del
*dmsg
= (struct netmsg_del
*)nmsg
;
4150 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
4151 struct ip_fw
*rule
, *prev
;
4153 ASSERT_NETISR_NCPUS(mycpuid
);
4155 rule
= dmsg
->start_rule
;
4156 KKASSERT(rule
->cpuid
== mycpuid
);
4157 dmsg
->start_rule
= rule
->sibling
;
4159 prev
= dmsg
->prev_rule
;
4161 KKASSERT(prev
->cpuid
== mycpuid
);
4164 * Move to the position on the next CPU
4165 * before the msg is forwarded.
4167 dmsg
->prev_rule
= prev
->sibling
;
4171 * flush pointers outside the loop, then delete all matching
4172 * rules. 'prev' remains the same throughout the cycle.
4174 ipfw_flush_rule_ptrs(ctx
);
4175 while (rule
&& rule
->rulenum
== dmsg
->rulenum
) {
4176 if (rule
->rule_flags
& IPFW_RULE_F_GENSTATE
) {
4177 /* Flush states generated by this rule. */
4178 ipfw_state_flush(ctx
, rule
);
4180 if (rule
->rule_flags
& IPFW_RULE_F_GENTRACK
) {
4181 /* Flush tracks generated by this rule. */
4182 ipfw_track_flush(ctx
, rule
);
4184 rule
= ipfw_delete_rule(ctx
, prev
, rule
);
4187 netisr_forwardmsg(&nmsg
->base
, mycpuid
+ 1);
4191 ipfw_alt_delete_rule(uint16_t rulenum
)
4193 struct ip_fw
*prev
, *rule
;
4194 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
4195 struct netmsg_del dmsg
;
4200 * Locate first rule to delete
4202 for (prev
= NULL
, rule
= ctx
->ipfw_layer3_chain
;
4203 rule
&& rule
->rulenum
< rulenum
;
4204 prev
= rule
, rule
= rule
->next
)
4206 if (rule
->rulenum
!= rulenum
)
4210 * Get rid of the rule duplications on all CPUs
4212 bzero(&dmsg
, sizeof(dmsg
));
4213 netmsg_init(&dmsg
.base
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
4214 ipfw_alt_delete_rule_dispatch
);
4215 dmsg
.prev_rule
= prev
;
4216 dmsg
.start_rule
= rule
;
4217 dmsg
.rulenum
= rulenum
;
4219 netisr_domsg_global(&dmsg
.base
);
4220 KKASSERT(dmsg
.prev_rule
== NULL
&& dmsg
.start_rule
== NULL
);
4225 ipfw_alt_delete_ruleset_dispatch(netmsg_t nmsg
)
4227 struct netmsg_del
*dmsg
= (struct netmsg_del
*)nmsg
;
4228 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
4229 struct ip_fw
*prev
, *rule
;
4234 ASSERT_NETISR_NCPUS(mycpuid
);
4236 ipfw_flush_rule_ptrs(ctx
);
4239 rule
= ctx
->ipfw_layer3_chain
;
4240 while (rule
!= NULL
) {
4241 if (rule
->set
== dmsg
->from_set
) {
4242 if (rule
->rule_flags
& IPFW_RULE_F_GENSTATE
) {
4243 /* Flush states generated by this rule. */
4244 ipfw_state_flush(ctx
, rule
);
4246 if (rule
->rule_flags
& IPFW_RULE_F_GENTRACK
) {
4247 /* Flush tracks generated by this rule. */
4248 ipfw_track_flush(ctx
, rule
);
4250 rule
= ipfw_delete_rule(ctx
, prev
, rule
);
4259 KASSERT(del
, ("no match set?!"));
4261 netisr_forwardmsg(&nmsg
->base
, mycpuid
+ 1);
4265 ipfw_alt_delete_ruleset(uint8_t set
)
4267 struct netmsg_del dmsg
;
4270 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
4275 * Check whether the 'set' exists. If it exists,
4276 * then check whether any rules within the set will
4277 * try to create states.
4280 for (rule
= ctx
->ipfw_layer3_chain
; rule
; rule
= rule
->next
) {
4281 if (rule
->set
== set
)
4285 return 0; /* XXX EINVAL? */
4290 bzero(&dmsg
, sizeof(dmsg
));
4291 netmsg_init(&dmsg
.base
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
4292 ipfw_alt_delete_ruleset_dispatch
);
4293 dmsg
.from_set
= set
;
4294 netisr_domsg_global(&dmsg
.base
);
4300 ipfw_alt_move_rule_dispatch(netmsg_t nmsg
)
4302 struct netmsg_del
*dmsg
= (struct netmsg_del
*)nmsg
;
4305 ASSERT_NETISR_NCPUS(mycpuid
);
4307 rule
= dmsg
->start_rule
;
4308 KKASSERT(rule
->cpuid
== mycpuid
);
4311 * Move to the position on the next CPU
4312 * before the msg is forwarded.
4314 dmsg
->start_rule
= rule
->sibling
;
4316 while (rule
&& rule
->rulenum
<= dmsg
->rulenum
) {
4317 if (rule
->rulenum
== dmsg
->rulenum
)
4318 rule
->set
= dmsg
->to_set
;
4321 netisr_forwardmsg(&nmsg
->base
, mycpuid
+ 1);
4325 ipfw_alt_move_rule(uint16_t rulenum
, uint8_t set
)
4327 struct netmsg_del dmsg
;
4328 struct netmsg_base
*nmsg
;
4330 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
4335 * Locate first rule to move
4337 for (rule
= ctx
->ipfw_layer3_chain
; rule
&& rule
->rulenum
<= rulenum
;
4338 rule
= rule
->next
) {
4339 if (rule
->rulenum
== rulenum
&& rule
->set
!= set
)
4342 if (rule
== NULL
|| rule
->rulenum
> rulenum
)
4343 return 0; /* XXX error? */
4345 bzero(&dmsg
, sizeof(dmsg
));
4347 netmsg_init(nmsg
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
4348 ipfw_alt_move_rule_dispatch
);
4349 dmsg
.start_rule
= rule
;
4350 dmsg
.rulenum
= rulenum
;
4353 netisr_domsg_global(nmsg
);
4354 KKASSERT(dmsg
.start_rule
== NULL
);
4359 ipfw_alt_move_ruleset_dispatch(netmsg_t nmsg
)
4361 struct netmsg_del
*dmsg
= (struct netmsg_del
*)nmsg
;
4362 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
4365 ASSERT_NETISR_NCPUS(mycpuid
);
4367 for (rule
= ctx
->ipfw_layer3_chain
; rule
; rule
= rule
->next
) {
4368 if (rule
->set
== dmsg
->from_set
)
4369 rule
->set
= dmsg
->to_set
;
4371 netisr_forwardmsg(&nmsg
->base
, mycpuid
+ 1);
4375 ipfw_alt_move_ruleset(uint8_t from_set
, uint8_t to_set
)
4377 struct netmsg_del dmsg
;
4378 struct netmsg_base
*nmsg
;
4382 bzero(&dmsg
, sizeof(dmsg
));
4384 netmsg_init(nmsg
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
4385 ipfw_alt_move_ruleset_dispatch
);
4386 dmsg
.from_set
= from_set
;
4387 dmsg
.to_set
= to_set
;
4389 netisr_domsg_global(nmsg
);
4394 ipfw_alt_swap_ruleset_dispatch(netmsg_t nmsg
)
4396 struct netmsg_del
*dmsg
= (struct netmsg_del
*)nmsg
;
4397 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
4400 ASSERT_NETISR_NCPUS(mycpuid
);
4402 for (rule
= ctx
->ipfw_layer3_chain
; rule
; rule
= rule
->next
) {
4403 if (rule
->set
== dmsg
->from_set
)
4404 rule
->set
= dmsg
->to_set
;
4405 else if (rule
->set
== dmsg
->to_set
)
4406 rule
->set
= dmsg
->from_set
;
4408 netisr_forwardmsg(&nmsg
->base
, mycpuid
+ 1);
4412 ipfw_alt_swap_ruleset(uint8_t set1
, uint8_t set2
)
4414 struct netmsg_del dmsg
;
4415 struct netmsg_base
*nmsg
;
4419 bzero(&dmsg
, sizeof(dmsg
));
4421 netmsg_init(nmsg
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
4422 ipfw_alt_swap_ruleset_dispatch
);
4423 dmsg
.from_set
= set1
;
4426 netisr_domsg_global(nmsg
);
4431 * Remove all rules with given number, and also do set manipulation.
4433 * The argument is an uint32_t. The low 16 bit are the rule or set number,
4434 * the next 8 bits are the new set, the top 8 bits are the command:
4436 * 0 delete rules with given number
4437 * 1 delete rules with given set number
4438 * 2 move rules with given number to new set
4439 * 3 move rules with given set number to new set
4440 * 4 swap sets with given numbers
4443 ipfw_ctl_alter(uint32_t arg
)
4446 uint8_t cmd
, new_set
;
4451 rulenum
= arg
& 0xffff;
4452 cmd
= (arg
>> 24) & 0xff;
4453 new_set
= (arg
>> 16) & 0xff;
4457 if (new_set
>= IPFW_DEFAULT_SET
)
4459 if (cmd
== 0 || cmd
== 2) {
4460 if (rulenum
== IPFW_DEFAULT_RULE
)
4463 if (rulenum
>= IPFW_DEFAULT_SET
)
4468 case 0: /* delete rules with given number */
4469 error
= ipfw_alt_delete_rule(rulenum
);
4472 case 1: /* delete all rules with given set number */
4473 error
= ipfw_alt_delete_ruleset(rulenum
);
4476 case 2: /* move rules with given number to new set */
4477 error
= ipfw_alt_move_rule(rulenum
, new_set
);
4480 case 3: /* move rules with given set number to new set */
4481 error
= ipfw_alt_move_ruleset(rulenum
, new_set
);
4484 case 4: /* swap two sets */
4485 error
= ipfw_alt_swap_ruleset(rulenum
, new_set
);
4492 * Clear counters for a specific rule.
4495 clear_counters(struct ip_fw
*rule
, int log_only
)
4497 ipfw_insn_log
*l
= (ipfw_insn_log
*)ACTION_PTR(rule
);
4499 if (log_only
== 0) {
4500 rule
->bcnt
= rule
->pcnt
= 0;
4501 rule
->timestamp
= 0;
4503 if (l
->o
.opcode
== O_LOG
)
4504 l
->log_left
= l
->max_log
;
4508 ipfw_zero_entry_dispatch(netmsg_t nmsg
)
4510 struct netmsg_zent
*zmsg
= (struct netmsg_zent
*)nmsg
;
4511 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
4514 ASSERT_NETISR_NCPUS(mycpuid
);
4516 if (zmsg
->rulenum
== 0) {
4517 KKASSERT(zmsg
->start_rule
== NULL
);
4519 ctx
->ipfw_norule_counter
= 0;
4520 for (rule
= ctx
->ipfw_layer3_chain
; rule
; rule
= rule
->next
)
4521 clear_counters(rule
, zmsg
->log_only
);
4523 struct ip_fw
*start
= zmsg
->start_rule
;
4525 KKASSERT(start
->cpuid
== mycpuid
);
4526 KKASSERT(start
->rulenum
== zmsg
->rulenum
);
4529 * We can have multiple rules with the same number, so we
4530 * need to clear them all.
4532 for (rule
= start
; rule
&& rule
->rulenum
== zmsg
->rulenum
;
4534 clear_counters(rule
, zmsg
->log_only
);
4537 * Move to the position on the next CPU
4538 * before the msg is forwarded.
4540 zmsg
->start_rule
= start
->sibling
;
4542 netisr_forwardmsg(&nmsg
->base
, mycpuid
+ 1);
4546 * Reset some or all counters on firewall rules.
4547 * @arg frwl is null to clear all entries, or contains a specific
4549 * @arg log_only is 1 if we only want to reset logs, zero otherwise.
4552 ipfw_ctl_zero_entry(int rulenum
, int log_only
)
4554 struct netmsg_zent zmsg
;
4555 struct netmsg_base
*nmsg
;
4557 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
4561 bzero(&zmsg
, sizeof(zmsg
));
4563 netmsg_init(nmsg
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
4564 ipfw_zero_entry_dispatch
);
4565 zmsg
.log_only
= log_only
;
4568 msg
= log_only
? "ipfw: All logging counts reset.\n"
4569 : "ipfw: Accounting cleared.\n";
4574 * Locate the first rule with 'rulenum'
4576 for (rule
= ctx
->ipfw_layer3_chain
; rule
; rule
= rule
->next
) {
4577 if (rule
->rulenum
== rulenum
)
4580 if (rule
== NULL
) /* we did not find any matching rules */
4582 zmsg
.start_rule
= rule
;
4583 zmsg
.rulenum
= rulenum
;
4585 msg
= log_only
? "ipfw: Entry %d logging count reset.\n"
4586 : "ipfw: Entry %d cleared.\n";
4588 netisr_domsg_global(nmsg
);
4589 KKASSERT(zmsg
.start_rule
== NULL
);
4592 log(LOG_SECURITY
| LOG_NOTICE
, msg
, rulenum
);
4597 * Check validity of the structure before insert.
4598 * Fortunately rules are simple, so this mostly need to check rule sizes.
4601 ipfw_check_ioc_rule(struct ipfw_ioc_rule
*rule
, int size
, uint32_t *rule_flags
)
4604 int have_action
= 0;
4609 /* Check for valid size */
4610 if (size
< sizeof(*rule
)) {
4611 kprintf("ipfw: rule too short\n");
4614 l
= IOC_RULESIZE(rule
);
4616 kprintf("ipfw: size mismatch (have %d want %d)\n", size
, l
);
4620 /* Check rule number */
4621 if (rule
->rulenum
== IPFW_DEFAULT_RULE
) {
4622 kprintf("ipfw: invalid rule number\n");
4627 * Now go for the individual checks. Very simple ones, basically only
4628 * instruction sizes.
4630 for (l
= rule
->cmd_len
, cmd
= rule
->cmd
; l
> 0;
4631 l
-= cmdlen
, cmd
+= cmdlen
) {
4632 cmdlen
= F_LEN(cmd
);
4634 kprintf("ipfw: opcode %d size truncated\n",
4639 DPRINTF("ipfw: opcode %d\n", cmd
->opcode
);
4641 if (cmd
->opcode
== O_KEEP_STATE
|| cmd
->opcode
== O_LIMIT
) {
4642 /* This rule will generate states. */
4643 *rule_flags
|= IPFW_RULE_F_GENSTATE
;
4644 if (cmd
->opcode
== O_LIMIT
)
4645 *rule_flags
|= IPFW_RULE_F_GENTRACK
;
4647 if (cmd
->opcode
== O_DEFRAG
)
4648 *rule_flags
|= IPFW_RULE_F_CROSSREF
;
4649 if (cmd
->opcode
== O_IP_SRC_IFIP
||
4650 cmd
->opcode
== O_IP_DST_IFIP
) {
4651 *rule_flags
|= IPFW_RULE_F_DYNIFADDR
;
4652 cmd
->arg1
&= IPFW_IFIP_SETTINGS
;
4655 switch (cmd
->opcode
) {
4670 case O_IPPRECEDENCE
:
4677 if (cmdlen
!= F_INSN_SIZE(ipfw_insn
))
4681 case O_IP_SRC_TABLE
:
4682 case O_IP_DST_TABLE
:
4683 if (cmdlen
!= F_INSN_SIZE(ipfw_insn
))
4685 if (cmd
->arg1
>= ipfw_table_max
) {
4686 kprintf("ipfw: invalid table id %u, max %d\n",
4687 cmd
->arg1
, ipfw_table_max
);
4694 if (cmdlen
!= F_INSN_SIZE(ipfw_insn_ifip
))
4706 if (cmdlen
!= F_INSN_SIZE(ipfw_insn_u32
))
4711 if (cmdlen
!= F_INSN_SIZE(ipfw_insn_limit
))
4716 if (cmdlen
!= F_INSN_SIZE(ipfw_insn_log
))
4719 ((ipfw_insn_log
*)cmd
)->log_left
=
4720 ((ipfw_insn_log
*)cmd
)->max_log
;
4726 if (cmdlen
!= F_INSN_SIZE(ipfw_insn_ip
))
4728 if (((ipfw_insn_ip
*)cmd
)->mask
.s_addr
== 0) {
4729 kprintf("ipfw: opcode %d, useless rule\n",
4737 if (cmd
->arg1
== 0 || cmd
->arg1
> 256) {
4738 kprintf("ipfw: invalid set size %d\n",
4742 if (cmdlen
!= F_INSN_SIZE(ipfw_insn_u32
) +
4748 if (cmdlen
!= F_INSN_SIZE(ipfw_insn_mac
))
4754 case O_IP_DSTPORT
: /* XXX artificial limit, 30 port pairs */
4755 if (cmdlen
< 2 || cmdlen
> 31)
4762 if (cmdlen
!= F_INSN_SIZE(ipfw_insn_if
))
4768 if (cmdlen
!= F_INSN_SIZE(ipfw_insn_pipe
))
4773 if (cmdlen
!= F_INSN_SIZE(ipfw_insn_sa
)) {
4778 fwd_addr
= ((ipfw_insn_sa
*)cmd
)->
4780 if (IN_MULTICAST(ntohl(fwd_addr
))) {
4781 kprintf("ipfw: try forwarding to "
4782 "multicast address\n");
4788 case O_FORWARD_MAC
: /* XXX not implemented yet */
4798 if (cmdlen
!= F_INSN_SIZE(ipfw_insn
))
4802 kprintf("ipfw: opcode %d, multiple actions"
4809 kprintf("ipfw: opcode %d, action must be"
4816 kprintf("ipfw: opcode %d, unknown opcode\n",
4821 if (have_action
== 0) {
4822 kprintf("ipfw: missing action\n");
4828 kprintf("ipfw: opcode %d size %d wrong\n",
4829 cmd
->opcode
, cmdlen
);
4834 ipfw_ctl_add_rule(struct sockopt
*sopt
)
4836 struct ipfw_ioc_rule
*ioc_rule
;
4838 uint32_t rule_flags
;
4843 size
= sopt
->sopt_valsize
;
4844 if (size
> (sizeof(uint32_t) * IPFW_RULE_SIZE_MAX
) ||
4845 size
< sizeof(*ioc_rule
)) {
4848 if (size
!= (sizeof(uint32_t) * IPFW_RULE_SIZE_MAX
)) {
4849 sopt
->sopt_val
= krealloc(sopt
->sopt_val
, sizeof(uint32_t) *
4850 IPFW_RULE_SIZE_MAX
, M_TEMP
, M_WAITOK
);
4852 ioc_rule
= sopt
->sopt_val
;
4854 error
= ipfw_check_ioc_rule(ioc_rule
, size
, &rule_flags
);
4858 ipfw_add_rule(ioc_rule
, rule_flags
);
4860 if (sopt
->sopt_dir
== SOPT_GET
)
4861 sopt
->sopt_valsize
= IOC_RULESIZE(ioc_rule
);
4866 ipfw_copy_rule(const struct ipfw_context
*ctx
, const struct ip_fw
*rule
,
4867 struct ipfw_ioc_rule
*ioc_rule
)
4869 const struct ip_fw
*sibling
;
4875 KASSERT(rule
->cpuid
== 0, ("rule does not belong to cpu0"));
4877 ioc_rule
->act_ofs
= rule
->act_ofs
;
4878 ioc_rule
->cmd_len
= rule
->cmd_len
;
4879 ioc_rule
->rulenum
= rule
->rulenum
;
4880 ioc_rule
->set
= rule
->set
;
4881 ioc_rule
->usr_flags
= rule
->usr_flags
;
4883 ioc_rule
->set_disable
= ctx
->ipfw_set_disable
;
4884 ioc_rule
->static_count
= static_count
;
4885 ioc_rule
->static_len
= static_ioc_len
;
4888 * Visit (read-only) all of the rule's duplications to get
4889 * the necessary statistics
4896 ioc_rule
->timestamp
= 0;
4897 for (sibling
= rule
; sibling
!= NULL
; sibling
= sibling
->sibling
) {
4898 ioc_rule
->pcnt
+= sibling
->pcnt
;
4899 ioc_rule
->bcnt
+= sibling
->bcnt
;
4900 if (sibling
->timestamp
> ioc_rule
->timestamp
)
4901 ioc_rule
->timestamp
= sibling
->timestamp
;
4906 KASSERT(i
== netisr_ncpus
,
4907 ("static rule is not duplicated on netisr_ncpus %d", netisr_ncpus
));
4909 bcopy(rule
->cmd
, ioc_rule
->cmd
, ioc_rule
->cmd_len
* 4 /* XXX */);
4911 return ((uint8_t *)ioc_rule
+ IOC_RULESIZE(ioc_rule
));
4915 ipfw_track_copy(const struct ipfw_trkcnt
*trk
, struct ipfw_ioc_state
*ioc_state
)
4917 struct ipfw_ioc_flowid
*ioc_id
;
4919 if (trk
->tc_expire
== 0) {
4920 /* Not a scanned one. */
4924 ioc_state
->expire
= TIME_LEQ(trk
->tc_expire
, time_uptime
) ?
4925 0 : trk
->tc_expire
- time_uptime
;
4926 ioc_state
->pcnt
= 0;
4927 ioc_state
->bcnt
= 0;
4929 ioc_state
->dyn_type
= O_LIMIT_PARENT
;
4930 ioc_state
->count
= trk
->tc_count
;
4932 ioc_state
->rulenum
= trk
->tc_rulenum
;
4934 ioc_id
= &ioc_state
->id
;
4935 ioc_id
->type
= ETHERTYPE_IP
;
4936 ioc_id
->u
.ip
.proto
= trk
->tc_proto
;
4937 ioc_id
->u
.ip
.src_ip
= trk
->tc_saddr
;
4938 ioc_id
->u
.ip
.dst_ip
= trk
->tc_daddr
;
4939 ioc_id
->u
.ip
.src_port
= trk
->tc_sport
;
4940 ioc_id
->u
.ip
.dst_port
= trk
->tc_dport
;
4946 ipfw_state_copy(const struct ipfw_state
*s
, struct ipfw_ioc_state
*ioc_state
)
4948 struct ipfw_ioc_flowid
*ioc_id
;
4950 if (s
->st_type
== O_ANCHOR
)
4953 ioc_state
->expire
= TIME_LEQ(s
->st_expire
, time_uptime
) ?
4954 0 : s
->st_expire
- time_uptime
;
4955 ioc_state
->pcnt
= s
->st_pcnt
;
4956 ioc_state
->bcnt
= s
->st_bcnt
;
4958 ioc_state
->dyn_type
= s
->st_type
;
4959 ioc_state
->count
= 0;
4961 ioc_state
->rulenum
= s
->st_rule
->rulenum
;
4963 ioc_id
= &ioc_state
->id
;
4964 ioc_id
->type
= ETHERTYPE_IP
;
4965 ioc_id
->u
.ip
.proto
= s
->st_proto
;
4966 ipfw_key_4tuple(&s
->st_key
,
4967 &ioc_id
->u
.ip
.src_ip
, &ioc_id
->u
.ip
.src_port
,
4968 &ioc_id
->u
.ip
.dst_ip
, &ioc_id
->u
.ip
.dst_port
);
4974 ipfw_state_copy_dispatch(netmsg_t nmsg
)
4976 struct netmsg_cpstate
*nm
= (struct netmsg_cpstate
*)nmsg
;
4977 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
4978 const struct ipfw_state
*s
;
4979 const struct ipfw_track
*t
;
4981 ASSERT_NETISR_NCPUS(mycpuid
);
4982 KASSERT(nm
->state_cnt
< nm
->state_cntmax
,
4983 ("invalid state count %d, max %d",
4984 nm
->state_cnt
, nm
->state_cntmax
));
4986 TAILQ_FOREACH(s
, &ctx
->ipfw_state_list
, st_link
) {
4987 if (ipfw_state_copy(s
, nm
->ioc_state
)) {
4990 if (nm
->state_cnt
== nm
->state_cntmax
)
4996 * Prepare tracks in the global track tree for userland.
4998 TAILQ_FOREACH(t
, &ctx
->ipfw_track_list
, t_link
) {
4999 struct ipfw_trkcnt
*trk
;
5001 if (t
->t_count
== NULL
) /* anchor */
5006 * Only one netisr can run this function at
5007 * any time, and only this function accesses
5008 * trkcnt's tc_expire, so this is safe w/o
5009 * ipfw_gd.ipfw_trkcnt_token.
5011 if (trk
->tc_expire
> t
->t_expire
)
5013 trk
->tc_expire
= t
->t_expire
;
5017 * Copy tracks in the global track tree to userland in
5020 if (mycpuid
== netisr_ncpus
- 1) {
5021 struct ipfw_trkcnt
*trk
;
5023 KASSERT(nm
->state_cnt
< nm
->state_cntmax
,
5024 ("invalid state count %d, max %d",
5025 nm
->state_cnt
, nm
->state_cntmax
));
5028 RB_FOREACH(trk
, ipfw_trkcnt_tree
, &ipfw_gd
.ipfw_trkcnt_tree
) {
5029 if (ipfw_track_copy(trk
, nm
->ioc_state
)) {
5032 if (nm
->state_cnt
== nm
->state_cntmax
) {
5041 if (nm
->state_cnt
== nm
->state_cntmax
) {
5042 /* No more space; done. */
5043 netisr_replymsg(&nm
->base
, 0);
5045 netisr_forwardmsg(&nm
->base
, mycpuid
+ 1);
5050 ipfw_ctl_get_rules(struct sockopt
*sopt
)
5052 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
5061 * pass up a copy of the current rules. Static rules
5062 * come first (the last of which has number IPFW_DEFAULT_RULE),
5063 * followed by a possibly empty list of states.
5066 size
= static_ioc_len
; /* size of static rules */
5069 * Size of the states.
5070 * XXX take tracks as state for userland compat.
5072 state_cnt
= ipfw_state_cntcoll() + ipfw_gd
.ipfw_trkcnt_cnt
;
5073 state_cnt
= (state_cnt
* 5) / 4; /* leave 25% headroom */
5074 size
+= state_cnt
* sizeof(struct ipfw_ioc_state
);
5076 if (sopt
->sopt_valsize
< size
) {
5077 /* short length, no need to return incomplete rules */
5078 /* XXX: if superuser, no need to zero buffer */
5079 bzero(sopt
->sopt_val
, sopt
->sopt_valsize
);
5082 bp
= sopt
->sopt_val
;
5084 for (rule
= ctx
->ipfw_layer3_chain
; rule
; rule
= rule
->next
)
5085 bp
= ipfw_copy_rule(ctx
, rule
, bp
);
5088 struct netmsg_cpstate nm
;
5090 size_t old_size
= size
;
5093 netmsg_init(&nm
.base
, NULL
, &curthread
->td_msgport
,
5094 MSGF_PRIORITY
, ipfw_state_copy_dispatch
);
5096 nm
.state_cntmax
= state_cnt
;
5098 netisr_domsg_global(&nm
.base
);
5101 * The # of states may be shrinked after the snapshot
5102 * of the state count was taken. To give user a correct
5103 * state count, nm->state_cnt is used to recalculate
5106 size
= static_ioc_len
+
5107 (nm
.state_cnt
* sizeof(struct ipfw_ioc_state
));
5108 KKASSERT(size
<= old_size
);
5111 sopt
->sopt_valsize
= size
;
5116 ipfw_set_disable_dispatch(netmsg_t nmsg
)
5118 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
5120 ASSERT_NETISR_NCPUS(mycpuid
);
5122 ctx
->ipfw_set_disable
= nmsg
->lmsg
.u
.ms_result32
;
5123 netisr_forwardmsg(&nmsg
->base
, mycpuid
+ 1);
5127 ipfw_ctl_set_disable(uint32_t disable
, uint32_t enable
)
5129 struct netmsg_base nmsg
;
5130 uint32_t set_disable
;
5134 /* IPFW_DEFAULT_SET is always enabled */
5135 enable
|= (1 << IPFW_DEFAULT_SET
);
5136 set_disable
= (ipfw_ctx
[mycpuid
]->ipfw_set_disable
| disable
) & ~enable
;
5138 bzero(&nmsg
, sizeof(nmsg
));
5139 netmsg_init(&nmsg
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
5140 ipfw_set_disable_dispatch
);
5141 nmsg
.lmsg
.u
.ms_result32
= set_disable
;
5143 netisr_domsg_global(&nmsg
);
5147 ipfw_table_create_dispatch(netmsg_t nm
)
5149 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
5150 int tblid
= nm
->lmsg
.u
.ms_result
;
5152 ASSERT_NETISR_NCPUS(mycpuid
);
5154 if (!rn_inithead((void **)&ctx
->ipfw_tables
[tblid
],
5155 rn_cpumaskhead(mycpuid
), 32))
5156 panic("ipfw: create table%d failed", tblid
);
5158 netisr_forwardmsg(&nm
->base
, mycpuid
+ 1);
5162 ipfw_table_create(struct sockopt
*sopt
)
5164 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
5165 struct ipfw_ioc_table
*tbl
;
5166 struct netmsg_base nm
;
5170 if (sopt
->sopt_valsize
!= sizeof(*tbl
))
5173 tbl
= sopt
->sopt_val
;
5174 if (tbl
->tableid
< 0 || tbl
->tableid
>= ipfw_table_max
)
5177 if (ctx
->ipfw_tables
[tbl
->tableid
] != NULL
)
5180 netmsg_init(&nm
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
5181 ipfw_table_create_dispatch
);
5182 nm
.lmsg
.u
.ms_result
= tbl
->tableid
;
5183 netisr_domsg_global(&nm
);
5189 ipfw_table_killrn(struct radix_node_head
*rnh
, struct radix_node
*rn
)
5191 struct radix_node
*ret
;
5193 ret
= rnh
->rnh_deladdr(rn
->rn_key
, rn
->rn_mask
, rnh
);
5195 panic("deleted other table entry");
5200 ipfw_table_killent(struct radix_node
*rn
, void *xrnh
)
5203 ipfw_table_killrn(xrnh
, rn
);
5208 ipfw_table_flush_oncpu(struct ipfw_context
*ctx
, int tableid
,
5211 struct radix_node_head
*rnh
;
5213 ASSERT_NETISR_NCPUS(mycpuid
);
5215 rnh
= ctx
->ipfw_tables
[tableid
];
5216 rnh
->rnh_walktree(rnh
, ipfw_table_killent
, rnh
);
5219 ctx
->ipfw_tables
[tableid
] = NULL
;
5224 ipfw_table_flush_dispatch(netmsg_t nmsg
)
5226 struct netmsg_tblflush
*nm
= (struct netmsg_tblflush
*)nmsg
;
5227 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
5229 ASSERT_NETISR_NCPUS(mycpuid
);
5231 ipfw_table_flush_oncpu(ctx
, nm
->tableid
, nm
->destroy
);
5232 netisr_forwardmsg(&nm
->base
, mycpuid
+ 1);
5236 ipfw_table_flushall_oncpu(struct ipfw_context
*ctx
, int destroy
)
5240 ASSERT_NETISR_NCPUS(mycpuid
);
5242 for (i
= 0; i
< ipfw_table_max
; ++i
) {
5243 if (ctx
->ipfw_tables
[i
] != NULL
)
5244 ipfw_table_flush_oncpu(ctx
, i
, destroy
);
5249 ipfw_table_flushall_dispatch(netmsg_t nmsg
)
5251 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
5253 ASSERT_NETISR_NCPUS(mycpuid
);
5255 ipfw_table_flushall_oncpu(ctx
, 0);
5256 netisr_forwardmsg(&nmsg
->base
, mycpuid
+ 1);
5260 ipfw_table_flush(struct sockopt
*sopt
)
5262 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
5263 struct ipfw_ioc_table
*tbl
;
5264 struct netmsg_tblflush nm
;
5268 if (sopt
->sopt_valsize
!= sizeof(*tbl
))
5271 tbl
= sopt
->sopt_val
;
5272 if (sopt
->sopt_name
== IP_FW_TBL_FLUSH
&& tbl
->tableid
< 0) {
5273 netmsg_init(&nm
.base
, NULL
, &curthread
->td_msgport
,
5274 MSGF_PRIORITY
, ipfw_table_flushall_dispatch
);
5275 netisr_domsg_global(&nm
.base
);
5279 if (tbl
->tableid
< 0 || tbl
->tableid
>= ipfw_table_max
)
5282 if (ctx
->ipfw_tables
[tbl
->tableid
] == NULL
)
5285 netmsg_init(&nm
.base
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
5286 ipfw_table_flush_dispatch
);
5287 nm
.tableid
= tbl
->tableid
;
5289 if (sopt
->sopt_name
== IP_FW_TBL_DESTROY
)
5291 netisr_domsg_global(&nm
.base
);
5297 ipfw_table_cntent(struct radix_node
*rn __unused
, void *xcnt
)
5306 ipfw_table_cpent(struct radix_node
*rn
, void *xcp
)
5308 struct ipfw_table_cp
*cp
= xcp
;
5309 struct ipfw_tblent
*te
= (struct ipfw_tblent
*)rn
;
5310 struct ipfw_ioc_tblent
*ioc_te
;
5315 KASSERT(cp
->te_idx
< cp
->te_cnt
, ("invalid table cp idx %d, cnt %d",
5316 cp
->te_idx
, cp
->te_cnt
));
5317 ioc_te
= &cp
->te
[cp
->te_idx
];
5319 if (te
->te_nodes
->rn_mask
!= NULL
) {
5320 memcpy(&ioc_te
->netmask
, te
->te_nodes
->rn_mask
,
5321 *te
->te_nodes
->rn_mask
);
5323 ioc_te
->netmask
.sin_len
= 0;
5325 memcpy(&ioc_te
->key
, &te
->te_key
, sizeof(ioc_te
->key
));
5327 ioc_te
->use
= te
->te_use
;
5328 ioc_te
->last_used
= te
->te_lastuse
;
5333 while ((te
= te
->te_sibling
) != NULL
) {
5337 ioc_te
->use
+= te
->te_use
;
5338 if (te
->te_lastuse
> ioc_te
->last_used
)
5339 ioc_te
->last_used
= te
->te_lastuse
;
5341 KASSERT(cnt
== netisr_ncpus
,
5342 ("invalid # of tblent %d, should be %d", cnt
, netisr_ncpus
));
5350 ipfw_table_get(struct sockopt
*sopt
)
5352 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
5353 struct radix_node_head
*rnh
;
5354 struct ipfw_ioc_table
*tbl
;
5355 struct ipfw_ioc_tblcont
*cont
;
5356 struct ipfw_table_cp cp
;
5361 if (sopt
->sopt_valsize
< sizeof(*tbl
))
5364 tbl
= sopt
->sopt_val
;
5365 if (tbl
->tableid
< 0) {
5366 struct ipfw_ioc_tbllist
*list
;
5370 * List available table ids.
5372 for (i
= 0; i
< ipfw_table_max
; ++i
) {
5373 if (ctx
->ipfw_tables
[i
] != NULL
)
5377 sz
= __offsetof(struct ipfw_ioc_tbllist
, tables
[cnt
]);
5378 if (sopt
->sopt_valsize
< sz
) {
5379 bzero(sopt
->sopt_val
, sopt
->sopt_valsize
);
5382 list
= sopt
->sopt_val
;
5383 list
->tablecnt
= cnt
;
5386 for (i
= 0; i
< ipfw_table_max
; ++i
) {
5387 if (ctx
->ipfw_tables
[i
] != NULL
) {
5388 KASSERT(cnt
< list
->tablecnt
,
5389 ("invalid idx %d, cnt %d",
5390 cnt
, list
->tablecnt
));
5391 list
->tables
[cnt
++] = i
;
5394 sopt
->sopt_valsize
= sz
;
5396 } else if (tbl
->tableid
>= ipfw_table_max
) {
5400 rnh
= ctx
->ipfw_tables
[tbl
->tableid
];
5403 rnh
->rnh_walktree(rnh
, ipfw_table_cntent
, &cnt
);
5405 sz
= __offsetof(struct ipfw_ioc_tblcont
, ent
[cnt
]);
5406 if (sopt
->sopt_valsize
< sz
) {
5407 bzero(sopt
->sopt_val
, sopt
->sopt_valsize
);
5410 cont
= sopt
->sopt_val
;
5416 rnh
->rnh_walktree(rnh
, ipfw_table_cpent
, &cp
);
5418 sopt
->sopt_valsize
= sz
;
5423 ipfw_table_add_dispatch(netmsg_t nmsg
)
5425 struct netmsg_tblent
*nm
= (struct netmsg_tblent
*)nmsg
;
5426 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
5427 struct radix_node_head
*rnh
;
5428 struct ipfw_tblent
*te
;
5430 ASSERT_NETISR_NCPUS(mycpuid
);
5432 rnh
= ctx
->ipfw_tables
[nm
->tableid
];
5434 te
= kmalloc(sizeof(*te
), M_IPFW
, M_WAITOK
| M_ZERO
);
5435 te
->te_nodes
->rn_key
= (char *)&te
->te_key
;
5436 memcpy(&te
->te_key
, nm
->key
, sizeof(te
->te_key
));
5438 if (rnh
->rnh_addaddr((char *)&te
->te_key
, (char *)nm
->netmask
, rnh
,
5439 te
->te_nodes
) == NULL
) {
5442 netisr_replymsg(&nm
->base
, EEXIST
);
5445 panic("rnh_addaddr failed");
5448 /* Link siblings. */
5449 if (nm
->sibling
!= NULL
)
5450 nm
->sibling
->te_sibling
= te
;
5453 netisr_forwardmsg(&nm
->base
, mycpuid
+ 1);
5457 ipfw_table_del_dispatch(netmsg_t nmsg
)
5459 struct netmsg_tblent
*nm
= (struct netmsg_tblent
*)nmsg
;
5460 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
5461 struct radix_node_head
*rnh
;
5462 struct radix_node
*rn
;
5464 ASSERT_NETISR_NCPUS(mycpuid
);
5466 rnh
= ctx
->ipfw_tables
[nm
->tableid
];
5467 rn
= rnh
->rnh_deladdr((char *)nm
->key
, (char *)nm
->netmask
, rnh
);
5470 netisr_replymsg(&nm
->base
, ESRCH
);
5473 panic("rnh_deladdr failed");
5477 netisr_forwardmsg(&nm
->base
, mycpuid
+ 1);
5481 ipfw_table_alt(struct sockopt
*sopt
)
5483 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
5484 struct ipfw_ioc_tblcont
*tbl
;
5485 struct ipfw_ioc_tblent
*te
;
5486 struct sockaddr_in key0
;
5487 struct sockaddr
*netmask
= NULL
, *key
;
5488 struct netmsg_tblent nm
;
5492 if (sopt
->sopt_valsize
!= sizeof(*tbl
))
5494 tbl
= sopt
->sopt_val
;
5496 if (tbl
->tableid
< 0 || tbl
->tableid
>= ipfw_table_max
)
5498 if (tbl
->entcnt
!= 1)
5501 if (ctx
->ipfw_tables
[tbl
->tableid
] == NULL
)
5505 if (te
->key
.sin_family
!= AF_INET
||
5506 te
->key
.sin_port
!= 0 ||
5507 te
->key
.sin_len
!= sizeof(struct sockaddr_in
))
5509 key
= (struct sockaddr
*)&te
->key
;
5511 if (te
->netmask
.sin_len
!= 0) {
5512 if (te
->netmask
.sin_port
!= 0 ||
5513 te
->netmask
.sin_len
> sizeof(struct sockaddr_in
))
5515 netmask
= (struct sockaddr
*)&te
->netmask
;
5516 sa_maskedcopy(key
, (struct sockaddr
*)&key0
, netmask
);
5517 key
= (struct sockaddr
*)&key0
;
5520 if (sopt
->sopt_name
== IP_FW_TBL_ADD
) {
5521 netmsg_init(&nm
.base
, NULL
, &curthread
->td_msgport
,
5522 MSGF_PRIORITY
, ipfw_table_add_dispatch
);
5524 netmsg_init(&nm
.base
, NULL
, &curthread
->td_msgport
,
5525 MSGF_PRIORITY
, ipfw_table_del_dispatch
);
5528 nm
.netmask
= netmask
;
5529 nm
.tableid
= tbl
->tableid
;
5531 return (netisr_domsg_global(&nm
.base
));
5535 ipfw_table_zeroent(struct radix_node
*rn
, void *arg __unused
)
5537 struct ipfw_tblent
*te
= (struct ipfw_tblent
*)rn
;
5545 ipfw_table_zero_dispatch(netmsg_t nmsg
)
5547 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
5548 struct radix_node_head
*rnh
;
5550 ASSERT_NETISR_NCPUS(mycpuid
);
5552 rnh
= ctx
->ipfw_tables
[nmsg
->lmsg
.u
.ms_result
];
5553 rnh
->rnh_walktree(rnh
, ipfw_table_zeroent
, NULL
);
5555 netisr_forwardmsg(&nmsg
->base
, mycpuid
+ 1);
5559 ipfw_table_zeroall_dispatch(netmsg_t nmsg
)
5561 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
5564 ASSERT_NETISR_NCPUS(mycpuid
);
5566 for (i
= 0; i
< ipfw_table_max
; ++i
) {
5567 struct radix_node_head
*rnh
= ctx
->ipfw_tables
[i
];
5570 rnh
->rnh_walktree(rnh
, ipfw_table_zeroent
, NULL
);
5572 netisr_forwardmsg(&nmsg
->base
, mycpuid
+ 1);
5576 ipfw_table_zero(struct sockopt
*sopt
)
5578 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
5579 struct netmsg_base nm
;
5580 struct ipfw_ioc_table
*tbl
;
5584 if (sopt
->sopt_valsize
!= sizeof(*tbl
))
5586 tbl
= sopt
->sopt_val
;
5588 if (tbl
->tableid
< 0) {
5589 netmsg_init(&nm
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
5590 ipfw_table_zeroall_dispatch
);
5591 netisr_domsg_global(&nm
);
5593 } else if (tbl
->tableid
>= ipfw_table_max
) {
5595 } else if (ctx
->ipfw_tables
[tbl
->tableid
] == NULL
) {
5599 netmsg_init(&nm
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
5600 ipfw_table_zero_dispatch
);
5601 nm
.lmsg
.u
.ms_result
= tbl
->tableid
;
5602 netisr_domsg_global(&nm
);
5608 ipfw_table_killexp(struct radix_node
*rn
, void *xnm
)
5610 struct netmsg_tblexp
*nm
= xnm
;
5611 struct ipfw_tblent
*te
= (struct ipfw_tblent
*)rn
;
5613 if (te
->te_expired
) {
5614 ipfw_table_killrn(nm
->rnh
, rn
);
5621 ipfw_table_expire_dispatch(netmsg_t nmsg
)
5623 struct netmsg_tblexp
*nm
= (struct netmsg_tblexp
*)nmsg
;
5624 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
5625 struct radix_node_head
*rnh
;
5627 ASSERT_NETISR_NCPUS(mycpuid
);
5629 rnh
= ctx
->ipfw_tables
[nm
->tableid
];
5631 rnh
->rnh_walktree(rnh
, ipfw_table_killexp
, nm
);
5633 KASSERT(nm
->expcnt
== nm
->cnt
* (mycpuid
+ 1),
5634 ("not all expired addresses (%d) were deleted (%d)",
5635 nm
->cnt
* (mycpuid
+ 1), nm
->expcnt
));
5637 netisr_forwardmsg(&nm
->base
, mycpuid
+ 1);
5641 ipfw_table_expireall_dispatch(netmsg_t nmsg
)
5643 struct netmsg_tblexp
*nm
= (struct netmsg_tblexp
*)nmsg
;
5644 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
5647 ASSERT_NETISR_NCPUS(mycpuid
);
5649 for (i
= 0; i
< ipfw_table_max
; ++i
) {
5650 struct radix_node_head
*rnh
= ctx
->ipfw_tables
[i
];
5655 rnh
->rnh_walktree(rnh
, ipfw_table_killexp
, nm
);
5658 KASSERT(nm
->expcnt
== nm
->cnt
* (mycpuid
+ 1),
5659 ("not all expired addresses (%d) were deleted (%d)",
5660 nm
->cnt
* (mycpuid
+ 1), nm
->expcnt
));
5662 netisr_forwardmsg(&nm
->base
, mycpuid
+ 1);
5666 ipfw_table_markexp(struct radix_node
*rn
, void *xnm
)
5668 struct netmsg_tblexp
*nm
= xnm
;
5669 struct ipfw_tblent
*te
;
5672 te
= (struct ipfw_tblent
*)rn
;
5673 lastuse
= te
->te_lastuse
;
5675 while ((te
= te
->te_sibling
) != NULL
) {
5676 if (te
->te_lastuse
> lastuse
)
5677 lastuse
= te
->te_lastuse
;
5679 if (!TIME_LEQ(lastuse
+ nm
->expire
, time_second
)) {
5684 te
= (struct ipfw_tblent
*)rn
;
5686 while ((te
= te
->te_sibling
) != NULL
)
5694 ipfw_table_expire(struct sockopt
*sopt
)
5696 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
5697 struct netmsg_tblexp nm
;
5698 struct ipfw_ioc_tblexp
*tbl
;
5699 struct radix_node_head
*rnh
;
5703 if (sopt
->sopt_valsize
!= sizeof(*tbl
))
5705 tbl
= sopt
->sopt_val
;
5710 nm
.expire
= tbl
->expire
;
5712 if (tbl
->tableid
< 0) {
5715 for (i
= 0; i
< ipfw_table_max
; ++i
) {
5716 rnh
= ctx
->ipfw_tables
[i
];
5719 rnh
->rnh_walktree(rnh
, ipfw_table_markexp
, &nm
);
5722 /* No addresses can be expired. */
5725 tbl
->expcnt
= nm
.cnt
;
5727 netmsg_init(&nm
.base
, NULL
, &curthread
->td_msgport
,
5728 MSGF_PRIORITY
, ipfw_table_expireall_dispatch
);
5730 netisr_domsg_global(&nm
.base
);
5731 KASSERT(nm
.expcnt
== nm
.cnt
* netisr_ncpus
,
5732 ("not all expired addresses (%d) were deleted (%d)",
5733 nm
.cnt
* netisr_ncpus
, nm
.expcnt
));
5736 } else if (tbl
->tableid
>= ipfw_table_max
) {
5740 rnh
= ctx
->ipfw_tables
[tbl
->tableid
];
5743 rnh
->rnh_walktree(rnh
, ipfw_table_markexp
, &nm
);
5745 /* No addresses can be expired. */
5748 tbl
->expcnt
= nm
.cnt
;
5750 netmsg_init(&nm
.base
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
5751 ipfw_table_expire_dispatch
);
5752 nm
.tableid
= tbl
->tableid
;
5753 netisr_domsg_global(&nm
.base
);
5754 KASSERT(nm
.expcnt
== nm
.cnt
* netisr_ncpus
,
5755 ("not all expired addresses (%d) were deleted (%d)",
5756 nm
.cnt
* netisr_ncpus
, nm
.expcnt
));
5761 ipfw_crossref_free_dispatch(netmsg_t nmsg
)
5763 struct ip_fw
*rule
= nmsg
->lmsg
.u
.ms_resultp
;
5765 KKASSERT((rule
->rule_flags
&
5766 (IPFW_RULE_F_CROSSREF
| IPFW_RULE_F_INVALID
)) ==
5767 (IPFW_RULE_F_CROSSREF
| IPFW_RULE_F_INVALID
));
5768 ipfw_free_rule(rule
);
5770 netisr_replymsg(&nmsg
->base
, 0);
5774 ipfw_crossref_reap(void)
5776 struct ip_fw
*rule
, *prev
= NULL
;
5780 rule
= ipfw_gd
.ipfw_crossref_free
;
5781 while (rule
!= NULL
) {
5782 uint64_t inflight
= 0;
5785 for (i
= 0; i
< netisr_ncpus
; ++i
)
5786 inflight
+= rule
->cross_rules
[i
]->cross_refs
;
5787 if (inflight
== 0) {
5788 struct ip_fw
*f
= rule
;
5797 ipfw_gd
.ipfw_crossref_free
= rule
;
5802 for (i
= 1; i
< netisr_ncpus
; ++i
) {
5803 struct netmsg_base nm
;
5805 netmsg_init(&nm
, NULL
, &curthread
->td_msgport
,
5806 MSGF_PRIORITY
, ipfw_crossref_free_dispatch
);
5807 nm
.lmsg
.u
.ms_resultp
= f
->cross_rules
[i
];
5808 netisr_domsg(&nm
, i
);
5810 KKASSERT((f
->rule_flags
&
5811 (IPFW_RULE_F_CROSSREF
| IPFW_RULE_F_INVALID
)) ==
5812 (IPFW_RULE_F_CROSSREF
| IPFW_RULE_F_INVALID
));
5820 if (ipfw_gd
.ipfw_crossref_free
!= NULL
) {
5821 callout_reset(&ipfw_gd
.ipfw_crossref_ch
, hz
,
5822 ipfw_crossref_timeo
, NULL
);
5827 * {set|get}sockopt parser.
5830 ipfw_ctl(struct sockopt
*sopt
)
5840 switch (sopt
->sopt_name
) {
5842 error
= ipfw_ctl_get_rules(sopt
);
5846 ipfw_flush(0 /* keep default rule */);
5850 error
= ipfw_ctl_add_rule(sopt
);
5855 * IP_FW_DEL is used for deleting single rules or sets,
5856 * and (ab)used to atomically manipulate sets.
5857 * Argument size is used to distinguish between the two:
5859 * delete single rule or set of rules,
5860 * or reassign rules (or sets) to a different set.
5861 * 2 * sizeof(uint32_t)
5862 * atomic disable/enable sets.
5863 * first uint32_t contains sets to be disabled,
5864 * second uint32_t contains sets to be enabled.
5866 masks
= sopt
->sopt_val
;
5867 size
= sopt
->sopt_valsize
;
5868 if (size
== sizeof(*masks
)) {
5870 * Delete or reassign static rule
5872 error
= ipfw_ctl_alter(masks
[0]);
5873 } else if (size
== (2 * sizeof(*masks
))) {
5875 * Set enable/disable
5877 ipfw_ctl_set_disable(masks
[0], masks
[1]);
5884 case IP_FW_RESETLOG
: /* argument is an int, the rule number */
5887 if (sopt
->sopt_val
!= 0) {
5888 error
= soopt_to_kbuf(sopt
, &rulenum
,
5889 sizeof(int), sizeof(int));
5893 error
= ipfw_ctl_zero_entry(rulenum
,
5894 sopt
->sopt_name
== IP_FW_RESETLOG
);
5897 case IP_FW_TBL_CREATE
:
5898 error
= ipfw_table_create(sopt
);
5903 error
= ipfw_table_alt(sopt
);
5906 case IP_FW_TBL_FLUSH
:
5907 case IP_FW_TBL_DESTROY
:
5908 error
= ipfw_table_flush(sopt
);
5912 error
= ipfw_table_get(sopt
);
5915 case IP_FW_TBL_ZERO
:
5916 error
= ipfw_table_zero(sopt
);
5919 case IP_FW_TBL_EXPIRE
:
5920 error
= ipfw_table_expire(sopt
);
5924 kprintf("ipfw_ctl invalid option %d\n", sopt
->sopt_name
);
5928 ipfw_crossref_reap();
5933 ipfw_keepalive_done(struct ipfw_context
*ctx
)
5936 KASSERT(ctx
->ipfw_flags
& IPFW_FLAG_KEEPALIVE
,
5937 ("keepalive is not in progress"));
5938 ctx
->ipfw_flags
&= ~IPFW_FLAG_KEEPALIVE
;
5939 callout_reset(&ctx
->ipfw_keepalive_ch
, dyn_keepalive_period
* hz
,
5940 ipfw_keepalive
, NULL
);
5944 ipfw_keepalive_more(struct ipfw_context
*ctx
)
5946 struct netmsg_base
*nm
= &ctx
->ipfw_keepalive_more
;
5948 KASSERT(ctx
->ipfw_flags
& IPFW_FLAG_KEEPALIVE
,
5949 ("keepalive is not in progress"));
5950 KASSERT(nm
->lmsg
.ms_flags
& MSGF_DONE
,
5951 ("keepalive more did not finish"));
5952 netisr_sendmsg_oncpu(nm
);
5956 ipfw_keepalive_loop(struct ipfw_context
*ctx
, struct ipfw_state
*anchor
)
5958 struct ipfw_state
*s
;
5959 int scanned
= 0, expired
= 0, kept
= 0;
5961 KASSERT(ctx
->ipfw_flags
& IPFW_FLAG_KEEPALIVE
,
5962 ("keepalive is not in progress"));
5964 while ((s
= TAILQ_NEXT(anchor
, st_link
)) != NULL
) {
5965 uint32_t ack_rev
, ack_fwd
;
5966 struct ipfw_flow_id id
;
5968 if (scanned
++ >= ipfw_state_scan_max
) {
5969 ipfw_keepalive_more(ctx
);
5973 TAILQ_REMOVE(&ctx
->ipfw_state_list
, anchor
, st_link
);
5974 TAILQ_INSERT_AFTER(&ctx
->ipfw_state_list
, s
, anchor
, st_link
);
5976 if (s
->st_type
== O_ANCHOR
)
5979 if (TIME_LEQ(s
->st_expire
, time_uptime
)) {
5980 /* State expired. */
5981 ipfw_state_del(ctx
, s
);
5982 if (++expired
>= ipfw_state_expire_max
) {
5983 ipfw_keepalive_more(ctx
);
5990 * Keep alive processing
5993 if (s
->st_proto
!= IPPROTO_TCP
)
5995 if ((s
->st_state
& IPFW_STATE_TCPSTATES
) != BOTH_SYN
)
5997 if (TIME_LEQ(time_uptime
+ dyn_keepalive_interval
,
5999 continue; /* too early */
6001 ipfw_key_4tuple(&s
->st_key
, &id
.src_ip
, &id
.src_port
,
6002 &id
.dst_ip
, &id
.dst_port
);
6003 ack_rev
= s
->st_ack_rev
;
6004 ack_fwd
= s
->st_ack_fwd
;
6006 send_pkt(&id
, ack_rev
- 1, ack_fwd
, TH_SYN
);
6007 send_pkt(&id
, ack_fwd
- 1, ack_rev
, 0);
6009 if (++kept
>= ipfw_keepalive_max
) {
6010 ipfw_keepalive_more(ctx
);
6014 TAILQ_REMOVE(&ctx
->ipfw_state_list
, anchor
, st_link
);
6015 ipfw_keepalive_done(ctx
);
6019 ipfw_keepalive_more_dispatch(netmsg_t nm
)
6021 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
6022 struct ipfw_state
*anchor
;
6024 ASSERT_NETISR_NCPUS(mycpuid
);
6025 KASSERT(ctx
->ipfw_flags
& IPFW_FLAG_KEEPALIVE
,
6026 ("keepalive is not in progress"));
6029 netisr_replymsg(&nm
->base
, 0);
6031 anchor
= &ctx
->ipfw_keepalive_anch
;
6032 if (!dyn_keepalive
|| ctx
->ipfw_state_cnt
== 0) {
6033 TAILQ_REMOVE(&ctx
->ipfw_state_list
, anchor
, st_link
);
6034 ipfw_keepalive_done(ctx
);
6037 ipfw_keepalive_loop(ctx
, anchor
);
6041 * This procedure is only used to handle keepalives. It is invoked
6042 * every dyn_keepalive_period
6045 ipfw_keepalive_dispatch(netmsg_t nm
)
6047 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
6048 struct ipfw_state
*anchor
;
6050 ASSERT_NETISR_NCPUS(mycpuid
);
6051 KASSERT((ctx
->ipfw_flags
& IPFW_FLAG_KEEPALIVE
) == 0,
6052 ("keepalive is in progress"));
6053 ctx
->ipfw_flags
|= IPFW_FLAG_KEEPALIVE
;
6057 netisr_replymsg(&nm
->base
, 0);
6060 if (!dyn_keepalive
|| ctx
->ipfw_state_cnt
== 0) {
6061 ipfw_keepalive_done(ctx
);
6065 anchor
= &ctx
->ipfw_keepalive_anch
;
6066 TAILQ_INSERT_HEAD(&ctx
->ipfw_state_list
, anchor
, st_link
);
6067 ipfw_keepalive_loop(ctx
, anchor
);
6071 * This procedure is only used to handle keepalives. It is invoked
6072 * every dyn_keepalive_period
6075 ipfw_keepalive(void *dummy __unused
)
6077 struct netmsg_base
*msg
;
6079 KKASSERT(mycpuid
< netisr_ncpus
);
6080 msg
= &ipfw_ctx
[mycpuid
]->ipfw_keepalive_nm
;
6083 if (msg
->lmsg
.ms_flags
& MSGF_DONE
)
6084 netisr_sendmsg_oncpu(msg
);
6089 ipfw_ip_input_dispatch(netmsg_t nmsg
)
6091 struct netmsg_genpkt
*nm
= (struct netmsg_genpkt
*)nmsg
;
6092 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
6093 struct mbuf
*m
= nm
->m
;
6094 struct ip_fw
*rule
= nm
->arg1
;
6096 ASSERT_NETISR_NCPUS(mycpuid
);
6097 KASSERT(rule
->cpuid
== mycpuid
,
6098 ("rule does not belong to cpu%d", mycpuid
));
6099 KASSERT(m
->m_pkthdr
.fw_flags
& IPFW_MBUF_CONTINUE
,
6100 ("mbuf does not have ipfw continue rule"));
6102 KASSERT(ctx
->ipfw_cont_rule
== NULL
,
6103 ("pending ipfw continue rule"));
6104 ctx
->ipfw_cont_rule
= rule
;
6108 * This rule is no longer used; decrement its cross_refs,
6109 * so this rule can be deleted.
6113 /* May not be cleared, if ipfw was unload/disabled. */
6114 ctx
->ipfw_cont_rule
= NULL
;
6118 ipfw_check_in(void *arg
, struct mbuf
**m0
, struct ifnet
*ifp
, int dir
)
6120 struct ip_fw_args args
;
6121 struct mbuf
*m
= *m0
;
6123 int tee
= 0, error
= 0, ret
, cpuid
;
6124 struct netmsg_genpkt
*nm
;
6127 if (m
->m_pkthdr
.fw_flags
& DUMMYNET_MBUF_TAGGED
) {
6128 /* Extract info from dummynet tag */
6129 mtag
= m_tag_find(m
, PACKET_TAG_DUMMYNET
, NULL
);
6130 KKASSERT(mtag
!= NULL
);
6131 args
.rule
= ((struct dn_pkt
*)m_tag_data(mtag
))->dn_priv
;
6132 KKASSERT(args
.rule
!= NULL
);
6134 m_tag_delete(m
, mtag
);
6135 m
->m_pkthdr
.fw_flags
&= ~DUMMYNET_MBUF_TAGGED
;
6136 } else if (m
->m_pkthdr
.fw_flags
& IPFW_MBUF_CONTINUE
) {
6137 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
6139 KKASSERT(ctx
->ipfw_cont_rule
!= NULL
);
6140 args
.rule
= ctx
->ipfw_cont_rule
;
6141 ctx
->ipfw_cont_rule
= NULL
;
6144 m
->m_pkthdr
.fw_flags
&= ~IPFW_MBUF_CONTINUE
;
6152 ret
= ipfw_chk(&args
);
6170 case IP_FW_DUMMYNET
:
6171 /* Send packet to the appropriate pipe */
6172 m
= ipfw_dummynet_io(m
, args
.cookie
, DN_TO_IP_IN
, &args
);
6181 * Must clear bridge tag when changing
6183 m
->m_pkthdr
.fw_flags
&= ~BRIDGE_MBUF_TAGGED
;
6184 if (ip_divert_p
!= NULL
) {
6185 m
= ip_divert_p(m
, tee
, 1);
6189 /* not sure this is the right error msg */
6194 case IP_FW_CONTINUE
:
6195 KASSERT(m
->m_flags
& M_HASH
, ("no hash"));
6196 cpuid
= netisr_hashcpu(m
->m_pkthdr
.hash
);
6197 KASSERT(cpuid
!= mycpuid
,
6198 ("continue on the same cpu%d", cpuid
));
6202 * Bump cross_refs to prevent this rule and its siblings
6203 * from being deleted, while this mbuf is inflight. The
6204 * cross_refs of the sibling rule on the target cpu will
6205 * be decremented, once this mbuf is going to be filtered
6206 * on the target cpu.
6208 args
.rule
->cross_refs
++;
6209 m
->m_pkthdr
.fw_flags
|= IPFW_MBUF_CONTINUE
;
6211 nm
= &m
->m_hdr
.mh_genmsg
;
6212 netmsg_init(&nm
->base
, NULL
, &netisr_apanic_rport
, 0,
6213 ipfw_ip_input_dispatch
);
6215 nm
->arg1
= args
.rule
->cross_rules
[cpuid
];
6216 netisr_sendmsg(&nm
->base
, cpuid
);
6218 /* This mbuf is dispatched; no longer valid. */
6223 panic("unknown ipfw return value: %d", ret
);
6231 ipfw_check_out(void *arg
, struct mbuf
**m0
, struct ifnet
*ifp
, int dir
)
6233 struct ip_fw_args args
;
6234 struct mbuf
*m
= *m0
;
6236 int tee
= 0, error
= 0, ret
;
6239 if (m
->m_pkthdr
.fw_flags
& DUMMYNET_MBUF_TAGGED
) {
6240 /* Extract info from dummynet tag */
6241 mtag
= m_tag_find(m
, PACKET_TAG_DUMMYNET
, NULL
);
6242 KKASSERT(mtag
!= NULL
);
6243 args
.rule
= ((struct dn_pkt
*)m_tag_data(mtag
))->dn_priv
;
6244 KKASSERT(args
.rule
!= NULL
);
6246 m_tag_delete(m
, mtag
);
6247 m
->m_pkthdr
.fw_flags
&= ~DUMMYNET_MBUF_TAGGED
;
6255 ret
= ipfw_chk(&args
);
6273 case IP_FW_DUMMYNET
:
6274 m
= ipfw_dummynet_io(m
, args
.cookie
, DN_TO_IP_OUT
, &args
);
6282 if (ip_divert_p
!= NULL
) {
6283 m
= ip_divert_p(m
, tee
, 0);
6287 /* not sure this is the right error msg */
6293 panic("unknown ipfw return value: %d", ret
);
6303 struct pfil_head
*pfh
;
6307 pfh
= pfil_head_get(PFIL_TYPE_AF
, AF_INET
);
6311 pfil_add_hook(ipfw_check_in
, NULL
, PFIL_IN
, pfh
);
6312 pfil_add_hook(ipfw_check_out
, NULL
, PFIL_OUT
, pfh
);
6318 struct pfil_head
*pfh
;
6322 pfh
= pfil_head_get(PFIL_TYPE_AF
, AF_INET
);
6326 pfil_remove_hook(ipfw_check_in
, NULL
, PFIL_IN
, pfh
);
6327 pfil_remove_hook(ipfw_check_out
, NULL
, PFIL_OUT
, pfh
);
6331 ipfw_sysctl_dyncnt(SYSCTL_HANDLER_ARGS
)
6335 dyn_cnt
= ipfw_state_cntcoll();
6336 dyn_cnt
+= ipfw_gd
.ipfw_trkcnt_cnt
;
6338 return (sysctl_handle_int(oidp
, &dyn_cnt
, 0, req
));
6342 ipfw_sysctl_statecnt(SYSCTL_HANDLER_ARGS
)
6346 state_cnt
= ipfw_state_cntcoll();
6347 return (sysctl_handle_int(oidp
, &state_cnt
, 0, req
));
6351 ipfw_sysctl_statemax(SYSCTL_HANDLER_ARGS
)
6353 int state_max
, error
;
6355 state_max
= ipfw_state_max
;
6356 error
= sysctl_handle_int(oidp
, &state_max
, 0, req
);
6357 if (error
|| req
->newptr
== NULL
)
6363 ipfw_state_max_set(state_max
);
6368 ipfw_sysctl_dynmax(SYSCTL_HANDLER_ARGS
)
6372 dyn_max
= ipfw_state_max
+ ipfw_track_max
;
6374 error
= sysctl_handle_int(oidp
, &dyn_max
, 0, req
);
6375 if (error
|| req
->newptr
== NULL
)
6381 ipfw_state_max_set(dyn_max
/ 2);
6382 ipfw_track_max
= dyn_max
/ 2;
6387 ipfw_sysctl_enable_dispatch(netmsg_t nmsg
)
6389 int enable
= nmsg
->lmsg
.u
.ms_result
;
6393 if (fw_enable
== enable
)
6402 netisr_replymsg(&nmsg
->base
, 0);
6406 ipfw_sysctl_enable(SYSCTL_HANDLER_ARGS
)
6408 struct netmsg_base nmsg
;
6412 error
= sysctl_handle_int(oidp
, &enable
, 0, req
);
6413 if (error
|| req
->newptr
== NULL
)
6416 netmsg_init(&nmsg
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
6417 ipfw_sysctl_enable_dispatch
);
6418 nmsg
.lmsg
.u
.ms_result
= enable
;
6420 return netisr_domsg(&nmsg
, 0);
6424 ipfw_sysctl_autoinc_step(SYSCTL_HANDLER_ARGS
)
6426 return sysctl_int_range(oidp
, arg1
, arg2
, req
,
6427 IPFW_AUTOINC_STEP_MIN
, IPFW_AUTOINC_STEP_MAX
);
6431 ipfw_sysctl_scancnt(SYSCTL_HANDLER_ARGS
)
6434 return sysctl_int_range(oidp
, arg1
, arg2
, req
, 1, INT_MAX
);
6438 ipfw_sysctl_stat(SYSCTL_HANDLER_ARGS
)
6443 for (cpu
= 0; cpu
< netisr_ncpus
; ++cpu
)
6444 stat
+= *((u_long
*)((uint8_t *)ipfw_ctx
[cpu
] + arg2
));
6446 error
= sysctl_handle_long(oidp
, &stat
, 0, req
);
6447 if (error
|| req
->newptr
== NULL
)
6450 /* Zero out this stat. */
6451 for (cpu
= 0; cpu
< netisr_ncpus
; ++cpu
)
6452 *((u_long
*)((uint8_t *)ipfw_ctx
[cpu
] + arg2
)) = 0;
6457 ipfw_ctx_init_dispatch(netmsg_t nmsg
)
6459 struct netmsg_ipfw
*fwmsg
= (struct netmsg_ipfw
*)nmsg
;
6460 struct ipfw_context
*ctx
;
6461 struct ip_fw
*def_rule
;
6463 ASSERT_NETISR_NCPUS(mycpuid
);
6465 ctx
= kmalloc(__offsetof(struct ipfw_context
,
6466 ipfw_tables
[ipfw_table_max
]), M_IPFW
, M_WAITOK
| M_ZERO
);
6468 RB_INIT(&ctx
->ipfw_state_tree
);
6469 TAILQ_INIT(&ctx
->ipfw_state_list
);
6471 RB_INIT(&ctx
->ipfw_track_tree
);
6472 TAILQ_INIT(&ctx
->ipfw_track_list
);
6474 callout_init_mp(&ctx
->ipfw_stateto_ch
);
6475 netmsg_init(&ctx
->ipfw_stateexp_nm
, NULL
, &netisr_adone_rport
,
6476 MSGF_DROPABLE
| MSGF_PRIORITY
, ipfw_state_expire_dispatch
);
6477 ctx
->ipfw_stateexp_anch
.st_type
= O_ANCHOR
;
6478 netmsg_init(&ctx
->ipfw_stateexp_more
, NULL
, &netisr_adone_rport
,
6479 MSGF_DROPABLE
, ipfw_state_expire_more_dispatch
);
6481 callout_init_mp(&ctx
->ipfw_trackto_ch
);
6482 netmsg_init(&ctx
->ipfw_trackexp_nm
, NULL
, &netisr_adone_rport
,
6483 MSGF_DROPABLE
| MSGF_PRIORITY
, ipfw_track_expire_dispatch
);
6484 netmsg_init(&ctx
->ipfw_trackexp_more
, NULL
, &netisr_adone_rport
,
6485 MSGF_DROPABLE
, ipfw_track_expire_more_dispatch
);
6487 callout_init_mp(&ctx
->ipfw_keepalive_ch
);
6488 netmsg_init(&ctx
->ipfw_keepalive_nm
, NULL
, &netisr_adone_rport
,
6489 MSGF_DROPABLE
| MSGF_PRIORITY
, ipfw_keepalive_dispatch
);
6490 ctx
->ipfw_keepalive_anch
.st_type
= O_ANCHOR
;
6491 netmsg_init(&ctx
->ipfw_keepalive_more
, NULL
, &netisr_adone_rport
,
6492 MSGF_DROPABLE
, ipfw_keepalive_more_dispatch
);
6494 ipfw_ctx
[mycpuid
] = ctx
;
6496 def_rule
= kmalloc(sizeof(*def_rule
), M_IPFW
, M_WAITOK
| M_ZERO
);
6498 def_rule
->act_ofs
= 0;
6499 def_rule
->rulenum
= IPFW_DEFAULT_RULE
;
6500 def_rule
->cmd_len
= 1;
6501 def_rule
->set
= IPFW_DEFAULT_SET
;
6503 def_rule
->cmd
[0].len
= 1;
6504 #ifdef IPFIREWALL_DEFAULT_TO_ACCEPT
6505 def_rule
->cmd
[0].opcode
= O_ACCEPT
;
6507 if (filters_default_to_accept
)
6508 def_rule
->cmd
[0].opcode
= O_ACCEPT
;
6510 def_rule
->cmd
[0].opcode
= O_DENY
;
6513 def_rule
->refcnt
= 1;
6514 def_rule
->cpuid
= mycpuid
;
6516 /* Install the default rule */
6517 ctx
->ipfw_default_rule
= def_rule
;
6518 ctx
->ipfw_layer3_chain
= def_rule
;
6520 /* Link rule CPU sibling */
6521 ipfw_link_sibling(fwmsg
, def_rule
);
6523 /* Statistics only need to be updated once */
6525 ipfw_inc_static_count(def_rule
);
6527 netisr_forwardmsg(&nmsg
->base
, mycpuid
+ 1);
6531 ipfw_crossref_reap_dispatch(netmsg_t nmsg
)
6536 netisr_replymsg(&nmsg
->base
, 0);
6538 ipfw_crossref_reap();
6542 ipfw_crossref_timeo(void *dummy __unused
)
6544 struct netmsg_base
*msg
= &ipfw_gd
.ipfw_crossref_nm
;
6546 KKASSERT(mycpuid
== 0);
6549 if (msg
->lmsg
.ms_flags
& MSGF_DONE
)
6550 netisr_sendmsg_oncpu(msg
);
6555 ipfw_ifaddr_dispatch(netmsg_t nmsg
)
6557 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
6558 struct ifnet
*ifp
= nmsg
->lmsg
.u
.ms_resultp
;
6561 ASSERT_NETISR_NCPUS(mycpuid
);
6563 for (f
= ctx
->ipfw_layer3_chain
; f
!= NULL
; f
= f
->next
) {
6567 if ((f
->rule_flags
& IPFW_RULE_F_DYNIFADDR
) == 0)
6570 for (l
= f
->cmd_len
, cmd
= f
->cmd
; l
> 0;
6571 l
-= cmdlen
, cmd
+= cmdlen
) {
6572 cmdlen
= F_LEN(cmd
);
6573 if (cmd
->opcode
== O_IP_SRC_IFIP
||
6574 cmd
->opcode
== O_IP_DST_IFIP
) {
6575 if (strncmp(ifp
->if_xname
,
6576 ((ipfw_insn_ifip
*)cmd
)->ifname
,
6578 cmd
->arg1
&= ~IPFW_IFIP_VALID
;
6582 netisr_forwardmsg(&nmsg
->base
, mycpuid
+ 1);
6586 ipfw_ifaddr(void *arg __unused
, struct ifnet
*ifp
,
6587 enum ifaddr_event event __unused
, struct ifaddr
*ifa __unused
)
6589 struct netmsg_base nm
;
6591 netmsg_init(&nm
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
6592 ipfw_ifaddr_dispatch
);
6593 nm
.lmsg
.u
.ms_resultp
= ifp
;
6594 netisr_domsg_global(&nm
);
6598 ipfw_init_dispatch(netmsg_t nmsg
)
6600 struct netmsg_ipfw fwmsg
;
6606 kprintf("IP firewall already loaded\n");
6611 if (ipfw_table_max
> UINT16_MAX
|| ipfw_table_max
<= 0)
6612 ipfw_table_max
= UINT16_MAX
;
6614 /* Initialize global track tree. */
6615 RB_INIT(&ipfw_gd
.ipfw_trkcnt_tree
);
6616 IPFW_TRKCNT_TOKINIT
;
6618 /* GC for freed crossref rules. */
6619 callout_init_mp(&ipfw_gd
.ipfw_crossref_ch
);
6620 netmsg_init(&ipfw_gd
.ipfw_crossref_nm
, NULL
, &netisr_adone_rport
,
6621 MSGF_PRIORITY
| MSGF_DROPABLE
, ipfw_crossref_reap_dispatch
);
6623 ipfw_state_max_set(ipfw_state_max
);
6624 ipfw_state_headroom
= 8 * netisr_ncpus
;
6626 bzero(&fwmsg
, sizeof(fwmsg
));
6627 netmsg_init(&fwmsg
.base
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
6628 ipfw_ctx_init_dispatch
);
6629 netisr_domsg_global(&fwmsg
.base
);
6631 ip_fw_chk_ptr
= ipfw_chk
;
6632 ip_fw_ctl_ptr
= ipfw_ctl
;
6633 ip_fw_dn_io_ptr
= ipfw_dummynet_io
;
6635 kprintf("ipfw2 initialized, default to %s, logging ",
6636 ipfw_ctx
[mycpuid
]->ipfw_default_rule
->cmd
[0].opcode
==
6637 O_ACCEPT
? "accept" : "deny");
6639 #ifdef IPFIREWALL_VERBOSE
6642 #ifdef IPFIREWALL_VERBOSE_LIMIT
6643 verbose_limit
= IPFIREWALL_VERBOSE_LIMIT
;
6645 if (fw_verbose
== 0) {
6646 kprintf("disabled\n");
6647 } else if (verbose_limit
== 0) {
6648 kprintf("unlimited\n");
6650 kprintf("limited to %d packets/entry by default\n",
6655 for (cpu
= 0; cpu
< netisr_ncpus
; ++cpu
) {
6656 callout_reset_bycpu(&ipfw_ctx
[cpu
]->ipfw_stateto_ch
, hz
,
6657 ipfw_state_expire_ipifunc
, NULL
, cpu
);
6658 callout_reset_bycpu(&ipfw_ctx
[cpu
]->ipfw_trackto_ch
, hz
,
6659 ipfw_track_expire_ipifunc
, NULL
, cpu
);
6660 callout_reset_bycpu(&ipfw_ctx
[cpu
]->ipfw_keepalive_ch
, hz
,
6661 ipfw_keepalive
, NULL
, cpu
);
6667 ipfw_ifaddr_event
= EVENTHANDLER_REGISTER(ifaddr_event
, ipfw_ifaddr
,
6668 NULL
, EVENTHANDLER_PRI_ANY
);
6669 if (ipfw_ifaddr_event
== NULL
)
6670 kprintf("ipfw: ifaddr_event register failed\n");
6673 netisr_replymsg(&nmsg
->base
, error
);
6679 struct netmsg_base smsg
;
6681 netmsg_init(&smsg
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
6682 ipfw_init_dispatch
);
6683 return netisr_domsg(&smsg
, 0);
6689 ipfw_ctx_fini_dispatch(netmsg_t nmsg
)
6691 struct ipfw_context
*ctx
= ipfw_ctx
[mycpuid
];
6693 ASSERT_NETISR_NCPUS(mycpuid
);
6695 callout_stop_sync(&ctx
->ipfw_stateto_ch
);
6696 callout_stop_sync(&ctx
->ipfw_trackto_ch
);
6697 callout_stop_sync(&ctx
->ipfw_keepalive_ch
);
6700 netisr_dropmsg(&ctx
->ipfw_stateexp_more
);
6701 netisr_dropmsg(&ctx
->ipfw_stateexp_nm
);
6702 netisr_dropmsg(&ctx
->ipfw_trackexp_more
);
6703 netisr_dropmsg(&ctx
->ipfw_trackexp_nm
);
6704 netisr_dropmsg(&ctx
->ipfw_keepalive_more
);
6705 netisr_dropmsg(&ctx
->ipfw_keepalive_nm
);
6708 ipfw_table_flushall_oncpu(ctx
, 1);
6710 netisr_forwardmsg(&nmsg
->base
, mycpuid
+ 1);
6714 ipfw_fini_dispatch(netmsg_t nmsg
)
6716 struct netmsg_base nm
;
6721 ipfw_crossref_reap();
6723 if (ipfw_gd
.ipfw_refcnt
!= 0) {
6731 /* Synchronize any inflight state/track expire IPIs. */
6732 lwkt_synchronize_ipiqs("ipfwfini");
6734 netmsg_init(&nm
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
6735 ipfw_ctx_fini_dispatch
);
6736 netisr_domsg_global(&nm
);
6738 callout_stop_sync(&ipfw_gd
.ipfw_crossref_ch
);
6740 netisr_dropmsg(&ipfw_gd
.ipfw_crossref_nm
);
6743 if (ipfw_ifaddr_event
!= NULL
)
6744 EVENTHANDLER_DEREGISTER(ifaddr_event
, ipfw_ifaddr_event
);
6746 ip_fw_chk_ptr
= NULL
;
6747 ip_fw_ctl_ptr
= NULL
;
6748 ip_fw_dn_io_ptr
= NULL
;
6749 ipfw_flush(1 /* kill default rule */);
6751 /* Free pre-cpu context */
6752 for (cpu
= 0; cpu
< netisr_ncpus
; ++cpu
)
6753 kfree(ipfw_ctx
[cpu
], M_IPFW
);
6755 kprintf("IP firewall unloaded\n");
6757 netisr_replymsg(&nmsg
->base
, error
);
6763 struct netmsg_base smsg
;
6765 netmsg_init(&smsg
, NULL
, &curthread
->td_msgport
, MSGF_PRIORITY
,
6766 ipfw_fini_dispatch
);
6767 return netisr_domsg(&smsg
, 0);
6770 #endif /* KLD_MODULE */
6773 ipfw_modevent(module_t mod
, int type
, void *unused
)
6784 kprintf("ipfw statically compiled, cannot unload\n");
6796 static moduledata_t ipfwmod
= {
6801 DECLARE_MODULE(ipfw
, ipfwmod
, SI_SUB_PROTO_END
, SI_ORDER_ANY
);
6802 MODULE_VERSION(ipfw
, 1);