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,
- ðer_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