summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2011-06-15 09:11:02 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2011-06-15 09:11:02 +0000
commitfd1f29bf19461cbc80443d08dd9bda476200d3cf (patch)
tree9c0a02009d03a8b5b9d289a216bae96f113aecea
parentec79616c56cc740bc77b32d8cf0f3e6ad7815d18 (diff)
Add IP_RECVRTABLE socket option to be used with a IPPROTO_IP
level that allows one to retrieve the original routing domain of UDP datagrams diverted by the pf via "divert-to" with a recvmsg(2). ok claudio
-rw-r--r--sys/netinet/in.h3
-rw-r--r--sys/netinet/in_pcb.h6
-rw-r--r--sys/netinet/ip_input.c17
-rw-r--r--sys/netinet/ip_output.c10
4 files changed, 31 insertions, 5 deletions
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index f204cbb3dc8..979f61ff831 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: in.h,v 1.88 2011/05/02 13:48:38 mikeb Exp $ */
+/* $OpenBSD: in.h,v 1.89 2011/06/15 09:11:01 mikeb Exp $ */
/* $NetBSD: in.h,v 1.20 1996/02/13 23:41:47 christos Exp $ */
/*
@@ -281,6 +281,7 @@ struct ip_opts {
#define IP_MINTTL 32 /* minimum TTL for packet or drop */
#define IP_RECVDSTPORT 33 /* bool; receive IP dst port w/dgram */
#define IP_PIPEX 34 /* bool; using PIPEX */
+#define IP_RECVRTABLE 35 /* bool; receive rdomain w/dgram */
#define IP_RTABLE 0x1021 /* int; routing table, see SO_RTABLE */
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index b631ec3d4f2..de634b82b7f 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_pcb.h,v 1.70 2010/09/23 04:45:15 yasuoka Exp $ */
+/* $OpenBSD: in_pcb.h,v 1.71 2011/06/15 09:11:01 mikeb Exp $ */
/* $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $ */
/*
@@ -174,9 +174,11 @@ struct inpcbtable {
#define INP_RECVIF 0x080 /* receive incoming interface */
#define INP_RECVTTL 0x040 /* receive incoming IP TTL */
#define INP_RECVDSTPORT 0x200 /* receive IP dst addr before rdr */
+#define INP_RECVRTABLE 0x400 /* receive routing table */
#define INP_CONTROLOPTS (INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR| \
- INP_RXSRCRT|INP_HOPLIMIT|INP_RECVIF|INP_RECVTTL|INP_RECVDSTPORT)
+ INP_RXSRCRT|INP_HOPLIMIT|INP_RECVIF|INP_RECVTTL|INP_RECVDSTPORT| \
+ INP_RECVRTABLE)
/*
* These flags' values should be determined by either the transport
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 0d71e404e78..812d650c449 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.191 2011/04/19 03:47:29 dlg Exp $ */
+/* $OpenBSD: ip_input.c,v 1.192 2011/06/15 09:11:01 mikeb Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -1790,5 +1790,20 @@ ip_savecontrol(struct inpcb *inp, struct mbuf **mp, struct ip *ip,
if (*mp)
mp = &(*mp)->m_next;
}
+ if (inp->inp_flags & INP_RECVRTABLE) {
+ u_int rtableid = inp->inp_rtableid;
+#if NPF > 0
+ struct pf_divert *divert;
+
+ if (m && m->m_pkthdr.pf.flags & PF_TAG_DIVERTED &&
+ (divert = pf_find_divert(m)) != NULL)
+ rtableid = divert->rdomain;
+#endif
+
+ *mp = sbcreatecontrol((caddr_t) &rtableid,
+ sizeof(u_int), IP_RECVRTABLE, IPPROTO_IP);
+ if (*mp)
+ mp = &(*mp)->m_next;
+ }
}
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index de189da7995..d8bdd6ee422 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_output.c,v 1.221 2011/05/28 12:51:40 weerd Exp $ */
+/* $OpenBSD: ip_output.c,v 1.222 2011/06/15 09:11:01 mikeb Exp $ */
/* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */
/*
@@ -1068,6 +1068,7 @@ ip_ctloutput(op, so, level, optname, mp)
case IP_RECVIF:
case IP_RECVTTL:
case IP_RECVDSTPORT:
+ case IP_RECVRTABLE:
if (m == NULL || m->m_len != sizeof(int))
error = EINVAL;
else {
@@ -1117,6 +1118,9 @@ ip_ctloutput(op, so, level, optname, mp)
case IP_RECVDSTPORT:
OPTSET(INP_RECVDSTPORT);
break;
+ case IP_RECVRTABLE:
+ OPTSET(INP_RECVRTABLE);
+ break;
}
}
break;
@@ -1448,6 +1452,7 @@ ip_ctloutput(op, so, level, optname, mp)
case IP_RECVIF:
case IP_RECVTTL:
case IP_RECVDSTPORT:
+ case IP_RECVRTABLE:
*mp = m = m_get(M_WAIT, MT_SOOPTS);
m->m_len = sizeof(int);
switch (optname) {
@@ -1486,6 +1491,9 @@ ip_ctloutput(op, so, level, optname, mp)
case IP_RECVDSTPORT:
optval = OPTBIT(INP_RECVDSTPORT);
break;
+ case IP_RECVRTABLE:
+ optval = OPTBIT(INP_RECVRTABLE);
+ break;
}
*mtod(m, int *) = optval;
break;