svn commit: r195862 - head/sys/netinet/ipfw

Julian Elischer julian at FreeBSD.org
Sat Jul 25 06:42:43 UTC 2009


Author: julian
Date: Sat Jul 25 06:42:42 2009
New Revision: 195862
URL: http://svn.freebsd.org/changeset/base/195862

Log:
  Catch ipfw up to the rest of the vimage code.
  It got left behind when it moved to its new location.
  
  Approved by:	re (kensmith)

Modified:
  head/sys/netinet/ipfw/ip_fw2.c

Modified: head/sys/netinet/ipfw/ip_fw2.c
==============================================================================
--- head/sys/netinet/ipfw/ip_fw2.c	Sat Jul 25 02:37:59 2009	(r195861)
+++ head/sys/netinet/ipfw/ip_fw2.c	Sat Jul 25 06:42:42 2009	(r195862)
@@ -152,6 +152,8 @@ struct table_entry {
 
 static VNET_DEFINE(int, autoinc_step);
 #define	V_autoinc_step			VNET(autoinc_step)
+static VNET_DEFINE(int, fw_deny_unknown_exthdrs);
+#define	V_fw_deny_unknown_exthdrs	VNET(fw_deny_unknown_exthdrs)
 
 extern int ipfw_chg_hook(SYSCTL_HANDLER_ARGS);
 
@@ -161,24 +163,38 @@ SYSCTL_VNET_PROC(_net_inet_ip_fw, OID_AU
     CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_enable), 0,
     ipfw_chg_hook, "I", "Enable ipfw");
 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, autoinc_step,
-    CTLFLAG_RW, &VNET_NAME(autoinc_step), 0, "Rule number auto-increment step");
+    CTLFLAG_RW, &VNET_NAME(autoinc_step), 0,
+    "Rule number auto-increment step");
 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, one_pass,
     CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_one_pass), 0,
     "Only do a single pass through ipfw when using dummynet(4)");
 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, verbose,
-    CTLFLAG_RW | CTLFLAG_SECURE3,
-    &VNET_NAME(fw_verbose), 0, "Log matches to ipfw rules");
+    CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_verbose), 0,
+    "Log matches to ipfw rules");
 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, verbose_limit,
     CTLFLAG_RW, &VNET_NAME(verbose_limit), 0,
     "Set upper limit of matches of ipfw rules logged");
 SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, default_rule, CTLFLAG_RD,
-    NULL, IPFW_DEFAULT_RULE, "The default/max possible rule number.");
+    NULL, IPFW_DEFAULT_RULE,
+    "The default/max possible rule number.");
 SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, tables_max, CTLFLAG_RD,
-    NULL, IPFW_TABLES_MAX, "The maximum number of tables.");
+    NULL, IPFW_TABLES_MAX,
+    "The maximum number of tables.");
 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, default_to_accept, CTLFLAG_RDTUN,
-    &default_to_accept, 0, "Make the default rule accept all packets.");
+    &default_to_accept, 0,
+    "Make the default rule accept all packets.");
 TUNABLE_INT("net.inet.ip.fw.default_to_accept", &default_to_accept);
-#endif /* SYSCTL_NODE */
+#ifdef INET6
+SYSCTL_DECL(_net_inet6_ip6);
+SYSCTL_NODE(_net_inet6_ip6, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
+SYSCTL_VNET_PROC(_net_inet6_ip6_fw, OID_AUTO, enable,
+    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw6_enable), 0,
+    ipfw_chg_hook, "I", "Enable ipfw+6");
+SYSCTL_VNET_INT(_net_inet6_ip6_fw, OID_AUTO, deny_unknown_exthdrs,
+    CTLFLAG_RW | CTLFLAG_SECURE, &VNET_NAME(fw_deny_unknown_exthdrs), 0,
+    "Deny packets with unknown IPv6 Extension Headers");
+#endif
+#endif
 
 /*
  * Description of dynamic rules.
@@ -277,16 +293,20 @@ static VNET_DEFINE(u_int32_t, dyn_max);	
 
 #ifdef SYSCTL_NODE
 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_buckets,
-    CTLFLAG_RW, &VNET_NAME(dyn_buckets), 0, "Number of dyn. buckets");
+    CTLFLAG_RW, &VNET_NAME(dyn_buckets), 0,
+    "Number of dyn. buckets");
 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, curr_dyn_buckets,
     CTLFLAG_RD, &VNET_NAME(curr_dyn_buckets), 0,
     "Current Number of dyn. buckets");
 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_count,
-    CTLFLAG_RD, &VNET_NAME(dyn_count), 0, "Number of dyn. rules");
+    CTLFLAG_RD, &VNET_NAME(dyn_count), 0,
+    "Number of dyn. rules");
 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_max,
-    CTLFLAG_RW, &VNET_NAME(dyn_max), 0, "Max number of dyn. rules");
+    CTLFLAG_RW, &VNET_NAME(dyn_max), 0,
+    "Max number of dyn. rules");
 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, static_count,
-    CTLFLAG_RD, &VNET_NAME(static_count), 0, "Number of static rules");
+    CTLFLAG_RD, &VNET_NAME(static_count), 0,
+    "Number of static rules");
 SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUTO, dyn_ack_lifetime,
     CTLFLAG_RW, &VNET_NAME(dyn_ack_lifetime), 0,
     "Lifetime of dyn. rules for acks");
@@ -310,21 +330,6 @@ SYSCTL_VNET_INT(_net_inet_ip_fw, OID_AUT
     "Enable keepalives for dyn. rules");
 #endif /* SYSCTL_NODE */
 
-#ifdef INET6
-/*
- * IPv6 specific variables
- */
-#ifdef SYSCTL_NODE
-SYSCTL_DECL(_net_inet6_ip6);
-#endif /* SYSCTL_NODE */
-
-static struct sysctl_ctx_list ip6_fw_sysctl_ctx;
-static struct sysctl_oid *ip6_fw_sysctl_tree;
-#endif /* INET6 */
-
-static VNET_DEFINE(int, fw_deny_unknown_exthdrs);
-#define	V_fw_deny_unknown_exthdrs	VNET(fw_deny_unknown_exthdrs)
-
 /*
  * L3HDR maps an ipv4 pointer into a layer3 header pointer of type T
  * Other macros just cast void * into the appropriate type
@@ -4511,17 +4516,22 @@ ipfw_ctl(struct sockopt *sopt)
 #undef RULE_MAXSIZE
 }
 
+
 /*
  * This procedure is only used to handle keepalives. It is invoked
  * every dyn_keepalive_period
  */
 static void
-ipfw_tick(void * __unused unused)
+ipfw_tick(void * vnetx) 
 {
 	struct mbuf *m0, *m, *mnext, **mtailp;
 	int i;
 	ipfw_dyn_rule *q;
+#ifdef VIMAGE
+	struct vnet *vp = vnetx;
+#endif
 
+        CURVNET_SET(vp);
 	if (V_dyn_keepalive == 0 || V_ipfw_dyn_v == NULL || V_dyn_count == 0)
 		goto done;
 
@@ -4566,14 +4576,100 @@ ipfw_tick(void * __unused unused)
 	}
 done:
 	callout_reset(&V_ipfw_timeout, V_dyn_keepalive_period * hz,
-		      ipfw_tick, NULL);
+		      ipfw_tick, vnetx);
+	CURVNET_RESTORE();
 }
 
+
+
+/****************
+ * Stuff that must be initialised only on boot or module load
+ */
 int
 ipfw_init(void)
 {
-	struct ip_fw default_rule;
+	int error = 0;
+
+	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();
+	/*
+ 	 * Only print out this stuff the first time around,
+	 * when called from the sysinit code.
+	 */
+	printf("ipfw2 "
+#ifdef INET6
+		"(+ipv6) "
+#endif
+		"initialized, divert %s, nat %s, "
+		"rule-based forwarding "
+#ifdef IPFIREWALL_FORWARD
+		"enabled, "
+#else
+		"disabled, "
+#endif
+		"default to %s, logging ",
+#ifdef IPDIVERT
+		"enabled",
+#else
+		"loadable",
+#endif
+#ifdef IPFIREWALL_NAT
+		"enabled",
+#else
+		"loadable",
+#endif
+		default_to_accept ? "accept" : "deny");
+
+	/*
+	 * Note: V_xxx variables can be accessed here but the iattach()
+     	 * may not have been called yet for the VIMGE case.
+	 * Tuneables will have been processed.
+	 */
+	if (V_fw_verbose == 0)
+		printf("disabled\n");
+	else if (V_verbose_limit == 0)
+		printf("unlimited\n");
+	else
+		printf("limited to %d packets/entry by default\n",
+		    V_verbose_limit);
+
+	/*
+	 * Other things that are only done the first time.
+	 * (now that we a re cuaranteed of success).
+	 */
+	ip_fw_ctl_ptr = ipfw_ctl;
+	ip_fw_chk_ptr = ipfw_chk;
+	return (error);
+}
+
+/****************
+ * Stuff that must be initialised for every instance
+ * (including the forst of course).
+ */
+static int
+vnet_ipfw_init(const void *unused)
+{
 	int error;
+	struct ip_fw default_rule;
+
+	/* First set up some values that are compile time options */
+#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 IPFIREWALL_NAT
+	LIST_INIT(&V_layer3_chain.nat);
+#endif
 
 	V_autoinc_step = 100;	/* bounded to 1..1000 in add_rule() */
 
@@ -4596,127 +4692,85 @@ ipfw_init(void)
 
 	V_fw_deny_unknown_exthdrs = 1;
 
-#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,
-	    &V_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,
-	    &V_fw_deny_unknown_exthdrs, 0,
-	    "Deny packets with unknown IPv6 Extension Headers");
-#endif
-
 	V_layer3_chain.rules = NULL;
 	IPFW_LOCK_INIT(&V_layer3_chain);
-	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(&V_ipfw_timeout, CALLOUT_MPSAFE);
 
 	bzero(&default_rule, sizeof default_rule);
-
 	default_rule.act_ofs = 0;
 	default_rule.rulenum = IPFW_DEFAULT_RULE;
 	default_rule.cmd_len = 1;
 	default_rule.set = RESVD_SET;
-
 	default_rule.cmd[0].len = 1;
 	default_rule.cmd[0].opcode = default_to_accept ? O_ACCEPT : O_DENY;
-
 	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(&V_layer3_chain);
-		uma_zdestroy(ipfw_dyn_rule_zone);
+		printf("leaving ipfw_iattach (1) with error %d\n", error);
 		return (error);
 	}
 
 	ip_fw_default_rule = V_layer3_chain.rules;
-	printf("ipfw2 "
-#ifdef INET6
-		"(+ipv6) "
-#endif
-		"initialized, divert %s, nat %s, "
-		"rule-based forwarding "
-#ifdef IPFIREWALL_FORWARD
-		"enabled, "
-#else
-		"disabled, "
-#endif
-		"default to %s, logging ",
-#ifdef IPDIVERT
-		"enabled",
-#else
-		"loadable",
-#endif
-#ifdef IPFIREWALL_NAT
-		"enabled",
-#else
-		"loadable",
-#endif
-
-		default_rule.cmd[0].opcode == O_ACCEPT ? "accept" : "deny");
 
-#ifdef IPFIREWALL_VERBOSE
-	V_fw_verbose = 1;
-#endif
-#ifdef IPFIREWALL_VERBOSE_LIMIT
-	V_verbose_limit = IPFIREWALL_VERBOSE_LIMIT;
-#endif
-	if (V_fw_verbose == 0)
-		printf("disabled\n");
-	else if (V_verbose_limit == 0)
-		printf("unlimited\n");
-	else
-		printf("limited to %d packets/entry by default\n",
-		    V_verbose_limit);
-
-	error = init_tables(&V_layer3_chain);
 	if (error) {
-		IPFW_DYN_LOCK_DESTROY();
 		IPFW_LOCK_DESTROY(&V_layer3_chain);
-		uma_zdestroy(ipfw_dyn_rule_zone);
+		printf("leaving ipfw_iattach (2) with error %d\n", error);
 		return (error);
 	}
-	ip_fw_ctl_ptr = ipfw_ctl;
-	ip_fw_chk_ptr = ipfw_chk;
+#ifdef VIMAGE  /* want a better way to do this */
+	callout_reset(&V_ipfw_timeout, hz, ipfw_tick, curvnet);	
+#else
 	callout_reset(&V_ipfw_timeout, hz, ipfw_tick, NULL);	
-	LIST_INIT(&V_layer3_chain.nat);
+#endif
+
+	/* First set up some values that are compile time options */
 	return (0);
 }
 
+/**********************
+ * Called for the removal of the last instance only on module unload.
+ */
 void
 ipfw_destroy(void)
 {
-	struct ip_fw *reap;
-
 	ip_fw_chk_ptr = NULL;
 	ip_fw_ctl_ptr = NULL;
+	uma_zdestroy(ipfw_dyn_rule_zone);
+	IPFW_DYN_LOCK_DESTROY();
+	printf("IP firewall unloaded\n");
+}
+
+/***********************
+ * Called for the removal of each instance.
+ */
+static int
+vnet_ipfw_uninit(const void *unused)
+{
+	struct ip_fw *reap;
+
 	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);
-	reap_rules(reap);
-	IPFW_DYN_LOCK_DESTROY();
-	uma_zdestroy(ipfw_dyn_rule_zone);
+	if (reap != NULL)
+		reap_rules(reap);
+	IPFW_LOCK_DESTROY(&V_layer3_chain);
 	if (V_ipfw_dyn_v != NULL)
 		free(V_ipfw_dyn_v, M_IPFW);
-	IPFW_LOCK_DESTROY(&V_layer3_chain);
+	return 0;
+}
 
-#ifdef INET6
-	/* Free IPv6 fw sysctl tree. */
-	sysctl_ctx_free(&ip6_fw_sysctl_ctx);
-#endif
+VNET_SYSINIT(vnet_ipfw_init, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY,
+    vnet_ipfw_init, NULL);
 
-	printf("IP firewall unloaded\n");
-}
+VNET_SYSUNINIT(vnet_ipfw_uninit, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY,
+    vnet_ipfw_uninit, NULL);
+
+ 


More information about the svn-src-head mailing list