diff options
author | green <green@FreeBSD.org> | 2004-10-03 00:26:35 +0000 |
---|---|---|
committer | green <green@FreeBSD.org> | 2004-10-03 00:26:35 +0000 |
commit | 4f70622005bf8214002abf3a3dcd4f7614f2dd59 (patch) | |
tree | 1f56ba6706068a376e7a3a3579fc28b31fa13cd0 /sys/netinet/ip_divert.c | |
parent | 4454a09917934bccea925f619fa53ec38b25a5d7 (diff) | |
download | FreeBSD-src-4f70622005bf8214002abf3a3dcd4f7614f2dd59.zip FreeBSD-src-4f70622005bf8214002abf3a3dcd4f7614f2dd59.tar.gz |
Add support to IPFW for classification based on "diverted" status
(that is, input via a divert socket).
Diffstat (limited to 'sys/netinet/ip_divert.c')
-rw-r--r-- | sys/netinet/ip_divert.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index 8f524bb..fa8a6ea 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -66,6 +66,7 @@ #include <netinet/ip.h> #include <netinet/ip_divert.h> #include <netinet/ip_var.h> +#include <netinet/ip_fw.h> /* * Divert sockets @@ -268,6 +269,8 @@ static int div_output(struct socket *so, struct mbuf *m, struct sockaddr_in *sin, struct mbuf *control) { + struct m_tag *mtag; + struct divert_tag *dt; int error = 0; KASSERT(m->m_pkthdr.rcvif == NULL, ("rcvif not null")); @@ -275,23 +278,22 @@ div_output(struct socket *so, struct mbuf *m, if (control) m_freem(control); /* XXX */ + mtag = m_tag_get(PACKET_TAG_DIVERT, + sizeof(struct divert_tag), M_NOWAIT); + if (mtag == NULL) { + error = ENOBUFS; + goto cantsend; + } + dt = (struct divert_tag *)(mtag+1); + dt->info = 0; + dt->cookie = 0; + m_tag_prepend(m, mtag); + /* Loopback avoidance and state recovery */ if (sin) { - struct m_tag *mtag; - struct divert_tag *dt; int i; - mtag = m_tag_get(PACKET_TAG_DIVERT, - sizeof(struct divert_tag), M_NOWAIT); - if (mtag == NULL) { - error = ENOBUFS; - goto cantsend; - } - dt = (struct divert_tag *)(mtag+1); - dt->info = 0; dt->cookie = sin->sin_port; - m_tag_prepend(m, mtag); - /* * Find receive interface with the given name, stuffed * (if it exists) in the sin_zero[] field. @@ -309,6 +311,7 @@ div_output(struct socket *so, struct mbuf *m, struct ip *const ip = mtod(m, struct ip *); struct inpcb *inp; + dt->info |= IP_FW_DIVERT_OUTPUT_FLAG; INP_INFO_WLOCK(&divcbinfo); inp = sotoinpcb(so); INP_LOCK(inp); @@ -341,6 +344,7 @@ div_output(struct socket *so, struct mbuf *m, INP_UNLOCK(inp); INP_INFO_WUNLOCK(&divcbinfo); } else { + dt->info |= IP_FW_DIVERT_LOOPBACK_FLAG; if (m->m_pkthdr.rcvif == NULL) { /* * No luck with the name, check by IP address. |