Remove the large part of struct ipsecstat. Only few fields of this

structure is used, but they already have equal fields in the struct
newipsecstat, that was introduced with FAST_IPSEC and then was merged
together with old ipsecstat structure.

This fixes kernel stack overflow on some architectures after migration
ipsecstat to PCPU counters.

Reported by:	Taku YAMAMOTO, Maciej Milewski
This commit is contained in:
Andrey V. Elsukov 2013-07-23 14:14:24 +00:00
parent 9604b6ac4a
commit 6794f46021
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=253571
8 changed files with 21 additions and 113 deletions

View File

@ -5705,7 +5705,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
#ifdef INET
case AF_INET:
if (ipsec4_in_reject(m, &inp->ip_inp.inp)) {
IPSECSTAT_INC(in_polvio);
IPSECSTAT_INC(ips_in_polvio);
SCTP_STAT_INCR(sctps_hdrops);
goto out;
}
@ -5714,7 +5714,7 @@ sctp_common_input_processing(struct mbuf **mm, int iphlen, int offset, int lengt
#ifdef INET6
case AF_INET6:
if (ipsec6_in_reject(m, &inp->ip_inp.inp)) {
IPSEC6STAT_INC(in_polvio);
IPSEC6STAT_INC(ips_in_polvio);
SCTP_STAT_INCR(sctps_hdrops);
goto out;
}

View File

@ -899,12 +899,12 @@ tcp_input(struct mbuf *m, int off0)
#ifdef IPSEC
#ifdef INET6
if (isipv6 && ipsec6_in_reject(m, inp)) {
IPSEC6STAT_INC(in_polvio);
IPSEC6STAT_INC(ips_in_polvio);
goto dropunlock;
} else
#endif /* INET6 */
if (ipsec4_in_reject(m, inp) != 0) {
IPSECSTAT_INC(in_polvio);
IPSECSTAT_INC(ips_in_polvio);
goto dropunlock;
}
#endif /* IPSEC */

View File

@ -282,7 +282,7 @@ udp_append(struct inpcb *inp, struct ip *ip, struct mbuf *n, int off,
/* Check AH/ESP integrity. */
if (ipsec4_in_reject(n, inp)) {
m_freem(n);
IPSECSTAT_INC(in_polvio);
IPSECSTAT_INC(ips_in_polvio);
return;
}
#ifdef IPSEC_NAT_T
@ -1294,7 +1294,7 @@ udp4_espdecap(struct inpcb *inp, struct mbuf *m, int off)
if (minlen > m->m_pkthdr.len)
minlen = m->m_pkthdr.len;
if ((m = m_pullup(m, minlen)) == NULL) {
IPSECSTAT_INC(in_inval);
IPSECSTAT_INC(ips_in_inval);
return (NULL); /* Bypass caller processing. */
}
data = mtod(m, caddr_t); /* Points to ip header. */
@ -1334,7 +1334,7 @@ udp4_espdecap(struct inpcb *inp, struct mbuf *m, int off)
uint32_t spi;
if (payload <= sizeof(struct esp)) {
IPSECSTAT_INC(in_inval);
IPSECSTAT_INC(ips_in_inval);
m_freem(m);
return (NULL); /* Discard. */
}
@ -1355,7 +1355,7 @@ udp4_espdecap(struct inpcb *inp, struct mbuf *m, int off)
tag = m_tag_get(PACKET_TAG_IPSEC_NAT_T_PORTS,
2 * sizeof(uint16_t), M_NOWAIT);
if (tag == NULL) {
IPSECSTAT_INC(in_nomem);
IPSECSTAT_INC(ips_in_nomem);
m_freem(m);
return (NULL); /* Discard. */
}

View File

@ -120,7 +120,7 @@ ip6_forward(struct mbuf *m, int srcrt)
* before forwarding packet actually.
*/
if (ipsec6_in_reject(m, NULL)) {
IPSEC6STAT_INC(in_polvio);
IPSEC6STAT_INC(ips_in_polvio);
m_freem(m);
return;
}
@ -182,7 +182,7 @@ ip6_forward(struct mbuf *m, int srcrt)
sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_OUTBOUND,
IP_FORWARDING, &error);
if (sp == NULL) {
IPSEC6STAT_INC(out_inval);
IPSEC6STAT_INC(ips_out_inval);
IP6STAT_INC(ip6s_cantforward);
if (mcopy) {
#if 0
@ -203,7 +203,7 @@ ip6_forward(struct mbuf *m, int srcrt)
/*
* This packet is just discarded.
*/
IPSEC6STAT_INC(out_polvio);
IPSEC6STAT_INC(ips_out_polvio);
IP6STAT_INC(ip6s_cantforward);
KEY_FREESP(&sp);
if (mcopy) {

View File

@ -269,7 +269,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
*/
if (n && ipsec6_in_reject(n, last)) {
m_freem(n);
IPSEC6STAT_INC(in_polvio);
IPSEC6STAT_INC(ips_in_polvio);
/* Do not inject data into pcb. */
} else
#endif /* IPSEC */
@ -301,7 +301,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto)
*/
if ((last != NULL) && ipsec6_in_reject(m, last)) {
m_freem(m);
IPSEC6STAT_INC(in_polvio);
IPSEC6STAT_INC(ips_in_polvio);
IP6STAT_DEC(ip6s_delivered);
/* Do not inject data into pcb. */
INP_RUNLOCK(last);

View File

@ -141,7 +141,7 @@ udp6_append(struct inpcb *inp, struct mbuf *n, int off,
/* Check AH/ESP integrity. */
if (ipsec6_in_reject(n, inp)) {
m_freem(n);
IPSEC6STAT_INC(in_polvio);
IPSEC6STAT_INC(ips_in_polvio);
return;
}
#endif /* IPSEC */

View File

@ -217,43 +217,17 @@ struct secspacq {
/* statistics for ipsec processing */
struct ipsecstat {
uint64_t in_success; /* succeeded inbound process */
uint64_t in_polvio;
/* security policy violation for inbound process */
uint64_t in_nosa; /* inbound SA is unavailable */
uint64_t in_inval; /* inbound processing failed due to EINVAL */
uint64_t in_nomem; /* inbound processing failed due to ENOBUFS */
uint64_t in_badspi; /* failed getting a SPI */
uint64_t in_ahreplay; /* AH replay check failed */
uint64_t in_espreplay; /* ESP replay check failed */
uint64_t in_ahauthsucc; /* AH authentication success */
uint64_t in_ahauthfail; /* AH authentication failure */
uint64_t in_espauthsucc; /* ESP authentication success */
uint64_t in_espauthfail; /* ESP authentication failure */
uint64_t in_esphist[256];
uint64_t in_ahhist[256];
uint64_t in_comphist[256];
uint64_t out_success; /* succeeded outbound process */
uint64_t out_polvio;
/* security policy violation for outbound process */
uint64_t out_nosa; /* outbound SA is unavailable */
uint64_t out_inval; /* outbound process failed due to EINVAL */
uint64_t out_nomem; /* inbound processing failed due to ENOBUFS */
uint64_t out_noroute; /* there is no route */
uint64_t out_esphist[256];
uint64_t out_ahhist[256];
uint64_t out_comphist[256];
uint64_t spdcachelookup;
uint64_t spdcachemiss;
uint64_t ips_in_polvio; /* input: sec policy violation */
uint64_t ips_in_nomem; /* input: no memory available */
uint64_t ips_in_inval; /* input: generic error */
uint64_t ips_out_polvio; /* output: sec policy violation */
uint64_t ips_out_nosa; /* output: SA unavailable */
uint64_t ips_out_nomem; /* output: no memory available */
uint64_t ips_out_noroute; /* output: no route available */
uint64_t ips_out_inval; /* output: generic error */
uint64_t ips_out_bundlesa; /* output: bundled SA processed */
uint64_t ips_mbcoalesced; /* mbufs coalesced during clone */
uint64_t ips_clcoalesced; /* clusters coalesced during clone */
uint64_t ips_clcopied; /* clusters copied during clone */

View File

@ -166,84 +166,18 @@ static struct val2str ipsec_compnames[] = {
{ -1, NULL },
};
static void ipsec_hist(const u_quad_t *hist, size_t histmax,
const struct val2str *name, const char *title);
static void print_ipsecstats(const struct ipsecstat *ipsecstat);
/*
* Dump IPSEC statistics structure.
*/
static void
ipsec_hist(const u_quad_t *hist, size_t histmax, const struct val2str *name,
const char *title)
{
int first;
size_t proto;
const struct val2str *p;
first = 1;
for (proto = 0; proto < histmax; proto++) {
if (hist[proto] <= 0)
continue;
if (first) {
printf("\t%s histogram:\n", title);
first = 0;
}
for (p = name; p && p->str; p++) {
if (p->val == (int)proto)
break;
}
if (p && p->str) {
printf("\t\t%s: %ju\n", p->str, (uintmax_t)hist[proto]);
} else {
printf("\t\t#%ld: %ju\n", (long)proto,
(uintmax_t)hist[proto]);
}
}
}
static void
print_ipsecstats(const struct ipsecstat *ipsecstat)
{
#define p(f, m) if (ipsecstat->f || sflag <= 1) \
printf(m, (uintmax_t)ipsecstat->f, plural(ipsecstat->f))
#define pes(f, m) if (ipsecstat->f || sflag <= 1) \
printf(m, (uintmax_t)ipsecstat->f, plurales(ipsecstat->f))
#define hist(f, n, t) \
ipsec_hist((f), sizeof(f)/sizeof(f[0]), (n), (t));
p(in_success, "\t%ju inbound packet%s processed successfully\n");
p(in_polvio, "\t%ju inbound packet%s violated process security "
"policy\n");
p(in_nosa, "\t%ju inbound packet%s with no SA available\n");
p(in_inval, "\t%ju invalid inbound packet%s\n");
p(in_nomem, "\t%ju inbound packet%s failed due to insufficient memory\n");
p(in_badspi, "\t%ju inbound packet%s failed getting SPI\n");
p(in_ahreplay, "\t%ju inbound packet%s failed on AH replay check\n");
p(in_espreplay, "\t%ju inbound packet%s failed on ESP replay check\n");
p(in_ahauthsucc, "\t%ju inbound packet%s considered authentic\n");
p(in_ahauthfail, "\t%ju inbound packet%s failed on authentication\n");
hist(ipsecstat->in_ahhist, ipsec_ahnames, "AH input");
hist(ipsecstat->in_esphist, ipsec_espnames, "ESP input");
hist(ipsecstat->in_comphist, ipsec_compnames, "IPComp input");
p(out_success, "\t%ju outbound packet%s processed successfully\n");
p(out_polvio, "\t%ju outbound packet%s violated process security "
"policy\n");
p(out_nosa, "\t%ju outbound packet%s with no SA available\n");
p(out_inval, "\t%ju invalid outbound packet%s\n");
p(out_nomem, "\t%ju outbound packet%s failed due to insufficient memory\n");
p(out_noroute, "\t%ju outbound packet%s with no route\n");
hist(ipsecstat->out_ahhist, ipsec_ahnames, "AH output");
hist(ipsecstat->out_esphist, ipsec_espnames, "ESP output");
hist(ipsecstat->out_comphist, ipsec_compnames, "IPComp output");
p(spdcachelookup, "\t%ju SPD cache lookup%s\n");
pes(spdcachemiss, "\t%ju SPD cache miss%s\n");
#undef pes
#undef hist
p(ips_in_polvio, "\t%ju inbound packet%s violated process "
"security policy\n");
p(ips_in_nomem, "\t%ju inbound packet%s failed due to "
"insufficient memory\n");
p(ips_in_inval, "\t%ju invalid inbound packet%s\n");
p(ips_out_polvio, "\t%ju outbound packet%s violated process "
"security policy\n");
p(ips_out_nosa, "\t%ju outbound packet%s with no SA available\n");