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
This commit is contained in:
parent
e50508df66
commit
6c69a7c30b
@ -1073,12 +1073,14 @@ bdg_forward(struct mbuf *m0, struct ifnet *dst)
|
||||
if (m0 != NULL)
|
||||
EH_RESTORE(m0); /* restore Ethernet header */
|
||||
|
||||
if ( (i & IP_FW_PORT_DENY_FLAG) || m0 == NULL) /* drop */
|
||||
if (i == IP_FW_DENY) /* drop */
|
||||
return m0;
|
||||
|
||||
KASSERT(m0 != NULL, ("bdg_forward: m0 is NULL"));
|
||||
|
||||
if (i == 0) /* a PASS rule. */
|
||||
goto forward;
|
||||
if (DUMMYNET_LOADED && (i & IP_FW_PORT_DYNT_FLAG)) {
|
||||
if (DUMMYNET_LOADED && (i == IP_FW_DUMMYNET)) {
|
||||
/*
|
||||
* Pass the pkt to dummynet, which consumes it.
|
||||
* If shared, make a copy and keep the original.
|
||||
@ -1095,7 +1097,7 @@ bdg_forward(struct mbuf *m0, struct ifnet *dst)
|
||||
}
|
||||
|
||||
args.oif = real_dst;
|
||||
ip_dn_io_ptr(m, (i & 0xffff),DN_TO_BDG_FWD, &args);
|
||||
ip_dn_io_ptr(m, args.cookie, DN_TO_BDG_FWD, &args);
|
||||
return m0;
|
||||
}
|
||||
/*
|
||||
|
@ -440,13 +440,15 @@ ether_ipfw_chk(struct mbuf **m0, struct ifnet *dst,
|
||||
*m0 = m;
|
||||
*rule = args.rule;
|
||||
|
||||
if ( (i & IP_FW_PORT_DENY_FLAG) || m == NULL) /* drop */
|
||||
if (i == IP_FW_DENY) /* drop */
|
||||
return 0;
|
||||
|
||||
if (i == 0) /* a PASS rule. */
|
||||
KASSERT(m != NULL, ("ether_ipfw_chk: m is NULL"));
|
||||
|
||||
if (i == IP_FW_PASS) /* a PASS rule. */
|
||||
return 1;
|
||||
|
||||
if (DUMMYNET_LOADED && (i & IP_FW_PORT_DYNT_FLAG)) {
|
||||
if (DUMMYNET_LOADED && (i == IP_FW_DUMMYNET)) {
|
||||
/*
|
||||
* Pass the pkt to dummynet, which consumes it.
|
||||
* If shared, make a copy and keep the original.
|
||||
@ -462,7 +464,7 @@ ether_ipfw_chk(struct mbuf **m0, struct ifnet *dst,
|
||||
*/
|
||||
*m0 = NULL ;
|
||||
}
|
||||
ip_dn_io_ptr(m, (i & 0xffff),
|
||||
ip_dn_io_ptr(m, args.cookie,
|
||||
dst ? DN_TO_ETH_OUT: DN_TO_ETH_DEMUX, &args);
|
||||
return 0;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
KASSERT(*m0 != NULL || ipfw == IP_FW_DENY, ("%s: m0 is NULL",
|
||||
__func__));
|
||||
|
||||
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);
|
||||
|
||||
/* 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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user