summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2017-12-04 13:40:36 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2017-12-04 13:40:36 +0000
commite9ccd89da6551d1faae9949e395f5ea14fb647ee (patch)
tree0521face8061aceb1dd8f5c1c4d56c09aee0cb5f
parent1764f0df2a112e820709360ae1c631b59cc1bc05 (diff)
Make divert lookup similar for all socket types. If PF_TAG_DIVERTED
is set, pf_find_divert() cannot fail so put an assert there. Explicitly check all possible divert types, panic in the default case. For raw sockets call pf_find_divert() before of the socket loop. Divert reply should not match on TCP or UDP listen sockets. OK sashan@ visa@
-rw-r--r--sys/netinet/in_pcb.c32
-rw-r--r--sys/netinet/ip_input.c11
-rw-r--r--sys/netinet/raw_ip.c38
-rw-r--r--sys/netinet/tcp_input.c14
-rw-r--r--sys/netinet6/raw_ip6.c40
5 files changed, 84 insertions, 51 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 785a34c1d5e..82c95755f82 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_pcb.c,v 1.226 2017/12/01 12:40:58 bluhm Exp $ */
+/* $OpenBSD: in_pcb.c,v 1.227 2017/12/04 13:40:34 bluhm Exp $ */
/* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */
/*
@@ -1147,10 +1147,19 @@ in_pcblookup_listen(struct inpcbtable *table, struct in_addr laddr,
if (m && m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) {
struct pf_divert *divert;
- if ((divert = pf_find_divert(m)) == NULL)
+ divert = pf_find_divert(m);
+ KASSERT(divert != NULL);
+ switch (divert->type) {
+ case PF_DIVERT_TO:
+ key1 = key2 = &divert->addr.v4;
+ lport = divert->port;
+ break;
+ case PF_DIVERT_REPLY:
return (NULL);
- key1 = key2 = &divert->addr.v4;
- lport = divert->port;
+ default:
+ panic("%s: unknown divert type %d, mbuf %p, divert %p",
+ __func__, divert->type, m, divert);
+ }
} else if (m && m->m_pkthdr.pf.flags & PF_TAG_TRANSLATE_LOCALHOST) {
key1 = &zeroin_addr;
key2 = &laddr;
@@ -1218,10 +1227,19 @@ in6_pcblookup_listen(struct inpcbtable *table, struct in6_addr *laddr,
if (m && m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) {
struct pf_divert *divert;
- if ((divert = pf_find_divert(m)) == NULL)
+ divert = pf_find_divert(m);
+ KASSERT(divert != NULL);
+ switch (divert->type) {
+ case PF_DIVERT_TO:
+ key1 = key2 = &divert->addr.v6;
+ lport = divert->port;
+ break;
+ case PF_DIVERT_REPLY:
return (NULL);
- key1 = key2 = &divert->addr.v6;
- lport = divert->port;
+ default:
+ panic("%s: unknown divert type %d, mbuf %p, divert %p",
+ __func__, divert->type, m, divert);
+ }
} else if (m && m->m_pkthdr.pf.flags & PF_TAG_TRANSLATE_LOCALHOST) {
key1 = &zeroin6_addr;
key2 = laddr;
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 695cf415b1c..8428a893976 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.334 2017/11/23 13:45:46 mpi Exp $ */
+/* $OpenBSD: ip_input.c,v 1.335 2017/12/04 13:40:34 bluhm Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -1769,12 +1769,15 @@ ip_savecontrol(struct inpcb *inp, struct mbuf **mp, struct ip *ip,
}
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) {
+ struct pf_divert *divert;
- if (m && m->m_pkthdr.pf.flags & PF_TAG_DIVERTED &&
- (divert = pf_find_divert(m)) != NULL)
+ divert = pf_find_divert(m);
+ KASSERT(divert != NULL);
rtableid = divert->rdomain;
+ }
#endif
*mp = sbcreatecontrol((caddr_t) &rtableid,
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 85986a64900..79f2a0ca94a 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_ip.c,v 1.107 2017/11/28 16:05:46 bluhm Exp $ */
+/* $OpenBSD: raw_ip.c,v 1.108 2017/12/04 13:40:34 bluhm Exp $ */
/* $NetBSD: raw_ip.c,v 1.25 1996/02/18 18:58:33 christos Exp $ */
/*
@@ -121,6 +121,7 @@ rip_input(struct mbuf **mp, int *offp, int proto, int af)
struct mbuf *m = *mp;
struct ip *ip = mtod(m, struct ip *);
struct inpcb *inp, *last = NULL;
+ struct in_addr *key;
struct mbuf *opts = NULL;
struct counters_ref ref;
uint64_t *counters;
@@ -128,6 +129,25 @@ rip_input(struct mbuf **mp, int *offp, int proto, int af)
KASSERT(af == AF_INET);
ripsrc.sin_addr = ip->ip_src;
+ key = &ip->ip_dst;
+#if NPF > 0
+ if (m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) {
+ struct pf_divert *divert;
+
+ divert = pf_find_divert(m);
+ KASSERT(divert != NULL);
+ switch (divert->type) {
+ case PF_DIVERT_TO:
+ key = &divert->addr.v4;
+ break;
+ case PF_DIVERT_REPLY:
+ break;
+ default:
+ panic("%s: unknown divert type %d, mbuf %p, divert %p",
+ __func__, divert->type, m, divert);
+ }
+ }
+#endif
NET_ASSERT_LOCKED();
TAILQ_FOREACH(inp, &rawcbtable.inpt_queue, inp_queue) {
if (inp->inp_socket->so_state & SS_CANTRCVMORE)
@@ -142,22 +162,8 @@ rip_input(struct mbuf **mp, int *offp, int proto, int af)
if (inp->inp_ip.ip_p && inp->inp_ip.ip_p != ip->ip_p)
continue;
-#if NPF > 0
- if (m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) {
- struct pf_divert *divert;
-
- /* XXX rdomain support */
- if ((divert = pf_find_divert(m)) == NULL)
- continue;
- if (divert->type == PF_DIVERT_REPLY)
- goto divert_reply;
- if (inp->inp_laddr.s_addr != divert->addr.v4.s_addr)
- continue;
- } else
- divert_reply:
-#endif
if (inp->inp_laddr.s_addr &&
- inp->inp_laddr.s_addr != ip->ip_dst.s_addr)
+ inp->inp_laddr.s_addr != key->s_addr)
continue;
if (inp->inp_faddr.s_addr &&
inp->inp_faddr.s_addr != ip->ip_src.s_addr)
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 1112bce418d..d52fd579650 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcp_input.c,v 1.353 2017/12/01 10:33:33 bluhm Exp $ */
+/* $OpenBSD: tcp_input.c,v 1.354 2017/12/04 13:40:34 bluhm Exp $ */
/* $NetBSD: tcp_input.c,v 1.23 1996/02/13 23:43:44 christos Exp $ */
/*
@@ -3454,9 +3454,6 @@ syn_cache_get(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
struct tcpcb *tp = NULL;
struct mbuf *am;
struct socket *oso;
-#if NPF > 0
- struct pf_divert *divert = NULL;
-#endif
NET_ASSERT_LOCKED();
@@ -3517,10 +3514,13 @@ syn_cache_get(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th,
}
#if NPF > 0
- if (m && m->m_pkthdr.pf.flags & PF_TAG_DIVERTED &&
- (divert = pf_find_divert(m)) != NULL)
+ if (m && m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) {
+ struct pf_divert *divert;
+
+ divert = pf_find_divert(m);
+ KASSERT(divert != NULL);
inp->inp_rtableid = divert->rdomain;
- else
+ } else
#endif
/* inherit rtable from listening socket */
inp->inp_rtableid = sc->sc_rtableid;
diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c
index 17987db85ad..8824f88987d 100644
--- a/sys/netinet6/raw_ip6.c
+++ b/sys/netinet6/raw_ip6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_ip6.c,v 1.124 2017/11/28 16:05:46 bluhm Exp $ */
+/* $OpenBSD: raw_ip6.c,v 1.125 2017/12/04 13:40:35 bluhm Exp $ */
/* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */
/*
@@ -122,6 +122,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *);
struct inpcb *in6p;
struct inpcb *last = NULL;
+ struct in6_addr *key;
struct sockaddr_in6 rip6src;
struct mbuf *opts = NULL;
@@ -136,6 +137,26 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
/* KAME hack: recover scopeid */
in6_recoverscope(&rip6src, &ip6->ip6_src);
+ key = &ip6->ip6_dst;
+#if NPF > 0
+ if (m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) {
+ struct pf_divert *divert;
+
+ /* XXX rdomain support */
+ divert = pf_find_divert(m);
+ KASSERT(divert != NULL);
+ switch (divert->type) {
+ case PF_DIVERT_TO:
+ key = &divert->addr.v6;
+ break;
+ case PF_DIVERT_REPLY:
+ break;
+ default:
+ panic("%s: unknown divert type %d, mbuf %p, divert %p",
+ __func__, divert->type, m, divert);
+ }
+ }
+#endif
NET_ASSERT_LOCKED();
TAILQ_FOREACH(in6p, &rawin6pcbtable.inpt_queue, inp_queue) {
if (in6p->inp_socket->so_state & SS_CANTRCVMORE)
@@ -145,23 +166,8 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af)
if ((in6p->inp_ipv6.ip6_nxt || proto == IPPROTO_ICMPV6) &&
in6p->inp_ipv6.ip6_nxt != proto)
continue;
-#if NPF > 0
- if (m->m_pkthdr.pf.flags & PF_TAG_DIVERTED) {
- struct pf_divert *divert;
-
- /* XXX rdomain support */
- if ((divert = pf_find_divert(m)) == NULL)
- continue;
- if (divert->type == PF_DIVERT_REPLY)
- goto divert_reply;
- if (!IN6_ARE_ADDR_EQUAL(&in6p->inp_laddr6,
- &divert->addr.v6))
- continue;
- } else
- divert_reply:
-#endif
if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->inp_laddr6) &&
- !IN6_ARE_ADDR_EQUAL(&in6p->inp_laddr6, &ip6->ip6_dst))
+ !IN6_ARE_ADDR_EQUAL(&in6p->inp_laddr6, key))
continue;
if (!IN6_IS_ADDR_UNSPECIFIED(&in6p->inp_faddr6) &&
!IN6_ARE_ADDR_EQUAL(&in6p->inp_faddr6, &ip6->ip6_src))