summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_divert.c
diff options
context:
space:
mode:
authorgreen <green@FreeBSD.org>2004-10-03 00:26:35 +0000
committergreen <green@FreeBSD.org>2004-10-03 00:26:35 +0000
commit4f70622005bf8214002abf3a3dcd4f7614f2dd59 (patch)
tree1f56ba6706068a376e7a3a3579fc28b31fa13cd0 /sys/netinet/ip_divert.c
parent4454a09917934bccea925f619fa53ec38b25a5d7 (diff)
downloadFreeBSD-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.c28
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.
OpenPOWER on IntegriCloud