Reintroduce net.inet6.ip6.fw.enable sysctl to dis/enable the ipv6 processing

seperately.  Also use pfil hook/unhook instead of keeping the check
functions in pfil just to return there based on the sysctl.  While here fix
some whitespace on a nearby SYSCTL_ macro.
This commit is contained in:
Max Laier 2006-05-12 04:41:27 +00:00
parent 3e20eaf592
commit e93187482d
4 changed files with 112 additions and 67 deletions

View File

@ -537,6 +537,9 @@ typedef int ip_fw_ctl_t(struct sockopt *);
extern ip_fw_ctl_t *ip_fw_ctl_ptr; extern ip_fw_ctl_t *ip_fw_ctl_ptr;
extern int fw_one_pass; extern int fw_one_pass;
extern int fw_enable; extern int fw_enable;
#ifdef INET6
extern int fw6_enable;
#endif
/* For kernel ipfw_ether and ipfw_bridge. */ /* For kernel ipfw_ether and ipfw_bridge. */
typedef int ip_fw_chk_t(struct ip_fw_args *args); typedef int ip_fw_chk_t(struct ip_fw_args *args);

View File

@ -165,11 +165,13 @@ struct table_entry {
static int fw_debug = 1; static int fw_debug = 1;
static int autoinc_step = 100; /* bounded to 1..1000 in add_rule() */ static int autoinc_step = 100; /* bounded to 1..1000 in add_rule() */
extern int ipfw_chg_hook(SYSCTL_HANDLER_ARGS);
#ifdef SYSCTL_NODE #ifdef SYSCTL_NODE
SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall"); SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, enable, SYSCTL_PROC(_net_inet_ip_fw, OID_AUTO, enable,
CTLFLAG_RW | CTLFLAG_SECURE3, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, &fw_enable, 0,
&fw_enable, 0, "Enable ipfw"); ipfw_chg_hook, "I", "Enable ipfw");
SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, autoinc_step, CTLFLAG_RW, SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, autoinc_step, CTLFLAG_RW,
&autoinc_step, 0, "Rule number autincrement step"); &autoinc_step, 0, "Rule number autincrement step");
SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, one_pass, SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, one_pass,
@ -4112,12 +4114,15 @@ ipfw_init(void)
/* Setup IPv6 fw sysctl tree. */ /* Setup IPv6 fw sysctl tree. */
sysctl_ctx_init(&ip6_fw_sysctl_ctx); sysctl_ctx_init(&ip6_fw_sysctl_ctx);
ip6_fw_sysctl_tree = SYSCTL_ADD_NODE(&ip6_fw_sysctl_ctx, ip6_fw_sysctl_tree = SYSCTL_ADD_NODE(&ip6_fw_sysctl_ctx,
SYSCTL_STATIC_CHILDREN(_net_inet6_ip6), OID_AUTO, "fw", SYSCTL_STATIC_CHILDREN(_net_inet6_ip6), OID_AUTO, "fw",
CTLFLAG_RW | CTLFLAG_SECURE, 0, "Firewall"); 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), SYSCTL_ADD_INT(&ip6_fw_sysctl_ctx, SYSCTL_CHILDREN(ip6_fw_sysctl_tree),
OID_AUTO, "deny_unknown_exthdrs", CTLFLAG_RW | CTLFLAG_SECURE, OID_AUTO, "deny_unknown_exthdrs", CTLFLAG_RW | CTLFLAG_SECURE,
&fw_deny_unknown_exthdrs, 0, &fw_deny_unknown_exthdrs, 0,
"Deny packets with unknown IPv6 Extension Headers"); "Deny packets with unknown IPv6 Extension Headers");
#endif #endif
layer3_chain.rules = NULL; layer3_chain.rules = NULL;

View File

@ -64,7 +64,12 @@
#include <machine/in_cksum.h> #include <machine/in_cksum.h>
static int ipfw_pfil_hooked = 0; int fw_enable = 1;
#ifdef INET6
int fw6_enable = 1;
#endif
int ipfw_chg_hook(SYSCTL_HANDLER_ARGS);
/* Dummynet hooks. */ /* Dummynet hooks. */
ip_dn_ruledel_t *ip_dn_ruledel_ptr = NULL; ip_dn_ruledel_t *ip_dn_ruledel_ptr = NULL;
@ -96,9 +101,6 @@ ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
KASSERT(dir == PFIL_IN, ("ipfw_check_in wrong direction!")); KASSERT(dir == PFIL_IN, ("ipfw_check_in wrong direction!"));
if (!fw_enable)
goto pass;
bzero(&args, sizeof(args)); bzero(&args, sizeof(args));
dn_tag = m_tag_find(*m0, PACKET_TAG_DUMMYNET, NULL); dn_tag = m_tag_find(*m0, PACKET_TAG_DUMMYNET, NULL);
@ -217,9 +219,6 @@ ipfw_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
KASSERT(dir == PFIL_OUT, ("ipfw_check_out wrong direction!")); KASSERT(dir == PFIL_OUT, ("ipfw_check_out wrong direction!"));
if (!fw_enable)
goto pass;
bzero(&args, sizeof(args)); bzero(&args, sizeof(args));
dn_tag = m_tag_find(*m0, PACKET_TAG_DUMMYNET, NULL); dn_tag = m_tag_find(*m0, PACKET_TAG_DUMMYNET, NULL);
@ -417,28 +416,13 @@ static int
ipfw_hook(void) ipfw_hook(void)
{ {
struct pfil_head *pfh_inet; struct pfil_head *pfh_inet;
#ifdef INET6
struct pfil_head *pfh_inet6;
#endif
if (ipfw_pfil_hooked)
return EEXIST;
pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET); pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
if (pfh_inet == NULL) if (pfh_inet == NULL)
return ENOENT; return ENOENT;
#ifdef INET6
pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
if (pfh_inet6 == NULL)
return ENOENT;
#endif
pfil_add_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet); pfil_add_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet);
pfil_add_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet); pfil_add_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet);
#ifdef INET6
pfil_add_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet6);
pfil_add_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet6);
#endif
return 0; return 0;
} }
@ -447,32 +431,87 @@ static int
ipfw_unhook(void) ipfw_unhook(void)
{ {
struct pfil_head *pfh_inet; struct pfil_head *pfh_inet;
#ifdef INET6
struct pfil_head *pfh_inet6;
#endif
if (!ipfw_pfil_hooked)
return ENOENT;
pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET); pfh_inet = pfil_head_get(PFIL_TYPE_AF, AF_INET);
if (pfh_inet == NULL) if (pfh_inet == NULL)
return ENOENT; return ENOENT;
#ifdef INET6
pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
if (pfh_inet6 == NULL)
return ENOENT;
#endif
pfil_remove_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet); pfil_remove_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet);
pfil_remove_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet); pfil_remove_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet);
#ifdef INET6
pfil_remove_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet6);
pfil_remove_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet6);
#endif
return 0; return 0;
} }
#ifdef INET6
static int
ipfw6_hook(void)
{
struct pfil_head *pfh_inet6;
pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
if (pfh_inet6 == NULL)
return ENOENT;
pfil_add_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet6);
pfil_add_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet6);
return 0;
}
static int
ipfw6_unhook(void)
{
struct pfil_head *pfh_inet6;
pfh_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
if (pfh_inet6 == NULL)
return ENOENT;
pfil_remove_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK, pfh_inet6);
pfil_remove_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK, pfh_inet6);
return 0;
}
#endif /* INET6 */
int
ipfw_chg_hook(SYSCTL_HANDLER_ARGS)
{
int enable = *(int *)arg1;
int error;
error = sysctl_handle_int(oidp, &enable, 0, req);
if (error)
return (error);
enable = (enable) ? 1 : 0;
if (enable == *(int *)arg1)
return (0);
if (arg1 == &fw_enable) {
if (enable)
error = ipfw_hook();
else
error = ipfw_unhook();
}
#ifdef INET6
if (arg1 == &fw6_enable) {
if (enable)
error = ipfw6_hook();
else
error = ipfw6_unhook();
}
#endif
if (error)
return (error);
*(int *)arg1 = enable;
return (0);
}
static int static int
ipfw_modevent(module_t mod, int type, void *unused) ipfw_modevent(module_t mod, int type, void *unused)
{ {
@ -480,31 +519,30 @@ ipfw_modevent(module_t mod, int type, void *unused)
switch (type) { switch (type) {
case MOD_LOAD: case MOD_LOAD:
if (ipfw_pfil_hooked) { if ((err = ipfw_init()) != 0) {
printf("IP firewall already loaded\n"); printf("ipfw_init() error\n");
err = EEXIST; break;
} else {
if ((err = ipfw_init()) != 0) {
printf("ipfw_init() error\n");
break;
}
if ((err = ipfw_hook()) != 0) {
printf("ipfw_hook() error\n");
break;
}
ipfw_pfil_hooked = 1;
} }
if ((err = ipfw_hook()) != 0) {
printf("ipfw_hook() error\n");
break;
}
#ifdef INET6
if ((err = ipfw6_hook()) != 0) {
printf("ipfw_hook() error\n");
break;
}
#endif
break; break;
case MOD_UNLOAD: case MOD_UNLOAD:
if (ipfw_pfil_hooked) { if ((err = ipfw_unhook()) > 0)
if ((err = ipfw_unhook()) > 0) break;
break; #ifdef INET6
ipfw_destroy(); if ((err = ipfw6_unhook()) > 0)
ipfw_pfil_hooked = 0; break;
} else { #endif
printf("IP firewall already unloaded\n"); ipfw_destroy();
}
break; break;
default: default:

View File

@ -198,7 +198,6 @@ SYSCTL_INT(_net_inet_ip, OID_AUTO, stealth, CTLFLAG_RW,
*/ */
ip_fw_chk_t *ip_fw_chk_ptr = NULL; ip_fw_chk_t *ip_fw_chk_ptr = NULL;
ip_dn_io_t *ip_dn_io_ptr = NULL; ip_dn_io_t *ip_dn_io_ptr = NULL;
int fw_enable = 1;
int fw_one_pass = 1; int fw_one_pass = 1;
static void ip_freef(struct ipqhead *, struct ipq *); static void ip_freef(struct ipqhead *, struct ipq *);