summaryrefslogtreecommitdiffstats
path: root/sys/netinet
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2005-01-14 09:00:46 +0000
committerglebius <glebius@FreeBSD.org>2005-01-14 09:00:46 +0000
commit4db2b8d392653d006688b34d58bdb4ff6bc93523 (patch)
treed9fa7d7031281028b0d46da348135c088236c843 /sys/netinet
parent3c319ea2eac56f153a87df3c9616031973d63110 (diff)
downloadFreeBSD-src-4db2b8d392653d006688b34d58bdb4ff6bc93523.zip
FreeBSD-src-4db2b8d392653d006688b34d58bdb4ff6bc93523.tar.gz
o Clean up interface between ip_fw_chk() and its callers:
- ip_fw_chk() returns action as function return value. Field retval is removed from args structure. Action is not flag any more. It is one of integer constants. - Any action-specific cookies are returned either in new "cookie" field in args structure (dummynet, future netgraph glue), or in mbuf tag attached to packet (divert, tee, some future action). o Convert parsing of return value from ip_fw_chk() in ipfw_check_{in,out}() to a switch structure, so that the functions are more readable, and a future actions can be added with less modifications. Approved by: andre MFC after: 2 months
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/ip_fw.h16
-rw-r--r--sys/netinet/ip_fw2.c49
-rw-r--r--sys/netinet/ip_fw_pfil.c126
3 files changed, 109 insertions, 82 deletions
diff --git a/sys/netinet/ip_fw.h b/sys/netinet/ip_fw.h
index e73d701..de92951 100644
--- a/sys/netinet/ip_fw.h
+++ b/sys/netinet/ip_fw.h
@@ -417,9 +417,17 @@ typedef struct _ipfw_table {
*/
#ifdef _KERNEL
-#define IP_FW_PORT_DYNT_FLAG 0x00010000
-#define IP_FW_PORT_TEE_FLAG 0x00020000
-#define IP_FW_PORT_DENY_FLAG 0x00040000
+/* Return values from ipfw_chk() */
+enum {
+ IP_FW_PASS = 0,
+ IP_FW_DENY,
+ IP_FW_DIVERT,
+ IP_FW_TEE,
+ IP_FW_DUMMYNET,
+ IP_FW_NETGRAPH,
+};
+
+/* flags for divert mtag */
#define IP_FW_DIVERT_LOOPBACK_FLAG 0x00080000
#define IP_FW_DIVERT_OUTPUT_FLAG 0x00100000
@@ -438,7 +446,7 @@ struct ip_fw_args {
int flags; /* for dummynet */
struct ipfw_flow_id f_id; /* grabbed from IP header */
- u_int32_t retval;
+ u_int32_t cookie; /* a cookie depending on rule action */
struct inpcb *inp;
};
diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c
index 1ac1eb4..0973a46 100644
--- a/sys/netinet/ip_fw2.c
+++ b/sys/netinet/ip_fw2.c
@@ -1695,20 +1695,17 @@ check_uidgid(ipfw_insn_u32 *insn,
* args->rule Pointer to the last matching rule (in/out)
* args->next_hop Socket we are forwarding to (out).
* args->f_id Addresses grabbed from the packet (out)
+ * args->cookie a cookie depending on rule action
*
* Return value:
*
- * IP_FW_PORT_DENY_FLAG the packet must be dropped.
- * 0 The packet is to be accepted and routed normally OR
- * the packet was denied/rejected and has been dropped;
- * in the latter case, *m is equal to NULL upon return.
- * port Divert the packet to port, with these caveats:
+ * IP_FW_PASS the packet must be accepted
+ * IP_FW_DENY the packet must be dropped
+ * IP_FW_DIVERT divert packet, port in m_tag
+ * IP_FW_TEE tee packet, port in m_tag
+ * IP_FW_DUMMYNET to dummynet, pipe in args->cookie
+ * IP_FW_NETGRAPH into netgraph, cookie args->cookie
*
- * - If IP_FW_PORT_TEE_FLAG is set, tee the packet instead
- * of diverting it (ie, 'ipfw tee').
- *
- * - If IP_FW_PORT_DYNT_FLAG is set, interpret the lower
- * 16 bits as a dummynet pipe number instead of diverting
*/
int
@@ -1806,7 +1803,7 @@ ipfw_chk(struct ip_fw_args *args)
struct m_tag *mtag;
if (m->m_flags & M_SKIP_FIREWALL)
- return 0; /* accept */
+ return (IP_FW_PASS); /* accept */
/*
* dyn_dir = MATCH_UNKNOWN when rules unchecked,
* MATCH_NONE when checked and not matched (q = NULL),
@@ -1904,7 +1901,7 @@ after_ip_checks:
*/
if (fw_one_pass) {
IPFW_RUNLOCK(chain);
- return 0;
+ return (IP_FW_PASS);
}
f = args->rule->next_rule;
@@ -1921,13 +1918,13 @@ after_ip_checks:
if (args->eh == NULL && skipto != 0) {
if (skipto >= IPFW_DEFAULT_RULE) {
IPFW_RUNLOCK(chain);
- return(IP_FW_PORT_DENY_FLAG); /* invalid */
+ return (IP_FW_DENY); /* invalid */
}
while (f && f->rulenum <= skipto)
f = f->next;
if (f == NULL) { /* drop packet */
IPFW_RUNLOCK(chain);
- return(IP_FW_PORT_DENY_FLAG);
+ return (IP_FW_DENY);
}
}
}
@@ -2408,7 +2405,7 @@ check_body:
case O_KEEP_STATE:
if (install_state(f,
(ipfw_insn_limit *)cmd, args)) {
- retval = IP_FW_PORT_DENY_FLAG;
+ retval = IP_FW_DENY;
goto done; /* error/limit violation */
}
match = 1;
@@ -2460,7 +2457,8 @@ check_body:
case O_PIPE:
case O_QUEUE:
args->rule = f; /* report matching rule */
- retval = cmd->arg1 | IP_FW_PORT_DYNT_FLAG;
+ args->cookie = cmd->arg1;
+ retval = IP_FW_DUMMYNET;
goto done;
case O_DIVERT:
@@ -2476,15 +2474,14 @@ check_body:
/* XXX statistic */
/* drop packet */
IPFW_RUNLOCK(chain);
- return IP_FW_PORT_DENY_FLAG;
+ return (IP_FW_DENY);
}
dt = (struct divert_tag *)(mtag+1);
dt->cookie = f->rulenum;
- dt->info = (cmd->opcode == O_DIVERT) ?
- cmd->arg1 :
- cmd->arg1 | IP_FW_PORT_TEE_FLAG;
+ dt->info = cmd->arg1;
m_tag_prepend(m, mtag);
- retval = dt->info;
+ retval = (cmd->opcode == O_DIVERT) ?
+ IP_FW_DIVERT : IP_FW_TEE;
goto done;
}
@@ -2518,7 +2515,7 @@ check_body:
}
/* FALLTHROUGH */
case O_DENY:
- retval = IP_FW_PORT_DENY_FLAG;
+ retval = IP_FW_DENY;
goto done;
case O_FORWARD_IP:
@@ -2527,7 +2524,7 @@ check_body:
if (!q || dyn_dir == MATCH_FORWARD)
args->next_hop =
&((ipfw_insn_sa *)cmd)->sa;
- retval = 0;
+ retval = IP_FW_PASS;
goto done;
default:
@@ -2552,7 +2549,7 @@ next_rule:; /* try next rule */
} /* end of outer for, scan rules */
printf("ipfw: ouch!, skip past end of rules, denying packet\n");
IPFW_RUNLOCK(chain);
- return(IP_FW_PORT_DENY_FLAG);
+ return (IP_FW_DENY);
done:
/* Update statistics */
@@ -2560,12 +2557,12 @@ done:
f->bcnt += pktlen;
f->timestamp = time_second;
IPFW_RUNLOCK(chain);
- return retval;
+ return (retval);
pullup_failed:
if (fw_verbose)
printf("ipfw: pullup failed\n");
- return(IP_FW_PORT_DENY_FLAG);
+ return (IP_FW_DENY);
}
/*
diff --git a/sys/netinet/ip_fw_pfil.c b/sys/netinet/ip_fw_pfil.c
index 44e8652..d186aab 100644
--- a/sys/netinet/ip_fw_pfil.c
+++ b/sys/netinet/ip_fw_pfil.c
@@ -82,6 +82,7 @@ ipfw_check_in(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
struct m_tag *dn_tag;
int ipfw = 0;
int divert;
+ int tee;
#ifdef IPFIREWALL_FORWARD
struct m_tag *fwd_tag;
#endif
@@ -108,35 +109,17 @@ again:
args.inp = inp;
ipfw = ipfw_chk(&args);
*m0 = args.m;
+ tee = 0;
- if ((ipfw & IP_FW_PORT_DENY_FLAG) || *m0 == NULL)
- goto drop;
-
- if (ipfw == 0 && args.next_hop == NULL)
- goto pass;
-
- if (DUMMYNET_LOADED && (ipfw & IP_FW_PORT_DYNT_FLAG) != 0) {
- ip_dn_io_ptr(*m0, ipfw & 0xffff, DN_TO_IP_IN, &args);
- *m0 = NULL;
- return 0; /* packet consumed */
- }
-
- if (ipfw != 0 && (ipfw & IP_FW_PORT_DYNT_FLAG) == 0) {
- if ((ipfw & IP_FW_PORT_TEE_FLAG) != 0)
- divert = ipfw_divert(m0, DIV_DIR_IN, 1);
- else
- divert = ipfw_divert(m0, DIV_DIR_IN, 0);
+ KASSERT(*m0 != NULL || ipfw == IP_FW_DENY, ("%s: m0 is NULL",
+ __func__));
- /* tee should continue again with the firewall. */
- if (divert) {
- *m0 = NULL;
- return 0; /* packet consumed */
- } else
- goto again; /* continue with packet */
- }
+ switch (ipfw) {
+ case IP_FW_PASS:
+ if (args.next_hop == NULL)
+ goto pass;
#ifdef IPFIREWALL_FORWARD
- if (ipfw == 0 && args.next_hop != NULL) {
fwd_tag = m_tag_get(PACKET_TAG_IPFORWARD,
sizeof(struct sockaddr_in), M_NOWAIT);
if (fwd_tag == NULL)
@@ -147,8 +130,35 @@ again:
if (in_localip(args.next_hop->sin_addr))
(*m0)->m_flags |= M_FASTFWD_OURS;
goto pass;
- }
#endif
+ break; /* not reached */
+
+ case IP_FW_DENY:
+ goto drop;
+ break; /* not reached */
+
+ case IP_FW_DUMMYNET:
+ if (!DUMMYNET_LOADED)
+ goto drop;
+ ip_dn_io_ptr(*m0, args.cookie, DN_TO_IP_IN, &args);
+ *m0 = NULL;
+ return 0; /* packet consumed */
+
+ case IP_FW_TEE:
+ tee = 1;
+ /* fall through */
+
+ case IP_FW_DIVERT:
+ divert = ipfw_divert(m0, DIV_DIR_IN, tee);
+ if (divert) {
+ *m0 = NULL;
+ return 0; /* packet consumed */
+ } else
+ goto again; /* continue with packet */
+
+ default:
+ KASSERT(0, ("%s: unknown retval", __func__));
+ }
drop:
if (*m0)
@@ -167,6 +177,7 @@ ipfw_check_out(void *arg, struct mbuf **m0, struct ifnet *ifp, int dir,
struct m_tag *dn_tag;
int ipfw = 0;
int divert;
+ int tee;
#ifdef IPFIREWALL_FORWARD
struct m_tag *fwd_tag;
#endif
@@ -194,34 +205,16 @@ again:
args.inp = inp;
ipfw = ipfw_chk(&args);
*m0 = args.m;
+ tee = 0;
- if ((ipfw & IP_FW_PORT_DENY_FLAG) || *m0 == NULL)
- goto drop;
-
- if (ipfw == 0 && args.next_hop == NULL)
- goto pass;
-
- if (DUMMYNET_LOADED && (ipfw & IP_FW_PORT_DYNT_FLAG) != 0) {
- ip_dn_io_ptr(*m0, ipfw & 0xffff, DN_TO_IP_OUT, &args);
- *m0 = NULL;
- return 0; /* packet consumed */
- }
-
- if (ipfw != 0 && (ipfw & IP_FW_PORT_DYNT_FLAG) == 0) {
- if ((ipfw & IP_FW_PORT_TEE_FLAG) != 0)
- divert = ipfw_divert(m0, DIV_DIR_OUT, 1);
- else
- divert = ipfw_divert(m0, DIV_DIR_OUT, 0);
-
- if (divert) {
- *m0 = NULL;
- return 0; /* packet consumed */
- } else
- goto again; /* continue with packet */
- }
+ KASSERT(*m0 != NULL || ipfw == IP_FW_DENY, ("%s: m0 is NULL",
+ __func__));
+ switch (ipfw) {
+ case IP_FW_PASS:
+ if (args.next_hop == NULL)
+ goto pass;
#ifdef IPFIREWALL_FORWARD
- if (ipfw == 0 && args.next_hop != NULL) {
/* Overwrite existing tag. */
fwd_tag = m_tag_find(*m0, PACKET_TAG_IPFORWARD, NULL);
if (fwd_tag == NULL) {
@@ -237,8 +230,37 @@ again:
if (in_localip(args.next_hop->sin_addr))
(*m0)->m_flags |= M_FASTFWD_OURS;
goto pass;
- }
#endif
+ break; /* not reached */
+
+ case IP_FW_DENY:
+ goto drop;
+ break; /* not reached */
+
+ case IP_FW_DUMMYNET:
+ if (!DUMMYNET_LOADED)
+ break;
+ ip_dn_io_ptr(*m0, args.cookie, DN_TO_IP_OUT, &args);
+ *m0 = NULL;
+ return 0; /* packet consumed */
+
+ break;
+
+ case IP_FW_TEE:
+ tee = 1;
+ /* fall through */
+
+ case IP_FW_DIVERT:
+ divert = ipfw_divert(m0, DIV_DIR_OUT, tee);
+ if (divert) {
+ *m0 = NULL;
+ return 0; /* packet consumed */
+ } else
+ goto again; /* continue with packet */
+
+ default:
+ KASSERT(0, ("%s: unknown retval", __func__));
+ }
drop:
if (*m0)
OpenPOWER on IntegriCloud