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
This commit is contained in:
Andrey V. Elsukov 2014-12-11 16:53:29 +00:00
parent e58320f127
commit 8922ddbe40
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=275704
3 changed files with 30 additions and 54 deletions

View File

@ -747,10 +747,6 @@ ip_input(struct mbuf *m)
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

View File

@ -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);
}
/*

View File

@ -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);
}
/*