Date: Tue, 4 Sep 2012 19:43:26 +0000 (UTC) From: "Alexander V. Chernikov" <melifaro@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r240099 - in head/sys: net netinet netinet/ipfw Message-ID: <201209041943.q84JhQ7h008917@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: melifaro Date: Tue Sep 4 19:43:26 2012 New Revision: 240099 URL: http://svn.freebsd.org/changeset/base/240099 Log: Introduce new link-layer PFIL hook V_link_pfil_hook. Merge ether_ipfw_chk() and part of bridge_pfil() into unified ipfw_check_frame() function called by PFIL. This change was suggested by rwatson? @ DevSummit. Remove ipfw headers from ether/bridge code since they are unneeded now. Note this thange introduce some (temporary) performance penalty since PFIL read lock has to be acquired for every link-level packet. MFC after: 3 weeks Modified: head/sys/net/if_bridge.c head/sys/net/if_ethersubr.c head/sys/net/if_var.h head/sys/netinet/ip_var.h head/sys/netinet/ipfw/ip_fw2.c head/sys/netinet/ipfw/ip_fw_pfil.c head/sys/netinet/ipfw/ip_fw_private.h Modified: head/sys/net/if_bridge.c ============================================================================== --- head/sys/net/if_bridge.c Tue Sep 4 19:19:36 2012 (r240098) +++ head/sys/net/if_bridge.c Tue Sep 4 19:43:26 2012 (r240099) @@ -100,7 +100,6 @@ __FBSDID("$FreeBSD$"); #include <sys/proc.h> #include <sys/lock.h> #include <sys/mutex.h> -#include <sys/rwlock.h> #include <net/bpf.h> #include <net/if.h> @@ -131,8 +130,6 @@ __FBSDID("$FreeBSD$"); #include <net/if_vlan_var.h> #include <net/route.h> -#include <netinet/ip_fw.h> -#include <netinet/ipfw/ip_fw_private.h> /* * Size of the route hash table. Must be a power of two. @@ -2981,7 +2978,6 @@ bridge_pfil(struct mbuf **mp, struct ifn { int snap, error, i, hlen; struct ether_header *eh1, eh2; - struct ip_fw_args args; struct ip *ip; struct llc llc1; u_int16_t ether_type; @@ -3055,6 +3051,16 @@ bridge_pfil(struct mbuf **mp, struct ifn goto bad; } + /* Run the packet through pfil before stripping link headers */ + if (PFIL_HOOKED(&V_link_pfil_hook) && pfil_ipfw != 0 && + dir == PFIL_OUT && ifp != NULL) { + + error = pfil_run_hooks(&V_link_pfil_hook, mp, ifp, dir, NULL); + + if (*mp == NULL || error != 0) /* packet consumed by filter */ + return (error); + } + /* Strip off the Ethernet header and keep a copy. */ m_copydata(*mp, 0, ETHER_HDR_LEN, (caddr_t) &eh2); m_adj(*mp, ETHER_HDR_LEN); @@ -3085,63 +3091,6 @@ bridge_pfil(struct mbuf **mp, struct ifn goto bad; } - /* XXX this section is also in if_ethersubr.c */ - // XXX PFIL_OUT or DIR_OUT ? - if (V_ip_fw_chk_ptr && pfil_ipfw != 0 && - dir == PFIL_OUT && ifp != NULL) { - struct m_tag *mtag; - - error = -1; - /* fetch the start point from existing tags, if any */ - mtag = m_tag_locate(*mp, MTAG_IPFW_RULE, 0, NULL); - if (mtag == NULL) { - args.rule.slot = 0; - } else { - struct ipfw_rule_ref *r; - - /* XXX can we free the tag after use ? */ - mtag->m_tag_id = PACKET_TAG_NONE; - r = (struct ipfw_rule_ref *)(mtag + 1); - /* packet already partially processed ? */ - if (r->info & IPFW_ONEPASS) - goto ipfwpass; - args.rule = *r; - } - - args.m = *mp; - args.oif = ifp; - args.next_hop = NULL; - args.next_hop6 = NULL; - args.eh = &eh2; - args.inp = NULL; /* used by ipfw uid/gid/jail rules */ - i = V_ip_fw_chk_ptr(&args); - *mp = args.m; - - if (*mp == NULL) - return (error); - - if (ip_dn_io_ptr && (i == IP_FW_DUMMYNET)) { - - /* put the Ethernet header back on */ - M_PREPEND(*mp, ETHER_HDR_LEN, M_DONTWAIT); - if (*mp == NULL) - return (error); - bcopy(&eh2, mtod(*mp, caddr_t), ETHER_HDR_LEN); - - /* - * Pass the pkt to dummynet, which consumes it. The - * packet will return to us via bridge_dummynet(). - */ - args.oif = ifp; - ip_dn_io_ptr(mp, DIR_FWD | PROTO_IFB, &args); - return (error); - } - - if (i != IP_FW_PASS) /* drop */ - goto bad; - } - -ipfwpass: error = 0; /* Modified: head/sys/net/if_ethersubr.c ============================================================================== --- head/sys/net/if_ethersubr.c Tue Sep 4 19:19:36 2012 (r240098) +++ head/sys/net/if_ethersubr.c Tue Sep 4 19:43:26 2012 (r240099) @@ -45,7 +45,6 @@ #include <sys/module.h> #include <sys/mbuf.h> #include <sys/random.h> -#include <sys/rwlock.h> #include <sys/socket.h> #include <sys/sockio.h> #include <sys/sysctl.h> @@ -63,6 +62,7 @@ #include <net/if_vlan_var.h> #include <net/if_llatbl.h> #include <net/pf_mtag.h> +#include <net/pfil.h> #include <net/vnet.h> #if defined(INET) || defined(INET6) @@ -71,8 +71,6 @@ #include <netinet/if_ether.h> #include <netinet/ip_carp.h> #include <netinet/ip_var.h> -#include <netinet/ip_fw.h> -#include <netinet/ipfw/ip_fw_private.h> #endif #ifdef INET6 #include <netinet6/nd6.h> @@ -106,6 +104,8 @@ CTASSERT(sizeof (struct ether_header) == CTASSERT(sizeof (struct ether_addr) == ETHER_ADDR_LEN); #endif +VNET_DEFINE(struct pfil_head, link_pfil_hook); /* Packet filter hooks */ + /* netgraph node hooks for ng_ether(4) */ void (*ng_ether_input_p)(struct ifnet *ifp, struct mbuf **mp); void (*ng_ether_input_orphan_p)(struct ifnet *ifp, struct mbuf *m); @@ -141,14 +141,6 @@ static MALLOC_DEFINE(M_ARPCOM, "arpcom", #define senderr(e) do { error = (e); goto bad;} while (0) -#if defined(INET) || defined(INET6) -int -ether_ipfw_chk(struct mbuf **m0, struct ifnet *dst, int shared); -static VNET_DEFINE(int, ether_ipfw); -#define V_ether_ipfw VNET(ether_ipfw) -#endif - - /* * Ethernet output routine. * Encapsulate a packet of type family for the local net. @@ -427,18 +419,17 @@ bad: if (m != NULL) int ether_output_frame(struct ifnet *ifp, struct mbuf *m) { -#if defined(INET) || defined(INET6) + int i; - if (V_ip_fw_chk_ptr && V_ether_ipfw != 0) { - if (ether_ipfw_chk(&m, ifp, 0) == 0) { - if (m) { - m_freem(m); - return EACCES; /* pkt dropped */ - } else - return 0; /* consumed e.g. in a pipe */ - } + if (PFIL_HOOKED(&V_link_pfil_hook)) { + i = pfil_run_hooks(&V_link_pfil_hook, &m, ifp, PFIL_OUT, NULL); + + if (i != 0) + return (EACCES); + + if (m == NULL) + return (0); } -#endif /* * Queue message on interface, update output statistics if @@ -448,113 +439,6 @@ ether_output_frame(struct ifnet *ifp, st } #if defined(INET) || defined(INET6) -/* - * ipfw processing for ethernet packets (in and out). - * The second parameter is NULL from ether_demux, and ifp from - * ether_output_frame. - */ -int -ether_ipfw_chk(struct mbuf **m0, struct ifnet *dst, int shared) -{ - struct ether_header *eh; - struct ether_header save_eh; - struct mbuf *m; - int i; - struct ip_fw_args args; - struct m_tag *mtag; - - /* fetch start point from rule, if any */ - mtag = m_tag_locate(*m0, MTAG_IPFW_RULE, 0, NULL); - if (mtag == NULL) { - args.rule.slot = 0; - } else { - /* dummynet packet, already partially processed */ - struct ipfw_rule_ref *r; - - /* XXX can we free it after use ? */ - mtag->m_tag_id = PACKET_TAG_NONE; - r = (struct ipfw_rule_ref *)(mtag + 1); - if (r->info & IPFW_ONEPASS) - return (1); - args.rule = *r; - } - - /* - * I need some amt of data to be contiguous, and in case others need - * the packet (shared==1) also better be in the first mbuf. - */ - m = *m0; - i = min( m->m_pkthdr.len, max_protohdr); - if ( shared || m->m_len < i) { - m = m_pullup(m, i); - if (m == NULL) { - *m0 = m; - return 0; - } - } - eh = mtod(m, struct ether_header *); - save_eh = *eh; /* save copy for restore below */ - m_adj(m, ETHER_HDR_LEN); /* strip ethernet header */ - - args.m = m; /* the packet we are looking at */ - args.oif = dst; /* destination, if any */ - args.next_hop = NULL; /* we do not support forward yet */ - args.next_hop6 = NULL; /* we do not support forward yet */ - args.eh = &save_eh; /* MAC header for bridged/MAC packets */ - args.inp = NULL; /* used by ipfw uid/gid/jail rules */ - i = V_ip_fw_chk_ptr(&args); - m = args.m; - if (m != NULL) { - /* - * Restore Ethernet header, as needed, in case the - * mbuf chain was replaced by ipfw. - */ - M_PREPEND(m, ETHER_HDR_LEN, M_DONTWAIT); - if (m == NULL) { - *m0 = m; - return 0; - } - if (eh != mtod(m, struct ether_header *)) - bcopy(&save_eh, mtod(m, struct ether_header *), - ETHER_HDR_LEN); - } - *m0 = m; - - if (i == IP_FW_DENY) /* drop */ - return 0; - - KASSERT(m != NULL, ("ether_ipfw_chk: m is NULL")); - - if (i == IP_FW_PASS) /* a PASS rule. */ - return 1; - - if (ip_dn_io_ptr && (i == IP_FW_DUMMYNET)) { - int dir; - /* - * Pass the pkt to dummynet, which consumes it. - * If shared, make a copy and keep the original. - */ - if (shared) { - m = m_copypacket(m, M_DONTWAIT); - if (m == NULL) - return 0; - } else { - /* - * Pass the original to dummynet and - * nothing back to the caller - */ - *m0 = NULL ; - } - dir = PROTO_LAYER2 | (dst ? DIR_OUT : DIR_IN); - ip_dn_io_ptr(&m, dir, &args); - return 0; - } - /* - * XXX at some point add support for divert/forward actions. - * If none of the above matches, we have to drop the pkt. - */ - return 0; -} #endif /* @@ -788,6 +672,35 @@ ether_init(__unused void *arg) SYSINIT(ether, SI_SUB_INIT_IF, SI_ORDER_ANY, ether_init, NULL); static void +vnet_ether_init(__unused void *arg) +{ + int i; + + /* Initialize packet filter hooks. */ + V_link_pfil_hook.ph_type = PFIL_TYPE_AF; + V_link_pfil_hook.ph_af = AF_LINK; + if ((i = pfil_head_register(&V_link_pfil_hook)) != 0) + printf("%s: WARNING: unable to register pfil link hook, " + "error %d\n", __func__, i); +} +VNET_SYSINIT(vnet_ether_init, SI_SUB_PROTO_IF, SI_ORDER_ANY, + vnet_ether_init, NULL); + +static void +vnet_ether_destroy(__unused void *arg) +{ + int i; + + if ((i = pfil_head_unregister(&V_link_pfil_hook)) != 0) + printf("%s: WARNING: unable to unregister pfil link hook, " + "error %d\n", __func__, i); +} +VNET_SYSUNINIT(vnet_ether_uninit, SI_SUB_PROTO_IF, SI_ORDER_ANY, + vnet_ether_destroy, NULL); + + + +static void ether_input(struct ifnet *ifp, struct mbuf *m) { @@ -807,7 +720,7 @@ void ether_demux(struct ifnet *ifp, struct mbuf *m) { struct ether_header *eh; - int isr; + int i, isr; u_short ether_type; #if defined(NETATALK) struct llc *l; @@ -815,19 +728,14 @@ ether_demux(struct ifnet *ifp, struct mb KASSERT(ifp != NULL, ("%s: NULL interface pointer", __func__)); -#if defined(INET) || defined(INET6) - /* - * Allow dummynet and/or ipfw to claim the frame. - * Do not do this for PROMISC frames in case we are re-entered. - */ - if (V_ip_fw_chk_ptr && V_ether_ipfw != 0 && !(m->m_flags & M_PROMISC)) { - if (ether_ipfw_chk(&m, NULL, 0) == 0) { - if (m) - m_freem(m); /* dropped; free mbuf chain */ - return; /* consumed */ - } + /* Do not grab PROMISC frames in case we are re-entered. */ + if (PFIL_HOOKED(&V_link_pfil_hook) && !(m->m_flags & M_PROMISC)) { + i = pfil_run_hooks(&V_link_pfil_hook, &m, ifp, PFIL_IN, NULL); + + if (i != 0 || m == NULL) + return; } -#endif + eh = mtod(m, struct ether_header *); ether_type = ntohs(eh->ether_type); @@ -1056,10 +964,6 @@ ether_reassign(struct ifnet *ifp, struct SYSCTL_DECL(_net_link); SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet"); -#if defined(INET) || defined(INET6) -SYSCTL_VNET_INT(_net_link_ether, OID_AUTO, ipfw, CTLFLAG_RW, - &VNET_NAME(ether_ipfw), 0, "Pass ether pkts through firewall"); -#endif #if 0 /* Modified: head/sys/net/if_var.h ============================================================================== --- head/sys/net/if_var.h Tue Sep 4 19:19:36 2012 (r240098) +++ head/sys/net/if_var.h Tue Sep 4 19:43:26 2012 (r240099) @@ -99,6 +99,9 @@ TAILQ_HEAD(ifaddrhead, ifaddr); /* insta TAILQ_HEAD(ifmultihead, ifmultiaddr); TAILQ_HEAD(ifgrouphead, ifg_group); +VNET_DECLARE(struct pfil_head, link_pfil_hook); /* packet filter hooks */ +#define V_link_pfil_hook VNET(link_pfil_hook) + /* * Structure defining a queue for a network interface. */ Modified: head/sys/netinet/ip_var.h ============================================================================== --- head/sys/netinet/ip_var.h Tue Sep 4 19:19:36 2012 (r240098) +++ head/sys/netinet/ip_var.h Tue Sep 4 19:43:26 2012 (r240099) @@ -292,9 +292,7 @@ enum { struct ip_fw_args; typedef int (*ip_fw_chk_ptr_t)(struct ip_fw_args *args); typedef int (*ip_fw_ctl_ptr_t)(struct sockopt *); -VNET_DECLARE(ip_fw_chk_ptr_t, ip_fw_chk_ptr); VNET_DECLARE(ip_fw_ctl_ptr_t, ip_fw_ctl_ptr); -#define V_ip_fw_chk_ptr VNET(ip_fw_chk_ptr) #define V_ip_fw_ctl_ptr VNET(ip_fw_ctl_ptr) /* Divert hooks. */ Modified: head/sys/netinet/ipfw/ip_fw2.c ============================================================================== --- head/sys/netinet/ipfw/ip_fw2.c Tue Sep 4 19:19:36 2012 (r240098) +++ head/sys/netinet/ipfw/ip_fw2.c Tue Sep 4 19:43:26 2012 (r240099) @@ -2645,10 +2645,9 @@ vnet_ipfw_init(const void *unused) V_ipfw_vnet_ready = 1; /* Open for business */ /* - * Hook the sockopt handler, and the layer2 (V_ip_fw_chk_ptr) - * and pfil hooks for ipv4 and ipv6. Even if the latter two fail - * we still keep the module alive because the sockopt and - * layer2 paths are still useful. + * Hook the sockopt handler and pfil hooks for ipv4 and ipv6. + * Even if the latter two fail we still keep the module alive + * because the sockopt and layer2 paths are still useful. * ipfw[6]_hook return 0 on success, ENOENT on failure, * so we can ignore the exact return value and just set a flag. * @@ -2659,7 +2658,6 @@ vnet_ipfw_init(const void *unused) * is checked on each packet because there are no pfil hooks. */ V_ip_fw_ctl_ptr = ipfw_ctl; - V_ip_fw_chk_ptr = ipfw_chk; error = ipfw_attach_hooks(1); return (error); } @@ -2681,7 +2679,6 @@ vnet_ipfw_uninit(const void *unused) * sure the update is propagated and nobody will be in. */ (void)ipfw_attach_hooks(0 /* detach */); - V_ip_fw_chk_ptr = NULL; V_ip_fw_ctl_ptr = NULL; IPFW_UH_WLOCK(chain); IPFW_UH_WUNLOCK(chain); Modified: head/sys/netinet/ipfw/ip_fw_pfil.c ============================================================================== --- head/sys/netinet/ipfw/ip_fw_pfil.c Tue Sep 4 19:19:36 2012 (r240098) +++ head/sys/netinet/ipfw/ip_fw_pfil.c Tue Sep 4 19:43:26 2012 (r240099) @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include <net/if.h> #include <net/route.h> +#include <net/ethernet.h> #include <net/pfil.h> #include <net/vnet.h> @@ -72,10 +73,17 @@ static VNET_DEFINE(int, fw6_enable) = 1; #define V_fw6_enable VNET(fw6_enable) #endif +static VNET_DEFINE(int, fwlink_enable) = 0; +#define V_fwlink_enable VNET(fwlink_enable) + int ipfw_chg_hook(SYSCTL_HANDLER_ARGS); /* Forward declarations. */ static int ipfw_divert(struct mbuf **, int, struct ipfw_rule_ref *, int); +static int ipfw_check_packet(void *, struct mbuf **, struct ifnet *, int, + struct inpcb *); +static int ipfw_check_frame(void *, struct mbuf **, struct ifnet *, int, + struct inpcb *); #ifdef SYSCTL_NODE @@ -92,6 +100,11 @@ SYSCTL_VNET_PROC(_net_inet6_ip6_fw, OID_ ipfw_chg_hook, "I", "Enable ipfw+6"); #endif /* INET6 */ +SYSCTL_DECL(_net_link_ether); +SYSCTL_VNET_PROC(_net_link_ether, OID_AUTO, ipfw, + CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fwlink_enable), 0, + ipfw_chg_hook, "I", "Pass ether pkts through firewall"); + SYSEND #endif /* SYSCTL_NODE */ @@ -101,8 +114,8 @@ SYSEND * dummynet, divert, netgraph or other modules. * The packet may be consumed. */ -int -ipfw_check_hook(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir, +static int +ipfw_check_packet(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir, struct inpcb *inp) { struct ip_fw_args args; @@ -278,6 +291,111 @@ again: return ret; } +/* + * ipfw processing for ethernet packets (in and out). + * Inteface is NULL from ether_demux, and ifp from + * ether_output_frame. + */ +static int +ipfw_check_frame(void *arg, struct mbuf **m0, struct ifnet *dst, int dir, + struct inpcb *inp) +{ + struct ether_header *eh; + struct ether_header save_eh; + struct mbuf *m; + int i, ret; + struct ip_fw_args args; + struct m_tag *mtag; + + /* fetch start point from rule, if any */ + mtag = m_tag_locate(*m0, MTAG_IPFW_RULE, 0, NULL); + if (mtag == NULL) { + args.rule.slot = 0; + } else { + /* dummynet packet, already partially processed */ + struct ipfw_rule_ref *r; + + /* XXX can we free it after use ? */ + mtag->m_tag_id = PACKET_TAG_NONE; + r = (struct ipfw_rule_ref *)(mtag + 1); + if (r->info & IPFW_ONEPASS) + return (0); + args.rule = *r; + } + + /* I need some amt of data to be contiguous */ + m = *m0; + i = min(m->m_pkthdr.len, max_protohdr); + if (m->m_len < i) { + m = m_pullup(m, i); + if (m == NULL) { + *m0 = m; + return (0); + } + } + eh = mtod(m, struct ether_header *); + save_eh = *eh; /* save copy for restore below */ + m_adj(m, ETHER_HDR_LEN); /* strip ethernet header */ + + args.m = m; /* the packet we are looking at */ + args.oif = dst; /* destination, if any */ + args.next_hop = NULL; /* we do not support forward yet */ + args.next_hop6 = NULL; /* we do not support forward yet */ + args.eh = &save_eh; /* MAC header for bridged/MAC packets */ + args.inp = NULL; /* used by ipfw uid/gid/jail rules */ + i = ipfw_chk(&args); + m = args.m; + if (m != NULL) { + /* + * Restore Ethernet header, as needed, in case the + * mbuf chain was replaced by ipfw. + */ + M_PREPEND(m, ETHER_HDR_LEN, M_DONTWAIT); + if (m == NULL) { + *m0 = NULL; + return (0); + } + if (eh != mtod(m, struct ether_header *)) + bcopy(&save_eh, mtod(m, struct ether_header *), + ETHER_HDR_LEN); + } + *m0 = m; + + ret = 0; + /* Check result of ipfw_chk() */ + switch (i) { + case IP_FW_PASS: + break; + + case IP_FW_DENY: + ret = EACCES; + break; /* i.e. drop */ + + case IP_FW_DUMMYNET: + ret = EACCES; + int dir; + + if (ip_dn_io_ptr == NULL) + break; /* i.e. drop */ + + *m0 = NULL; + dir = PROTO_LAYER2 | (dst ? DIR_OUT : DIR_IN); + ip_dn_io_ptr(&m, dir, &args); + return 0; + + default: + KASSERT(0, ("%s: unknown retval", __func__)); + } + + if (ret != 0) { + if (*m0) + FREE_PKT(*m0); + *m0 = NULL; + } + + return ret; +} + /* do the divert, return 1 on error 0 on success */ static int ipfw_divert(struct mbuf **m0, int incoming, struct ipfw_rule_ref *rule, @@ -379,13 +497,16 @@ static int ipfw_hook(int onoff, int pf) { struct pfil_head *pfh; + void *hook_func; pfh = pfil_head_get(PFIL_TYPE_AF, pf); if (pfh == NULL) return ENOENT; + hook_func = (pf == AF_LINK) ? ipfw_check_frame : ipfw_check_packet; + (void) (onoff ? pfil_add_hook : pfil_remove_hook) - (ipfw_check_hook, NULL, PFIL_IN | PFIL_OUT | PFIL_WAITOK, pfh); + (hook_func, NULL, PFIL_IN | PFIL_OUT | PFIL_WAITOK, pfh); return 0; } @@ -409,51 +530,58 @@ ipfw_attach_hooks(int arg) printf("ipfw6_hook() error\n"); } #endif + if (arg == 0) /* detach */ + ipfw_hook(0, AF_LINK); + else if (V_fwlink_enable && ipfw_hook(1, AF_LINK) != 0) { + error = ENOENT; + printf("ipfw_link_hook() error\n"); + } return error; } int ipfw_chg_hook(SYSCTL_HANDLER_ARGS) { - int enable; - int oldenable; + int *enable; + int newval; int error; int af; if (arg1 == &VNET_NAME(fw_enable)) { - enable = V_fw_enable; + enable = &V_fw_enable; af = AF_INET; } #ifdef INET6 else if (arg1 == &VNET_NAME(fw6_enable)) { - enable = V_fw6_enable; + enable = &V_fw6_enable; af = AF_INET6; } #endif + else if (arg1 == &VNET_NAME(fwlink_enable)) { + enable = &V_fwlink_enable; + af = AF_LINK; + } else return (EINVAL); - oldenable = enable; + newval = *enable; - error = sysctl_handle_int(oidp, &enable, 0, req); + /* Handle sysctl change */ + error = sysctl_handle_int(oidp, &newval, 0, req); if (error) return (error); - enable = (enable) ? 1 : 0; + /* Formalize new value */ + newval = (newval) ? 1 : 0; - if (enable == oldenable) + if (*enable == newval) return (0); - error = ipfw_hook(enable, af); + error = ipfw_hook(newval, af); if (error) return (error); - if (af == AF_INET) - V_fw_enable = enable; -#ifdef INET6 - else if (af == AF_INET6) - V_fw6_enable = enable; -#endif + *enable = newval; return (0); } Modified: head/sys/netinet/ipfw/ip_fw_private.h ============================================================================== --- head/sys/netinet/ipfw/ip_fw_private.h Tue Sep 4 19:19:36 2012 (r240098) +++ head/sys/netinet/ipfw/ip_fw_private.h Tue Sep 4 19:43:26 2012 (r240099) @@ -270,10 +270,6 @@ int ipfw_ctl(struct sockopt *sopt); int ipfw_chk(struct ip_fw_args *args); void ipfw_reap_rules(struct ip_fw *head); -/* In ip_fw_pfil */ -int ipfw_check_hook(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir, - struct inpcb *inp); - /* In ip_fw_table.c */ struct radix_node; int ipfw_lookup_table(struct ip_fw_chain *ch, uint16_t tbl, in_addr_t addr,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201209041943.q84JhQ7h008917>