2005-01-07 01:45:51 +00:00
|
|
|
/*-
|
2017-11-27 15:23:17 +00:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
|
|
|
|
*
|
2004-08-17 22:05:54 +00:00
|
|
|
* Copyright (c) 2004 Andre Oppermann, Internet Business Solutions AG
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
2007-10-07 20:44:24 +00:00
|
|
|
#include <sys/cdefs.h>
|
|
|
|
__FBSDID("$FreeBSD$");
|
|
|
|
|
2004-08-17 22:05:54 +00:00
|
|
|
#include "opt_ipfw.h"
|
|
|
|
#include "opt_inet.h"
|
2011-09-27 13:27:17 +00:00
|
|
|
#include "opt_inet6.h"
|
2004-08-17 22:05:54 +00:00
|
|
|
#ifndef INET
|
|
|
|
#error IPFIREWALL requires INET.
|
|
|
|
#endif /* INET */
|
|
|
|
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/systm.h>
|
|
|
|
#include <sys/malloc.h>
|
|
|
|
#include <sys/mbuf.h>
|
|
|
|
#include <sys/module.h>
|
|
|
|
#include <sys/kernel.h>
|
Conditionally compile out V_ globals while instantiating the appropriate
container structures, depending on VIMAGE_GLOBALS compile time option.
Make VIMAGE_GLOBALS a new compile-time option, which by default will not
be defined, resulting in instatiations of global variables selected for
V_irtualization (enclosed in #ifdef VIMAGE_GLOBALS blocks) to be
effectively compiled out. Instantiate new global container structures
to hold V_irtualized variables: vnet_net_0, vnet_inet_0, vnet_inet6_0,
vnet_ipsec_0, vnet_netgraph_0, and vnet_gif_0.
Update the VSYM() macro so that depending on VIMAGE_GLOBALS the V_
macros resolve either to the original globals, or to fields inside
container structures, i.e. effectively
#ifdef VIMAGE_GLOBALS
#define V_rt_tables rt_tables
#else
#define V_rt_tables vnet_net_0._rt_tables
#endif
Update SYSCTL_V_*() macros to operate either on globals or on fields
inside container structs.
Extend the internal kldsym() lookups with the ability to resolve
selected fields inside the virtualization container structs. This
applies only to the fields which are explicitly registered for kldsym()
visibility via VNET_MOD_DECLARE() and vnet_mod_register(), currently
this is done only in sys/net/if.c.
Fix a few broken instances of MODULE_GLOBAL() macro use in SCTP code,
and modify the MODULE_GLOBAL() macro to resolve to V_ macros, which in
turn result in proper code being generated depending on VIMAGE_GLOBALS.
De-virtualize local static variables in sys/contrib/pf/net/pf_subr.c
which were prematurely V_irtualized by automated V_ prepending scripts
during earlier merging steps. PF virtualization will be done
separately, most probably after next PF import.
Convert a few variable initializations at instantiation to
initialization in init functions, most notably in ipfw. Also convert
TUNABLE_INT() initializers for V_ variables to TUNABLE_FETCH_INT() in
initializer functions.
Discussed at: devsummit Strassburg
Reviewed by: bz, julian
Approved by: julian (mentor)
Obtained from: //depot/projects/vimage-commit2/...
X-MFC after: never
Sponsored by: NLnet Foundation, The FreeBSD Foundation
2008-12-10 23:12:39 +00:00
|
|
|
#include <sys/lock.h>
|
|
|
|
#include <sys/rwlock.h>
|
2004-08-17 22:05:54 +00:00
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <sys/sysctl.h>
|
|
|
|
|
|
|
|
#include <net/if.h>
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
#include <net/if_var.h>
|
2004-08-17 22:05:54 +00:00
|
|
|
#include <net/route.h>
|
2012-09-04 19:43:26 +00:00
|
|
|
#include <net/ethernet.h>
|
2004-08-17 22:05:54 +00:00
|
|
|
#include <net/pfil.h>
|
2009-08-21 11:20:10 +00:00
|
|
|
#include <net/vnet.h>
|
2004-08-17 22:05:54 +00:00
|
|
|
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <netinet/in_systm.h>
|
|
|
|
#include <netinet/ip.h>
|
|
|
|
#include <netinet/ip_var.h>
|
|
|
|
#include <netinet/ip_fw.h>
|
2011-06-27 12:21:11 +00:00
|
|
|
#ifdef INET6
|
|
|
|
#include <netinet/ip6.h>
|
|
|
|
#include <netinet6/ip6_var.h>
|
2015-03-13 09:03:25 +00:00
|
|
|
#include <netinet6/scope6_var.h>
|
2011-06-27 12:21:11 +00:00
|
|
|
#endif
|
2012-09-14 11:51:49 +00:00
|
|
|
|
2009-12-28 12:29:13 +00:00
|
|
|
#include <netgraph/ng_ipfw.h>
|
2004-08-17 22:05:54 +00:00
|
|
|
|
2012-09-14 11:51:49 +00:00
|
|
|
#include <netpfil/ipfw/ip_fw_private.h>
|
|
|
|
|
2004-08-17 22:05:54 +00:00
|
|
|
#include <machine/in_cksum.h>
|
|
|
|
|
2018-07-24 16:35:52 +00:00
|
|
|
VNET_DEFINE_STATIC(int, fw_enable) = 1;
|
2009-12-16 10:48:40 +00:00
|
|
|
#define V_fw_enable VNET(fw_enable)
|
|
|
|
|
2006-05-12 04:41:27 +00:00
|
|
|
#ifdef INET6
|
2018-07-24 16:35:52 +00:00
|
|
|
VNET_DEFINE_STATIC(int, fw6_enable) = 1;
|
2009-12-16 10:48:40 +00:00
|
|
|
#define V_fw6_enable VNET(fw6_enable)
|
2008-12-11 16:26:38 +00:00
|
|
|
#endif
|
2006-05-12 04:41:27 +00:00
|
|
|
|
2018-07-24 16:35:52 +00:00
|
|
|
VNET_DEFINE_STATIC(int, fwlink_enable) = 0;
|
2012-09-04 19:43:26 +00:00
|
|
|
#define V_fwlink_enable VNET(fwlink_enable)
|
|
|
|
|
2006-05-12 04:41:27 +00:00
|
|
|
int ipfw_chg_hook(SYSCTL_HANDLER_ARGS);
|
2004-08-17 22:05:54 +00:00
|
|
|
|
2004-10-19 21:14:57 +00:00
|
|
|
/* Forward declarations. */
|
2019-03-14 22:31:12 +00:00
|
|
|
static int ipfw_divert(struct mbuf **, struct ip_fw_args *, bool);
|
2004-08-17 22:05:54 +00:00
|
|
|
|
2009-12-16 10:48:40 +00:00
|
|
|
#ifdef SYSCTL_NODE
|
Bring in the most recent version of ipfw and dummynet, developed
and tested over the past two months in the ipfw3-head branch. This
also happens to be the same code available in the Linux and Windows
ports of ipfw and dummynet.
The major enhancement is a completely restructured version of
dummynet, with support for different packet scheduling algorithms
(loadable at runtime), faster queue/pipe lookup, and a much cleaner
internal architecture and kernel/userland ABI which simplifies
future extensions.
In addition to the existing schedulers (FIFO and WF2Q+), we include
a Deficit Round Robin (DRR or RR for brevity) scheduler, and a new,
very fast version of WF2Q+ called QFQ.
Some test code is also present (in sys/netinet/ipfw/test) that
lets you build and test schedulers in userland.
Also, we have added a compatibility layer that understands requests
from the RELENG_7 and RELENG_8 versions of the /sbin/ipfw binaries,
and replies correctly (at least, it does its best; sometimes you
just cannot tell who sent the request and how to answer).
The compatibility layer should make it possible to MFC this code in a
relatively short time.
Some minor glitches (e.g. handling of ipfw set enable/disable,
and a workaround for a bug in RELENG_7's /sbin/ipfw) will be
fixed with separate commits.
CREDITS:
This work has been partly supported by the ONELAB2 project, and
mostly developed by Riccardo Panicucci and myself.
The code for the qfq scheduler is mostly from Fabio Checconi,
and Marta Carbone and Francesco Magno have helped with testing,
debugging and some bug fixes.
2010-03-02 17:40:48 +00:00
|
|
|
|
|
|
|
SYSBEGIN(f1)
|
|
|
|
|
2009-12-16 10:48:40 +00:00
|
|
|
SYSCTL_DECL(_net_inet_ip_fw);
|
2014-11-07 09:39:05 +00:00
|
|
|
SYSCTL_PROC(_net_inet_ip_fw, OID_AUTO, enable,
|
|
|
|
CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3,
|
|
|
|
&VNET_NAME(fw_enable), 0, ipfw_chg_hook, "I", "Enable ipfw");
|
2009-12-16 10:48:40 +00:00
|
|
|
#ifdef INET6
|
|
|
|
SYSCTL_DECL(_net_inet6_ip6_fw);
|
2014-11-07 09:39:05 +00:00
|
|
|
SYSCTL_PROC(_net_inet6_ip6_fw, OID_AUTO, enable,
|
|
|
|
CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3,
|
|
|
|
&VNET_NAME(fw6_enable), 0, ipfw_chg_hook, "I", "Enable ipfw+6");
|
2009-12-16 10:48:40 +00:00
|
|
|
#endif /* INET6 */
|
Bring in the most recent version of ipfw and dummynet, developed
and tested over the past two months in the ipfw3-head branch. This
also happens to be the same code available in the Linux and Windows
ports of ipfw and dummynet.
The major enhancement is a completely restructured version of
dummynet, with support for different packet scheduling algorithms
(loadable at runtime), faster queue/pipe lookup, and a much cleaner
internal architecture and kernel/userland ABI which simplifies
future extensions.
In addition to the existing schedulers (FIFO and WF2Q+), we include
a Deficit Round Robin (DRR or RR for brevity) scheduler, and a new,
very fast version of WF2Q+ called QFQ.
Some test code is also present (in sys/netinet/ipfw/test) that
lets you build and test schedulers in userland.
Also, we have added a compatibility layer that understands requests
from the RELENG_7 and RELENG_8 versions of the /sbin/ipfw binaries,
and replies correctly (at least, it does its best; sometimes you
just cannot tell who sent the request and how to answer).
The compatibility layer should make it possible to MFC this code in a
relatively short time.
Some minor glitches (e.g. handling of ipfw set enable/disable,
and a workaround for a bug in RELENG_7's /sbin/ipfw) will be
fixed with separate commits.
CREDITS:
This work has been partly supported by the ONELAB2 project, and
mostly developed by Riccardo Panicucci and myself.
The code for the qfq scheduler is mostly from Fabio Checconi,
and Marta Carbone and Francesco Magno have helped with testing,
debugging and some bug fixes.
2010-03-02 17:40:48 +00:00
|
|
|
|
2012-09-04 19:43:26 +00:00
|
|
|
SYSCTL_DECL(_net_link_ether);
|
2014-11-07 09:39:05 +00:00
|
|
|
SYSCTL_PROC(_net_link_ether, OID_AUTO, ipfw,
|
|
|
|
CTLFLAG_VNET | CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3,
|
|
|
|
&VNET_NAME(fwlink_enable), 0, ipfw_chg_hook, "I",
|
|
|
|
"Pass ether pkts through firewall");
|
2012-09-04 19:43:26 +00:00
|
|
|
|
Bring in the most recent version of ipfw and dummynet, developed
and tested over the past two months in the ipfw3-head branch. This
also happens to be the same code available in the Linux and Windows
ports of ipfw and dummynet.
The major enhancement is a completely restructured version of
dummynet, with support for different packet scheduling algorithms
(loadable at runtime), faster queue/pipe lookup, and a much cleaner
internal architecture and kernel/userland ABI which simplifies
future extensions.
In addition to the existing schedulers (FIFO and WF2Q+), we include
a Deficit Round Robin (DRR or RR for brevity) scheduler, and a new,
very fast version of WF2Q+ called QFQ.
Some test code is also present (in sys/netinet/ipfw/test) that
lets you build and test schedulers in userland.
Also, we have added a compatibility layer that understands requests
from the RELENG_7 and RELENG_8 versions of the /sbin/ipfw binaries,
and replies correctly (at least, it does its best; sometimes you
just cannot tell who sent the request and how to answer).
The compatibility layer should make it possible to MFC this code in a
relatively short time.
Some minor glitches (e.g. handling of ipfw set enable/disable,
and a workaround for a bug in RELENG_7's /sbin/ipfw) will be
fixed with separate commits.
CREDITS:
This work has been partly supported by the ONELAB2 project, and
mostly developed by Riccardo Panicucci and myself.
The code for the qfq scheduler is mostly from Fabio Checconi,
and Marta Carbone and Francesco Magno have helped with testing,
debugging and some bug fixes.
2010-03-02 17:40:48 +00:00
|
|
|
SYSEND
|
|
|
|
|
2009-12-16 10:48:40 +00:00
|
|
|
#endif /* SYSCTL_NODE */
|
|
|
|
|
2009-12-28 10:47:04 +00:00
|
|
|
/*
|
|
|
|
* The pfilter hook to pass packets to ipfw_chk and then to
|
|
|
|
* dummynet, divert, netgraph or other modules.
|
|
|
|
* The packet may be consumed.
|
|
|
|
*/
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
static pfil_return_t
|
2019-03-14 22:28:50 +00:00
|
|
|
ipfw_check_packet(struct mbuf **m0, struct ifnet *ifp, int flags,
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
void *ruleset __unused, struct inpcb *inp)
|
2004-08-17 22:05:54 +00:00
|
|
|
{
|
|
|
|
struct ip_fw_args args;
|
2010-01-04 19:01:22 +00:00
|
|
|
struct m_tag *tag;
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
pfil_return_t ret;
|
2019-03-14 22:32:50 +00:00
|
|
|
int ipfw;
|
2010-01-04 19:01:22 +00:00
|
|
|
|
2019-03-14 22:28:50 +00:00
|
|
|
args.flags = (flags & PFIL_IN) ? IPFW_ARGS_IN : IPFW_ARGS_OUT;
|
2004-09-13 16:46:05 +00:00
|
|
|
again:
|
2010-01-04 19:01:22 +00:00
|
|
|
/*
|
|
|
|
* extract and remove the tag if present. If we are left
|
|
|
|
* with onepass, optimize the outgoing path.
|
|
|
|
*/
|
|
|
|
tag = m_tag_locate(*m0, MTAG_IPFW_RULE, 0, NULL);
|
|
|
|
if (tag != NULL) {
|
|
|
|
args.rule = *((struct ipfw_rule_ref *)(tag+1));
|
|
|
|
m_tag_delete(*m0, tag);
|
2012-10-08 22:58:28 +00:00
|
|
|
if (args.rule.info & IPFW_ONEPASS)
|
2011-06-21 06:06:47 +00:00
|
|
|
return (0);
|
2019-01-10 01:47:57 +00:00
|
|
|
args.flags |= IPFW_ARGS_REF;
|
2007-11-06 23:01:42 +00:00
|
|
|
}
|
|
|
|
|
2004-08-17 22:05:54 +00:00
|
|
|
args.m = *m0;
|
2019-03-14 22:28:50 +00:00
|
|
|
args.ifp = ifp;
|
2004-09-29 04:54:33 +00:00
|
|
|
args.inp = inp;
|
2004-08-17 22:05:54 +00:00
|
|
|
|
2010-01-04 19:01:22 +00:00
|
|
|
ipfw = ipfw_chk(&args);
|
|
|
|
*m0 = args.m;
|
2009-04-27 17:37:36 +00:00
|
|
|
|
2019-03-18 10:39:14 +00:00
|
|
|
KASSERT(*m0 != NULL || ipfw == IP_FW_DENY ||
|
|
|
|
ipfw == IP_FW_NAT64, ("%s: m0 is NULL", __func__));
|
2004-08-17 22:05:54 +00:00
|
|
|
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
ret = PFIL_PASS;
|
2005-01-14 09:00:46 +00:00
|
|
|
switch (ipfw) {
|
|
|
|
case IP_FW_PASS:
|
2009-12-28 10:47:04 +00:00
|
|
|
/* next_hop may be set by ipfw_chk */
|
2019-01-10 01:47:57 +00:00
|
|
|
if ((args.flags & (IPFW_ARGS_NH4 | IPFW_ARGS_NH4PTR |
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
IPFW_ARGS_NH6 | IPFW_ARGS_NH6PTR)) == 0)
|
2019-01-10 01:47:57 +00:00
|
|
|
break;
|
2012-10-25 09:39:14 +00:00
|
|
|
#if (!defined(INET6) && !defined(INET))
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
ret = PFIL_DROPPED;
|
2009-12-28 10:47:04 +00:00
|
|
|
#else
|
2010-01-04 19:01:22 +00:00
|
|
|
{
|
2019-01-10 01:47:57 +00:00
|
|
|
void *psa;
|
2011-08-20 17:05:11 +00:00
|
|
|
size_t len;
|
|
|
|
#ifdef INET
|
2019-01-10 01:47:57 +00:00
|
|
|
if (args.flags & (IPFW_ARGS_NH4 | IPFW_ARGS_NH4PTR)) {
|
|
|
|
MPASS((args.flags & (IPFW_ARGS_NH4 |
|
|
|
|
IPFW_ARGS_NH4PTR)) != (IPFW_ARGS_NH4 |
|
|
|
|
IPFW_ARGS_NH4PTR));
|
|
|
|
MPASS((args.flags & (IPFW_ARGS_NH6 |
|
|
|
|
IPFW_ARGS_NH6PTR)) == 0);
|
2011-08-20 17:05:11 +00:00
|
|
|
len = sizeof(struct sockaddr_in);
|
2019-01-10 01:47:57 +00:00
|
|
|
psa = (args.flags & IPFW_ARGS_NH4) ?
|
|
|
|
&args.hopstore : args.next_hop;
|
|
|
|
if (in_localip(satosin(psa)->sin_addr))
|
|
|
|
(*m0)->m_flags |= M_FASTFWD_OURS;
|
|
|
|
(*m0)->m_flags |= M_IP_NEXTHOP;
|
|
|
|
}
|
|
|
|
#endif /* INET */
|
|
|
|
#ifdef INET6
|
|
|
|
if (args.flags & (IPFW_ARGS_NH6 | IPFW_ARGS_NH6PTR)) {
|
|
|
|
MPASS((args.flags & (IPFW_ARGS_NH6 |
|
|
|
|
IPFW_ARGS_NH6PTR)) != (IPFW_ARGS_NH6 |
|
|
|
|
IPFW_ARGS_NH6PTR));
|
|
|
|
MPASS((args.flags & (IPFW_ARGS_NH4 |
|
|
|
|
IPFW_ARGS_NH4PTR)) == 0);
|
|
|
|
len = sizeof(struct sockaddr_in6);
|
|
|
|
psa = args.next_hop6;
|
|
|
|
(*m0)->m_flags |= M_IP6_NEXTHOP;
|
|
|
|
}
|
|
|
|
#endif /* INET6 */
|
|
|
|
/*
|
|
|
|
* Incoming packets should not be tagged so we do not
|
2009-12-28 10:47:04 +00:00
|
|
|
* m_tag_find. Outgoing packets may be tagged, so we
|
|
|
|
* reuse the tag if present.
|
|
|
|
*/
|
2019-03-14 22:28:50 +00:00
|
|
|
tag = (flags & PFIL_IN) ? NULL :
|
2009-12-28 10:47:04 +00:00
|
|
|
m_tag_find(*m0, PACKET_TAG_IPFORWARD, NULL);
|
2019-01-10 01:47:57 +00:00
|
|
|
if (tag != NULL) {
|
|
|
|
m_tag_unlink(*m0, tag);
|
2009-12-28 10:47:04 +00:00
|
|
|
} else {
|
2019-01-10 01:47:57 +00:00
|
|
|
tag = m_tag_get(PACKET_TAG_IPFORWARD, len,
|
2011-08-20 17:05:11 +00:00
|
|
|
M_NOWAIT);
|
2019-01-10 01:47:57 +00:00
|
|
|
if (tag == NULL) {
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
ret = PFIL_DROPPED;
|
|
|
|
break;
|
2009-12-28 10:47:04 +00:00
|
|
|
}
|
|
|
|
}
|
2019-01-10 01:47:57 +00:00
|
|
|
if ((args.flags & IPFW_ARGS_NH6) == 0)
|
|
|
|
bcopy(psa, tag + 1, len);
|
|
|
|
m_tag_prepend(*m0, tag);
|
|
|
|
ret = 0;
|
2011-08-20 17:05:11 +00:00
|
|
|
#ifdef INET6
|
2019-01-10 01:47:57 +00:00
|
|
|
/* IPv6 next hop needs additional handling */
|
|
|
|
if (args.flags & (IPFW_ARGS_NH6 | IPFW_ARGS_NH6PTR)) {
|
2015-03-13 09:03:25 +00:00
|
|
|
struct sockaddr_in6 *sa6;
|
|
|
|
|
2019-01-10 01:47:57 +00:00
|
|
|
sa6 = satosin6(tag + 1);
|
|
|
|
if (args.flags & IPFW_ARGS_NH6) {
|
|
|
|
sa6->sin6_family = AF_INET6;
|
|
|
|
sa6->sin6_len = sizeof(*sa6);
|
|
|
|
sa6->sin6_addr = args.hopstore6.sin6_addr;
|
|
|
|
sa6->sin6_port = args.hopstore6.sin6_port;
|
|
|
|
sa6->sin6_scope_id =
|
|
|
|
args.hopstore6.sin6_scope_id;
|
|
|
|
}
|
2015-03-13 09:03:25 +00:00
|
|
|
/*
|
|
|
|
* If nh6 address is link-local we should convert
|
|
|
|
* it to kernel internal form before doing any
|
|
|
|
* comparisons.
|
|
|
|
*/
|
|
|
|
if (sa6_embedscope(sa6, V_ip6_use_defzone) != 0) {
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
ret = PFIL_DROPPED;
|
2015-03-13 09:03:25 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (in6_localip(&sa6->sin6_addr))
|
2011-08-20 17:05:11 +00:00
|
|
|
(*m0)->m_flags |= M_FASTFWD_OURS;
|
|
|
|
}
|
2019-01-10 01:47:57 +00:00
|
|
|
#endif /* INET6 */
|
2010-01-04 19:01:22 +00:00
|
|
|
}
|
2012-10-25 09:39:14 +00:00
|
|
|
#endif /* INET || INET6 */
|
2009-12-28 10:47:04 +00:00
|
|
|
break;
|
2005-01-14 09:00:46 +00:00
|
|
|
|
|
|
|
case IP_FW_DENY:
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
ret = PFIL_DROPPED;
|
|
|
|
break;
|
2005-01-14 09:00:46 +00:00
|
|
|
|
|
|
|
case IP_FW_DUMMYNET:
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
if (ip_dn_io_ptr == NULL) {
|
|
|
|
ret = PFIL_DROPPED;
|
|
|
|
break;
|
|
|
|
}
|
2019-01-10 02:01:20 +00:00
|
|
|
MPASS(args.flags & IPFW_ARGS_REF);
|
2019-03-14 22:32:50 +00:00
|
|
|
if (args.flags & (IPFW_ARGS_IP4 | IPFW_ARGS_IP6))
|
|
|
|
(void )ip_dn_io_ptr(m0, &args);
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
else {
|
|
|
|
ret = PFIL_DROPPED;
|
|
|
|
break;
|
|
|
|
}
|
2009-12-28 10:47:04 +00:00
|
|
|
/*
|
|
|
|
* XXX should read the return value.
|
|
|
|
* dummynet normally eats the packet and sets *m0=NULL
|
|
|
|
* unless the packet can be sent immediately. In this
|
|
|
|
* case args is updated and we should re-run the
|
|
|
|
* check without clearing args.
|
|
|
|
*/
|
2007-11-06 23:01:42 +00:00
|
|
|
if (*m0 != NULL)
|
|
|
|
goto again;
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
ret = PFIL_CONSUMED;
|
2005-01-14 09:00:46 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case IP_FW_TEE:
|
|
|
|
case IP_FW_DIVERT:
|
2009-12-28 10:47:04 +00:00
|
|
|
if (ip_divert_ptr == NULL) {
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
ret = PFIL_DROPPED;
|
|
|
|
break;
|
2009-12-28 10:47:04 +00:00
|
|
|
}
|
2019-01-10 02:01:20 +00:00
|
|
|
MPASS(args.flags & IPFW_ARGS_REF);
|
2019-03-14 22:31:12 +00:00
|
|
|
(void )ipfw_divert(m0, &args, ipfw == IP_FW_TEE);
|
2010-01-04 19:01:22 +00:00
|
|
|
/* continue processing for the original packet (tee). */
|
|
|
|
if (*m0)
|
|
|
|
goto again;
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
ret = PFIL_CONSUMED;
|
2009-12-28 10:47:04 +00:00
|
|
|
break;
|
2005-01-14 09:00:46 +00:00
|
|
|
|
2005-02-05 12:06:33 +00:00
|
|
|
case IP_FW_NGTEE:
|
|
|
|
case IP_FW_NETGRAPH:
|
2010-01-07 10:08:05 +00:00
|
|
|
if (ng_ipfw_input_p == NULL) {
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
ret = PFIL_DROPPED;
|
|
|
|
break;
|
2009-12-28 10:47:04 +00:00
|
|
|
}
|
2019-01-10 02:01:20 +00:00
|
|
|
MPASS(args.flags & IPFW_ARGS_REF);
|
2019-03-14 22:30:05 +00:00
|
|
|
(void )ng_ipfw_input_p(m0, &args, ipfw == IP_FW_NGTEE);
|
2009-12-28 10:47:04 +00:00
|
|
|
if (ipfw == IP_FW_NGTEE) /* ignore errors for NGTEE */
|
|
|
|
goto again; /* continue with packet */
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
ret = PFIL_CONSUMED;
|
2009-12-28 10:47:04 +00:00
|
|
|
break;
|
2005-02-05 12:06:33 +00:00
|
|
|
|
2006-12-29 21:59:17 +00:00
|
|
|
case IP_FW_NAT:
|
2010-09-28 23:23:23 +00:00
|
|
|
/* honor one-pass in case of successful nat */
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
if (V_fw_one_pass)
|
2019-01-10 01:47:57 +00:00
|
|
|
break;
|
2010-09-28 23:23:23 +00:00
|
|
|
goto again;
|
|
|
|
|
2009-04-01 20:23:47 +00:00
|
|
|
case IP_FW_REASS:
|
2009-12-28 10:47:04 +00:00
|
|
|
goto again; /* continue with packet */
|
2019-01-10 01:47:57 +00:00
|
|
|
|
2019-03-11 10:42:09 +00:00
|
|
|
case IP_FW_NAT64:
|
|
|
|
ret = PFIL_CONSUMED;
|
|
|
|
break;
|
|
|
|
|
2005-01-14 09:00:46 +00:00
|
|
|
default:
|
|
|
|
KASSERT(0, ("%s: unknown retval", __func__));
|
|
|
|
}
|
2004-08-17 22:05:54 +00:00
|
|
|
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
if (ret != PFIL_PASS) {
|
2009-12-28 10:47:04 +00:00
|
|
|
if (*m0)
|
2010-01-04 19:01:22 +00:00
|
|
|
FREE_PKT(*m0);
|
2009-12-28 10:47:04 +00:00
|
|
|
*m0 = NULL;
|
|
|
|
}
|
2012-10-06 10:02:11 +00:00
|
|
|
|
2019-01-10 01:47:57 +00:00
|
|
|
return (ret);
|
2004-08-17 22:05:54 +00:00
|
|
|
}
|
|
|
|
|
2012-09-04 19:43:26 +00:00
|
|
|
/*
|
|
|
|
* ipfw processing for ethernet packets (in and out).
|
|
|
|
*/
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
static pfil_return_t
|
PFIL_MEMPTR for ipfw link level hook
With new pfil(9) KPI it is possible to pass a void pointer with length
instead of mbuf pointer to a packet filter. Until this commit no filters
supported that, so pfil run through a shim function pfil_fake_mbuf().
Now the ipfw(4) hook named "default-link", that is instantiated when
net.link.ether.ipfw sysctl is on, supports processing pointer/length
packets natively.
- ip_fw_args now has union for either mbuf or void *, and if flags have
non-zero length, then we use the void *.
- through ipfw_chk() we handle mem/mbuf cases differently.
- ether_header goes away from args. It is ipfw_chk() responsibility
to do parsing of Ethernet header.
- ipfw_log() now uses different bpf APIs to log packets.
Although ipfw_chk() is now capable to process pointer/length packets,
this commit adds support for the link level hook only, see
ipfw_check_frame(). Potentially the IP processing hook ipfw_check_packet()
can be improved too, but that requires more changes since the hook
supports more complex actions: NAT, divert, etc.
Reviewed by: ae
Differential Revision: https://reviews.freebsd.org/D19357
2019-03-14 22:52:16 +00:00
|
|
|
ipfw_check_frame(pfil_packet_t p, struct ifnet *ifp, int flags,
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
void *ruleset __unused, struct inpcb *inp)
|
2012-09-04 19:43:26 +00:00
|
|
|
{
|
2019-01-10 01:47:57 +00:00
|
|
|
struct ip_fw_args args;
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
pfil_return_t ret;
|
PFIL_MEMPTR for ipfw link level hook
With new pfil(9) KPI it is possible to pass a void pointer with length
instead of mbuf pointer to a packet filter. Until this commit no filters
supported that, so pfil run through a shim function pfil_fake_mbuf().
Now the ipfw(4) hook named "default-link", that is instantiated when
net.link.ether.ipfw sysctl is on, supports processing pointer/length
packets natively.
- ip_fw_args now has union for either mbuf or void *, and if flags have
non-zero length, then we use the void *.
- through ipfw_chk() we handle mem/mbuf cases differently.
- ether_header goes away from args. It is ipfw_chk() responsibility
to do parsing of Ethernet header.
- ipfw_log() now uses different bpf APIs to log packets.
Although ipfw_chk() is now capable to process pointer/length packets,
this commit adds support for the link level hook only, see
ipfw_check_frame(). Potentially the IP processing hook ipfw_check_packet()
can be improved too, but that requires more changes since the hook
supports more complex actions: NAT, divert, etc.
Reviewed by: ae
Differential Revision: https://reviews.freebsd.org/D19357
2019-03-14 22:52:16 +00:00
|
|
|
bool mem, realloc;
|
|
|
|
int ipfw;
|
2012-09-04 19:43:26 +00:00
|
|
|
|
PFIL_MEMPTR for ipfw link level hook
With new pfil(9) KPI it is possible to pass a void pointer with length
instead of mbuf pointer to a packet filter. Until this commit no filters
supported that, so pfil run through a shim function pfil_fake_mbuf().
Now the ipfw(4) hook named "default-link", that is instantiated when
net.link.ether.ipfw sysctl is on, supports processing pointer/length
packets natively.
- ip_fw_args now has union for either mbuf or void *, and if flags have
non-zero length, then we use the void *.
- through ipfw_chk() we handle mem/mbuf cases differently.
- ether_header goes away from args. It is ipfw_chk() responsibility
to do parsing of Ethernet header.
- ipfw_log() now uses different bpf APIs to log packets.
Although ipfw_chk() is now capable to process pointer/length packets,
this commit adds support for the link level hook only, see
ipfw_check_frame(). Potentially the IP processing hook ipfw_check_packet()
can be improved too, but that requires more changes since the hook
supports more complex actions: NAT, divert, etc.
Reviewed by: ae
Differential Revision: https://reviews.freebsd.org/D19357
2019-03-14 22:52:16 +00:00
|
|
|
if (flags & PFIL_MEMPTR) {
|
|
|
|
mem = true;
|
|
|
|
realloc = false;
|
|
|
|
args.flags = PFIL_LENGTH(flags) | IPFW_ARGS_ETHER;
|
|
|
|
args.mem = p.mem;
|
|
|
|
} else {
|
|
|
|
mem = realloc = false;
|
|
|
|
args.flags = IPFW_ARGS_ETHER;
|
2012-09-04 19:43:26 +00:00
|
|
|
}
|
PFIL_MEMPTR for ipfw link level hook
With new pfil(9) KPI it is possible to pass a void pointer with length
instead of mbuf pointer to a packet filter. Until this commit no filters
supported that, so pfil run through a shim function pfil_fake_mbuf().
Now the ipfw(4) hook named "default-link", that is instantiated when
net.link.ether.ipfw sysctl is on, supports processing pointer/length
packets natively.
- ip_fw_args now has union for either mbuf or void *, and if flags have
non-zero length, then we use the void *.
- through ipfw_chk() we handle mem/mbuf cases differently.
- ether_header goes away from args. It is ipfw_chk() responsibility
to do parsing of Ethernet header.
- ipfw_log() now uses different bpf APIs to log packets.
Although ipfw_chk() is now capable to process pointer/length packets,
this commit adds support for the link level hook only, see
ipfw_check_frame(). Potentially the IP processing hook ipfw_check_packet()
can be improved too, but that requires more changes since the hook
supports more complex actions: NAT, divert, etc.
Reviewed by: ae
Differential Revision: https://reviews.freebsd.org/D19357
2019-03-14 22:52:16 +00:00
|
|
|
args.flags |= (flags & PFIL_IN) ? IPFW_ARGS_IN : IPFW_ARGS_OUT;
|
2019-03-14 22:28:50 +00:00
|
|
|
args.ifp = ifp;
|
PFIL_MEMPTR for ipfw link level hook
With new pfil(9) KPI it is possible to pass a void pointer with length
instead of mbuf pointer to a packet filter. Until this commit no filters
supported that, so pfil run through a shim function pfil_fake_mbuf().
Now the ipfw(4) hook named "default-link", that is instantiated when
net.link.ether.ipfw sysctl is on, supports processing pointer/length
packets natively.
- ip_fw_args now has union for either mbuf or void *, and if flags have
non-zero length, then we use the void *.
- through ipfw_chk() we handle mem/mbuf cases differently.
- ether_header goes away from args. It is ipfw_chk() responsibility
to do parsing of Ethernet header.
- ipfw_log() now uses different bpf APIs to log packets.
Although ipfw_chk() is now capable to process pointer/length packets,
this commit adds support for the link level hook only, see
ipfw_check_frame(). Potentially the IP processing hook ipfw_check_packet()
can be improved too, but that requires more changes since the hook
supports more complex actions: NAT, divert, etc.
Reviewed by: ae
Differential Revision: https://reviews.freebsd.org/D19357
2019-03-14 22:52:16 +00:00
|
|
|
args.inp = inp;
|
|
|
|
|
|
|
|
again:
|
|
|
|
if (!mem) {
|
2012-09-04 19:43:26 +00:00
|
|
|
/*
|
PFIL_MEMPTR for ipfw link level hook
With new pfil(9) KPI it is possible to pass a void pointer with length
instead of mbuf pointer to a packet filter. Until this commit no filters
supported that, so pfil run through a shim function pfil_fake_mbuf().
Now the ipfw(4) hook named "default-link", that is instantiated when
net.link.ether.ipfw sysctl is on, supports processing pointer/length
packets natively.
- ip_fw_args now has union for either mbuf or void *, and if flags have
non-zero length, then we use the void *.
- through ipfw_chk() we handle mem/mbuf cases differently.
- ether_header goes away from args. It is ipfw_chk() responsibility
to do parsing of Ethernet header.
- ipfw_log() now uses different bpf APIs to log packets.
Although ipfw_chk() is now capable to process pointer/length packets,
this commit adds support for the link level hook only, see
ipfw_check_frame(). Potentially the IP processing hook ipfw_check_packet()
can be improved too, but that requires more changes since the hook
supports more complex actions: NAT, divert, etc.
Reviewed by: ae
Differential Revision: https://reviews.freebsd.org/D19357
2019-03-14 22:52:16 +00:00
|
|
|
* Fetch start point from rule, if any.
|
|
|
|
* Remove the tag if present.
|
2012-09-04 19:43:26 +00:00
|
|
|
*/
|
PFIL_MEMPTR for ipfw link level hook
With new pfil(9) KPI it is possible to pass a void pointer with length
instead of mbuf pointer to a packet filter. Until this commit no filters
supported that, so pfil run through a shim function pfil_fake_mbuf().
Now the ipfw(4) hook named "default-link", that is instantiated when
net.link.ether.ipfw sysctl is on, supports processing pointer/length
packets natively.
- ip_fw_args now has union for either mbuf or void *, and if flags have
non-zero length, then we use the void *.
- through ipfw_chk() we handle mem/mbuf cases differently.
- ether_header goes away from args. It is ipfw_chk() responsibility
to do parsing of Ethernet header.
- ipfw_log() now uses different bpf APIs to log packets.
Although ipfw_chk() is now capable to process pointer/length packets,
this commit adds support for the link level hook only, see
ipfw_check_frame(). Potentially the IP processing hook ipfw_check_packet()
can be improved too, but that requires more changes since the hook
supports more complex actions: NAT, divert, etc.
Reviewed by: ae
Differential Revision: https://reviews.freebsd.org/D19357
2019-03-14 22:52:16 +00:00
|
|
|
struct m_tag *mtag;
|
|
|
|
|
|
|
|
mtag = m_tag_locate(*p.m, MTAG_IPFW_RULE, 0, NULL);
|
|
|
|
if (mtag != NULL) {
|
|
|
|
args.rule = *((struct ipfw_rule_ref *)(mtag+1));
|
|
|
|
m_tag_delete(*p.m, mtag);
|
|
|
|
if (args.rule.info & IPFW_ONEPASS)
|
|
|
|
return (PFIL_PASS);
|
|
|
|
args.flags |= IPFW_ARGS_REF;
|
2012-09-04 19:43:26 +00:00
|
|
|
}
|
PFIL_MEMPTR for ipfw link level hook
With new pfil(9) KPI it is possible to pass a void pointer with length
instead of mbuf pointer to a packet filter. Until this commit no filters
supported that, so pfil run through a shim function pfil_fake_mbuf().
Now the ipfw(4) hook named "default-link", that is instantiated when
net.link.ether.ipfw sysctl is on, supports processing pointer/length
packets natively.
- ip_fw_args now has union for either mbuf or void *, and if flags have
non-zero length, then we use the void *.
- through ipfw_chk() we handle mem/mbuf cases differently.
- ether_header goes away from args. It is ipfw_chk() responsibility
to do parsing of Ethernet header.
- ipfw_log() now uses different bpf APIs to log packets.
Although ipfw_chk() is now capable to process pointer/length packets,
this commit adds support for the link level hook only, see
ipfw_check_frame(). Potentially the IP processing hook ipfw_check_packet()
can be improved too, but that requires more changes since the hook
supports more complex actions: NAT, divert, etc.
Reviewed by: ae
Differential Revision: https://reviews.freebsd.org/D19357
2019-03-14 22:52:16 +00:00
|
|
|
args.m = *p.m;
|
2012-09-04 19:43:26 +00:00
|
|
|
}
|
PFIL_MEMPTR for ipfw link level hook
With new pfil(9) KPI it is possible to pass a void pointer with length
instead of mbuf pointer to a packet filter. Until this commit no filters
supported that, so pfil run through a shim function pfil_fake_mbuf().
Now the ipfw(4) hook named "default-link", that is instantiated when
net.link.ether.ipfw sysctl is on, supports processing pointer/length
packets natively.
- ip_fw_args now has union for either mbuf or void *, and if flags have
non-zero length, then we use the void *.
- through ipfw_chk() we handle mem/mbuf cases differently.
- ether_header goes away from args. It is ipfw_chk() responsibility
to do parsing of Ethernet header.
- ipfw_log() now uses different bpf APIs to log packets.
Although ipfw_chk() is now capable to process pointer/length packets,
this commit adds support for the link level hook only, see
ipfw_check_frame(). Potentially the IP processing hook ipfw_check_packet()
can be improved too, but that requires more changes since the hook
supports more complex actions: NAT, divert, etc.
Reviewed by: ae
Differential Revision: https://reviews.freebsd.org/D19357
2019-03-14 22:52:16 +00:00
|
|
|
|
|
|
|
ipfw = ipfw_chk(&args);
|
2012-09-04 19:43:26 +00:00
|
|
|
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
ret = PFIL_PASS;
|
PFIL_MEMPTR for ipfw link level hook
With new pfil(9) KPI it is possible to pass a void pointer with length
instead of mbuf pointer to a packet filter. Until this commit no filters
supported that, so pfil run through a shim function pfil_fake_mbuf().
Now the ipfw(4) hook named "default-link", that is instantiated when
net.link.ether.ipfw sysctl is on, supports processing pointer/length
packets natively.
- ip_fw_args now has union for either mbuf or void *, and if flags have
non-zero length, then we use the void *.
- through ipfw_chk() we handle mem/mbuf cases differently.
- ether_header goes away from args. It is ipfw_chk() responsibility
to do parsing of Ethernet header.
- ipfw_log() now uses different bpf APIs to log packets.
Although ipfw_chk() is now capable to process pointer/length packets,
this commit adds support for the link level hook only, see
ipfw_check_frame(). Potentially the IP processing hook ipfw_check_packet()
can be improved too, but that requires more changes since the hook
supports more complex actions: NAT, divert, etc.
Reviewed by: ae
Differential Revision: https://reviews.freebsd.org/D19357
2019-03-14 22:52:16 +00:00
|
|
|
switch (ipfw) {
|
2012-09-04 19:43:26 +00:00
|
|
|
case IP_FW_PASS:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IP_FW_DENY:
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
ret = PFIL_DROPPED;
|
|
|
|
break;
|
2012-09-04 19:43:26 +00:00
|
|
|
|
|
|
|
case IP_FW_DUMMYNET:
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
if (ip_dn_io_ptr == NULL) {
|
|
|
|
ret = PFIL_DROPPED;
|
|
|
|
break;
|
|
|
|
}
|
PFIL_MEMPTR for ipfw link level hook
With new pfil(9) KPI it is possible to pass a void pointer with length
instead of mbuf pointer to a packet filter. Until this commit no filters
supported that, so pfil run through a shim function pfil_fake_mbuf().
Now the ipfw(4) hook named "default-link", that is instantiated when
net.link.ether.ipfw sysctl is on, supports processing pointer/length
packets natively.
- ip_fw_args now has union for either mbuf or void *, and if flags have
non-zero length, then we use the void *.
- through ipfw_chk() we handle mem/mbuf cases differently.
- ether_header goes away from args. It is ipfw_chk() responsibility
to do parsing of Ethernet header.
- ipfw_log() now uses different bpf APIs to log packets.
Although ipfw_chk() is now capable to process pointer/length packets,
this commit adds support for the link level hook only, see
ipfw_check_frame(). Potentially the IP processing hook ipfw_check_packet()
can be improved too, but that requires more changes since the hook
supports more complex actions: NAT, divert, etc.
Reviewed by: ae
Differential Revision: https://reviews.freebsd.org/D19357
2019-03-14 22:52:16 +00:00
|
|
|
if (mem) {
|
|
|
|
if (pfil_realloc(&p, flags, ifp) != 0) {
|
|
|
|
ret = PFIL_DROPPED;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
mem = false;
|
|
|
|
realloc = true;
|
|
|
|
}
|
2019-01-10 02:01:20 +00:00
|
|
|
MPASS(args.flags & IPFW_ARGS_REF);
|
PFIL_MEMPTR for ipfw link level hook
With new pfil(9) KPI it is possible to pass a void pointer with length
instead of mbuf pointer to a packet filter. Until this commit no filters
supported that, so pfil run through a shim function pfil_fake_mbuf().
Now the ipfw(4) hook named "default-link", that is instantiated when
net.link.ether.ipfw sysctl is on, supports processing pointer/length
packets natively.
- ip_fw_args now has union for either mbuf or void *, and if flags have
non-zero length, then we use the void *.
- through ipfw_chk() we handle mem/mbuf cases differently.
- ether_header goes away from args. It is ipfw_chk() responsibility
to do parsing of Ethernet header.
- ipfw_log() now uses different bpf APIs to log packets.
Although ipfw_chk() is now capable to process pointer/length packets,
this commit adds support for the link level hook only, see
ipfw_check_frame(). Potentially the IP processing hook ipfw_check_packet()
can be improved too, but that requires more changes since the hook
supports more complex actions: NAT, divert, etc.
Reviewed by: ae
Differential Revision: https://reviews.freebsd.org/D19357
2019-03-14 22:52:16 +00:00
|
|
|
ip_dn_io_ptr(p.m, &args);
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
return (PFIL_CONSUMED);
|
2012-09-04 19:43:26 +00:00
|
|
|
|
2018-10-27 07:32:26 +00:00
|
|
|
case IP_FW_NGTEE:
|
|
|
|
case IP_FW_NETGRAPH:
|
|
|
|
if (ng_ipfw_input_p == NULL) {
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
ret = PFIL_DROPPED;
|
|
|
|
break;
|
2018-10-27 07:32:26 +00:00
|
|
|
}
|
PFIL_MEMPTR for ipfw link level hook
With new pfil(9) KPI it is possible to pass a void pointer with length
instead of mbuf pointer to a packet filter. Until this commit no filters
supported that, so pfil run through a shim function pfil_fake_mbuf().
Now the ipfw(4) hook named "default-link", that is instantiated when
net.link.ether.ipfw sysctl is on, supports processing pointer/length
packets natively.
- ip_fw_args now has union for either mbuf or void *, and if flags have
non-zero length, then we use the void *.
- through ipfw_chk() we handle mem/mbuf cases differently.
- ether_header goes away from args. It is ipfw_chk() responsibility
to do parsing of Ethernet header.
- ipfw_log() now uses different bpf APIs to log packets.
Although ipfw_chk() is now capable to process pointer/length packets,
this commit adds support for the link level hook only, see
ipfw_check_frame(). Potentially the IP processing hook ipfw_check_packet()
can be improved too, but that requires more changes since the hook
supports more complex actions: NAT, divert, etc.
Reviewed by: ae
Differential Revision: https://reviews.freebsd.org/D19357
2019-03-14 22:52:16 +00:00
|
|
|
if (mem) {
|
|
|
|
if (pfil_realloc(&p, flags, ifp) != 0) {
|
|
|
|
ret = PFIL_DROPPED;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
mem = false;
|
|
|
|
realloc = true;
|
|
|
|
}
|
2019-01-10 02:01:20 +00:00
|
|
|
MPASS(args.flags & IPFW_ARGS_REF);
|
PFIL_MEMPTR for ipfw link level hook
With new pfil(9) KPI it is possible to pass a void pointer with length
instead of mbuf pointer to a packet filter. Until this commit no filters
supported that, so pfil run through a shim function pfil_fake_mbuf().
Now the ipfw(4) hook named "default-link", that is instantiated when
net.link.ether.ipfw sysctl is on, supports processing pointer/length
packets natively.
- ip_fw_args now has union for either mbuf or void *, and if flags have
non-zero length, then we use the void *.
- through ipfw_chk() we handle mem/mbuf cases differently.
- ether_header goes away from args. It is ipfw_chk() responsibility
to do parsing of Ethernet header.
- ipfw_log() now uses different bpf APIs to log packets.
Although ipfw_chk() is now capable to process pointer/length packets,
this commit adds support for the link level hook only, see
ipfw_check_frame(). Potentially the IP processing hook ipfw_check_packet()
can be improved too, but that requires more changes since the hook
supports more complex actions: NAT, divert, etc.
Reviewed by: ae
Differential Revision: https://reviews.freebsd.org/D19357
2019-03-14 22:52:16 +00:00
|
|
|
(void )ng_ipfw_input_p(p.m, &args, ipfw == IP_FW_NGTEE);
|
|
|
|
if (ipfw == IP_FW_NGTEE) /* ignore errors for NGTEE */
|
2018-10-27 07:32:26 +00:00
|
|
|
goto again; /* continue with packet */
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
ret = PFIL_CONSUMED;
|
2018-10-27 07:32:26 +00:00
|
|
|
break;
|
|
|
|
|
2012-09-04 19:43:26 +00:00
|
|
|
default:
|
|
|
|
KASSERT(0, ("%s: unknown retval", __func__));
|
|
|
|
}
|
|
|
|
|
PFIL_MEMPTR for ipfw link level hook
With new pfil(9) KPI it is possible to pass a void pointer with length
instead of mbuf pointer to a packet filter. Until this commit no filters
supported that, so pfil run through a shim function pfil_fake_mbuf().
Now the ipfw(4) hook named "default-link", that is instantiated when
net.link.ether.ipfw sysctl is on, supports processing pointer/length
packets natively.
- ip_fw_args now has union for either mbuf or void *, and if flags have
non-zero length, then we use the void *.
- through ipfw_chk() we handle mem/mbuf cases differently.
- ether_header goes away from args. It is ipfw_chk() responsibility
to do parsing of Ethernet header.
- ipfw_log() now uses different bpf APIs to log packets.
Although ipfw_chk() is now capable to process pointer/length packets,
this commit adds support for the link level hook only, see
ipfw_check_frame(). Potentially the IP processing hook ipfw_check_packet()
can be improved too, but that requires more changes since the hook
supports more complex actions: NAT, divert, etc.
Reviewed by: ae
Differential Revision: https://reviews.freebsd.org/D19357
2019-03-14 22:52:16 +00:00
|
|
|
if (!mem && ret != PFIL_PASS) {
|
|
|
|
if (*p.m)
|
|
|
|
FREE_PKT(*p.m);
|
|
|
|
*p.m = NULL;
|
2012-09-04 19:43:26 +00:00
|
|
|
}
|
|
|
|
|
PFIL_MEMPTR for ipfw link level hook
With new pfil(9) KPI it is possible to pass a void pointer with length
instead of mbuf pointer to a packet filter. Until this commit no filters
supported that, so pfil run through a shim function pfil_fake_mbuf().
Now the ipfw(4) hook named "default-link", that is instantiated when
net.link.ether.ipfw sysctl is on, supports processing pointer/length
packets natively.
- ip_fw_args now has union for either mbuf or void *, and if flags have
non-zero length, then we use the void *.
- through ipfw_chk() we handle mem/mbuf cases differently.
- ether_header goes away from args. It is ipfw_chk() responsibility
to do parsing of Ethernet header.
- ipfw_log() now uses different bpf APIs to log packets.
Although ipfw_chk() is now capable to process pointer/length packets,
this commit adds support for the link level hook only, see
ipfw_check_frame(). Potentially the IP processing hook ipfw_check_packet()
can be improved too, but that requires more changes since the hook
supports more complex actions: NAT, divert, etc.
Reviewed by: ae
Differential Revision: https://reviews.freebsd.org/D19357
2019-03-14 22:52:16 +00:00
|
|
|
if (realloc && ret == PFIL_PASS)
|
|
|
|
ret = PFIL_REALLOCED;
|
|
|
|
|
2019-01-10 01:47:57 +00:00
|
|
|
return (ret);
|
2012-09-04 19:43:26 +00:00
|
|
|
}
|
|
|
|
|
2010-01-04 19:01:22 +00:00
|
|
|
/* do the divert, return 1 on error 0 on success */
|
|
|
|
static int
|
2019-03-14 22:31:12 +00:00
|
|
|
ipfw_divert(struct mbuf **m0, struct ip_fw_args *args, bool tee)
|
2004-08-17 22:05:54 +00:00
|
|
|
{
|
|
|
|
/*
|
2004-09-13 16:46:05 +00:00
|
|
|
* ipfw_chk() has already tagged the packet with the divert tag.
|
2004-08-17 22:05:54 +00:00
|
|
|
* If tee is set, copy packet and return original.
|
|
|
|
* If not tee, consume packet and send it to divert socket.
|
|
|
|
*/
|
2009-12-28 10:47:04 +00:00
|
|
|
struct mbuf *clone;
|
2011-06-27 12:21:11 +00:00
|
|
|
struct ip *ip = mtod(*m0, struct ip *);
|
2010-01-04 19:01:22 +00:00
|
|
|
struct m_tag *tag;
|
2004-10-19 21:14:57 +00:00
|
|
|
|
2004-08-17 22:05:54 +00:00
|
|
|
/* Cloning needed for tee? */
|
2019-03-14 22:31:12 +00:00
|
|
|
if (tee == false) {
|
2009-12-28 10:47:04 +00:00
|
|
|
clone = *m0; /* use the original mbuf */
|
|
|
|
*m0 = NULL;
|
|
|
|
} else {
|
2012-12-05 08:04:20 +00:00
|
|
|
clone = m_dup(*m0, M_NOWAIT);
|
2009-12-28 10:47:04 +00:00
|
|
|
/* If we cannot duplicate the mbuf, we sacrifice the divert
|
|
|
|
* chain and continue with the tee-ed packet.
|
|
|
|
*/
|
|
|
|
if (clone == NULL)
|
2010-01-04 19:01:22 +00:00
|
|
|
return 1;
|
2009-12-28 10:47:04 +00:00
|
|
|
}
|
2004-08-17 22:05:54 +00:00
|
|
|
|
|
|
|
/*
|
2009-12-28 10:47:04 +00:00
|
|
|
* Divert listeners can normally handle non-fragmented packets,
|
|
|
|
* but we can only reass in the non-tee case.
|
|
|
|
* This means that listeners on a tee rule may get fragments,
|
|
|
|
* and have to live with that.
|
|
|
|
* Note that we now have the 'reass' ipfw option so if we care
|
|
|
|
* we can do it before a 'tee'.
|
2004-08-17 22:05:54 +00:00
|
|
|
*/
|
2019-03-14 22:31:12 +00:00
|
|
|
if (tee == false) switch (ip->ip_v) {
|
2011-06-27 12:21:11 +00:00
|
|
|
case IPVERSION:
|
|
|
|
if (ntohs(ip->ip_off) & (IP_MF | IP_OFFMASK)) {
|
2009-12-28 10:47:04 +00:00
|
|
|
int hlen;
|
|
|
|
struct mbuf *reass;
|
2004-08-17 22:05:54 +00:00
|
|
|
|
2009-12-28 10:47:04 +00:00
|
|
|
reass = ip_reass(clone); /* Reassemble packet. */
|
|
|
|
if (reass == NULL)
|
2010-01-04 19:01:22 +00:00
|
|
|
return 0; /* not an error */
|
2009-12-28 10:47:04 +00:00
|
|
|
/* if reass = NULL then it was consumed by ip_reass */
|
2004-08-17 22:05:54 +00:00
|
|
|
/*
|
|
|
|
* IP header checksum fixup after reassembly and leave header
|
|
|
|
* in network byte order.
|
|
|
|
*/
|
2009-12-28 10:47:04 +00:00
|
|
|
ip = mtod(reass, struct ip *);
|
|
|
|
hlen = ip->ip_hl << 2;
|
|
|
|
ip->ip_sum = 0;
|
|
|
|
if (hlen == sizeof(struct ip))
|
|
|
|
ip->ip_sum = in_cksum_hdr(ip);
|
|
|
|
else
|
|
|
|
ip->ip_sum = in_cksum(reass, hlen);
|
|
|
|
clone = reass;
|
2011-06-27 12:21:11 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
#ifdef INET6
|
|
|
|
case IPV6_VERSION >> 4:
|
|
|
|
{
|
|
|
|
struct ip6_hdr *const ip6 = mtod(clone, struct ip6_hdr *);
|
|
|
|
|
|
|
|
if (ip6->ip6_nxt == IPPROTO_FRAGMENT) {
|
|
|
|
int nxt, off;
|
|
|
|
|
|
|
|
off = sizeof(struct ip6_hdr);
|
|
|
|
nxt = frag6_input(&clone, &off, 0);
|
|
|
|
if (nxt == IPPROTO_DONE)
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
2004-08-17 22:05:54 +00:00
|
|
|
}
|
2011-06-27 12:21:11 +00:00
|
|
|
|
2010-01-04 19:01:22 +00:00
|
|
|
/* attach a tag to the packet with the reinject info */
|
|
|
|
tag = m_tag_alloc(MTAG_IPFW_RULE, 0,
|
|
|
|
sizeof(struct ipfw_rule_ref), M_NOWAIT);
|
|
|
|
if (tag == NULL) {
|
|
|
|
FREE_PKT(clone);
|
|
|
|
return 1;
|
|
|
|
}
|
2019-03-14 22:31:12 +00:00
|
|
|
*((struct ipfw_rule_ref *)(tag+1)) = args->rule;
|
2010-01-04 19:01:22 +00:00
|
|
|
m_tag_prepend(clone, tag);
|
2004-08-17 22:05:54 +00:00
|
|
|
|
|
|
|
/* Do the dirty job... */
|
2019-03-14 22:31:12 +00:00
|
|
|
ip_divert_ptr(clone, args->flags & IPFW_ARGS_IN);
|
2010-01-04 19:01:22 +00:00
|
|
|
return 0;
|
2006-05-12 04:41:27 +00:00
|
|
|
}
|
|
|
|
|
2009-12-28 10:47:04 +00:00
|
|
|
/*
|
|
|
|
* attach or detach hooks for a given protocol family
|
|
|
|
*/
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
VNET_DEFINE_STATIC(pfil_hook_t, ipfw_inet_hook);
|
|
|
|
#define V_ipfw_inet_hook VNET(ipfw_inet_hook)
|
2019-02-01 00:33:17 +00:00
|
|
|
#ifdef INET6
|
|
|
|
VNET_DEFINE_STATIC(pfil_hook_t, ipfw_inet6_hook);
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
#define V_ipfw_inet6_hook VNET(ipfw_inet6_hook)
|
2019-02-01 00:33:17 +00:00
|
|
|
#endif
|
|
|
|
VNET_DEFINE_STATIC(pfil_hook_t, ipfw_link_hook);
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
#define V_ipfw_link_hook VNET(ipfw_link_hook)
|
|
|
|
|
2019-03-21 16:15:29 +00:00
|
|
|
static void
|
|
|
|
ipfw_hook(int pf)
|
2006-05-12 04:41:27 +00:00
|
|
|
{
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
struct pfil_hook_args pha;
|
|
|
|
pfil_hook_t *h;
|
|
|
|
|
|
|
|
pha.pa_version = PFIL_VERSION;
|
2019-03-21 16:15:29 +00:00
|
|
|
pha.pa_flags = PFIL_IN | PFIL_OUT;
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
pha.pa_modname = "ipfw";
|
|
|
|
pha.pa_ruleset = NULL;
|
|
|
|
|
|
|
|
switch (pf) {
|
|
|
|
case AF_INET:
|
|
|
|
pha.pa_func = ipfw_check_packet;
|
|
|
|
pha.pa_type = PFIL_TYPE_IP4;
|
|
|
|
pha.pa_rulname = "default";
|
|
|
|
h = &V_ipfw_inet_hook;
|
|
|
|
break;
|
|
|
|
#ifdef INET6
|
|
|
|
case AF_INET6:
|
|
|
|
pha.pa_func = ipfw_check_packet;
|
|
|
|
pha.pa_type = PFIL_TYPE_IP6;
|
|
|
|
pha.pa_rulname = "default6";
|
|
|
|
h = &V_ipfw_inet6_hook;
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case AF_LINK:
|
|
|
|
pha.pa_func = ipfw_check_frame;
|
|
|
|
pha.pa_type = PFIL_TYPE_ETHERNET;
|
|
|
|
pha.pa_rulname = "default-link";
|
2019-03-21 16:15:29 +00:00
|
|
|
pha.pa_flags |= PFIL_MEMPTR;
|
New pfil(9) KPI together with newborn pfil API and control utility.
The KPI have been reviewed and cleansed of features that were planned
back 20 years ago and never implemented. The pfil(9) internals have
been made opaque to protocols with only returned types and function
declarations exposed. The KPI is made more strict, but at the same time
more extensible, as kernel uses same command structures that userland
ioctl uses.
In nutshell [KA]PI is about declaring filtering points, declaring
filters and linking and unlinking them together.
New [KA]PI makes it possible to reconfigure pfil(9) configuration:
change order of hooks, rehook filter from one filtering point to a
different one, disconnect a hook on output leaving it on input only,
prepend/append a filter to existing list of filters.
Now it possible for a single packet filter to provide multiple rulesets
that may be linked to different points. Think of per-interface ACLs in
Cisco or Juniper. None of existing packet filters yet support that,
however limited usage is already possible, e.g. default ruleset can
be moved to single interface, as soon as interface would pride their
filtering points.
Another future feature is possiblity to create pfil heads, that provide
not an mbuf pointer but just a memory pointer with length. That would
allow filtering at very early stages of a packet lifecycle, e.g. when
packet has just been received by a NIC and no mbuf was yet allocated.
Differential Revision: https://reviews.freebsd.org/D18951
2019-01-31 23:01:03 +00:00
|
|
|
h = &V_ipfw_link_hook;
|
|
|
|
break;
|
|
|
|
}
|
2012-09-04 19:43:26 +00:00
|
|
|
|
2019-03-21 16:15:29 +00:00
|
|
|
*h = pfil_add_hook(&pha);
|
|
|
|
}
|
2004-08-17 22:05:54 +00:00
|
|
|
|
2019-03-21 16:15:29 +00:00
|
|
|
static void
|
|
|
|
ipfw_unhook(int pf)
|
|
|
|
{
|
|
|
|
|
|
|
|
switch (pf) {
|
|
|
|
case AF_INET:
|
|
|
|
pfil_remove_hook(V_ipfw_inet_hook);
|
|
|
|
break;
|
|
|
|
#ifdef INET6
|
|
|
|
case AF_INET6:
|
|
|
|
pfil_remove_hook(V_ipfw_inet6_hook);
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case AF_LINK:
|
|
|
|
pfil_remove_hook(V_ipfw_link_hook);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
ipfw_link(int pf, bool unlink)
|
|
|
|
{
|
|
|
|
struct pfil_link_args pla;
|
|
|
|
|
|
|
|
pla.pa_version = PFIL_VERSION;
|
|
|
|
pla.pa_flags = PFIL_IN | PFIL_OUT | PFIL_HEADPTR | PFIL_HOOKPTR;
|
|
|
|
if (unlink)
|
|
|
|
pla.pa_flags |= PFIL_UNLINK;
|
|
|
|
|
|
|
|
switch (pf) {
|
|
|
|
case AF_INET:
|
|
|
|
pla.pa_head = V_inet_pfil_head;
|
|
|
|
pla.pa_hook = V_ipfw_inet_hook;
|
|
|
|
break;
|
|
|
|
#ifdef INET6
|
|
|
|
case AF_INET6:
|
|
|
|
pla.pa_head = V_inet6_pfil_head;
|
|
|
|
pla.pa_hook = V_ipfw_inet6_hook;
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
case AF_LINK:
|
|
|
|
pla.pa_head = V_link_pfil_head;
|
|
|
|
pla.pa_hook = V_ipfw_link_hook;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (pfil_link(&pla));
|
2004-08-17 22:05:54 +00:00
|
|
|
}
|
2006-05-12 04:41:27 +00:00
|
|
|
|
2009-12-16 10:48:40 +00:00
|
|
|
int
|
2019-03-21 16:15:29 +00:00
|
|
|
ipfw_attach_hooks(void)
|
2009-12-16 10:48:40 +00:00
|
|
|
{
|
|
|
|
int error = 0;
|
|
|
|
|
2019-03-21 16:15:29 +00:00
|
|
|
ipfw_hook(AF_INET);
|
|
|
|
TUNABLE_INT_FETCH("net.inet.ip.fw.enable", &V_fw_enable);
|
|
|
|
if (V_fw_enable && (error = ipfw_link(AF_INET, false)) != 0)
|
2009-12-16 10:48:40 +00:00
|
|
|
printf("ipfw_hook() error\n");
|
|
|
|
#ifdef INET6
|
2019-03-21 16:15:29 +00:00
|
|
|
ipfw_hook(AF_INET6);
|
|
|
|
TUNABLE_INT_FETCH("net.inet6.ip6.fw.enable", &V_fw6_enable);
|
|
|
|
if (V_fw6_enable && (error = ipfw_link(AF_INET6, false)) != 0)
|
2009-12-16 10:48:40 +00:00
|
|
|
printf("ipfw6_hook() error\n");
|
|
|
|
#endif
|
2019-03-21 16:15:29 +00:00
|
|
|
ipfw_hook(AF_LINK);
|
|
|
|
TUNABLE_INT_FETCH("net.link.ether.ipfw", &V_fwlink_enable);
|
|
|
|
if (V_fwlink_enable && (error = ipfw_link(AF_LINK, false)) != 0)
|
2012-09-04 19:43:26 +00:00
|
|
|
printf("ipfw_link_hook() error\n");
|
2019-03-21 16:15:29 +00:00
|
|
|
|
|
|
|
return (error);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ipfw_detach_hooks(void)
|
|
|
|
{
|
|
|
|
|
|
|
|
ipfw_unhook(AF_INET);
|
|
|
|
#ifdef INET6
|
|
|
|
ipfw_unhook(AF_INET6);
|
|
|
|
#endif
|
|
|
|
ipfw_unhook(AF_LINK);
|
2009-12-16 10:48:40 +00:00
|
|
|
}
|
|
|
|
|
2006-05-12 04:41:27 +00:00
|
|
|
int
|
|
|
|
ipfw_chg_hook(SYSCTL_HANDLER_ARGS)
|
|
|
|
{
|
2012-09-04 19:43:26 +00:00
|
|
|
int newval;
|
2006-05-12 04:41:27 +00:00
|
|
|
int error;
|
2009-12-28 10:47:04 +00:00
|
|
|
int af;
|
2006-05-12 04:41:27 +00:00
|
|
|
|
2014-03-21 17:07:18 +00:00
|
|
|
if (arg1 == &V_fw_enable)
|
2009-12-28 10:47:04 +00:00
|
|
|
af = AF_INET;
|
2009-10-11 05:59:43 +00:00
|
|
|
#ifdef INET6
|
2014-03-21 17:07:18 +00:00
|
|
|
else if (arg1 == &V_fw6_enable)
|
2009-12-28 10:47:04 +00:00
|
|
|
af = AF_INET6;
|
2009-08-21 11:20:10 +00:00
|
|
|
#endif
|
2014-03-21 17:07:18 +00:00
|
|
|
else if (arg1 == &V_fwlink_enable)
|
2012-09-04 19:43:26 +00:00
|
|
|
af = AF_LINK;
|
2009-10-11 05:59:43 +00:00
|
|
|
else
|
|
|
|
return (EINVAL);
|
|
|
|
|
2014-03-21 17:07:18 +00:00
|
|
|
newval = *(int *)arg1;
|
2012-09-04 19:43:26 +00:00
|
|
|
/* Handle sysctl change */
|
|
|
|
error = sysctl_handle_int(oidp, &newval, 0, req);
|
2009-10-11 05:59:43 +00:00
|
|
|
|
2006-05-12 04:41:27 +00:00
|
|
|
if (error)
|
|
|
|
return (error);
|
|
|
|
|
2012-09-04 19:43:26 +00:00
|
|
|
/* Formalize new value */
|
|
|
|
newval = (newval) ? 1 : 0;
|
2006-05-12 04:41:27 +00:00
|
|
|
|
2014-03-21 17:07:18 +00:00
|
|
|
if (*(int *)arg1 == newval)
|
2006-05-12 04:41:27 +00:00
|
|
|
return (0);
|
|
|
|
|
2019-03-21 16:15:29 +00:00
|
|
|
error = ipfw_link(af, newval == 0 ? true : false);
|
2009-12-28 10:47:04 +00:00
|
|
|
if (error)
|
|
|
|
return (error);
|
2014-03-21 17:07:18 +00:00
|
|
|
*(int *)arg1 = newval;
|
2006-05-12 04:41:27 +00:00
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
2009-12-16 10:48:40 +00:00
|
|
|
/* end of file */
|