Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F161694013
D16162.id45067.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D16162.id45067.diff
View Options
Index: head/sys/net/if.c
===================================================================
--- head/sys/net/if.c
+++ head/sys/net/if.c
@@ -3903,6 +3903,44 @@
}
/*
+ * Tunnel interfaces can nest, also they may cause infinite recursion
+ * calls when misconfigured. We'll prevent this by detecting loops.
+ * High nesting level may cause stack exhaustion. We'll prevent this
+ * by introducing upper limit.
+ *
+ * Return 0, if tunnel nesting count is equal or less than limit.
+ */
+int
+if_tunnel_check_nesting(struct ifnet *ifp, struct mbuf *m, uint32_t cookie,
+ int limit)
+{
+ struct m_tag *mtag;
+ int count;
+
+ count = 1;
+ mtag = NULL;
+ while ((mtag = m_tag_locate(m, cookie, 0, mtag)) != NULL) {
+ if (*(struct ifnet **)(mtag + 1) == ifp) {
+ log(LOG_NOTICE, "%s: loop detected\n", if_name(ifp));
+ return (EIO);
+ }
+ count++;
+ }
+ if (count > limit) {
+ log(LOG_NOTICE,
+ "%s: if_output recursively called too many times(%d)\n",
+ if_name(ifp), count);
+ return (EIO);
+ }
+ mtag = m_tag_alloc(cookie, 0, sizeof(struct ifnet *), M_NOWAIT);
+ if (mtag == NULL)
+ return (ENOMEM);
+ *(struct ifnet **)(mtag + 1) = ifp;
+ m_tag_prepend(m, mtag);
+ return (0);
+}
+
+/*
* Get the link layer address that was read from the hardware at attach.
*
* This is only set by Ethernet NICs (IFT_ETHER), but laggX interfaces re-type
Index: head/sys/net/if_gif.c
===================================================================
--- head/sys/net/if_gif.c
+++ head/sys/net/if_gif.c
@@ -104,7 +104,6 @@
void (*ng_gif_attach_p)(struct ifnet *ifp);
void (*ng_gif_detach_p)(struct ifnet *ifp);
-static int gif_check_nesting(struct ifnet *, struct mbuf *);
static void gif_delete_tunnel(struct gif_softc *);
static int gif_ioctl(struct ifnet *, u_long, caddr_t);
static int gif_transmit(struct ifnet *, struct mbuf *);
@@ -256,6 +255,7 @@
free(hash, M_GIF);
}
+#define MTAG_GIF 1080679712
static int
gif_transmit(struct ifnet *ifp, struct mbuf *m)
{
@@ -285,7 +285,8 @@
if ((ifp->if_flags & IFF_MONITOR) != 0 ||
(ifp->if_flags & IFF_UP) == 0 ||
sc->gif_family == 0 ||
- (error = gif_check_nesting(ifp, m)) != 0) {
+ (error = if_tunnel_check_nesting(ifp, m, MTAG_GIF,
+ V_max_gif_nesting)) != 0) {
m_freem(m);
goto err;
}
@@ -378,42 +379,6 @@
}
-#define MTAG_GIF 1080679712
-static int
-gif_check_nesting(struct ifnet *ifp, struct mbuf *m)
-{
- struct m_tag *mtag;
- int count;
-
- /*
- * gif may cause infinite recursion calls when misconfigured.
- * We'll prevent this by detecting loops.
- *
- * High nesting level may cause stack exhaustion.
- * We'll prevent this by introducing upper limit.
- */
- count = 1;
- mtag = NULL;
- while ((mtag = m_tag_locate(m, MTAG_GIF, 0, mtag)) != NULL) {
- if (*(struct ifnet **)(mtag + 1) == ifp) {
- log(LOG_NOTICE, "%s: loop detected\n", if_name(ifp));
- return (EIO);
- }
- count++;
- }
- if (count > V_max_gif_nesting) {
- log(LOG_NOTICE,
- "%s: if_output recursively called too many times(%d)\n",
- if_name(ifp), count);
- return (EIO);
- }
- mtag = m_tag_alloc(MTAG_GIF, 0, sizeof(struct ifnet *), M_NOWAIT);
- if (mtag == NULL)
- return (ENOMEM);
- *(struct ifnet **)(mtag + 1) = ifp;
- m_tag_prepend(m, mtag);
- return (0);
-}
int
gif_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
Index: head/sys/net/if_gre.c
===================================================================
--- head/sys/net/if_gre.c
+++ head/sys/net/if_gre.c
@@ -503,37 +503,7 @@
return (IPPROTO_DONE);
}
-#define MTAG_GRE 1307983903
static int
-gre_check_nesting(struct ifnet *ifp, struct mbuf *m)
-{
- struct m_tag *mtag;
- int count;
-
- count = 1;
- mtag = NULL;
- while ((mtag = m_tag_locate(m, MTAG_GRE, 0, mtag)) != NULL) {
- if (*(struct ifnet **)(mtag + 1) == ifp) {
- log(LOG_NOTICE, "%s: loop detected\n", ifp->if_xname);
- return (EIO);
- }
- count++;
- }
- if (count > V_max_gre_nesting) {
- log(LOG_NOTICE,
- "%s: if_output recursively called too many times(%d)\n",
- ifp->if_xname, count);
- return (EIO);
- }
- mtag = m_tag_alloc(MTAG_GRE, 0, sizeof(struct ifnet *), M_NOWAIT);
- if (mtag == NULL)
- return (ENOMEM);
- *(struct ifnet **)(mtag + 1) = ifp;
- m_tag_prepend(m, mtag);
- return (0);
-}
-
-static int
gre_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
struct route *ro)
{
@@ -569,6 +539,7 @@
*opts = htonl(seq);
}
+#define MTAG_GRE 1307983903
static int
gre_transmit(struct ifnet *ifp, struct mbuf *m)
{
@@ -592,7 +563,8 @@
if ((ifp->if_flags & IFF_MONITOR) != 0 ||
(ifp->if_flags & IFF_UP) == 0 ||
sc->gre_family == 0 ||
- (error = gre_check_nesting(ifp, m)) != 0) {
+ (error = if_tunnel_check_nesting(ifp, m, MTAG_GRE,
+ V_max_gre_nesting)) != 0) {
m_freem(m);
goto drop;
}
Index: head/sys/net/if_me.c
===================================================================
--- head/sys/net/if_me.c
+++ head/sys/net/if_me.c
@@ -455,37 +455,7 @@
return (IPPROTO_DONE);
}
-#define MTAG_ME 1414491977
static int
-me_check_nesting(struct ifnet *ifp, struct mbuf *m)
-{
- struct m_tag *mtag;
- int count;
-
- count = 1;
- mtag = NULL;
- while ((mtag = m_tag_locate(m, MTAG_ME, 0, mtag)) != NULL) {
- if (*(struct ifnet **)(mtag + 1) == ifp) {
- log(LOG_NOTICE, "%s: loop detected\n", ifp->if_xname);
- return (EIO);
- }
- count++;
- }
- if (count > V_max_me_nesting) {
- log(LOG_NOTICE,
- "%s: if_output recursively called too many times(%d)\n",
- ifp->if_xname, count);
- return (EIO);
- }
- mtag = m_tag_alloc(MTAG_ME, 0, sizeof(struct ifnet *), M_NOWAIT);
- if (mtag == NULL)
- return (ENOMEM);
- *(struct ifnet **)(mtag + 1) = ifp;
- m_tag_prepend(m, mtag);
- return (0);
-}
-
-static int
me_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
struct route *ro __unused)
{
@@ -499,6 +469,7 @@
return (ifp->if_transmit(ifp, m));
}
+#define MTAG_ME 1414491977
static int
me_transmit(struct ifnet *ifp, struct mbuf *m)
{
@@ -519,7 +490,8 @@
if (sc == NULL || !ME_READY(sc) ||
(ifp->if_flags & IFF_MONITOR) != 0 ||
(ifp->if_flags & IFF_UP) == 0 ||
- (error = me_check_nesting(ifp, m) != 0)) {
+ (error = if_tunnel_check_nesting(ifp, m, MTAG_ME,
+ V_max_me_nesting)) != 0) {
m_freem(m);
goto drop;
}
Index: head/sys/net/if_var.h
===================================================================
--- head/sys/net/if_var.h
+++ head/sys/net/if_var.h
@@ -644,6 +644,7 @@
void if_ref(struct ifnet *);
void if_rele(struct ifnet *);
int if_setlladdr(struct ifnet *, const u_char *, int);
+int if_tunnel_check_nesting(struct ifnet *, struct mbuf *, uint32_t, int);
void if_up(struct ifnet *);
int ifioctl(struct socket *, u_long, caddr_t, struct thread *);
int ifpromisc(struct ifnet *, int);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Jul 7, 12:29 AM (12 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34775094
Default Alt Text
D16162.id45067.diff (6 KB)
Attached To
Mode
D16162: Add generic function if_tunnel_check_nesting() and use it in tunneling interfaces
Attached
Detach File
Event Timeline
Log In to Comment