X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=dummynet%2Fip_fw_pfil.c;h=368192ad5862a7eb2940a294f9ccaeab8a78ebc6;hb=31b969263c34f46f398eec33c0b0e95947842cda;hp=bc1f011477c96eafd08fc0920c70b62e12a0dde9;hpb=5f337135c613b2ee3cb24ade7617ecaae0a74681;p=ipfw.git diff --git a/dummynet/ip_fw_pfil.c b/dummynet/ip_fw_pfil.c index bc1f011..368192a 100644 --- a/dummynet/ip_fw_pfil.c +++ b/dummynet/ip_fw_pfil.c @@ -49,6 +49,9 @@ __FBSDID("$FreeBSD: src/sys/netinet/ip_fw_pfil.c,v 1.25.2.2 2008/04/25 10:26:30 #include #include +#include + +#include "missing.h" #include #include @@ -61,11 +64,9 @@ __FBSDID("$FreeBSD: src/sys/netinet/ip_fw_pfil.c,v 1.25.2.2 2008/04/25 10:26:30 #include -#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); @@ -105,6 +106,8 @@ ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir, 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); } @@ -115,16 +118,22 @@ again: 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__)); @@ -151,7 +160,6 @@ again: goto drop; break; /* not reached */ - /* here packets come after the ipfw classification */ case IP_FW_DUMMYNET: if (ip_dn_io_ptr == NULL) goto drop; @@ -231,6 +239,8 @@ ipfw_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir, 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); } @@ -241,6 +251,8 @@ again: 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); } @@ -248,10 +260,14 @@ again: 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__)); @@ -423,7 +439,7 @@ nodivert: return 1; } -static int +int ipfw_hook(void) { struct pfil_head *pfh_inet; @@ -432,13 +448,15 @@ ipfw_hook(void) 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; @@ -447,14 +465,16 @@ ipfw_unhook(void) 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; @@ -463,13 +483,15 @@ ipfw6_hook(void) 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; @@ -478,8 +500,10 @@ ipfw6_unhook(void) 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; } @@ -488,38 +512,54 @@ ipfw6_unhook(void) 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); }