Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/net if_gre: Ensure that gre_h is aligned



details:   https://anonhg.NetBSD.org/src/rev/58de81763ace
branches:  trunk
changeset: 1018648:58de81763ace
user:      roy <roy%NetBSD.org@localhost>
date:      Fri Feb 12 19:57:49 2021 +0000

description:
if_gre: Ensure that gre_h is aligned

diffstat:

 sys/net/if_gre.c |  30 +++++++++++++++++++++++-------
 sys/net/if_gre.h |   7 ++++++-
 2 files changed, 29 insertions(+), 8 deletions(-)

diffs (86 lines):

diff -r 4fe6e3ffd1ef -r 58de81763ace sys/net/if_gre.c
--- a/sys/net/if_gre.c  Fri Feb 12 19:48:26 2021 +0000
+++ b/sys/net/if_gre.c  Fri Feb 12 19:57:49 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_gre.c,v 1.177 2020/01/29 04:18:34 thorpej Exp $ */
+/*     $NetBSD: if_gre.c,v 1.178 2021/02/12 19:57:49 roy Exp $ */
 
 /*
  * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
@@ -45,7 +45,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_gre.c,v 1.177 2020/01/29 04:18:34 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_gre.c,v 1.178 2021/02/12 19:57:49 roy Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_atalk.h"
@@ -395,10 +395,26 @@
                sc->sc_error_ev.ev_count++;
                return;
        }
-       if (m->m_len < sizeof(*gh) && (m = m_pullup(m, sizeof(*gh))) == NULL) {
-               GRE_DPRINTF(sc, "m_pullup failed\n");
-               sc->sc_pullup_ev.ev_count++;
-               return;
+
+       /* If the GRE header is not aligned, slurp it up into a new
+        * mbuf with space for link headers, in the event we forward
+        * it.  Otherwise, if it is aligned, make sure the entire
+        * base GRE header is in the first mbuf of the chain.
+        */
+       if (GRE_HDR_ALIGNED_P(mtod(m, void *)) == 0) {
+               if ((m = m_copyup(m, sizeof(struct gre_h),
+                   (max_linkhdr + 3) & ~3)) == NULL) {
+                       /* XXXJRT new stat, please */
+                       GRE_DPRINTF(sc, "m_copyup failed\n");
+                       sc->sc_pullup_ev.ev_count++;
+                       return;
+               }
+       } else if (__predict_false(m->m_len < sizeof(struct gre_h))) {
+               if ((m = m_pullup(m, sizeof(struct gre_h))) == NULL) {
+                       GRE_DPRINTF(sc, "m_pullup failed\n");
+                       sc->sc_pullup_ev.ev_count++;
+                       return;
+               }
        }
        gh = mtod(m, const struct gre_h *);
 
@@ -940,7 +956,6 @@
 #endif
 
        M_PREPEND(m, sizeof(*gh), M_DONTWAIT);
-
        if (m == NULL) {
                IF_DROP(&ifp->if_snd);
                error = ENOBUFS;
@@ -948,6 +963,7 @@
        }
 
        gh = mtod(m, struct gre_h *);
+       KASSERT(GRE_HDR_ALIGNED_P(gh));
        gh->flags = 0;
        gh->ptype = etype;
        /* XXX Need to handle IP ToS.  Look at how I handle IP TTL. */
diff -r 4fe6e3ffd1ef -r 58de81763ace sys/net/if_gre.h
--- a/sys/net/if_gre.h  Fri Feb 12 19:48:26 2021 +0000
+++ b/sys/net/if_gre.h  Fri Feb 12 19:57:49 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: if_gre.h,v 1.47 2021/02/03 18:13:13 roy Exp $ */
+/*     $NetBSD: if_gre.h,v 1.48 2021/02/12 19:57:49 roy Exp $ */
 
 /*
  * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
@@ -131,6 +131,11 @@
                                Present if (rt_pres == 1)
  */
 };
+#ifdef __NO_STRICT_ALIGNMENT
+#define        GRE_HDR_ALIGNED_P(gh)   1
+#else
+#define        GRE_HDR_ALIGNED_P(gh)   ((((vaddr_t) (gh)) & 3) == 0)
+#endif
 #ifdef __CTASSERT
 __CTASSERT(sizeof(struct gre_h) == 4);
 #endif



Home | Main Index | Thread Index | Old Index