From 8922ddbe40e98fae2ddbeebb10ea64b4da8e03bc Mon Sep 17 00:00:00 2001 From: "Andrey V. Elsukov" Date: Thu, 11 Dec 2014 16:53:29 +0000 Subject: [PATCH] Move ip_ipsec_fwd() from ip_input() into ip_forward(). Remove check for presence PACKET_TAG_IPSEC_IN_DONE mbuf tag from ip_ipsec_fwd(). PACKET_TAG_IPSEC_IN_DONE tag means that packet is already handled by IPSEC code. This means that before IPSEC processing it was destined to our address and security policy was checked in the ip_ipsec_input(). After IPSEC processing packet has new IP addresses and destination address isn't our own. So, anyway we can't check security policy from the mbuf tag, because it corresponds to different addresses. We should check security policy that corresponds to packet attributes in both cases - when it has a mbuf tag and when it has not. Obtained from: Yandex LLC Sponsored by: Yandex LLC --- sys/netinet/ip_input.c | 11 +++++++---- sys/netinet/ip_ipsec.c | 38 ++++++++++++-------------------------- sys/netinet6/ip6_ipsec.c | 35 +++++++++++------------------------ 3 files changed, 30 insertions(+), 54 deletions(-) diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index a8ed5a6525c..adbc449de07 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -747,10 +747,6 @@ passin: IPSTAT_INC(ips_cantforward); m_freem(m); } else { -#ifdef IPSEC - if (ip_ipsec_fwd(m)) - goto bad; -#endif /* IPSEC */ ip_forward(m, dchg); } return; @@ -1452,6 +1448,13 @@ ip_forward(struct mbuf *m, int srcrt) m_freem(m); return; } +#ifdef IPSEC + if (ip_ipsec_fwd(m) != 0) { + IPSTAT_INC(ips_cantforward); + m_freem(m); + return; + } +#endif /* IPSEC */ #ifdef IPSTEALTH if (!V_ipstealth) { #endif diff --git a/sys/netinet/ip_ipsec.c b/sys/netinet/ip_ipsec.c index ad6dec2229b..22bbba35767 100644 --- a/sys/netinet/ip_ipsec.c +++ b/sys/netinet/ip_ipsec.c @@ -101,41 +101,27 @@ ip_ipsec_filtertunnel(struct mbuf *m) /* * Check if this packet has an active SA and needs to be dropped instead * of forwarded. - * Called from ip_input(). + * Called from ip_forward(). * 1 = drop packet, 0 = forward packet. */ int ip_ipsec_fwd(struct mbuf *m) { - struct m_tag *mtag; - struct tdb_ident *tdbi; struct secpolicy *sp; int error; - mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL); - if (mtag != NULL) { - tdbi = (struct tdb_ident *)(mtag + 1); - sp = ipsec_getpolicy(tdbi, IPSEC_DIR_INBOUND); - } else { - sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, - IP_FORWARDING, &error); + sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, + IP_FORWARDING, &error); + if (sp != NULL) { + /* + * Check security policy against packet attributes. + */ + error = ipsec_in_reject(sp, m); + KEY_FREESP(&sp); } - if (sp == NULL) { /* NB: can happen if error */ - /*XXX error stat???*/ - DPRINTF(("ip_input: no SP for forwarding\n")); /*XXX*/ - return 1; - } - - /* - * Check security policy against packet attributes. - */ - error = ipsec_in_reject(sp, m); - KEY_FREESP(&sp); - if (error) { - IPSTAT_INC(ips_cantforward); - return 1; - } - return 0; + if (error != 0) + return (1); + return (0); } /* diff --git a/sys/netinet6/ip6_ipsec.c b/sys/netinet6/ip6_ipsec.c index 6472a36c8a6..b48c0686602 100644 --- a/sys/netinet6/ip6_ipsec.c +++ b/sys/netinet6/ip6_ipsec.c @@ -125,35 +125,22 @@ int ip6_ipsec_fwd(struct mbuf *m) { #ifdef IPSEC - struct m_tag *mtag; - struct tdb_ident *tdbi; struct secpolicy *sp; int error; - mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL); - if (mtag != NULL) { - tdbi = (struct tdb_ident *)(mtag + 1); - sp = ipsec_getpolicy(tdbi, IPSEC_DIR_INBOUND); - } else { - sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, - IP_FORWARDING, &error); - } - if (sp == NULL) { /* NB: can happen if error */ - /*XXX error stat???*/ - DPRINTF(("%s: no SP for forwarding\n", __func__)); /*XXX*/ - return 1; - } - /* - * Check security policy against packet attributes. - */ - error = ipsec_in_reject(sp, m); - KEY_FREESP(&sp); - if (error) { - IP6STAT_INC(ip6s_cantforward); - return 1; + sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, + IP_FORWARDING, &error); + if (sp != NULL) { + /* + * Check security policy against packet attributes. + */ + error = ipsec_in_reject(sp, m); + KEY_FREESP(&sp); } + if (error != 0) + return (1); #endif /* IPSEC */ - return 0; + return (0); } /*