PERFORCE change 112781 for review

Marko Zec zec at FreeBSD.org
Thu Jan 11 10:11:58 PST 2007


http://perforce.freebsd.org/chv.cgi?CH=112781

Change 112781 by zec at zec_tca51 on 2007/01/11 18:11:40

	First pass at virtualizing ipfw.

Affected files ...

.. //depot/projects/vimage/src/sys/net/if_ethersubr.c#6 edit
.. //depot/projects/vimage/src/sys/netinet/ip_fw.h#3 edit
.. //depot/projects/vimage/src/sys/netinet/ip_fw2.c#5 edit
.. //depot/projects/vimage/src/sys/netinet/ip_fw_pfil.c#3 edit
.. //depot/projects/vimage/src/sys/sys/vimage.h#10 edit

Differences ...

==== //depot/projects/vimage/src/sys/net/if_ethersubr.c#6 (text+ko) ====

@@ -131,8 +131,10 @@
 int
 ether_ipfw_chk(struct mbuf **m0, struct ifnet *dst,
 	struct ip_fw **rule, int shared);
+#ifndef VIMAGE
 static int ether_ipfw;
 #endif
+#endif
 
 /*
  * Ethernet output routine.
@@ -380,9 +382,10 @@
 {
 	int error;
 #if defined(INET) || defined(INET6)
+	INIT_VNET_IPFW(ifp->if_vnetb);
 	struct ip_fw *rule = ip_dn_claim_rule(m);
 
-	if (IPFW_LOADED && ether_ipfw != 0) {
+	if (IPFW_LOADED && V_ether_ipfw != 0) {
 		if (ether_ipfw_chk(&m, ifp, &rule, 0) == 0) {
 			if (m) {
 				m_freem(m);
@@ -411,13 +414,14 @@
 ether_ipfw_chk(struct mbuf **m0, struct ifnet *dst,
 	struct ip_fw **rule, int shared)
 {
+	INIT_VNET_IPFW(dst->if_vnetb);
 	struct ether_header *eh;
 	struct ether_header save_eh;
 	struct mbuf *m;
 	int i;
 	struct ip_fw_args args;
 
-	if (*rule != NULL && fw_one_pass)
+	if (*rule != NULL && V_fw_one_pass)
 		return 1; /* dummynet packet, already partially processed */
 
 	/*
@@ -704,7 +708,8 @@
 
 #if defined(INET) || defined(INET6)
 post_stats:
-	if (IPFW_LOADED && ether_ipfw != 0) {
+	INIT_VNET_IPFW(ifp->if_vnetb);
+	if (IPFW_LOADED && V_ether_ipfw != 0) {
 		if (ether_ipfw_chk(&m, NULL, &rule, 0) == 0) {
 			if (m)
 				m_freem(m);
@@ -930,8 +935,8 @@
 SYSCTL_DECL(_net_link);
 SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet");
 #if defined(INET) || defined(INET6)
-SYSCTL_INT(_net_link_ether, OID_AUTO, ipfw, CTLFLAG_RW,
-	    &ether_ipfw,0,"Pass ether pkts through firewall");
+SYSCTL_V_INT(V_NET, vnet_ipfw, _net_link_ether, OID_AUTO, ipfw, CTLFLAG_RW,
+	     ether_ipfw, 0, "Pass ether pkts through firewall");
 #endif
 
 #if 0

==== //depot/projects/vimage/src/sys/netinet/ip_fw.h#3 (text+ko) ====

@@ -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
@@ -533,6 +536,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,
@@ -602,16 +633,109 @@
 
 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);
 extern	ip_fw_chk_t	*ip_fw_chk_ptr;
 #define	IPFW_LOADED	(ip_fw_chk_ptr != NULL)
 
+/*
+ * Stack virtualization support.
+ */
+ 
+#ifdef VIMAGE
+struct vnet_ipfw {
+	struct	vnet_base *parent_vnetb;
+
+	int	_fw_one_pass;
+	int	_fw_enable;
+	int	_fw6_enable;
+	int	_ether_ipfw;
+
+	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(vnetb) \
+	INIT_FROM_VNET_BASE(vnetb, 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_ether_ipfw		VNET_IPFW(ether_ipfw)
+
+#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 */

==== //depot/projects/vimage/src/sys/netinet/ip_fw2.c#5 (text+ko) ====

@@ -114,6 +114,19 @@
 
 #include <security/mac/mac_framework.h>
 
+static int	vnet_ipfw_iattach(void);
+
+#ifdef VIMAGE
+static struct vnet_modinfo vnet_ipfw_modinfo = {
+	.id		= VNET_MOD_IPFW,
+	.flags		= VNET_MFLAG_ORDER_2ND,
+	.name		= "ipfw",
+	.symmap		= NULL,
+	.i_attach	= vnet_ipfw_iattach,
+	.i_detach	= NULL,
+};
+#endif
+
 /*
  * set_disable contains one bit per set value (0..31).
  * If the bit is set, all rules with the corresponding set
@@ -122,41 +135,23 @@
  * 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;
-};
-
-#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)
 #define	IPFW_WLOCK_ASSERT(_chain)	do {				\
-	rw_assert(&(_chain)->rwmtx, RA_WLOCKED);					\
+	rw_assert(&(_chain)->rwmtx, RA_WLOCKED);			\
 	NET_ASSERT_GIANT();						\
 } while (0)
 
@@ -168,40 +163,42 @@
 /*
  * list of rules for layer 3
  */
+#ifndef VIMAGE
 static 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");
 
-struct table_entry {
-	struct radix_node	rn[2];
-	struct sockaddr_in	addr, mask;
-	u_int32_t		value;
-};
+#ifndef VIMAGE
+static int fw_debug;
+static int autoinc_step;
+#endif
 
-static int fw_debug = 1;
-static int autoinc_step = 100; /* bounded to 1..1000 in add_rule() */
-
+#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.
@@ -239,9 +236,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() \
@@ -254,12 +253,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
@@ -268,40 +269,42 @@
  * 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");
 
 #ifdef INET6
 /*
@@ -317,8 +320,9 @@
 #ifdef IPFIREWALL_NAT
 MODULE_DEPEND(ipfw, libalias, 1, 1, 1);
 #endif
-static int fw_deny_unknown_exthdrs = 1;
-
+#ifndef VIMAGE
+static int fw_deny_unknown_exthdrs;
+#endif
 
 /*
  * L3HDR maps an ipv4 pointer into a layer3 header pointer of type T
@@ -655,6 +659,7 @@
 	return 1;
 
 }
+
 static __inline int
 hash_packet6(struct ipfw_flow_id *id)
 {
@@ -765,7 +770,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)
@@ -779,6 +786,7 @@
 	struct mbuf *m, struct ifnet *oif, u_short offset, uint32_t tablearg,
 	struct ip  *ip)
 {
+	INIT_VNET_IPFW(curvnetb);
 	struct ether_header *eh = args->eh;
 	char *action;
 	int limit_reached = 0;
@@ -788,11 +796,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);
@@ -1047,6 +1055,7 @@
 static __inline int
 hash_packet(struct ipfw_flow_id *id)
 {
+	INIT_VNET_IPFW(curvnetb);
 	u_int32_t i;
 
 #ifdef INET6
@@ -1055,7 +1064,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;
 }
 
@@ -1073,12 +1082,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)
@@ -1098,6 +1107,7 @@
 static void
 remove_dyn_rule(struct ip_fw *rule, ipfw_dyn_rule *keep_me)
 {
+	INIT_VNET_IPFW(curvnetb);
 	static u_int32_t last_remove = 0;
 
 #define FORCE (keep_me == NULL)
@@ -1107,7 +1117,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)
@@ -1120,8 +1130,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.
 			 */
@@ -1148,7 +1158,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:
@@ -1168,6 +1178,7 @@
 lookup_dyn_rule_locked(struct ipfw_flow_id *pkt, int *match_direction,
 	struct tcphdr *tcp)
 {
+	INIT_VNET_IPFW(curvnetb);
 	/*
 	 * stateful ipfw extensions.
 	 * Lookup into dynamic session queue
@@ -1181,14 +1192,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 &&
@@ -1238,8 +1249,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);
@@ -1249,7 +1260,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 */
@@ -1272,13 +1283,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:
@@ -1290,16 +1301,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)
@@ -1324,6 +1335,7 @@
 static void
 realloc_dynamic_table(void)
 {
+	INIT_VNET_IPFW(curvnetb);
 	IPFW_DYN_LOCK_ASSERT();
 
 	/*
@@ -1332,21 +1344,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;
 	}
 }
 
@@ -1363,15 +1375,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(curvnetb);
 	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);
@@ -1393,21 +1406,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;
 }
 
@@ -1418,15 +1431,16 @@
 static ipfw_dyn_rule *
 lookup_dyn_parent(struct ipfw_flow_id *pkt, struct ip_fw *rule)
 {
+	INIT_VNET_IPFW(curvnetb);
 	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 &&
@@ -1443,7 +1457,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;
 			}
@@ -1461,6 +1475,7 @@
 install_state(struct ip_fw *rule, ipfw_insn_limit *cmd,
     struct ip_fw_args *args, uint32_t tablearg)
 {
+	INIT_VNET_IPFW(curvnetb);
 	static int last_log;
 	ipfw_dyn_rule *q;
 	struct in_addr da;
@@ -1490,11 +1505,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__);
@@ -1555,7 +1570,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
 					/*
@@ -1786,6 +1801,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(curvnetb);
 	struct radix_node_head *rnh;
 	struct table_entry *ent;
 
@@ -1799,14 +1815,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);
 }
 
@@ -2079,9 +2095,9 @@
 	struct cfg_nat *ptr;
 	struct ifaddr *ifa;
 
-	IPFW_WLOCK(&layer3_chain);			
+	IPFW_WLOCK(&V_layer3_chain);			
 	/* Check every nat entry... */
-	LIST_FOREACH(ptr, &layer3_chain.nat, _next) {
+	LIST_FOREACH(ptr, &V_layer3_chain.nat, _next) {
 		/* ...using nic 'ifp->if_xname' as dynamic alias address. */
 		if (strncmp(ptr->if_name, ifp->if_xname, IF_NAMESIZE) == 0) {
 			mtx_lock(&ifp->if_addr_mtx);
@@ -2097,15 +2113,15 @@
 			mtx_unlock(&ifp->if_addr_mtx);
 		}
 	}
-	IPFW_WUNLOCK(&layer3_chain);	
+	IPFW_WUNLOCK(&V_layer3_chain);	
 }
 
 static void
 flush_nat_ptrs(const int i) {
 	struct ip_fw *rule;
 
-	IPFW_WLOCK_ASSERT(&layer3_chain);
-	for (rule = layer3_chain.rules; rule; rule = rule->next) {
+	IPFW_WLOCK_ASSERT(&V_layer3_chain);
+	for (rule = V_layer3_chain.rules; rule; rule = rule->next) {
 		ipfw_insn_nat *cmd = (ipfw_insn_nat *)ACTION_PTR(rule);
 		if (cmd->o.opcode != O_NAT)
 			continue;
@@ -2118,19 +2134,19 @@
 lookup_nat(const int i) {
 	struct cfg_nat *ptr;
 
-	LIST_FOREACH(ptr, &layer3_chain.nat, _next)
+	LIST_FOREACH(ptr, &V_layer3_chain.nat, _next)
 		if (ptr->id == i)
 			return(ptr);
 	return (NULL);
 }
 
 #define HOOK_NAT(b, p) do {                                     \
-	IPFW_WLOCK_ASSERT(&layer3_chain);                       \
+	IPFW_WLOCK_ASSERT(&V_layer3_chain);                       \
         LIST_INSERT_HEAD(b, p, _next);                          \
 } while (0)
 
 #define UNHOOK_NAT(p) do {                                      \
-	IPFW_WLOCK_ASSERT(&layer3_chain);                       \
+	IPFW_WLOCK_ASSERT(&V_layer3_chain);                       \
         LIST_REMOVE(p, _next);                                  \
 } while (0)
 
@@ -2283,6 +2299,7 @@
 ipfw_chk(struct ip_fw_args *args)
 {
 	INIT_VNET_INET(curvnetb);
+	INIT_VNET_IPFW(curvnetb);
 
 	/*
 	 * Local variables holding state during the processing of a packet:
@@ -2386,7 +2403,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;
 
 	/*
@@ -2485,7 +2502,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;
 				}
@@ -2509,7 +2526,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;
 				}
@@ -2578,7 +2595,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;
@@ -2659,7 +2676,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);
 		}
@@ -2704,7 +2721,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;
@@ -3094,7 +3111,7 @@
 			}
 
 			case O_LOG:
-				if (fw_verbose)
+				if (V_fw_verbose)
 					ipfw_log(f, hlen, args, m,
 					    oif, offset, tablearg, ip);
 				match = 1;
@@ -3695,7 +3712,7 @@
 	return (retval);
 
 pullup_failed:
-	if (fw_verbose)
+	if (V_fw_verbose)
 		printf("ipfw: pullup failed\n");
 	return (IP_FW_DENY);
 }
@@ -3723,6 +3740,7 @@
 static int
 add_rule(struct ip_fw_chain *chain, struct ip_fw *input_rule)
 {
+	INIT_VNET_IPFW(curvnetb);
 	struct ip_fw *rule, *f, *prev;
 	int l = RULESIZE(input_rule);
 
@@ -3753,10 +3771,10 @@
 	 * If rulenum is 0, find highest numbered rule before the

>>> TRUNCATED FOR MAIL (1000 lines) <<<


More information about the p4-projects mailing list