vimage patches and example run.
Norikatsu Shigemura
nork at ninth-nine.com
Sat May 17 02:44:03 UTC 2008
On Sat, 17 May 2008 11:32:01 +0900
Norikatsu Shigemura <nork at freebsd.org> wrote:
> Please replace my attached patches for your vimage.diff.
Sorry. I forgot to attach patches.
-------------- next part --------------
--- sys/netinet/ip_fw.h.orig 2008-05-10 16:10:53.000000000 +0900
+++ sys/netinet/ip_fw.h 2008-05-17 10:49:58.974783431 +0900
@@ -28,6 +28,9 @@
#ifndef _IPFW2_H
#define _IPFW2_H
+#include <sys/rwlock.h>
+#include <net/radix.h>
+
/*
* The kernel representation of ipfw rules is made of a list of
* 'instructions' (for all practical purposes equivalent to BPF
@@ -550,6 +553,34 @@
*/
#ifdef _KERNEL
+/*
+ * Data structure to cache our ucred related
+ * information. This structure only gets used if
+ * the user specified UID/GID based constraints in
+ * a firewall rule.
+ */
+struct ip_fw_ugid {
+ gid_t fw_groups[NGROUPS];
+ int fw_ngroups;
+ uid_t fw_uid;
+ int fw_prid;
+};
+
+#define IPFW_TABLES_MAX 128
+struct ip_fw_chain {
+ struct ip_fw *rules; /* list of rules */
+ struct ip_fw *reap; /* list of rules to reap */
+ LIST_HEAD(, cfg_nat) nat; /* list of nat entries */
+ struct radix_node_head *tables[IPFW_TABLES_MAX];
+ struct rwlock rwmtx;
+};
+
+struct table_entry {
+ struct radix_node rn[2];
+ struct sockaddr_in addr, mask;
+ u_int32_t value;
+};
+
/* Return values from ipfw_chk() */
enum {
IP_FW_PASS = 0,
@@ -619,11 +650,14 @@
typedef int ip_fw_ctl_t(struct sockopt *);
extern ip_fw_ctl_t *ip_fw_ctl_ptr;
+
+#ifndef VIMAGE
extern int fw_one_pass;
extern int fw_enable;
#ifdef INET6
extern int fw6_enable;
#endif
+#endif
/* For kernel ipfw_ether and ipfw_bridge. */
typedef int ip_fw_chk_t(struct ip_fw_args *args);
@@ -632,14 +666,6 @@
#ifdef IPFW_INTERNAL
-#define IPFW_TABLES_MAX 128
-struct ip_fw_chain {
- struct ip_fw *rules; /* list of rules */
- struct ip_fw *reap; /* list of rules to reap */
- LIST_HEAD(, cfg_nat) nat; /* list of nat entries */
- struct radix_node_head *tables[IPFW_TABLES_MAX];
- struct rwlock rwmtx;
-};
#define IPFW_LOCK_INIT(_chain) \
rw_init(&(_chain)->rwmtx, "IPFW static rules")
#define IPFW_LOCK_DESTROY(_chain) rw_destroy(&(_chain)->rwmtx)
@@ -662,5 +688,89 @@
typedef int ipfw_nat_cfg_t(struct sockopt *);
#endif
+/*
+ * Stack virtualization support.
+ */
+#ifdef VIMAGE
+struct vnet_ipfw {
+ int _fw_one_pass;
+ int _fw_enable;
+ int _fw6_enable;
+
+ u_int32_t _set_disable;
+ int _fw_deny_unknown_exthdrs;
+ int _fw_verbose;
+ int _verbose_limit;
+ int _fw_debug;
+ int _autoinc_step;
+
+ ipfw_dyn_rule **_ipfw_dyn_v;
+ struct ip_fw_chain _layer3_chain;
+ u_int32_t _dyn_buckets;
+ u_int32_t _curr_dyn_buckets;
+
+ u_int32_t _dyn_ack_lifetime;
+ u_int32_t _dyn_syn_lifetime;
+ u_int32_t _dyn_fin_lifetime;
+ u_int32_t _dyn_rst_lifetime;
+ u_int32_t _dyn_udp_lifetime;
+ u_int32_t _dyn_short_lifetime;
+ u_int32_t _dyn_keepalive_interval;
+ u_int32_t _dyn_keepalive_period;
+ u_int32_t _dyn_keepalive;
+ u_int32_t _static_count;
+ u_int32_t _static_len;
+ u_int32_t _dyn_count;
+ u_int32_t _dyn_max;
+
+ u_int64_t _norule_counter;
+
+ struct callout _ipfw_timeout;
+};
+#endif
+
+/*
+ * Symbol translation macros
+ */
+
+#define INIT_VNET_IPFW(vnet) \
+ INIT_FROM_VNET(vnet, VNET_MOD_IPFW, struct vnet_ipfw, vnet_ipfw)
+
+#define VNET_IPFW(sym) VSYM(vnet_ipfw, sym)
+
+#define V_fw_one_pass VNET_IPFW(fw_one_pass)
+#define V_fw_enable VNET_IPFW(fw_enable)
+#define V_fw6_enable VNET_IPFW(fw6_enable)
+
+#define V_set_disable VNET_IPFW(set_disable)
+#define V_fw_deny_unknown_exthdrs VNET_IPFW(fw_deny_unknown_exthdrs)
+#define V_fw_verbose VNET_IPFW(fw_verbose)
+#define V_verbose_limit VNET_IPFW(verbose_limit)
+
+#define V_fw_debug VNET_IPFW(fw_debug)
+#define V_autoinc_step VNET_IPFW(autoinc_step)
+
+#define V_ipfw_dyn_v VNET_IPFW(ipfw_dyn_v)
+#define V_layer3_chain VNET_IPFW(layer3_chain)
+#define V_dyn_buckets VNET_IPFW(dyn_buckets)
+#define V_curr_dyn_buckets VNET_IPFW(curr_dyn_buckets)
+
+#define V_dyn_ack_lifetime VNET_IPFW(dyn_ack_lifetime)
+#define V_dyn_syn_lifetime VNET_IPFW(dyn_syn_lifetime)
+#define V_dyn_fin_lifetime VNET_IPFW(dyn_fin_lifetime)
+#define V_dyn_rst_lifetime VNET_IPFW(dyn_rst_lifetime)
+#define V_dyn_udp_lifetime VNET_IPFW(dyn_udp_lifetime)
+#define V_dyn_short_lifetime VNET_IPFW(dyn_short_lifetime)
+#define V_dyn_keepalive_interval VNET_IPFW(dyn_keepalive_interval)
+#define V_dyn_keepalive_period VNET_IPFW(dyn_keepalive_period)
+#define V_dyn_keepalive VNET_IPFW(dyn_keepalive)
+#define V_static_count VNET_IPFW(static_count)
+#define V_static_len VNET_IPFW(static_len)
+#define V_dyn_count VNET_IPFW(dyn_count)
+#define V_dyn_max VNET_IPFW(dyn_max)
+
+#define V_norule_counter VNET_IPFW(norule_counter)
+#define V_ipfw_timeout VNET_IPFW(ipfw_timeout)
+
#endif /* _KERNEL */
#endif /* _IPFW2_H */
-------------- next part --------------
--- sys/netinet/ip_fw2.c.orig 2008-05-10 16:10:53.000000000 +0900
+++ sys/netinet/ip_fw2.c 2008-05-17 11:13:34.347364537 +0900
@@ -45,6 +45,7 @@
#include "opt_inet6.h"
#include "opt_ipsec.h"
#include "opt_mac.h"
+#include "opt_vimage.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -64,6 +65,9 @@
#include <sys/sysctl.h>
#include <sys/syslog.h>
#include <sys/ucred.h>
+#include <sys/vimage.h>
+
+#include <net/vnet.h>
#include <net/if.h>
#include <net/radix.h>
#include <net/route.h>
@@ -71,6 +75,7 @@
#define IPFW_INTERNAL /* Access to protected data structures in ip_fw.h. */
+#include <netinet/vinet.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
@@ -106,6 +111,11 @@
#include <security/mac/mac_framework.h>
+static int vnet_ipfw_iattach(const void *);
+static int vnet_ipfw_idetach(const void *);
+
+VNET_MOD_DECLARE(IPFW, ipfw, vnet_ipfw_iattach, vnet_ipfw_idetach, INET, NULL)
+
/*
* set_disable contains one bit per set value (0..31).
* If the bit is set, all rules with the corresponding set
@@ -114,32 +124,24 @@
* and CANNOT be disabled.
* Rules in set RESVD_SET can only be deleted explicitly.
*/
+#ifndef VIMAGE
static u_int32_t set_disable;
static int fw_verbose;
static int verbose_limit;
static struct callout ipfw_timeout;
+#endif
+
static uma_zone_t ipfw_dyn_rule_zone;
#define IPFW_DEFAULT_RULE 65535
/*
- * Data structure to cache our ucred related
- * information. This structure only gets used if
- * the user specified UID/GID based constraints in
- * a firewall rule.
- */
-struct ip_fw_ugid {
- gid_t fw_groups[NGROUPS];
- int fw_ngroups;
- uid_t fw_uid;
- int fw_prid;
-};
-
-/*
* list of rules for layer 3
*/
+#ifndef VIMAGE
struct ip_fw_chain layer3_chain;
+#endif
MALLOC_DEFINE(M_IPFW, "IpFw/IpAcct", "IpFw/IpAcct chain's");
MALLOC_DEFINE(M_IPFW_TBL, "ipfw_tbl", "IpFw tables");
@@ -150,35 +152,35 @@
ipfw_nat_cfg_t *ipfw_nat_get_cfg_ptr;
ipfw_nat_cfg_t *ipfw_nat_get_log_ptr;
-struct table_entry {
- struct radix_node rn[2];
- struct sockaddr_in addr, mask;
- u_int32_t value;
-};
-
-static int fw_debug = 1;
-static int autoinc_step = 100; /* bounded to 1..1000 in add_rule() */
+#ifndef VIMAGE
+static int fw_debug;
+static int autoinc_step;
+#endif
+#ifdef VIMAGE
+extern int ipfw_chg_hook(SYSCTL_HANDLER_V_ARGS);
+#else
extern int ipfw_chg_hook(SYSCTL_HANDLER_ARGS);
+#endif
#ifdef SYSCTL_NODE
SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
-SYSCTL_PROC(_net_inet_ip_fw, OID_AUTO, enable,
- CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, &fw_enable, 0,
+SYSCTL_V_PROC(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, enable,
+ CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, fw_enable, 0,
ipfw_chg_hook, "I", "Enable ipfw");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, autoinc_step, CTLFLAG_RW,
- &autoinc_step, 0, "Rule number autincrement step");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, one_pass,
- CTLFLAG_RW | CTLFLAG_SECURE3,
- &fw_one_pass, 0,
+SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, autoinc_step,
+ CTLFLAG_RW, autoinc_step, 0, "Rule number autincrement step");
+SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, one_pass,
+ CTLFLAG_RW | CTLFLAG_SECURE3, fw_one_pass, 0,
"Only do a single pass through ipfw when using dummynet(4)");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, debug, CTLFLAG_RW,
- &fw_debug, 0, "Enable printing of debug ip_fw statements");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, verbose,
+SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, debug, CTLFLAG_RW,
+ fw_debug, 0, "Enable printing of debug ip_fw statements");
+SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, verbose,
CTLFLAG_RW | CTLFLAG_SECURE3,
- &fw_verbose, 0, "Log matches to ipfw rules");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit, CTLFLAG_RW,
- &verbose_limit, 0, "Set upper limit of matches of ipfw rules logged");
+ fw_verbose, 0, "Log matches to ipfw rules");
+SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, verbose_limit,
+ CTLFLAG_RW,
+ verbose_limit, 0, "Set upper limit of matches of ipfw rules logged");
/*
* Description of dynamic rules.
@@ -216,9 +218,11 @@
* obey the 'randomized match', and we do not do multiple
* passes through the firewall. XXX check the latter!!!
*/
+#ifndef VIMAGE
static ipfw_dyn_rule **ipfw_dyn_v = NULL;
-static u_int32_t dyn_buckets = 256; /* must be power of 2 */
-static u_int32_t curr_dyn_buckets = 256; /* must be power of 2 */
+static u_int32_t dyn_buckets;
+static u_int32_t curr_dyn_buckets;
+#endif
static struct mtx ipfw_dyn_mtx; /* mutex guarding dynamic rules */
#define IPFW_DYN_LOCK_INIT() \
@@ -231,12 +235,14 @@
/*
* Timeouts for various events in handing dynamic rules.
*/
-static u_int32_t dyn_ack_lifetime = 300;
-static u_int32_t dyn_syn_lifetime = 20;
-static u_int32_t dyn_fin_lifetime = 1;
-static u_int32_t dyn_rst_lifetime = 1;
-static u_int32_t dyn_udp_lifetime = 10;
-static u_int32_t dyn_short_lifetime = 5;
+#ifndef VIMAGE
+static u_int32_t dyn_ack_lifetime;
+static u_int32_t dyn_syn_lifetime;
+static u_int32_t dyn_fin_lifetime;
+static u_int32_t dyn_rst_lifetime;
+static u_int32_t dyn_udp_lifetime;
+static u_int32_t dyn_short_lifetime;
+#endif
/*
* Keepalives are sent if dyn_keepalive is set. They are sent every
@@ -245,54 +251,65 @@
* dyn_rst_lifetime and dyn_fin_lifetime should be strictly lower
* than dyn_keepalive_period.
*/
-
-static u_int32_t dyn_keepalive_interval = 20;
-static u_int32_t dyn_keepalive_period = 5;
-static u_int32_t dyn_keepalive = 1; /* do send keepalives */
+#ifndef VIMAGE
+static u_int32_t dyn_keepalive_interval;
+static u_int32_t dyn_keepalive_period;
+static u_int32_t dyn_keepalive;
static u_int32_t static_count; /* # of static rules */
static u_int32_t static_len; /* size in bytes of static rules */
-static u_int32_t dyn_count; /* # of dynamic rules */
-static u_int32_t dyn_max = 4096; /* max # of dynamic rules */
+static u_int32_t dyn_count; /* # of dynamic rules */
+static u_int32_t dyn_max; /* max # of dynamic rules */
+#endif
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_buckets, CTLFLAG_RW,
- &dyn_buckets, 0, "Number of dyn. buckets");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, curr_dyn_buckets, CTLFLAG_RD,
- &curr_dyn_buckets, 0, "Current Number of dyn. buckets");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_count, CTLFLAG_RD,
- &dyn_count, 0, "Number of dyn. rules");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_max, CTLFLAG_RW,
- &dyn_max, 0, "Max number of dyn. rules");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, static_count, CTLFLAG_RD,
- &static_count, 0, "Number of static rules");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_ack_lifetime, CTLFLAG_RW,
- &dyn_ack_lifetime, 0, "Lifetime of dyn. rules for acks");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_syn_lifetime, CTLFLAG_RW,
- &dyn_syn_lifetime, 0, "Lifetime of dyn. rules for syn");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_fin_lifetime, CTLFLAG_RW,
- &dyn_fin_lifetime, 0, "Lifetime of dyn. rules for fin");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_rst_lifetime, CTLFLAG_RW,
- &dyn_rst_lifetime, 0, "Lifetime of dyn. rules for rst");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_udp_lifetime, CTLFLAG_RW,
- &dyn_udp_lifetime, 0, "Lifetime of dyn. rules for UDP");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_short_lifetime, CTLFLAG_RW,
- &dyn_short_lifetime, 0, "Lifetime of dyn. rules for other situations");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_keepalive, CTLFLAG_RW,
- &dyn_keepalive, 0, "Enable keepalives for dyn. rules");
+SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, dyn_buckets,
+ CTLFLAG_RW, dyn_buckets, 0, "Number of dyn. buckets");
+SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, curr_dyn_buckets,
+ CTLFLAG_RD, curr_dyn_buckets, 0, "Current Number of dyn. buckets");
+SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, dyn_count,
+ CTLFLAG_RD, dyn_count, 0, "Number of dyn. rules");
+SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, dyn_max,
+ CTLFLAG_RW, dyn_max, 0, "Max number of dyn. rules");
+SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, static_count,
+ CTLFLAG_RD, static_count, 0, "Number of static rules");
+SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, dyn_ack_lifetime,
+ CTLFLAG_RW, dyn_ack_lifetime, 0, "Lifetime of dyn. rules for acks");
+SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, dyn_syn_lifetime,
+ CTLFLAG_RW, dyn_syn_lifetime, 0, "Lifetime of dyn. rules for syn");
+SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, dyn_fin_lifetime,
+ CTLFLAG_RW, dyn_fin_lifetime, 0, "Lifetime of dyn. rules for fin");
+SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, dyn_rst_lifetime,
+ CTLFLAG_RW, dyn_rst_lifetime, 0, "Lifetime of dyn. rules for rst");
+SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, dyn_udp_lifetime,
+ CTLFLAG_RW, dyn_udp_lifetime, 0, "Lifetime of dyn. rules for UDP");
+SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, dyn_short_lifetime,
+ CTLFLAG_RW, dyn_short_lifetime, 0,
+ "Lifetime of dyn. rules for other situations");
+SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, dyn_keepalive,
+ CTLFLAG_RW, dyn_keepalive, 0, "Enable keepalives for dyn. rules");
+
+#ifndef VIMAGE
+static int fw_deny_unknown_exthdrs;
+#endif
#ifdef INET6
/*
* IPv6 specific variables
*/
-SYSCTL_DECL(_net_inet6_ip6);
-static struct sysctl_ctx_list ip6_fw_sysctl_ctx;
-static struct sysctl_oid *ip6_fw_sysctl_tree;
+SYSCTL_DECL(_net_inet6_ip6);
+SYSCTL_NODE(_net_inet6_ip6, OID_AUTO, fw, CTLFLAG_RW | CTLFLAG_SECURE,
+ 0, "Firewall");
+SYSCTL_V_PROC(V_NET, vnet_ipfw, _net_inet6_ip6_fw, OID_AUTO, enable,
+ CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, fw6_enable, 0,
+ ipfw_chg_hook, "I", "Enable ipfw+6");
+SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet6_ip6_fw, OID_AUTO,
+ deny_unknown_exthdrs, CTLFLAG_RW | CTLFLAG_SECURE,
+ fw_deny_unknown_exthdrs, 0,
+ "Deny packets with unknown IPv6 Extension Headers");
#endif /* INET6 */
#endif /* SYSCTL_NODE */
-static int fw_deny_unknown_exthdrs = 1;
-
/*
* L3HDR maps an ipv4 pointer into a layer3 header pointer of type T
@@ -562,12 +579,13 @@
static int
search_ip6_addr_net (struct in6_addr * ip6_addr)
{
+ INIT_VNET_NET(curvnet);
struct ifnet *mdc;
struct ifaddr *mdc2;
struct in6_ifaddr *fdm;
struct in6_addr copia;
- TAILQ_FOREACH(mdc, &ifnet, if_link)
+ TAILQ_FOREACH(mdc, &V_ifnet, if_link)
TAILQ_FOREACH(mdc2, &mdc->if_addrlist, ifa_list) {
if (mdc2->ifa_addr->sa_family == AF_INET6) {
fdm = (struct in6_ifaddr *)mdc2;
@@ -629,6 +647,7 @@
return 1;
}
+
static __inline int
hash_packet6(struct ipfw_flow_id *id)
{
@@ -739,7 +758,9 @@
#endif /* INET6 */
+#ifndef VIMAGE
static u_int64_t norule_counter; /* counter for ipfw_log(NULL...) */
+#endif
#define SNPARGS(buf, len) buf + len, sizeof(buf) > len ? sizeof(buf) - len : 0
#define SNP(buf) buf, sizeof(buf)
@@ -753,6 +774,7 @@
struct mbuf *m, struct ifnet *oif, u_short offset, uint32_t tablearg,
struct ip *ip)
{
+ INIT_VNET_IPFW(curvnet);
struct ether_header *eh = args->eh;
char *action;
int limit_reached = 0;
@@ -762,11 +784,11 @@
proto[0] = '\0';
if (f == NULL) { /* bogus pkt */
- if (verbose_limit != 0 && norule_counter >= verbose_limit)
+ if (V_verbose_limit != 0 && V_norule_counter >= V_verbose_limit)
return;
- norule_counter++;
- if (norule_counter == verbose_limit)
- limit_reached = verbose_limit;
+ V_norule_counter++;
+ if (V_norule_counter == V_verbose_limit)
+ limit_reached = V_verbose_limit;
action = "Refuse";
} else { /* O_LOG is the first action, find the real one */
ipfw_insn *cmd = ACTION_PTR(f);
@@ -1023,6 +1045,7 @@
static __inline int
hash_packet(struct ipfw_flow_id *id)
{
+ INIT_VNET_IPFW(curvnet);
u_int32_t i;
#ifdef INET6
@@ -1031,7 +1054,7 @@
else
#endif /* INET6 */
i = (id->dst_ip) ^ (id->src_ip) ^ (id->dst_port) ^ (id->src_port);
- i &= (curr_dyn_buckets - 1);
+ i &= (V_curr_dyn_buckets - 1);
return i;
}
@@ -1049,12 +1072,12 @@
q->parent->count--; \
DEB(printf("ipfw: unlink entry 0x%08x %d -> 0x%08x %d, %d left\n",\
(q->id.src_ip), (q->id.src_port), \
- (q->id.dst_ip), (q->id.dst_port), dyn_count-1 ); ) \
+ (q->id.dst_ip), (q->id.dst_port), V_dyn_count-1 ); ) \
if (prev != NULL) \
prev->next = q = q->next; \
else \
head = q = q->next; \
- dyn_count--; \
+ V_dyn_count--; \
uma_zfree(ipfw_dyn_rule_zone, old_q); }
#define TIME_LEQ(a,b) ((int)((a)-(b)) <= 0)
@@ -1074,6 +1097,7 @@
static void
remove_dyn_rule(struct ip_fw *rule, ipfw_dyn_rule *keep_me)
{
+ INIT_VNET_IPFW(curvnet);
static u_int32_t last_remove = 0;
#define FORCE (keep_me == NULL)
@@ -1083,7 +1107,7 @@
IPFW_DYN_LOCK_ASSERT();
- if (ipfw_dyn_v == NULL || dyn_count == 0)
+ if (V_ipfw_dyn_v == NULL || V_dyn_count == 0)
return;
/* do not expire more than once per second, it is useless */
if (!FORCE && last_remove == time_uptime)
@@ -1096,8 +1120,8 @@
* them in a second pass.
*/
next_pass:
- for (i = 0 ; i < curr_dyn_buckets ; i++) {
- for (prev=NULL, q = ipfw_dyn_v[i] ; q ; ) {
+ for (i = 0 ; i < V_curr_dyn_buckets ; i++) {
+ for (prev=NULL, q = V_ipfw_dyn_v[i] ; q ; ) {
/*
* Logic can become complex here, so we split tests.
*/
@@ -1124,7 +1148,7 @@
goto next;
}
if (q->dyn_type != O_LIMIT_PARENT || !q->count) {
- UNLINK_DYN_RULE(prev, ipfw_dyn_v[i], q);
+ UNLINK_DYN_RULE(prev, V_ipfw_dyn_v[i], q);
continue;
}
next:
@@ -1144,6 +1168,7 @@
lookup_dyn_rule_locked(struct ipfw_flow_id *pkt, int *match_direction,
struct tcphdr *tcp)
{
+ INIT_VNET_IPFW(curvnet);
/*
* stateful ipfw extensions.
* Lookup into dynamic session queue
@@ -1157,14 +1182,14 @@
IPFW_DYN_LOCK_ASSERT();
- if (ipfw_dyn_v == NULL)
+ if (V_ipfw_dyn_v == NULL)
goto done; /* not found */
i = hash_packet( pkt );
- for (prev=NULL, q = ipfw_dyn_v[i] ; q != NULL ; ) {
+ for (prev=NULL, q = V_ipfw_dyn_v[i] ; q != NULL ; ) {
if (q->dyn_type == O_LIMIT_PARENT && q->count)
goto next;
if (TIME_LEQ( q->expire, time_uptime)) { /* expire entry */
- UNLINK_DYN_RULE(prev, ipfw_dyn_v[i], q);
+ UNLINK_DYN_RULE(prev, V_ipfw_dyn_v[i], q);
continue;
}
if (pkt->proto == q->id.proto &&
@@ -1214,8 +1239,8 @@
if ( prev != NULL) { /* found and not in front */
prev->next = q->next;
- q->next = ipfw_dyn_v[i];
- ipfw_dyn_v[i] = q;
+ q->next = V_ipfw_dyn_v[i];
+ V_ipfw_dyn_v[i] = q;
}
if (pkt->proto == IPPROTO_TCP) { /* update state according to flags */
u_char flags = pkt->flags & (TH_FIN|TH_SYN|TH_RST);
@@ -1225,7 +1250,7 @@
q->state |= (dir == MATCH_FORWARD ) ? flags : (flags << 8);
switch (q->state) {
case TH_SYN: /* opening */
- q->expire = time_uptime + dyn_syn_lifetime;
+ q->expire = time_uptime + V_dyn_syn_lifetime;
break;
case BOTH_SYN: /* move to established */
@@ -1248,13 +1273,13 @@
}
}
}
- q->expire = time_uptime + dyn_ack_lifetime;
+ q->expire = time_uptime + V_dyn_ack_lifetime;
break;
case BOTH_SYN | BOTH_FIN: /* both sides closed */
- if (dyn_fin_lifetime >= dyn_keepalive_period)
- dyn_fin_lifetime = dyn_keepalive_period - 1;
- q->expire = time_uptime + dyn_fin_lifetime;
+ if (V_dyn_fin_lifetime >= V_dyn_keepalive_period)
+ V_dyn_fin_lifetime = V_dyn_keepalive_period - 1;
+ q->expire = time_uptime + V_dyn_fin_lifetime;
break;
default:
@@ -1266,16 +1291,16 @@
if ( (q->state & ((TH_RST << 8)|TH_RST)) == 0)
printf("invalid state: 0x%x\n", q->state);
#endif
- if (dyn_rst_lifetime >= dyn_keepalive_period)
- dyn_rst_lifetime = dyn_keepalive_period - 1;
- q->expire = time_uptime + dyn_rst_lifetime;
+ if (V_dyn_rst_lifetime >= V_dyn_keepalive_period)
+ V_dyn_rst_lifetime = V_dyn_keepalive_period - 1;
+ q->expire = time_uptime + V_dyn_rst_lifetime;
break;
}
} else if (pkt->proto == IPPROTO_UDP) {
- q->expire = time_uptime + dyn_udp_lifetime;
+ q->expire = time_uptime + V_dyn_udp_lifetime;
} else {
/* other protocols */
- q->expire = time_uptime + dyn_short_lifetime;
+ q->expire = time_uptime + V_dyn_short_lifetime;
}
done:
if (match_direction)
@@ -1300,6 +1325,7 @@
static void
realloc_dynamic_table(void)
{
+ INIT_VNET_IPFW(curvnet);
IPFW_DYN_LOCK_ASSERT();
/*
@@ -1308,21 +1334,21 @@
* default to 1024.
*/
- if (dyn_buckets > 65536)
- dyn_buckets = 1024;
- if ((dyn_buckets & (dyn_buckets-1)) != 0) { /* not a power of 2 */
- dyn_buckets = curr_dyn_buckets; /* reset */
+ if (V_dyn_buckets > 65536)
+ V_dyn_buckets = 1024;
+ if ((V_dyn_buckets & (V_dyn_buckets-1)) != 0) { /* not a power of 2 */
+ V_dyn_buckets = V_curr_dyn_buckets; /* reset */
return;
}
- curr_dyn_buckets = dyn_buckets;
- if (ipfw_dyn_v != NULL)
- free(ipfw_dyn_v, M_IPFW);
+ V_curr_dyn_buckets = V_dyn_buckets;
+ if (V_ipfw_dyn_v != NULL)
+ free(V_ipfw_dyn_v, M_IPFW);
for (;;) {
- ipfw_dyn_v = malloc(curr_dyn_buckets * sizeof(ipfw_dyn_rule *),
+ V_ipfw_dyn_v = malloc(V_curr_dyn_buckets * sizeof(ipfw_dyn_rule *),
M_IPFW, M_NOWAIT | M_ZERO);
- if (ipfw_dyn_v != NULL || curr_dyn_buckets <= 2)
+ if (V_ipfw_dyn_v != NULL || V_curr_dyn_buckets <= 2)
break;
- curr_dyn_buckets /= 2;
+ V_curr_dyn_buckets /= 2;
}
}
@@ -1339,15 +1365,16 @@
static ipfw_dyn_rule *
add_dyn_rule(struct ipfw_flow_id *id, u_int8_t dyn_type, struct ip_fw *rule)
{
+ INIT_VNET_IPFW(curvnet);
ipfw_dyn_rule *r;
int i;
IPFW_DYN_LOCK_ASSERT();
- if (ipfw_dyn_v == NULL ||
- (dyn_count == 0 && dyn_buckets != curr_dyn_buckets)) {
+ if (V_ipfw_dyn_v == NULL ||
+ (V_dyn_count == 0 && V_dyn_buckets != V_curr_dyn_buckets)) {
realloc_dynamic_table();
- if (ipfw_dyn_v == NULL)
+ if (V_ipfw_dyn_v == NULL)
return NULL; /* failed ! */
}
i = hash_packet(id);
@@ -1369,21 +1396,21 @@
}
r->id = *id;
- r->expire = time_uptime + dyn_syn_lifetime;
+ r->expire = time_uptime + V_dyn_syn_lifetime;
r->rule = rule;
r->dyn_type = dyn_type;
r->pcnt = r->bcnt = 0;
r->count = 0;
r->bucket = i;
- r->next = ipfw_dyn_v[i];
- ipfw_dyn_v[i] = r;
- dyn_count++;
+ r->next = V_ipfw_dyn_v[i];
+ V_ipfw_dyn_v[i] = r;
+ V_dyn_count++;
DEB(printf("ipfw: add dyn entry ty %d 0x%08x %d -> 0x%08x %d, total %d\n",
dyn_type,
(r->id.src_ip), (r->id.src_port),
(r->id.dst_ip), (r->id.dst_port),
- dyn_count ); )
+ V_dyn_count ); )
return r;
}
@@ -1394,15 +1421,16 @@
static ipfw_dyn_rule *
lookup_dyn_parent(struct ipfw_flow_id *pkt, struct ip_fw *rule)
{
+ INIT_VNET_IPFW(curvnet);
ipfw_dyn_rule *q;
int i;
IPFW_DYN_LOCK_ASSERT();
- if (ipfw_dyn_v) {
+ if (V_ipfw_dyn_v) {
int is_v6 = IS_IP6_FLOW_ID(pkt);
i = hash_packet( pkt );
- for (q = ipfw_dyn_v[i] ; q != NULL ; q=q->next)
+ for (q = V_ipfw_dyn_v[i] ; q != NULL ; q=q->next)
if (q->dyn_type == O_LIMIT_PARENT &&
rule== q->rule &&
pkt->proto == q->id.proto &&
@@ -1419,7 +1447,7 @@
pkt->dst_ip == q->id.dst_ip)
)
) {
- q->expire = time_uptime + dyn_short_lifetime;
+ q->expire = time_uptime + V_dyn_short_lifetime;
DEB(printf("ipfw: lookup_dyn_parent found 0x%p\n",q);)
return q;
}
@@ -1437,6 +1465,7 @@
install_state(struct ip_fw *rule, ipfw_insn_limit *cmd,
struct ip_fw_args *args, uint32_t tablearg)
{
+ INIT_VNET_IPFW(curvnet);
static int last_log;
ipfw_dyn_rule *q;
struct in_addr da;
@@ -1466,11 +1495,11 @@
return (0);
}
- if (dyn_count >= dyn_max)
+ if (V_dyn_count >= V_dyn_max)
/* Run out of slots, try to remove any expired rule. */
remove_dyn_rule(NULL, (ipfw_dyn_rule *)1);
- if (dyn_count >= dyn_max) {
+ if (V_dyn_count >= V_dyn_max) {
if (last_log != time_uptime) {
last_log = time_uptime;
printf("ipfw: %s: Too many dynamic rules\n", __func__);
@@ -1532,7 +1561,7 @@
/* See if we can remove some expired rule. */
remove_dyn_rule(rule, parent);
if (parent->count >= conn_limit) {
- if (fw_verbose && last_log != time_uptime) {
+ if (V_fw_verbose && last_log != time_uptime) {
last_log = time_uptime;
#ifdef INET6
/*
@@ -1598,6 +1627,7 @@
send_pkt(struct mbuf *replyto, struct ipfw_flow_id *id, u_int32_t seq,
u_int32_t ack, int flags)
{
+ INIT_VNET_INET(curvnet);
struct mbuf *m;
struct ip *ip;
struct tcphdr *tcp;
@@ -1675,7 +1705,7 @@
/*
* now fill fields left out earlier
*/
- ip->ip_ttl = ip_defttl;
+ ip->ip_ttl = V_ip_defttl;
ip->ip_len = m->m_pkthdr.len;
m->m_flags |= M_SKIP_FIREWALL;
return (m);
@@ -1765,6 +1795,7 @@
add_table_entry(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
uint8_t mlen, uint32_t value)
{
+ INIT_VNET_IPFW(curvnet);
struct radix_node_head *rnh;
struct table_entry *ent;
@@ -1778,14 +1809,14 @@
ent->addr.sin_len = ent->mask.sin_len = 8;
ent->mask.sin_addr.s_addr = htonl(mlen ? ~((1 << (32 - mlen)) - 1) : 0);
ent->addr.sin_addr.s_addr = addr & ent->mask.sin_addr.s_addr;
- IPFW_WLOCK(&layer3_chain);
+ IPFW_WLOCK(&V_layer3_chain);
if (rnh->rnh_addaddr(&ent->addr, &ent->mask, rnh, (void *)ent) ==
NULL) {
- IPFW_WUNLOCK(&layer3_chain);
+ IPFW_WUNLOCK(&V_layer3_chain);
free(ent, M_IPFW_TBL);
return (EEXIST);
}
- IPFW_WUNLOCK(&layer3_chain);
+ IPFW_WUNLOCK(&V_layer3_chain);
return (0);
}
@@ -1969,6 +2000,7 @@
u_int16_t src_port, struct ip_fw_ugid *ugp, int *lookup,
struct inpcb *inp)
{
+ INIT_VNET_INET(curvnet);
struct inpcbinfo *pi;
int wildcard;
struct inpcb *pcb;
@@ -1996,10 +2028,10 @@
return (0);
if (proto == IPPROTO_TCP) {
wildcard = 0;
- pi = &tcbinfo;
+ pi = &V_tcbinfo;
} else if (proto == IPPROTO_UDP) {
wildcard = INPLOOKUP_WILDCARD;
- pi = &udbinfo;
+ pi = &V_udbinfo;
} else
return 0;
match = 0;
@@ -2085,6 +2117,9 @@
int
ipfw_chk(struct ip_fw_args *args)
{
+ INIT_VNET_INET(curvnet);
+ INIT_VNET_IPFW(curvnet);
+
/*
* Local variables holding state during the processing of a packet:
*
@@ -2187,7 +2222,7 @@
*/
int dyn_dir = MATCH_UNKNOWN;
ipfw_dyn_rule *q = NULL;
- struct ip_fw_chain *chain = &layer3_chain;
+ struct ip_fw_chain *chain = &V_layer3_chain;
struct m_tag *mtag;
/*
@@ -2291,7 +2326,7 @@
printf("IPFW2: IPV6 - Unknown Routing "
"Header type(%d)\n",
((struct ip6_rthdr *)ulp)->ip6r_type);
- if (fw_deny_unknown_exthdrs)
+ if (V_fw_deny_unknown_exthdrs)
return (IP_FW_DENY);
break;
}
@@ -2315,7 +2350,7 @@
if (offset == 0) {
printf("IPFW2: IPV6 - Invalid Fragment "
"Header\n");
- if (fw_deny_unknown_exthdrs)
+ if (V_fw_deny_unknown_exthdrs)
return (IP_FW_DENY);
break;
}
@@ -2387,7 +2422,7 @@
default:
printf("IPFW2: IPV6 - Unknown Extension "
"Header(%d), ext_hd=%x\n", proto, ext_hd);
- if (fw_deny_unknown_exthdrs)
+ if (V_fw_deny_unknown_exthdrs)
return (IP_FW_DENY);
PULLUP_TO(hlen, ulp, struct ip6_ext);
break;
@@ -2468,7 +2503,7 @@
* XXX should not happen here, but optimized out in
* the caller.
*/
- if (fw_one_pass) {
+ if (V_fw_one_pass) {
IPFW_RUNLOCK(chain);
return (IP_FW_PASS);
}
@@ -2513,7 +2548,7 @@
int l, cmdlen, skip_or; /* skip rest of OR block */
again:
- if (set_disable & (1 << f->set) )
+ if (V_set_disable & (1 << f->set) )
continue;
skip_or = 0;
@@ -2899,7 +2934,7 @@
}
case O_LOG:
- if (fw_verbose)
+ if (V_fw_verbose)
ipfw_log(f, hlen, args, m,
oif, offset, tablearg, ip);
match = 1;
@@ -3315,7 +3350,7 @@
if (t == NULL) {
nat_id = (cmd->arg1 == IP_FW_TABLEARG) ?
tablearg : cmd->arg1;
- LOOKUP_NAT(layer3_chain, nat_id, t);
+ LOOKUP_NAT(V_layer3_chain, nat_id, t);
if (t == NULL) {
retval = IP_FW_DENY;
goto done;
@@ -3362,7 +3397,7 @@
return (retval);
pullup_failed:
- if (fw_verbose)
+ if (V_fw_verbose)
printf("ipfw: pullup failed\n");
return (IP_FW_DENY);
}
@@ -3390,6 +3425,7 @@
static int
add_rule(struct ip_fw_chain *chain, struct ip_fw *input_rule)
{
+ INIT_VNET_IPFW(curvnet);
struct ip_fw *rule, *f, *prev;
int l = RULESIZE(input_rule);
@@ -3420,10 +3456,10 @@
* If rulenum is 0, find highest numbered rule before the
* default rule, and add autoinc_step
*/
- if (autoinc_step < 1)
- autoinc_step = 1;
- else if (autoinc_step > 1000)
- autoinc_step = 1000;
+ if (V_autoinc_step < 1)
+ V_autoinc_step = 1;
+ else if (V_autoinc_step > 1000)
+ V_autoinc_step = 1000;
if (rule->rulenum == 0) {
/*
* locate the highest numbered rule before default
@@ -3433,8 +3469,8 @@
break;
rule->rulenum = f->rulenum;
}
- if (rule->rulenum < IPFW_DEFAULT_RULE - autoinc_step)
- rule->rulenum += autoinc_step;
+ if (rule->rulenum < IPFW_DEFAULT_RULE - V_autoinc_step)
+ rule->rulenum += V_autoinc_step;
input_rule->rulenum = rule->rulenum;
}
@@ -3455,11 +3491,11 @@
}
flush_rule_ptrs(chain);
done:
- static_count++;
- static_len += l;
+ V_static_count++;
+ V_static_len += l;
IPFW_WUNLOCK(chain);
DEB(printf("ipfw: installed rule %d, static count now %d\n",
- rule->rulenum, static_count);)
+ rule->rulenum, V_static_count);)
return (0);
}
@@ -3475,6 +3511,7 @@
remove_rule(struct ip_fw_chain *chain, struct ip_fw *rule,
struct ip_fw *prev)
{
+ INIT_VNET_IPFW(curvnet);
struct ip_fw *n;
int l = RULESIZE(rule);
@@ -3488,8 +3525,8 @@
chain->rules = n;
else
prev->next = n;
- static_count--;
- static_len -= l;
+ V_static_count--;
+ V_static_len -= l;
rule->next = chain->reap;
chain->reap = rule;
@@ -3689,6 +3726,7 @@
static int
zero_entry(struct ip_fw_chain *chain, u_int32_t arg, int log_only)
{
+ INIT_VNET_IPFW(curvnet);
struct ip_fw *rule;
char *msg;
@@ -3703,7 +3741,7 @@
IPFW_WLOCK(chain);
if (rulenum == 0) {
- norule_counter = 0;
+ V_norule_counter = 0;
for (rule = chain->rules; rule; rule = rule->next) {
/* Skip rules from another set. */
if (cmd == 1 && rule->set != set)
@@ -3737,7 +3775,7 @@
}
IPFW_WUNLOCK(chain);
- if (fw_verbose)
+ if (V_fw_verbose)
log(LOG_SECURITY | LOG_NOTICE, msg, rulenum);
return (0);
}
@@ -4056,6 +4094,7 @@
static size_t
ipfw_getrules(struct ip_fw_chain *chain, void *buf, size_t space)
{
+ INIT_VNET_IPFW(curvnet);
char *bp = buf;
char *ep = bp + space;
struct ip_fw *rule;
@@ -4080,20 +4119,21 @@
* in a wild attempt to keep the ABI the same.
* Why do we do this on EVERY rule?
*/
- bcopy(&set_disable, &(((struct ip_fw *)bp)->next_rule),
- sizeof(set_disable));
+ bcopy(&V_set_disable,
+ &(((struct ip_fw *)bp)->next_rule),
+ sizeof(V_set_disable));
if (((struct ip_fw *)bp)->timestamp)
((struct ip_fw *)bp)->timestamp += boot_seconds;
bp += i;
}
}
IPFW_RUNLOCK(chain);
- if (ipfw_dyn_v) {
+ if (V_ipfw_dyn_v) {
ipfw_dyn_rule *p, *last = NULL;
IPFW_DYN_LOCK();
- for (i = 0 ; i < curr_dyn_buckets; i++)
- for (p = ipfw_dyn_v[i] ; p != NULL; p = p->next) {
+ for (i = 0 ; i < V_curr_dyn_buckets; i++)
+ for (p = V_ipfw_dyn_v[i] ; p != NULL; p = p->next) {
if (bp + sizeof *p <= ep) {
ipfw_dyn_rule *dst =
(ipfw_dyn_rule *)bp;
@@ -4136,6 +4176,7 @@
static int
ipfw_ctl(struct sockopt *sopt)
{
+ INIT_VNET_IPFW(curvnet);
#define RULE_MAXSIZE (256*sizeof(u_int32_t))
int error;
size_t size;
@@ -4172,9 +4213,9 @@
* change between calculating the size and returning the
* data in which case we'll just return what fits.
*/
- size = static_len; /* size of static rules */
- if (ipfw_dyn_v) /* add size of dyn.rules */
- size += (dyn_count * sizeof(ipfw_dyn_rule));
+ size = V_static_len; /* size of static rules */
+ if (V_ipfw_dyn_v) /* add size of dyn.rules */
+ size += (V_dyn_count * sizeof(ipfw_dyn_rule));
/*
* XXX todo: if the user passes a short length just to know
@@ -4183,7 +4224,7 @@
*/
buf = malloc(size, M_TEMP, M_WAITOK);
error = sooptcopyout(sopt, buf,
- ipfw_getrules(&layer3_chain, buf, size));
+ ipfw_getrules(&V_layer3_chain, buf, size));
free(buf, M_TEMP);
break;
@@ -4201,12 +4242,12 @@
* the old list without the need for a lock.
*/
- IPFW_WLOCK(&layer3_chain);
- layer3_chain.reap = NULL;
- free_chain(&layer3_chain, 0 /* keep default rule */);
- rule = layer3_chain.reap;
- layer3_chain.reap = NULL;
- IPFW_WUNLOCK(&layer3_chain);
+ IPFW_WLOCK(&V_layer3_chain);
+ V_layer3_chain.reap = NULL;
+ free_chain(&V_layer3_chain, 0 /* keep default rule */);
+ rule = V_layer3_chain.reap;
+ V_layer3_chain.reap = NULL;
+ IPFW_WUNLOCK(&V_layer3_chain);
if (rule != NULL)
reap_rules(rule);
break;
@@ -4218,7 +4259,7 @@
if (error == 0)
error = check_ipfw_struct(rule, sopt->sopt_valsize);
if (error == 0) {
- error = add_rule(&layer3_chain, rule);
+ error = add_rule(&V_layer3_chain, rule);
size = RULESIZE(rule);
if (!error && sopt->sopt_dir == SOPT_GET)
error = sooptcopyout(sopt, rule, size);
@@ -4245,10 +4286,10 @@
break;
size = sopt->sopt_valsize;
if (size == sizeof(u_int32_t)) /* delete or reassign */
- error = del_entry(&layer3_chain, rulenum[0]);
+ error = del_entry(&V_layer3_chain, rulenum[0]);
else if (size == 2*sizeof(u_int32_t)) /* set enable/disable */
- set_disable =
- (set_disable | rulenum[0]) & ~rulenum[1] &
+ V_set_disable =
+ (V_set_disable | rulenum[0]) & ~rulenum[1] &
~(1<<RESVD_SET); /* set RESVD_SET always enabled */
else
error = EINVAL;
@@ -4263,7 +4304,7 @@
if (error)
break;
}
- error = zero_entry(&layer3_chain, rulenum[0],
+ error = zero_entry(&V_layer3_chain, rulenum[0],
sopt->sopt_name == IP_FW_RESETLOG);
break;
@@ -4275,7 +4316,7 @@
sizeof(ent), sizeof(ent));
if (error)
break;
- error = add_table_entry(&layer3_chain, ent.tbl,
+ error = add_table_entry(&V_layer3_chain, ent.tbl,
ent.addr, ent.masklen, ent.value);
}
break;
@@ -4288,7 +4329,7 @@
sizeof(ent), sizeof(ent));
if (error)
break;
- error = del_table_entry(&layer3_chain, ent.tbl,
+ error = del_table_entry(&V_layer3_chain, ent.tbl,
ent.addr, ent.masklen);
}
break;
@@ -4301,9 +4342,9 @@
sizeof(tbl), sizeof(tbl));
if (error)
break;
- IPFW_WLOCK(&layer3_chain);
- error = flush_table(&layer3_chain, tbl);
- IPFW_WUNLOCK(&layer3_chain);
+ IPFW_WLOCK(&V_layer3_chain);
+ error = flush_table(&V_layer3_chain, tbl);
+ IPFW_WUNLOCK(&V_layer3_chain);
}
break;
@@ -4314,9 +4355,9 @@
if ((error = sooptcopyin(sopt, &tbl, sizeof(tbl),
sizeof(tbl))))
break;
- IPFW_RLOCK(&layer3_chain);
- error = count_table(&layer3_chain, tbl, &cnt);
- IPFW_RUNLOCK(&layer3_chain);
+ IPFW_RLOCK(&V_layer3_chain);
+ error = count_table(&V_layer3_chain, tbl, &cnt);
+ IPFW_RUNLOCK(&V_layer3_chain);
if (error)
break;
error = sooptcopyout(sopt, &cnt, sizeof(cnt));
@@ -4340,9 +4381,9 @@
}
tbl->size = (size - sizeof(*tbl)) /
sizeof(ipfw_table_entry);
- IPFW_RLOCK(&layer3_chain);
- error = dump_table(&layer3_chain, tbl);
- IPFW_RUNLOCK(&layer3_chain);
+ IPFW_RLOCK(&V_layer3_chain);
+ error = dump_table(&V_layer3_chain, tbl);
+ IPFW_RUNLOCK(&V_layer3_chain);
if (error) {
free(tbl, M_TEMP);
break;
@@ -4420,13 +4461,16 @@
* every dyn_keepalive_period
*/
static void
-ipfw_tick(void * __unused unused)
+ipfw_tick(void *arg)
{
+#ifdef VIMAGE
+ struct vnet_ipfw *vnet_ipfw = arg;
+#endif
struct mbuf *m0, *m, *mnext, **mtailp;
int i;
ipfw_dyn_rule *q;
- if (dyn_keepalive == 0 || ipfw_dyn_v == NULL || dyn_count == 0)
+ if (V_dyn_keepalive == 0 || V_ipfw_dyn_v == NULL || V_dyn_count == 0)
goto done;
/*
@@ -4438,15 +4482,15 @@
m0 = NULL;
mtailp = &m0;
IPFW_DYN_LOCK();
- for (i = 0 ; i < curr_dyn_buckets ; i++) {
- for (q = ipfw_dyn_v[i] ; q ; q = q->next ) {
+ for (i = 0 ; i < V_curr_dyn_buckets ; i++) {
+ for (q = V_ipfw_dyn_v[i] ; q ; q = q->next ) {
if (q->dyn_type == O_LIMIT_PARENT)
continue;
if (q->id.proto != IPPROTO_TCP)
continue;
if ( (q->state & BOTH_SYN) != BOTH_SYN)
continue;
- if (TIME_LEQ( time_uptime+dyn_keepalive_interval,
+ if (TIME_LEQ( time_uptime + V_dyn_keepalive_interval,
q->expire))
continue; /* too early */
if (TIME_LEQ(q->expire, time_uptime))
@@ -4469,37 +4513,40 @@
ip_output(m, NULL, NULL, 0, NULL, NULL);
}
done:
- callout_reset(&ipfw_timeout, dyn_keepalive_period*hz, ipfw_tick, NULL);
+ callout_reset(&V_ipfw_timeout, V_dyn_keepalive_period * hz,
+ ipfw_tick, arg);
}
-int
-ipfw_init(void)
+static int vnet_ipfw_iattach(const void *unused)
{
+ INIT_VNET_IPFW(curvnet);
struct ip_fw default_rule;
int error;
-#ifdef INET6
- /* Setup IPv6 fw sysctl tree. */
- sysctl_ctx_init(&ip6_fw_sysctl_ctx);
- ip6_fw_sysctl_tree = SYSCTL_ADD_NODE(&ip6_fw_sysctl_ctx,
- SYSCTL_STATIC_CHILDREN(_net_inet6_ip6), OID_AUTO, "fw",
- CTLFLAG_RW | CTLFLAG_SECURE, 0, "Firewall");
- SYSCTL_ADD_PROC(&ip6_fw_sysctl_ctx, SYSCTL_CHILDREN(ip6_fw_sysctl_tree),
- OID_AUTO, "enable", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3,
- &fw6_enable, 0, ipfw_chg_hook, "I", "Enable ipfw+6");
- SYSCTL_ADD_INT(&ip6_fw_sysctl_ctx, SYSCTL_CHILDREN(ip6_fw_sysctl_tree),
- OID_AUTO, "deny_unknown_exthdrs", CTLFLAG_RW | CTLFLAG_SECURE,
- &fw_deny_unknown_exthdrs, 0,
- "Deny packets with unknown IPv6 Extension Headers");
-#endif
-
- layer3_chain.rules = NULL;
- IPFW_LOCK_INIT(&layer3_chain);
+ V_fw_debug = 1;
+ V_autoinc_step = 100; /* bounded to 1..1000 in add_rule() */
+ V_dyn_buckets = 256; /* must be power of 2 */
+ V_curr_dyn_buckets = 256; /* must be power of 2 */
+ V_dyn_ack_lifetime = 300;
+ V_dyn_syn_lifetime = 20;
+ V_dyn_fin_lifetime = 1;
+ V_dyn_rst_lifetime = 1;
+ V_dyn_udp_lifetime = 10;
+ V_dyn_short_lifetime = 5;
+ V_dyn_keepalive_interval = 20;
+ V_dyn_keepalive_period = 5;
+ V_dyn_keepalive = 1; /* do send keepalives */
+ V_dyn_max = 4096; /* max # of dynamic rules */
+ V_fw_deny_unknown_exthdrs = 1;
+
+ V_layer3_chain.rules = NULL;
+ IPFW_LOCK_INIT(&V_layer3_chain);
+#if 0 /* XXX Marko fix this! */
ipfw_dyn_rule_zone = uma_zcreate("IPFW dynamic rule",
sizeof(ipfw_dyn_rule), NULL, NULL, NULL, NULL,
UMA_ALIGN_PTR, 0);
- IPFW_DYN_LOCK_INIT();
- callout_init(&ipfw_timeout, CALLOUT_MPSAFE);
+#endif
+ callout_init(&V_ipfw_timeout, CALLOUT_MPSAFE);
bzero(&default_rule, sizeof default_rule);
@@ -4515,17 +4562,66 @@
#endif
O_DENY;
- error = add_rule(&layer3_chain, &default_rule);
+ error = add_rule(&V_layer3_chain, &default_rule);
if (error != 0) {
printf("ipfw2: error %u initializing default rule "
"(support disabled)\n", error);
IPFW_DYN_LOCK_DESTROY();
- IPFW_LOCK_DESTROY(&layer3_chain);
+ IPFW_LOCK_DESTROY(&V_layer3_chain);
uma_zdestroy(ipfw_dyn_rule_zone);
return (error);
}
- ip_fw_default_rule = layer3_chain.rules;
+ ip_fw_default_rule = V_layer3_chain.rules;
+
+#ifdef IPFIREWALL_VERBOSE
+ V_fw_verbose = 1;
+#endif
+#ifdef IPFIREWALL_VERBOSE_LIMIT
+ V_verbose_limit = IPFIREWALL_VERBOSE_LIMIT;
+#endif
+
+ error = init_tables(&V_layer3_chain);
+ if (error) {
+ panic("init_tables"); /* XXX Marko fix this ! */
+ }
+#ifdef VIMAGE
+ callout_reset(&V_ipfw_timeout, hz, ipfw_tick, (void *) vnet_ipfw);
+#else
+ callout_reset(&V_ipfw_timeout, hz, ipfw_tick, NULL);
+#endif
+
+#ifdef IPFIREWALL_NAT
+ LIST_INIT(&V_layer3_chain.nat);
+#endif
+
+ return 0;
+}
+
+int
+ipfw_init(void)
+{
+ ipfw_dyn_rule_zone = uma_zcreate("IPFW dynamic rule",
+ sizeof(ipfw_dyn_rule), NULL, NULL, NULL, NULL,
+ UMA_ALIGN_PTR, 0);
+ IPFW_DYN_LOCK_INIT();
+
+#if 0 /* MARKO XXX */
+ /* error = init_tables(&V_layer3_chain); moved to _iattach() */
+ if (error) {
+ IPFW_DYN_LOCK_DESTROY();
+ IPFW_LOCK_DESTROY(&V_layer3_chain);
+ uma_zdestroy(ipfw_dyn_rule_zone);
+ return (error);
+ }
+#endif
+
+#ifdef VIMAGE
+ vnet_mod_register(&vnet_ipfw_modinfo);
+#else
+ vnet_ipfw_iattach(NULL);
+#endif
+
printf("ipfw2 "
#ifdef INET6
"(+ipv6) "
@@ -4543,68 +4639,74 @@
#else
"loadable",
#endif
+
#ifdef IPFIREWALL_NAT
"enabled",
#else
- "loadable",
+ "disabled, ",
#endif
- default_rule.cmd[0].opcode == O_ACCEPT ? "accept" : "deny");
+#ifdef IPFIREWALL_DEFAULT_TO_ACCEPT
+ "accept"
+#else
+ "deny"
+#endif
+ );
#ifdef IPFIREWALL_VERBOSE
- fw_verbose = 1;
-#endif
-#ifdef IPFIREWALL_VERBOSE_LIMIT
- verbose_limit = IPFIREWALL_VERBOSE_LIMIT;
-#endif
- if (fw_verbose == 0)
printf("disabled\n");
- else if (verbose_limit == 0)
+#else
+# ifndef IPFIREWALL_VERBOSE_LIMIT
printf("unlimited\n");
- else
+# else
printf("limited to %d packets/entry by default\n",
- verbose_limit);
+ IPFIREWALL_VERBOSE_LIMIT);
+# endif
+#endif
- error = init_tables(&layer3_chain);
- if (error) {
- IPFW_DYN_LOCK_DESTROY();
- IPFW_LOCK_DESTROY(&layer3_chain);
- uma_zdestroy(ipfw_dyn_rule_zone);
- return (error);
- }
ip_fw_ctl_ptr = ipfw_ctl;
ip_fw_chk_ptr = ipfw_chk;
- callout_reset(&ipfw_timeout, hz, ipfw_tick, NULL);
- LIST_INIT(&layer3_chain.nat);
return (0);
}
-void
-ipfw_destroy(void)
+static int vnet_ipfw_idetach(const void *unused)
{
+ INIT_VNET_IPFW(curvnet);
struct ip_fw *reap;
- ip_fw_chk_ptr = NULL;
- ip_fw_ctl_ptr = NULL;
- callout_drain(&ipfw_timeout);
- IPFW_WLOCK(&layer3_chain);
- flush_tables(&layer3_chain);
- layer3_chain.reap = NULL;
- free_chain(&layer3_chain, 1 /* kill default rule */);
- reap = layer3_chain.reap, layer3_chain.reap = NULL;
- IPFW_WUNLOCK(&layer3_chain);
+ callout_drain(&V_ipfw_timeout);
+ IPFW_WLOCK(&V_layer3_chain);
+ flush_tables(&V_layer3_chain);
+ V_layer3_chain.reap = NULL;
+ free_chain(&V_layer3_chain, 1 /* kill default rule */);
+ reap = V_layer3_chain.reap, V_layer3_chain.reap = NULL;
+ IPFW_WUNLOCK(&V_layer3_chain);
if (reap != NULL)
reap_rules(reap);
- IPFW_DYN_LOCK_DESTROY();
- uma_zdestroy(ipfw_dyn_rule_zone);
- if (ipfw_dyn_v != NULL)
- free(ipfw_dyn_v, M_IPFW);
- IPFW_LOCK_DESTROY(&layer3_chain);
+ IPFW_LOCK_DESTROY(&V_layer3_chain);
+ if (V_ipfw_dyn_v != NULL)
+ free(V_ipfw_dyn_v, M_IPFW);
-#ifdef INET6
- /* Free IPv6 fw sysctl tree. */
- sysctl_ctx_free(&ip6_fw_sysctl_ctx);
+ return 0;
+}
+
+void
+ipfw_destroy(void)
+{
+ ip_fw_chk_ptr = NULL;
+ ip_fw_ctl_ptr = NULL;
+
+#ifdef VIMAGE
+ vnet_mod_deregister(&vnet_ipfw_modinfo);
+#else
+ vnet_ipfw_idetach(NULL);
+#endif
+
+#ifdef IPFIREWALL_NAT
+ EVENTHANDLER_DEREGISTER(ifaddr_event, ifaddr_event_tag);
#endif
+ IPFW_DYN_LOCK_DESTROY();
+ uma_zdestroy(ipfw_dyn_rule_zone);
printf("IP firewall unloaded\n");
}
More information about the freebsd-current
mailing list