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 int fw_one_pass;
extern int fw_enable;
#ifdef INET6
extern int fw6_enable;
#endif
/* For kernel ipfw_ether and ipfw_bridge. */
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 autoinc_step = 100; /* bounded to 1..1000 in add_rule() */
extern int ipfw_chg_hook(SYSCTL_HANDLER_ARGS);
#ifdef SYSCTL_NODE
SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, enable,
CTLFLAG_RW | CTLFLAG_SECURE3,
&fw_enable, 0, "Enable ipfw");
SYSCTL_PROC(_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,
@ -4112,12 +4114,15 @@ ipfw_init(void)
/* 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_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,
&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,
&fw_deny_unknown_exthdrs, 0,
"Deny packets with unknown IPv6 Extension Headers");
OID_AUTO, "deny_unknown_exthdrs", CTLFLAG_RW | CTLFLAG_SECURE,
&fw_deny_unknown_exthdrs, 0,
"Deny packets with unknown IPv6 Extension Headers");
#endif
layer3_chain.rules = NULL;

View File

@ -64,7 +64,12 @@
#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. */
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!"));
if (!fw_enable)
goto pass;
bzero(&args, sizeof(args));
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!"));
if (!fw_enable)
goto pass;
bzero(&args, sizeof(args));
dn_tag = m_tag_find(*m0, PACKET_TAG_DUMMYNET, NULL);
@ -417,28 +416,13 @@ static int
ipfw_hook(void)
{
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);
if (pfh_inet == NULL)
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_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;
}
@ -447,32 +431,87 @@ static int
ipfw_unhook(void)
{
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);
if (pfh_inet == NULL)
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_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;
}
#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
ipfw_modevent(module_t mod, int type, void *unused)
{
@ -480,31 +519,30 @@ ipfw_modevent(module_t mod, int type, void *unused)
switch (type) {
case MOD_LOAD:
if (ipfw_pfil_hooked) {
printf("IP firewall already loaded\n");
err = EEXIST;
} 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_init()) != 0) {
printf("ipfw_init() error\n");
break;
}
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;
case MOD_UNLOAD:
if (ipfw_pfil_hooked) {
if ((err = ipfw_unhook()) > 0)
break;
ipfw_destroy();
ipfw_pfil_hooked = 0;
} else {
printf("IP firewall already unloaded\n");
}
if ((err = ipfw_unhook()) > 0)
break;
#ifdef INET6
if ((err = ipfw6_unhook()) > 0)
break;
#endif
ipfw_destroy();
break;
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_dn_io_t *ip_dn_io_ptr = NULL;
int fw_enable = 1;
int fw_one_pass = 1;
static void ip_freef(struct ipqhead *, struct ipq *);