Module Name:    src
Committed By:   roy
Date:           Sat Feb 13 07:28:05 UTC 2021

Modified Files:
        src/sys/net: if_ether.h if_ethersubr.c

Log Message:
if_ether: Ensure that ether_header is aligned


To generate a diff of this commit:
cvs rdiff -u -r1.84 -r1.85 src/sys/net/if_ether.h
cvs rdiff -u -r1.289 -r1.290 src/sys/net/if_ethersubr.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net/if_ether.h
diff -u src/sys/net/if_ether.h:1.84 src/sys/net/if_ether.h:1.85
--- src/sys/net/if_ether.h:1.84	Wed Feb  3 18:13:13 2021
+++ src/sys/net/if_ether.h	Sat Feb 13 07:28:04 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_ether.h,v 1.84 2021/02/03 18:13:13 roy Exp $	*/
+/*	$NetBSD: if_ether.h,v 1.85 2021/02/13 07:28:04 roy Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1993
@@ -89,7 +89,11 @@ struct ether_header {
 	uint8_t  ether_shost[ETHER_ADDR_LEN];
 	uint16_t ether_type;
 };
-
+#ifdef __NO_STRICT_ALIGNMENT
+#define	ETHER_HDR_ALIGNED_P(eh)	1
+#else
+#define	ETHER_HDR_ALIGNED_P(eh)	((((vaddr_t) (eh)) & 3) == 0)
+#endif
 #ifdef __CTASSERT
 __CTASSERT(sizeof(struct ether_addr) == 6);
 __CTASSERT(sizeof(struct ether_header) == 14);

Index: src/sys/net/if_ethersubr.c
diff -u src/sys/net/if_ethersubr.c:1.289 src/sys/net/if_ethersubr.c:1.290
--- src/sys/net/if_ethersubr.c:1.289	Sat Sep 26 18:38:09 2020
+++ src/sys/net/if_ethersubr.c	Sat Feb 13 07:28:04 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_ethersubr.c,v 1.289 2020/09/26 18:38:09 roy Exp $	*/
+/*	$NetBSD: if_ethersubr.c,v 1.290 2021/02/13 07:28:04 roy Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.289 2020/09/26 18:38:09 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_ethersubr.c,v 1.290 2021/02/13 07:28:04 roy Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -648,9 +648,18 @@ ether_input(struct ifnet *ifp, struct mb
 
 	if ((ifp->if_flags & IFF_UP) == 0)
 		goto drop;
-	if (m->m_len < sizeof(*eh)) {
-		m = m_pullup(m, sizeof(*eh));
-		if (m == NULL)
+
+	/* If the Ethernet 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 Ethernet header is in the first mbuf of the chain.
+	 */
+	if (ETHER_HDR_ALIGNED_P(mtod(m, void *)) == 0) {
+		if ((m = m_copyup(m, sizeof(*eh),
+		    (max_linkhdr + 3) & ~3)) == NULL)
+			goto dropped;
+	} else if (__predict_false(m->m_len < sizeof(*eh))) {
+		if ((m = m_pullup(m, sizeof(*eh))) == NULL)
 			goto dropped;
 	}
 

Reply via email to