#include <sys/mbuf.h>
#include <sys/module.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/rwlock.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sysctl.h>
+#include <sys/ucred.h>
#include <net/if.h>
+#include <net/route.h>
#include <net/pfil.h>
+#include <net/vnet.h>
#include <netinet/in.h>
+#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/ip_fw.h>
#include <machine/in_cksum.h>
-#include "missing.h"
-
-int fw_enable = 1;
+VNET_DEFINE(int, fw_enable) = 1;
#ifdef INET6
-int fw6_enable = 1;
+VNET_DEFINE(int, fw6_enable) = 1;
#endif
int ipfw_chg_hook(SYSCTL_HANDLER_ARGS);
KASSERT(ng_tag->dir == NG_IPFW_IN,
("ng_ipfw tag with wrong direction"));
args.rule = ng_tag->rule;
+ args.rule_id = ng_tag->rule_id;
+ args.chain_id = ng_tag->chain_id;
m_tag_delete(*m0, (struct m_tag *)ng_tag);
}
dt = (struct dn_pkt_tag *)(dn_tag+1);
args.rule = dt->rule;
+ args.rule_id = dt->rule_id;
+ args.chain_id = dt->chain_id;
m_tag_delete(*m0, dn_tag);
}
args.m = *m0;
args.inp = inp;
- ipfw = ipfw_chk(&args);
- *m0 = args.m; /* args.m can be modified by ipfw_chk */
tee = 0;
+ if (V_fw_one_pass == 0 || args.rule == NULL) {
+ ipfw = ipfw_chk(&args);
+ *m0 = args.m;
+ } else
+ ipfw = IP_FW_PASS;
+
KASSERT(*m0 != NULL || ipfw == IP_FW_DENY, ("%s: m0 is NULL",
__func__));
goto drop;
break; /* not reached */
- /* here packets come after the ipfw classification */
case IP_FW_DUMMYNET:
if (ip_dn_io_ptr == NULL)
goto drop;
KASSERT(ng_tag->dir == NG_IPFW_OUT,
("ng_ipfw tag with wrong direction"));
args.rule = ng_tag->rule;
+ args.rule_id = ng_tag->rule_id;
+ args.chain_id = ng_tag->chain_id;
m_tag_delete(*m0, (struct m_tag *)ng_tag);
}
dt = (struct dn_pkt_tag *)(dn_tag+1);
args.rule = dt->rule;
+ args.rule_id = dt->rule_id;
+ args.chain_id = dt->chain_id;
m_tag_delete(*m0, dn_tag);
}
args.m = *m0;
args.oif = ifp;
args.inp = inp;
- ipfw = ipfw_chk(&args);
- *m0 = args.m; /* args.m can be modified by ipfw_chk */
tee = 0;
+ if (V_fw_one_pass == 0 || args.rule == NULL) {
+ ipfw = ipfw_chk(&args);
+ *m0 = args.m;
+ } else
+ ipfw = IP_FW_PASS;
+
KASSERT(*m0 != NULL || ipfw == IP_FW_DENY, ("%s: m0 is NULL",
__func__));
return 1;
}
-static int
+int
ipfw_hook(void)
{
struct pfil_head *pfh_inet;
if (pfh_inet == NULL)
return ENOENT;
- 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);
+ (void)pfil_add_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK,
+ pfh_inet);
+ (void)pfil_add_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK,
+ pfh_inet);
return 0;
}
-static int
+int
ipfw_unhook(void)
{
struct pfil_head *pfh_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);
+ (void)pfil_remove_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK,
+ pfh_inet);
+ (void)pfil_remove_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK,
+ pfh_inet);
return 0;
}
#ifdef INET6
-static int
+int
ipfw6_hook(void)
{
struct pfil_head *pfh_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);
+ (void)pfil_add_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK,
+ pfh_inet6);
+ (void)pfil_add_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK,
+ pfh_inet6);
return 0;
}
-static int
+int
ipfw6_unhook(void)
{
struct pfil_head *pfh_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);
+ (void)pfil_remove_hook(ipfw_check_in, NULL, PFIL_IN | PFIL_WAITOK,
+ pfh_inet6);
+ (void)pfil_remove_hook(ipfw_check_out, NULL, PFIL_OUT | PFIL_WAITOK,
+ pfh_inet6);
return 0;
}
int
ipfw_chg_hook(SYSCTL_HANDLER_ARGS)
{
- int enable = *(int *)arg1;
+ int enable;
+ int oldenable;
int error;
+ if (arg1 == &VNET_NAME(fw_enable)) {
+ enable = V_fw_enable;
+ }
+#ifdef INET6
+ else if (arg1 == &VNET_NAME(fw6_enable)) {
+ enable = V_fw6_enable;
+ }
+#endif
+ else
+ return (EINVAL);
+
+ oldenable = enable;
+
error = sysctl_handle_int(oidp, &enable, 0, req);
+
if (error)
return (error);
enable = (enable) ? 1 : 0;
- if (enable == *(int *)arg1)
+ if (enable == oldenable)
return (0);
- if (arg1 == &fw_enable) {
+ if (arg1 == &VNET_NAME(fw_enable)) {
if (enable)
error = ipfw_hook();
else
error = ipfw_unhook();
+ if (error)
+ return (error);
+ V_fw_enable = enable;
}
#ifdef INET6
- if (arg1 == &fw6_enable) {
+ else if (arg1 == &VNET_NAME(fw6_enable)) {
if (enable)
error = ipfw6_hook();
else
error = ipfw6_unhook();
+ if (error)
+ return (error);
+ V_fw6_enable = enable;
}
#endif
- if (error)
- return (error);
-
- *(int *)arg1 = enable;
-
return (0);
}