From 67c8ae0802e5b708541ca404efd85c35330e6640 Mon Sep 17 00:00:00 2001 From: glebius Date: Sat, 5 Feb 2005 12:06:33 +0000 Subject: Add a ng_ipfw node, implementing a quick and simple interface between ipfw(4) and netgraph(4) facilities. Reviewed by: andre, brooks, julian --- sys/netinet/ip_fw.h | 7 +++++++ sys/netinet/ip_fw2.c | 23 +++++++++++++++++++++++ sys/netinet/ip_fw_pfil.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+) (limited to 'sys/netinet') 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 #include #include + +#include + #include #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 #include +#include + #include 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__)); } -- cgit v1.1