summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2005-02-05 12:06:33 +0000
committerglebius <glebius@FreeBSD.org>2005-02-05 12:06:33 +0000
commit67c8ae0802e5b708541ca404efd85c35330e6640 (patch)
treeba193f3100298c12106c55572c263d432178852d /sys/netinet
parenta7fbfc9eab2af6e0c8b1b9bb3b7e89c11f6153f4 (diff)
downloadFreeBSD-src-67c8ae0802e5b708541ca404efd85c35330e6640.zip
FreeBSD-src-67c8ae0802e5b708541ca404efd85c35330e6640.tar.gz
Add a ng_ipfw node, implementing a quick and simple interface between
ipfw(4) and netgraph(4) facilities. Reviewed by: andre, brooks, julian
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_fw.h7
-rw-r--r--sys/netinet/ip_fw2.c23
-rw-r--r--sys/netinet/ip_fw_pfil.c47
3 files changed, 77 insertions, 0 deletions
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index de92951..0da6f43 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -138,6 +138,12 @@ enum ipfw_opcodes { /* arguments (4 byte each) */
O_DIVERTED, /* arg1=bitmap (1:loop, 2:out) */
O_TCPDATALEN, /* arg1 = tcp data len */
+ /*
+ * actions for ng_ipfw
+ */
+ O_NETGRAPH, /* send to ng_ipfw */
+ O_NGTEE, /* copy to ng_ipfw */
+
O_LAST_OPCODE /* not an opcode! */
};
@@ -425,6 +431,7 @@ enum {
IP_FW_TEE,
IP_FW_DUMMYNET,
IP_FW_NETGRAPH,
+ IP_FW_NGTEE,
};
/* flags for divert mtag */
diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c
index 172de80..57aa13c 100644
--- a/sys/netinet/ip_fw2.c
+++ b/sys/netinet/ip_fw2.c
@@ -77,6 +77,9 @@
#include <netinet/tcpip.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
+
+#include <netgraph/ng_ipfw.h>
+
#include <altq/if_altq.h>
#ifdef IPSEC
@@ -649,6 +652,14 @@ ipfw_log(struct ip_fw *f, u_int hlen, struct ether_header *eh,
sa->sa.sin_port);
}
break;
+ case O_NETGRAPH:
+ snprintf(SNPARGS(action2, 0), "Netgraph %d",
+ cmd->arg1);
+ break;
+ case O_NGTEE:
+ snprintf(SNPARGS(action2, 0), "Ngtee %d",
+ cmd->arg1);
+ break;
default:
action = "UNKNOWN";
break;
@@ -2528,6 +2539,14 @@ check_body:
retval = IP_FW_PASS;
goto done;
+ case O_NETGRAPH:
+ case O_NGTEE:
+ args->rule = f; /* report matching rule */
+ args->cookie = cmd->arg1;
+ retval = (cmd->opcode == O_NETGRAPH) ?
+ IP_FW_NETGRAPH : IP_FW_NGTEE;
+ goto done;
+
default:
panic("-- unknown opcode %d\n", cmd->opcode);
} /* end of switch() on opcodes */
@@ -3108,6 +3127,10 @@ check_ipfw_struct(struct ip_fw *rule, int size)
case O_TEE:
if (ip_divert_ptr == NULL)
return EINVAL;
+ case O_NETGRAPH:
+ case O_NGTEE:
+ if (!NG_IPFW_LOADED)
+ return EINVAL;
case O_FORWARD_MAC: /* XXX not implemented yet */
case O_CHECK_STATE:
case O_COUNT:
diff --git a/sys/netinet/ip_fw_pfil.c b/sys/netinet/ip_fw_pfil.c
index 22308bb..0103d8c 100644
--- a/sys/netinet/ip_fw_pfil.c
+++ b/sys/netinet/ip_fw_pfil.c
@@ -59,6 +59,8 @@
#include <netinet/ip_divert.h>
#include <netinet/ip_dummynet.h>
+#include <netgraph/ng_ipfw.h>
+
#include <machine/in_cksum.h>
static int ipfw_pfil_hooked = 0;
@@ -69,6 +71,9 @@ ip_dn_ruledel_t *ip_dn_ruledel_ptr = NULL;
/* Divert hooks. */
ip_divert_packet_t *ip_divert_ptr = NULL;
+/* ng_ipfw hooks. */
+ng_ipfw_input_t *ng_ipfw_input_p = NULL;
+
/* Forward declarations. */
static int ipfw_divert(struct mbuf **, int, int);
#define DIV_DIR_IN 1
@@ -79,6 +84,7 @@ ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
struct inpcb *inp)
{
struct ip_fw_args args;
+ struct ng_ipfw_tag *ng_tag;
struct m_tag *dn_tag;
int ipfw = 0;
int divert;
@@ -104,6 +110,15 @@ ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
m_tag_delete(*m0, dn_tag);
}
+ ng_tag = (struct ng_ipfw_tag *)m_tag_locate(*m0, NGM_IPFW_COOKIE, 0,
+ NULL);
+ if (ng_tag != NULL) {
+ KASSERT(ng_tag->dir == NG_IPFW_IN,
+ ("ng_ipfw tag with wrong direction"));
+ args.rule = ng_tag->rule;
+ m_tag_delete(*m0, (struct m_tag *)ng_tag);
+ }
+
again:
args.m = *m0;
args.inp = inp;
@@ -156,6 +171,17 @@ again:
} else
goto again; /* continue with packet */
+ case IP_FW_NGTEE:
+ if (!NG_IPFW_LOADED)
+ goto drop;
+ (void)ng_ipfw_input_p(m0, NG_IPFW_IN, &args, 1);
+ goto again; /* continue with packet */
+
+ case IP_FW_NETGRAPH:
+ if (!NG_IPFW_LOADED)
+ goto drop;
+ return ng_ipfw_input_p(m0, NG_IPFW_IN, &args, 0);
+
default:
KASSERT(0, ("%s: unknown retval", __func__));
}
@@ -174,6 +200,7 @@ ipfw_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
struct inpcb *inp)
{
struct ip_fw_args args;
+ struct ng_ipfw_tag *ng_tag;
struct m_tag *dn_tag;
int ipfw = 0;
int divert;
@@ -199,6 +226,15 @@ ipfw_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
m_tag_delete(*m0, dn_tag);
}
+ ng_tag = (struct ng_ipfw_tag *)m_tag_locate(*m0, NGM_IPFW_COOKIE, 0,
+ NULL);
+ if (ng_tag != NULL) {
+ KASSERT(ng_tag->dir == NG_IPFW_OUT,
+ ("ng_ipfw tag with wrong direction"));
+ args.rule = ng_tag->rule;
+ m_tag_delete(*m0, (struct m_tag *)ng_tag);
+ }
+
again:
args.m = *m0;
args.oif = ifp;
@@ -258,6 +294,17 @@ again:
} else
goto again; /* continue with packet */
+ case IP_FW_NGTEE:
+ if (!NG_IPFW_LOADED)
+ goto drop;
+ (void)ng_ipfw_input_p(m0, NG_IPFW_OUT, &args, 1);
+ goto again; /* continue with packet */
+
+ case IP_FW_NETGRAPH:
+ if (!NG_IPFW_LOADED)
+ goto drop;
+ return ng_ipfw_input_p(m0, NG_IPFW_OUT, &args, 0);
+
default:
KASSERT(0, ("%s: unknown retval", __func__));
}
OpenPOWER on IntegriCloud