diff options
author | Luigi Rizzo <luigi@FreeBSD.org> | 2010-01-04 19:01:22 +0000 |
---|---|---|
committer | Luigi Rizzo <luigi@FreeBSD.org> | 2010-01-04 19:01:22 +0000 |
commit | 7173b6e55475228fc29873667bfdb7561450642a (patch) | |
tree | e632a2ed87ca91743db2bb3ace9525de5d414d89 /sys/netinet/ip_divert.c | |
parent | 290dac20e61cccee6ac73284a3b181fe59e4473e (diff) | |
download | src-7173b6e55475228fc29873667bfdb7561450642a.tar.gz src-7173b6e55475228fc29873667bfdb7561450642a.zip |
Various cleanup done in ipfw3-head branch including:
- use a uniform mtag format for all packets that exit and re-enter
the firewall in the middle of a rulechain. On reentry, all tags
containing reinject info are renamed to MTAG_IPFW_RULE so the
processing is simpler.
- make ipfw and dummynet use ip_len and ip_off in network format
everywhere. Conversion is done only once instead of tracking
the format in every place.
- use a macro FREE_PKT to dispose of mbufs. This eases portability.
On passing i also removed a few typos, staticise or localise variables,
remove useless declarations and other minor things.
Overall the code shrinks a bit and is hopefully more readable.
I have tested functionality for all but ng_ipfw and if_bridge/if_ethersubr.
For ng_ipfw i am actually waiting for feedback from glebius@ because
we might have some small changes to make.
For if_bridge and if_ethersubr feedback would be welcome
(there are still some redundant parts in these two modules that
I would like to remove, but first i need to check functionality).
Notes
Notes:
svn path=/head/; revision=201527
Diffstat (limited to 'sys/netinet/ip_divert.c')
-rw-r--r-- | sys/netinet/ip_divert.c | 56 |
1 files changed, 28 insertions, 28 deletions
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index 85c619f4460c..811ca062c2e9 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -52,19 +52,12 @@ __FBSDID("$FreeBSD$"); #include <sys/priv.h> #include <sys/proc.h> #include <sys/protosw.h> -#include <sys/rwlock.h> -#include <sys/signalvar.h> #include <sys/socket.h> #include <sys/socketvar.h> -#include <sys/sx.h> #include <sys/sysctl.h> -#include <sys/systm.h> - -#include <vm/uma.h> #include <net/if.h> #include <net/netisr.h> -#include <net/route.h> #include <net/vnet.h> #include <netinet/in.h> @@ -72,7 +65,6 @@ __FBSDID("$FreeBSD$"); #include <netinet/in_systm.h> #include <netinet/in_var.h> #include <netinet/ip.h> -#include <netinet/ip_divert.h> #include <netinet/ip_var.h> #include <netinet/ip_fw.h> #include <netinet/ipfw/ip_fw_private.h> @@ -194,7 +186,7 @@ div_destroy(void) * IPPROTO_DIVERT is not in the real IP protocol number space; this * function should never be called. Just in case, drop any packets. */ -void +static void div_input(struct mbuf *m, int off) { @@ -218,9 +210,8 @@ divert_packet(struct mbuf *m, int incoming) struct sockaddr_in divsrc; struct m_tag *mtag; - mtag = m_tag_find(m, PACKET_TAG_DIVERT, NULL); + mtag = m_tag_locate(m, MTAG_IPFW_RULE, 0, NULL); if (mtag == NULL) { - printf("%s: no divert tag\n", __func__); m_freem(m); return; } @@ -245,14 +236,15 @@ divert_packet(struct mbuf *m, int incoming) ip->ip_len = htons(ip->ip_len); } #endif + bzero(&divsrc, sizeof(divsrc)); + divsrc.sin_len = sizeof(divsrc); + divsrc.sin_family = AF_INET; + /* record matching rule, in host format */ + divsrc.sin_port = ((struct ipfw_rule_ref *)(mtag+1))->rulenum; /* * Record receive interface address, if any. * But only for incoming packets. */ - bzero(&divsrc, sizeof(divsrc)); - divsrc.sin_len = sizeof(divsrc); - divsrc.sin_family = AF_INET; - divsrc.sin_port = divert_cookie(mtag); /* record matching rule */ if (incoming) { struct ifaddr *ifa; struct ifnet *ifp; @@ -300,7 +292,7 @@ divert_packet(struct mbuf *m, int incoming) /* Put packet on socket queue, if any */ sa = NULL; - nport = htons((u_int16_t)divert_info(mtag)); + nport = htons((u_int16_t)(((struct ipfw_rule_ref *)(mtag+1))->info)); INP_INFO_RLOCK(&V_divcbinfo); LIST_FOREACH(inp, &V_divcb, inp_list) { /* XXX why does only one socket match? */ @@ -339,7 +331,7 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin, struct mbuf *control) { struct m_tag *mtag; - struct divert_tag *dt; + struct ipfw_rule_ref *dt; int error = 0; struct mbuf *options; @@ -354,23 +346,31 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin, if (control) m_freem(control); /* XXX */ - if ((mtag = m_tag_find(m, PACKET_TAG_DIVERT, NULL)) == NULL) { - mtag = m_tag_get(PACKET_TAG_DIVERT, sizeof(struct divert_tag), - M_NOWAIT | M_ZERO); + mtag = m_tag_locate(m, MTAG_IPFW_RULE, 0, NULL); + if (mtag == NULL) { + /* this should be normal */ + mtag = m_tag_alloc(MTAG_IPFW_RULE, 0, + sizeof(struct ipfw_rule_ref), M_NOWAIT | M_ZERO); if (mtag == NULL) { error = ENOBUFS; goto cantsend; } - dt = (struct divert_tag *)(mtag+1); m_tag_prepend(m, mtag); - } else - dt = (struct divert_tag *)(mtag+1); + } + dt = (struct ipfw_rule_ref *)(mtag+1); /* Loopback avoidance and state recovery */ if (sin) { int i; - dt->cookie = sin->sin_port; + /* set the starting point. We provide a non-zero slot, + * but a non_matching chain_id to skip that info and use + * the rulenum/rule_id. + */ + dt->slot = 1; /* dummy, chain_id is invalid */ + dt->chain_id = 0; + dt->rulenum = sin->sin_port+1; /* host format ? */ + dt->rule_id = 0; /* * Find receive interface with the given name, stuffed * (if it exists) in the sin_zero[] field. @@ -388,7 +388,7 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin, struct ip *const ip = mtod(m, struct ip *); struct inpcb *inp; - dt->info |= IP_FW_DIVERT_OUTPUT_FLAG; + dt->info |= IPFW_IS_DIVERT | IPFW_INFO_OUT; INP_INFO_WLOCK(&V_divcbinfo); inp = sotoinpcb(so); INP_RLOCK(inp); @@ -454,7 +454,7 @@ div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin, m_freem(options); } } else { - dt->info |= IP_FW_DIVERT_LOOPBACK_FLAG; + dt->info |= IPFW_IS_DIVERT | IPFW_INFO_IN; if (m->m_pkthdr.rcvif == NULL) { /* * No luck with the name, check by IP address. @@ -588,7 +588,7 @@ div_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam, return div_output(so, m, (struct sockaddr_in *)nam, control); } -void +static void div_ctlinput(int cmd, struct sockaddr *sa, void *vip) { struct in_addr faddr; @@ -801,5 +801,5 @@ static moduledata_t ipdivertmod = { }; DECLARE_MODULE(ipdivert, ipdivertmod, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); -MODULE_DEPEND(dummynet, ipfw, 2, 2, 2); +MODULE_DEPEND(ipdivert, ipfw, 2, 2, 2); MODULE_VERSION(ipdivert, 1); |