unify processing to check nesting count for some tunnel protocols.

This commit is contained in:
knakahara 2017-12-06 08:23:17 +00:00
parent 6b500088e0
commit d4228bae36
4 changed files with 48 additions and 68 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: if.c,v 1.403 2017/12/06 08:12:54 ozaki-r Exp $ */
/* $NetBSD: if.c,v 1.404 2017/12/06 08:23:17 knakahara Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2008 The NetBSD Foundation, Inc.
@ -90,7 +90,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.403 2017/12/06 08:12:54 ozaki-r Exp $");
__KERNEL_RCSID(0, "$NetBSD: if.c,v 1.404 2017/12/06 08:23:17 knakahara Exp $");
#if defined(_KERNEL_OPT)
#include "opt_inet.h"
@ -2762,6 +2762,43 @@ if_held(struct ifnet *ifp)
return psref_held(&ifp->if_psref, ifnet_psref_class);
}
/*
* Some tunnel interfaces can nest, e.g. IPv4 over IPv4 gif(4) tunnel over IPv4.
* Check the tunnel nesting count.
* Return > 0, if tunnel nesting count is more than limit.
* Return 0, if tunnel nesting count is equal or less than limit.
*/
int
if_tunnel_check_nesting(struct ifnet *ifp, struct mbuf *m, int limit)
{
struct m_tag *mtag;
int *count;
mtag = m_tag_find(m, PACKET_TAG_TUNNEL_INFO, NULL);
if (mtag != NULL) {
count = (int *)(mtag + 1);
if (++(*count) > limit) {
log(LOG_NOTICE,
"%s: recursively called too many times(%d)\n",
ifp->if_xname, *count);
return EIO;
}
} else {
mtag = m_tag_get(PACKET_TAG_TUNNEL_INFO, sizeof(*count),
M_NOWAIT);
if (mtag != NULL) {
m_tag_prepend(m, mtag);
count = (int *)(mtag + 1);
*count = 0;
} else {
log(LOG_DEBUG,
"%s: m_tag_get() failed, recursion calls are not prevented.\n",
ifp->if_xname);
}
}
return 0;
}
/* common */
int

View File

@ -1,4 +1,4 @@
/* $NetBSD: if.h,v 1.247 2017/12/06 08:12:54 ozaki-r Exp $ */
/* $NetBSD: if.h,v 1.248 2017/12/06 08:23:17 knakahara Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -1034,6 +1034,8 @@ void if_put(const struct ifnet *, struct psref *);
void if_acquire(struct ifnet *, struct psref *);
#define if_release if_put
int if_tunnel_check_nesting(struct ifnet *, struct mbuf *, int);
static inline if_index_t
if_get_index(const struct ifnet *ifp)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_gif.c,v 1.134 2017/11/27 05:05:50 knakahara Exp $ */
/* $NetBSD: if_gif.c,v 1.135 2017/12/06 08:23:17 knakahara Exp $ */
/* $KAME: if_gif.c,v 1.76 2001/08/20 02:01:02 kjc Exp $ */
/*
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.134 2017/11/27 05:05:50 knakahara Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.135 2017/12/06 08:23:17 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@ -445,34 +445,8 @@ out:
static int
gif_check_nesting(struct ifnet *ifp, struct mbuf *m)
{
struct m_tag *mtag;
int *count;
mtag = m_tag_find(m, PACKET_TAG_TUNNEL_INFO, NULL);
if (mtag != NULL) {
count = (int *)(mtag + 1);
if (++(*count) > max_gif_nesting) {
log(LOG_NOTICE,
"%s: recursively called too many times(%d)\n",
if_name(ifp),
*count);
return EIO;
}
} else {
mtag = m_tag_get(PACKET_TAG_TUNNEL_INFO, sizeof(*count),
M_NOWAIT);
if (mtag != NULL) {
m_tag_prepend(m, mtag);
count = (int *)(mtag + 1);
*count = 0;
} else {
log(LOG_DEBUG,
"%s: m_tag_get() failed, recursion calls are not prevented.\n",
if_name(ifp));
}
}
return 0;
return if_tunnel_check_nesting(ifp, m, max_gif_nesting);
}
static int

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_l2tp.c,v 1.15 2017/11/16 03:07:18 ozaki-r Exp $ */
/* $NetBSD: if_l2tp.c,v 1.16 2017/12/06 08:23:17 knakahara Exp $ */
/*
* Copyright (c) 2017 Internet Initiative Japan Inc.
@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_l2tp.c,v 1.15 2017/11/16 03:07:18 ozaki-r Exp $");
__KERNEL_RCSID(0, "$NetBSD: if_l2tp.c,v 1.16 2017/12/06 08:23:17 knakahara Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@ -1336,44 +1336,11 @@ l2tp_encap_detach(struct l2tp_variant *var)
return error;
}
/*
* TODO:
* unify with gif_check_nesting().
*/
int
l2tp_check_nesting(struct ifnet *ifp, struct mbuf *m)
{
struct m_tag *mtag;
int *count;
mtag = m_tag_find(m, PACKET_TAG_TUNNEL_INFO, NULL);
if (mtag != NULL) {
count = (int *)(mtag + 1);
if (++(*count) > max_l2tp_nesting) {
log(LOG_NOTICE,
"%s: recursively called too many times(%d)\n",
if_name(ifp),
*count);
return EIO;
}
} else {
mtag = m_tag_get(PACKET_TAG_TUNNEL_INFO, sizeof(*count),
M_NOWAIT);
if (mtag != NULL) {
m_tag_prepend(m, mtag);
count = (int *)(mtag + 1);
*count = 0;
}
#ifdef L2TP_DEBUG
else {
log(LOG_DEBUG,
"%s: m_tag_get() failed, recursion calls are not prevented.\n",
if_name(ifp));
}
#endif
}
return 0;
return if_tunnel_check_nesting(ifp, m, max_l2tp_nesting);
}
/*