unify processing to check nesting count for some tunnel protocols.
This commit is contained in:
parent
6b500088e0
commit
d4228bae36
41
sys/net/if.c
41
sys/net/if.c
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue