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)
This commit is contained in:
parent
45289e2ded
commit
9d85f50ad5
@ -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_AUTO, enable,
|
||||
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); /* max # of dynamic rules */
|
||||
|
||||
#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_AUTO, dyn_keepalive,
|
||||
"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,80 +4576,29 @@ 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;
|
||||
int error = 0;
|
||||
|
||||
V_autoinc_step = 100; /* bounded to 1..1000 in add_rule() */
|
||||
|
||||
V_ipfw_dyn_v = NULL;
|
||||
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;
|
||||
|
||||
#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);
|
||||
return (error);
|
||||
}
|
||||
|
||||
ip_fw_default_rule = V_layer3_chain.rules;
|
||||
/*
|
||||
* Only print out this stuff the first time around,
|
||||
* when called from the sysinit code.
|
||||
*/
|
||||
printf("ipfw2 "
|
||||
#ifdef INET6
|
||||
"(+ipv6) "
|
||||
@ -4662,15 +4621,13 @@ ipfw_init(void)
|
||||
#else
|
||||
"loadable",
|
||||
#endif
|
||||
default_to_accept ? "accept" : "deny");
|
||||
|
||||
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
|
||||
/*
|
||||
* 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)
|
||||
@ -4679,44 +4636,141 @@ ipfw_init(void)
|
||||
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);
|
||||
return (error);
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
callout_reset(&V_ipfw_timeout, hz, ipfw_tick, NULL);
|
||||
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() */
|
||||
|
||||
V_ipfw_dyn_v = NULL;
|
||||
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);
|
||||
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_LOCK_DESTROY(&V_layer3_chain);
|
||||
printf("leaving ipfw_iattach (1) with error %d\n", error);
|
||||
return (error);
|
||||
}
|
||||
|
||||
ip_fw_default_rule = V_layer3_chain.rules;
|
||||
|
||||
if (error) {
|
||||
IPFW_LOCK_DESTROY(&V_layer3_chain);
|
||||
printf("leaving ipfw_iattach (2) with error %d\n", error);
|
||||
return (error);
|
||||
}
|
||||
#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);
|
||||
#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);
|
||||
|
||||
#ifdef INET6
|
||||
/* Free IPv6 fw sysctl tree. */
|
||||
sysctl_ctx_free(&ip6_fw_sysctl_ctx);
|
||||
#endif
|
||||
|
||||
printf("IP firewall unloaded\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
VNET_SYSINIT(vnet_ipfw_init, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY,
|
||||
vnet_ipfw_init, NULL);
|
||||
|
||||
VNET_SYSUNINIT(vnet_ipfw_uninit, SI_SUB_KTHREAD_INIT, SI_ORDER_ANY,
|
||||
vnet_ipfw_uninit, NULL);
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user