From d4228bae36fc63d4782d0841e13b18345cee7f2c Mon Sep 17 00:00:00 2001 From: knakahara Date: Wed, 6 Dec 2017 08:23:17 +0000 Subject: [PATCH] unify processing to check nesting count for some tunnel protocols. --- sys/net/if.c | 41 +++++++++++++++++++++++++++++++++++++++-- sys/net/if.h | 4 +++- sys/net/if_gif.c | 32 +++----------------------------- sys/net/if_l2tp.c | 39 +++------------------------------------ 4 files changed, 48 insertions(+), 68 deletions(-) diff --git a/sys/net/if.c b/sys/net/if.c index e1f6190b746d..b647af5dfda1 100644 --- a/sys/net/if.c +++ b/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 -__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 diff --git a/sys/net/if.h b/sys/net/if.h index 582d8b1b1dbd..0e3efba7345a 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -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) { diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c index c209608709d9..23b83004ec5b 100644 --- a/sys/net/if_gif.c +++ b/sys/net/if_gif.c @@ -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 -__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 diff --git a/sys/net/if_l2tp.c b/sys/net/if_l2tp.c index 5c677c0791f2..12d7bedaa920 100644 --- a/sys/net/if_l2tp.c +++ b/sys/net/if_l2tp.c @@ -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 -__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); } /*