summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authormlaier <mlaier@FreeBSD.org>2006-05-12 04:41:27 +0000
committermlaier <mlaier@FreeBSD.org>2006-05-12 04:41:27 +0000
commit95826ec6b414b9b651fe4cf4b08cf9e0e16a11f2 (patch)
tree8c7da3df3d9265ef97f64e2b6617e900ce33f24e /sys/netinet
parentc44b3e762ea073484239a80b3968a71c3d903f4f (diff)
downloadFreeBSD-src-95826ec6b414b9b651fe4cf4b08cf9e0e16a11f2.zip
FreeBSD-src-95826ec6b414b9b651fe4cf4b08cf9e0e16a11f2.tar.gz
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.
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_fw.h3
-rw-r--r--sys/netinet/ip_fw2.c21
-rw-r--r--sys/netinet/ip_fw_pfil.c146
-rw-r--r--sys/netinet/ip_input.c1
4 files changed, 108 insertions, 63 deletions
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index 05d8b7d..0893e46 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -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);
diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c
index 49be308..dacaa57 100644
--- a/sys/netinet/ip_fw2.c
+++ b/sys/netinet/ip_fw2.c
@@ -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;
diff --git a/sys/netinet/ip_fw_pfil.c b/sys/netinet/ip_fw_pfil.c
index 65fbf82..a58f96f 100644
--- a/sys/netinet/ip_fw_pfil.c
+++ b/sys/netinet/ip_fw_pfil.c
@@ -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,31 +431,86 @@ 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;
+
+ 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);
+
+ 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;
-#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;
}
+#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:
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index f3e477f..a860074 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -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 *);
OpenPOWER on IntegriCloud