[Midnightbsd-cvs] src [9936] trunk/sys/netgraph: sync with freebsd

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Fri May 25 16:03:58 EDT 2018


Revision: 9936
          http://svnweb.midnightbsd.org/src/?rev=9936
Author:   laffer1
Date:     2018-05-25 16:03:57 -0400 (Fri, 25 May 2018)
Log Message:
-----------
sync with freebsd

Modified Paths:
--------------
    trunk/sys/netgraph/NOTES
    trunk/sys/netgraph/netgraph.h
    trunk/sys/netgraph/ng_UI.c
    trunk/sys/netgraph/ng_UI.h
    trunk/sys/netgraph/ng_async.c
    trunk/sys/netgraph/ng_async.h
    trunk/sys/netgraph/ng_atmllc.c
    trunk/sys/netgraph/ng_atmllc.h
    trunk/sys/netgraph/ng_base.c
    trunk/sys/netgraph/ng_bpf.c
    trunk/sys/netgraph/ng_bpf.h
    trunk/sys/netgraph/ng_bridge.c
    trunk/sys/netgraph/ng_bridge.h
    trunk/sys/netgraph/ng_car.c
    trunk/sys/netgraph/ng_car.h
    trunk/sys/netgraph/ng_cisco.c
    trunk/sys/netgraph/ng_cisco.h
    trunk/sys/netgraph/ng_deflate.c
    trunk/sys/netgraph/ng_deflate.h
    trunk/sys/netgraph/ng_device.c
    trunk/sys/netgraph/ng_device.h
    trunk/sys/netgraph/ng_echo.c
    trunk/sys/netgraph/ng_echo.h
    trunk/sys/netgraph/ng_eiface.c
    trunk/sys/netgraph/ng_eiface.h
    trunk/sys/netgraph/ng_etf.c
    trunk/sys/netgraph/ng_etf.h
    trunk/sys/netgraph/ng_ether.c
    trunk/sys/netgraph/ng_ether.h
    trunk/sys/netgraph/ng_ether_echo.c
    trunk/sys/netgraph/ng_ether_echo.h
    trunk/sys/netgraph/ng_fec.c
    trunk/sys/netgraph/ng_fec.h
    trunk/sys/netgraph/ng_frame_relay.c
    trunk/sys/netgraph/ng_frame_relay.h
    trunk/sys/netgraph/ng_gif.c
    trunk/sys/netgraph/ng_gif.h
    trunk/sys/netgraph/ng_gif_demux.c
    trunk/sys/netgraph/ng_gif_demux.h
    trunk/sys/netgraph/ng_hole.c
    trunk/sys/netgraph/ng_hole.h
    trunk/sys/netgraph/ng_hub.c
    trunk/sys/netgraph/ng_hub.h
    trunk/sys/netgraph/ng_iface.c
    trunk/sys/netgraph/ng_iface.h
    trunk/sys/netgraph/ng_ip_input.c
    trunk/sys/netgraph/ng_ip_input.h
    trunk/sys/netgraph/ng_ipfw.c
    trunk/sys/netgraph/ng_ipfw.h
    trunk/sys/netgraph/ng_ksocket.c
    trunk/sys/netgraph/ng_ksocket.h
    trunk/sys/netgraph/ng_l2tp.c
    trunk/sys/netgraph/ng_l2tp.h
    trunk/sys/netgraph/ng_lmi.c
    trunk/sys/netgraph/ng_lmi.h
    trunk/sys/netgraph/ng_message.h
    trunk/sys/netgraph/ng_mppc.c
    trunk/sys/netgraph/ng_mppc.h
    trunk/sys/netgraph/ng_nat.c
    trunk/sys/netgraph/ng_nat.h
    trunk/sys/netgraph/ng_one2many.c
    trunk/sys/netgraph/ng_one2many.h
    trunk/sys/netgraph/ng_parse.c
    trunk/sys/netgraph/ng_parse.h
    trunk/sys/netgraph/ng_patch.c
    trunk/sys/netgraph/ng_patch.h
    trunk/sys/netgraph/ng_pipe.c
    trunk/sys/netgraph/ng_pipe.h
    trunk/sys/netgraph/ng_ppp.c
    trunk/sys/netgraph/ng_ppp.h
    trunk/sys/netgraph/ng_pppoe.c
    trunk/sys/netgraph/ng_pppoe.h
    trunk/sys/netgraph/ng_pptpgre.c
    trunk/sys/netgraph/ng_pptpgre.h
    trunk/sys/netgraph/ng_pred1.c
    trunk/sys/netgraph/ng_pred1.h
    trunk/sys/netgraph/ng_rfc1490.c
    trunk/sys/netgraph/ng_rfc1490.h
    trunk/sys/netgraph/ng_sample.c
    trunk/sys/netgraph/ng_sample.h
    trunk/sys/netgraph/ng_socket.c
    trunk/sys/netgraph/ng_socket.h
    trunk/sys/netgraph/ng_socketvar.h
    trunk/sys/netgraph/ng_source.c
    trunk/sys/netgraph/ng_source.h
    trunk/sys/netgraph/ng_split.c
    trunk/sys/netgraph/ng_split.h
    trunk/sys/netgraph/ng_sppp.c
    trunk/sys/netgraph/ng_sppp.h
    trunk/sys/netgraph/ng_tag.c
    trunk/sys/netgraph/ng_tag.h
    trunk/sys/netgraph/ng_tcpmss.c
    trunk/sys/netgraph/ng_tcpmss.h
    trunk/sys/netgraph/ng_tee.c
    trunk/sys/netgraph/ng_tee.h
    trunk/sys/netgraph/ng_tty.c
    trunk/sys/netgraph/ng_tty.h
    trunk/sys/netgraph/ng_vjc.c
    trunk/sys/netgraph/ng_vjc.h
    trunk/sys/netgraph/ng_vlan.c
    trunk/sys/netgraph/ng_vlan.h

Added Paths:
-----------
    trunk/sys/netgraph/ng_checksum.c
    trunk/sys/netgraph/ng_checksum.h

Property Changed:
----------------
    trunk/sys/netgraph/NOTES

Modified: trunk/sys/netgraph/NOTES
===================================================================
--- trunk/sys/netgraph/NOTES	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/NOTES	2018-05-25 20:03:57 UTC (rev 9936)
@@ -1,4 +1,5 @@
 $MidnightBSD$
+$FreeBSD: stable/10/sys/netgraph/NOTES 198448 2009-10-24 18:49:17Z ru $
 Development ideas..
 
 Archie's suggestions... :-)


Property changes on: trunk/sys/netgraph/NOTES
___________________________________________________________________
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Modified: trunk/sys/netgraph/netgraph.h
===================================================================
--- trunk/sys/netgraph/netgraph.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/netgraph.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/netgraph.h 314667 2017-03-04 13:03:31Z avg $
  * $Whistle: netgraph.h,v 1.29 1999/11/01 07:56:13 julian Exp $
  */
 
@@ -1136,7 +1136,7 @@
  */
 int	ng_address_ID(node_p here, item_p item, ng_ID_t ID, ng_ID_t retaddr);
 int	ng_address_hook(node_p here, item_p item, hook_p hook, ng_ID_t retaddr);
-int	ng_address_path(node_p here, item_p item, char *address, ng_ID_t raddr);
+int	ng_address_path(node_p here, item_p item, const char *address, ng_ID_t raddr);
 int	ng_bypass(hook_p hook1, hook_p hook2);
 hook_p	ng_findhook(node_p node, const char *name);
 struct	ng_type *ng_findtype(const char *type);
@@ -1162,7 +1162,7 @@
 int	ng_uncallout(struct callout *c, node_p node);
 int	ng_callout(struct callout *c, node_p node, hook_p hook, int ticks,
 	    ng_item_fn *fn, void * arg1, int arg2);
-#define	ng_callout_init(c)	callout_init(c, CALLOUT_MPSAFE)
+#define	ng_callout_init(c)	callout_init(c, 1)
 
 /* Flags for netgraph functions. */
 #define	NG_NOFLAGS	0x00000000	/* no special options */

Modified: trunk/sys/netgraph/ng_UI.c
===================================================================
--- trunk/sys/netgraph/ng_UI.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_UI.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_UI.c 243882 2012-12-05 08:04:20Z glebius $
  * $Whistle: ng_UI.c,v 1.14 1999/11/01 09:24:51 julian Exp $
  */
 
@@ -189,7 +189,7 @@
 		m_adj(m, ptr - start);
 		NG_FWD_NEW_DATA(error, item, priv->uplink, m);	/* m -> NULL */
 	} else if (hook == priv->uplink) {
-		M_PREPEND(m, 1, M_DONTWAIT);	/* Prepend IP NLPID */
+		M_PREPEND(m, 1, M_NOWAIT);	/* Prepend IP NLPID */
 		if (!m)
 			ERROUT(ENOBUFS);
 		mtod(m, u_char *)[0] = HDLC_UI;

Modified: trunk/sys/netgraph/ng_UI.h
===================================================================
--- trunk/sys/netgraph/ng_UI.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_UI.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_UI.h 139823 2005-01-07 01:45:51Z imp $
  * $Whistle: ng_UI.h,v 1.6 1999/01/20 00:54:15 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_async.c
===================================================================
--- trunk/sys/netgraph/ng_async.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_async.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_async.c 227293 2011-11-07 06:44:47Z ed $
  * $Whistle: ng_async.c,v 1.17 1999/11/01 09:24:51 julian Exp $
  */
 

Modified: trunk/sys/netgraph/ng_async.h
===================================================================
--- trunk/sys/netgraph/ng_async.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_async.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_async.h 139823 2005-01-07 01:45:51Z imp $
  * $Whistle: ng_async.h,v 1.5 1999/01/25 01:17:14 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_atmllc.c
===================================================================
--- trunk/sys/netgraph/ng_atmllc.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_atmllc.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_atmllc.c 243882 2012-12-05 08:04:20Z glebius $
  */
 
 #include <sys/param.h>
@@ -154,7 +154,7 @@
 	int	error;
 
 	priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
-	m = NGI_M(item);
+	NGI_GET_M(item, m);
 	outhook = NULL;
 	padding = 0;
 
@@ -171,6 +171,7 @@
 		if (m->m_len < sizeof(struct atmllc) + ETHER_HDR_LEN) {
 			m = m_pullup(m, sizeof(struct atmllc) + ETHER_HDR_LEN);
 			if (m == NULL) {
+				NG_FREE_ITEM(item);
 				return (ENOMEM);
 			}
 		}
@@ -202,7 +203,7 @@
 		m_adj(m, sizeof(struct atmllc) + padding);
 	} else if (hook == priv->ether) {
 		/* Add the LLC header */
-		M_PREPEND(m, NG_ATMLLC_HEADER_LEN + 2, M_DONTWAIT);
+		M_PREPEND(m, NG_ATMLLC_HEADER_LEN + 2, M_NOWAIT);
 		if (m == NULL) {
 			printf("ng_atmllc: M_PREPEND failed\n");
 			NG_FREE_ITEM(item);
@@ -219,7 +220,7 @@
 		outhook = priv->atm;
 	} else if (hook == priv->fddi) {
 		/* Add the LLC header */
-		M_PREPEND(m, NG_ATMLLC_HEADER_LEN + 3, M_DONTWAIT);
+		M_PREPEND(m, NG_ATMLLC_HEADER_LEN + 3, M_NOWAIT);
 		if (m == NULL) {
 			printf("ng_atmllc: M_PREPEND failed\n");
 			NG_FREE_ITEM(item);
@@ -237,6 +238,7 @@
 	}
 
 	if (outhook == NULL) {
+		NG_FREE_M(m);
 		NG_FREE_ITEM(item);
 		return (0);
 	}

Modified: trunk/sys/netgraph/ng_atmllc.h
===================================================================
--- trunk/sys/netgraph/ng_atmllc.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_atmllc.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_atmllc.h 139823 2005-01-07 01:45:51Z imp $
  */
 
 #ifndef	_NETGRAPH_ATMLLC_H_

Modified: trunk/sys/netgraph/ng_base.c
===================================================================
--- trunk/sys/netgraph/ng_base.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_base.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -35,7 +35,7 @@
  * Authors: Julian Elischer <julian at freebsd.org>
  *          Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_base.c 333629 2018-05-15 13:19:00Z sbruno $
  * $Whistle: ng_base.c,v 1.39 1999/01/28 23:54:53 julian Exp $
  */
 
@@ -93,7 +93,7 @@
 #endif	/* NETGRAPH_DEBUG */
 /*
  * DEAD versions of the structures.
- * In order to avoid races, it is sometimes neccesary to point
+ * In order to avoid races, it is sometimes necessary to point
  * at SOMETHING even though theoretically, the current entity is
  * INVALID. Use these to avoid these races.
  */
@@ -469,7 +469,7 @@
 	&ng_generic_linkinfo_array_type_info
 };
 
-DEFINE_PARSE_STRUCT_TYPE(typelist, TYPELIST, (&ng_generic_nodeinfoarray_type));
+DEFINE_PARSE_STRUCT_TYPE(typelist, TYPELIST, (&ng_generic_typeinfoarray_type));
 DEFINE_PARSE_STRUCT_TYPE(hooklist, HOOKLIST,
 	(&ng_generic_nodeinfo_type, &ng_generic_linkinfo_array_type));
 DEFINE_PARSE_STRUCT_TYPE(listnodes, LISTNODES,
@@ -545,7 +545,7 @@
 	  NGM_LISTTYPES,
 	  "listtypes",
 	  NULL,
-	  &ng_generic_typeinfo_type
+	  &ng_generic_typelist_type
 	},
 	{
 	  NGM_GENERIC_COOKIE,
@@ -790,6 +790,8 @@
 	if (node == &ng_deadnode)
 		return;
 
+	CURVNET_SET(node->nd_vnet);
+
 	if (refcount_release(&node->nd_refs)) { /* we were the last */
 
 		node->nd_type->refs--; /* XXX maybe should get types lock? */
@@ -808,6 +810,7 @@
 		mtx_destroy(&node->nd_input_queue.q_mtx);
 		NG_FREE_NODE(node);
 	}
+	CURVNET_RESTORE();
 }
 
 /************************************************************************
@@ -2945,7 +2948,7 @@
 uma_zone_t			ng_qdzone;
 static int			numthreads = 0; /* number of queue threads */
 static int			maxalloc = 4096;/* limit the damage of a leak */
-static int			maxdata = 512;	/* limit the damage of a DoS */
+static int			maxdata = 4096;	/* limit the damage of a DoS */
 
 TUNABLE_INT("net.graph.threads", &numthreads);
 SYSCTL_INT(_net_graph, OID_AUTO, threads, CTLFLAG_RDTUN, &numthreads,
@@ -3246,8 +3249,8 @@
 };
 DECLARE_MODULE(netgraph, netgraph_mod, SI_SUB_NETGRAPH, SI_ORDER_FIRST);
 SYSCTL_NODE(_net, OID_AUTO, graph, CTLFLAG_RW, 0, "netgraph Family");
-SYSCTL_INT(_net_graph, OID_AUTO, abi_version, CTLFLAG_RD, 0, NG_ABI_VERSION,"");
-SYSCTL_INT(_net_graph, OID_AUTO, msg_version, CTLFLAG_RD, 0, NG_VERSION, "");
+SYSCTL_INT(_net_graph, OID_AUTO, abi_version, CTLFLAG_RD, SYSCTL_NULL_INT_PTR, NG_ABI_VERSION,"");
+SYSCTL_INT(_net_graph, OID_AUTO, msg_version, CTLFLAG_RD, SYSCTL_NULL_INT_PTR, NG_VERSION, "");
 
 #ifdef	NETGRAPH_DEBUG
 void
@@ -3602,7 +3605,7 @@
 }
 
 int
-ng_address_path(node_p here, item_p item, char *address, ng_ID_t retaddr)
+ng_address_path(node_p here, item_p item, const char *address, ng_ID_t retaddr)
 {
 	node_p	dest = NULL;
 	hook_p	hook = NULL;
@@ -3811,7 +3814,7 @@
 	item = c->c_arg;
 	/* Do an extra check */
 	if ((rval > 0) && (c->c_func == &ng_callout_trampoline) &&
-	    (NGI_NODE(item) == node)) {
+	    (item != NULL) && (NGI_NODE(item) == node)) {
 		/*
 		 * We successfully removed it from the queue before it ran
 		 * So now we need to unreference everything that was
@@ -3821,7 +3824,11 @@
 	}
 	c->c_arg = NULL;
 
-	return (rval);
+	/*
+	 * Callers only want to know if the callout was cancelled and
+	 * not draining or stopped.
+	 */
+	return (rval > 0);
 }
 
 /*

Modified: trunk/sys/netgraph/ng_bpf.c
===================================================================
--- trunk/sys/netgraph/ng_bpf.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_bpf.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_bpf.c 227293 2011-11-07 06:44:47Z ed $
  * $Whistle: ng_bpf.c,v 1.3 1999/12/03 20:30:23 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_bpf.h
===================================================================
--- trunk/sys/netgraph/ng_bpf.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_bpf.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_bpf.h 141751 2005-02-12 18:10:26Z ru $
  * $Whistle: ng_bpf.h,v 1.3 1999/12/03 20:30:23 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_bridge.c
===================================================================
--- trunk/sys/netgraph/ng_bridge.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_bridge.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_bridge.c 243882 2012-12-05 08:04:20Z glebius $
  */
 
 /*
@@ -720,7 +720,7 @@
 			 * It's usable link but not the reserved (first) one.
 			 * Copy mbuf info for sending.
 			 */
-			m2 = m_dup(m, M_DONTWAIT);	/* XXX m_copypacket() */
+			m2 = m_dup(m, M_NOWAIT);	/* XXX m_copypacket() */
 			if (m2 == NULL) {
 				link->stats.memoryFailures++;
 				NG_FREE_ITEM(item);

Modified: trunk/sys/netgraph/ng_bridge.h
===================================================================
--- trunk/sys/netgraph/ng_bridge.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_bridge.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_bridge.h 207680 2010-05-05 22:06:05Z zec $
  */
 
 #ifndef _NETGRAPH_NG_BRIDGE_H_

Modified: trunk/sys/netgraph/ng_car.c
===================================================================
--- trunk/sys/netgraph/ng_car.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_car.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_car.c 220768 2011-04-18 09:12:27Z glebius $
  */
 
 /*

Modified: trunk/sys/netgraph/ng_car.h
===================================================================
--- trunk/sys/netgraph/ng_car.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_car.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_car.h 174795 2007-12-19 22:50:14Z mav $
  */
 
 #ifndef _NETGRAPH_NG_CAR_H_

Added: trunk/sys/netgraph/ng_checksum.c
===================================================================
--- trunk/sys/netgraph/ng_checksum.c	                        (rev 0)
+++ trunk/sys/netgraph/ng_checksum.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -0,0 +1,730 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2015 Dmitry Vagin <daemon.hammer at ya.ru>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/sys/netgraph/ng_checksum.c 309387 2016-12-02 05:38:25Z julian $");
+
+#include "opt_inet.h"
+#include "opt_inet6.h"
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/endian.h>
+#include <sys/malloc.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+
+#include <net/bpf.h>
+#include <net/ethernet.h>
+#include <net/if.h>
+#include <net/if_vlan_var.h>
+
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/ip6.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <machine/in_cksum.h>
+
+#include <netgraph/ng_message.h>
+#include <netgraph/ng_parse.h>
+#include <netgraph/netgraph.h>
+
+#include <netgraph/ng_checksum.h>
+
+/* private data */
+struct ng_checksum_priv {
+	hook_p in;
+	hook_p out;
+	uint8_t dlt;	/* DLT_XXX from bpf.h */
+	struct ng_checksum_config *conf;
+	struct ng_checksum_stats stats;
+};
+
+typedef struct ng_checksum_priv *priv_p;
+
+/* Netgraph methods */
+static ng_constructor_t	ng_checksum_constructor;
+static ng_rcvmsg_t	ng_checksum_rcvmsg;
+static ng_shutdown_t	ng_checksum_shutdown;
+static ng_newhook_t	ng_checksum_newhook;
+static ng_rcvdata_t	ng_checksum_rcvdata;
+static ng_disconnect_t	ng_checksum_disconnect;
+
+#define ERROUT(x) { error = (x); goto done; }
+
+static const struct ng_parse_struct_field ng_checksum_config_type_fields[]
+	= NG_CHECKSUM_CONFIG_TYPE;
+static const struct ng_parse_type ng_checksum_config_type = {
+	&ng_parse_struct_type,
+	&ng_checksum_config_type_fields
+};
+
+static const struct ng_parse_struct_field ng_checksum_stats_fields[]
+	= NG_CHECKSUM_STATS_TYPE;
+static const struct ng_parse_type ng_checksum_stats_type = {
+	&ng_parse_struct_type,
+	&ng_checksum_stats_fields
+};
+
+static const struct ng_cmdlist ng_checksum_cmdlist[] = {
+	{
+		NGM_CHECKSUM_COOKIE,
+		NGM_CHECKSUM_GETDLT,
+		"getdlt",
+		NULL,
+		&ng_parse_uint8_type
+	},
+	{
+		NGM_CHECKSUM_COOKIE,
+		NGM_CHECKSUM_SETDLT,
+		"setdlt",
+		&ng_parse_uint8_type,
+		NULL
+	},
+	{
+		NGM_CHECKSUM_COOKIE,
+		NGM_CHECKSUM_GETCONFIG,
+		"getconfig",
+		NULL,
+		&ng_checksum_config_type
+	},
+	{
+		NGM_CHECKSUM_COOKIE,
+		NGM_CHECKSUM_SETCONFIG,
+		"setconfig",
+		&ng_checksum_config_type,
+		NULL
+	},
+	{
+		NGM_CHECKSUM_COOKIE,
+		NGM_CHECKSUM_GET_STATS,
+		"getstats",
+		NULL,
+		&ng_checksum_stats_type
+	},
+	{
+		NGM_CHECKSUM_COOKIE,
+		NGM_CHECKSUM_CLR_STATS,
+		"clrstats",
+		NULL,
+		NULL
+	},
+	{
+		NGM_CHECKSUM_COOKIE,
+		NGM_CHECKSUM_GETCLR_STATS,
+		"getclrstats",
+		NULL,
+		&ng_checksum_stats_type
+	},
+	{ 0 }
+};
+
+static struct ng_type typestruct = {
+	.version =	NG_ABI_VERSION,
+	.name =		NG_CHECKSUM_NODE_TYPE,
+	.constructor =	ng_checksum_constructor,
+	.rcvmsg =	ng_checksum_rcvmsg,
+	.shutdown =	ng_checksum_shutdown,
+	.newhook =	ng_checksum_newhook,
+	.rcvdata =	ng_checksum_rcvdata,
+	.disconnect =	ng_checksum_disconnect,
+	.cmdlist =	ng_checksum_cmdlist,
+};
+
+NETGRAPH_INIT(checksum, &typestruct);
+
+static int
+ng_checksum_constructor(node_p node)
+{
+	priv_p priv;
+
+	priv = malloc(sizeof(*priv), M_NETGRAPH, M_WAITOK|M_ZERO);
+	priv->dlt = DLT_RAW;
+
+	NG_NODE_SET_PRIVATE(node, priv);
+
+	return (0);
+}
+
+static int
+ng_checksum_newhook(node_p node, hook_p hook, const char *name)
+{
+	const priv_p priv = NG_NODE_PRIVATE(node);
+
+	if (strncmp(name, NG_CHECKSUM_HOOK_IN, strlen(NG_CHECKSUM_HOOK_IN)) == 0) {
+		priv->in = hook;
+	} else if (strncmp(name, NG_CHECKSUM_HOOK_OUT, strlen(NG_CHECKSUM_HOOK_OUT)) == 0) {
+		priv->out = hook;
+	} else
+		return (EINVAL);
+
+	return (0);
+}
+
+static int
+ng_checksum_rcvmsg(node_p node, item_p item, hook_p lasthook)
+{
+	const priv_p priv = NG_NODE_PRIVATE(node);
+	struct ng_checksum_config *conf, *newconf;
+	struct ng_mesg *msg;
+	struct ng_mesg *resp = NULL;
+	int error = 0;
+
+	NGI_GET_MSG(item, msg);
+
+	if  (msg->header.typecookie != NGM_CHECKSUM_COOKIE)
+		ERROUT(EINVAL);
+
+	switch (msg->header.cmd)
+	{
+		case NGM_CHECKSUM_GETDLT:
+			NG_MKRESPONSE(resp, msg, sizeof(uint8_t), M_WAITOK);
+
+			if (resp == NULL)
+				ERROUT(ENOMEM);
+
+			*((uint8_t *) resp->data) = priv->dlt;
+
+			break;
+
+		case NGM_CHECKSUM_SETDLT:
+			if (msg->header.arglen != sizeof(uint8_t))
+				ERROUT(EINVAL);
+
+			switch (*(uint8_t *) msg->data)
+			{
+				case DLT_EN10MB:
+				case DLT_RAW:
+					priv->dlt = *(uint8_t *) msg->data;
+					break;
+
+				default:
+					ERROUT(EINVAL);
+			}
+
+			break;
+
+		case NGM_CHECKSUM_GETCONFIG:
+			if (priv->conf == NULL)
+				ERROUT(0);
+
+			NG_MKRESPONSE(resp, msg, sizeof(struct ng_checksum_config), M_WAITOK);
+
+			if (resp == NULL)
+				ERROUT(ENOMEM);
+
+			bcopy(priv->conf, resp->data, sizeof(struct ng_checksum_config));
+
+			break;
+
+		case NGM_CHECKSUM_SETCONFIG:
+			conf = (struct ng_checksum_config *) msg->data;
+
+			if (msg->header.arglen != sizeof(struct ng_checksum_config))
+				ERROUT(EINVAL);
+
+			conf->csum_flags &= NG_CHECKSUM_CSUM_IPV4|NG_CHECKSUM_CSUM_IPV6;
+			conf->csum_offload &= NG_CHECKSUM_CSUM_IPV4|NG_CHECKSUM_CSUM_IPV6;
+
+			newconf = malloc(sizeof(struct ng_checksum_config), M_NETGRAPH, M_WAITOK|M_ZERO);
+
+			bcopy(conf, newconf, sizeof(struct ng_checksum_config));
+
+			if (priv->conf)
+				free(priv->conf, M_NETGRAPH);
+
+			priv->conf = newconf;
+
+			break;
+
+		case NGM_CHECKSUM_GET_STATS:
+		case NGM_CHECKSUM_CLR_STATS:
+		case NGM_CHECKSUM_GETCLR_STATS:
+			if (msg->header.cmd != NGM_CHECKSUM_CLR_STATS) {
+				NG_MKRESPONSE(resp, msg, sizeof(struct ng_checksum_stats), M_WAITOK);
+
+				if (resp == NULL)
+					ERROUT(ENOMEM);
+
+				bcopy(&(priv->stats), resp->data, sizeof(struct ng_checksum_stats));
+			}
+
+			if (msg->header.cmd != NGM_CHECKSUM_GET_STATS)
+				bzero(&(priv->stats), sizeof(struct ng_checksum_stats));
+
+			break;
+
+		default:
+			ERROUT(EINVAL);
+	}
+
+done:
+	NG_RESPOND_MSG(error, node, item, resp);
+	NG_FREE_MSG(msg);
+
+	return (error);
+}
+
+#define	PULLUP_CHECK(mbuf, length) do {					\
+	pullup_len += length;						\
+	if (((mbuf)->m_pkthdr.len < pullup_len) ||			\
+	    (pullup_len > MHLEN)) {					\
+		return (EINVAL);					\
+	}								\
+	if ((mbuf)->m_len < pullup_len &&				\
+	    (((mbuf) = m_pullup((mbuf), pullup_len)) == NULL)) {	\
+		return (ENOBUFS);					\
+	}								\
+} while (0)
+
+#ifdef INET
+static int
+checksum_ipv4(priv_p priv, struct mbuf *m, int l3_offset)
+{
+	struct ip *ip4;
+	int pullup_len;
+	int hlen, plen;
+	int processed = 0;
+
+	pullup_len = l3_offset;
+
+	PULLUP_CHECK(m, sizeof(struct ip));
+	ip4 = (struct ip *) mtodo(m, l3_offset);
+
+	if (ip4->ip_v != IPVERSION)
+		return (EOPNOTSUPP);
+
+	hlen = ip4->ip_hl << 2;
+	plen = ntohs(ip4->ip_len);
+
+	if (hlen < sizeof(struct ip) || m->m_pkthdr.len < l3_offset + plen)
+		return (EINVAL);
+
+	if (m->m_pkthdr.csum_flags & CSUM_IP) {
+		ip4->ip_sum = 0;
+
+		if ((priv->conf->csum_offload & CSUM_IP) == 0) {
+			if (hlen == sizeof(struct ip))
+				ip4->ip_sum = in_cksum_hdr(ip4);
+			else
+				ip4->ip_sum = in_cksum_skip(m, l3_offset + hlen, l3_offset);
+
+			m->m_pkthdr.csum_flags &= ~CSUM_IP;
+		}
+
+		processed = 1;
+	}
+
+	pullup_len = l3_offset + hlen;
+
+	/* We can not calculate a checksum fragmented packets */
+	if (ip4->ip_off & htons(IP_MF|IP_OFFMASK)) {
+		m->m_pkthdr.csum_flags &= ~(CSUM_TCP|CSUM_UDP);
+		return (0);
+	}
+
+	switch (ip4->ip_p)
+	{
+		case IPPROTO_TCP:
+			if (m->m_pkthdr.csum_flags & CSUM_TCP) {
+				struct tcphdr *th;
+
+				PULLUP_CHECK(m, sizeof(struct tcphdr));
+				th = (struct tcphdr *) mtodo(m, l3_offset + hlen);
+
+				th->th_sum = in_pseudo(ip4->ip_src.s_addr,
+				    ip4->ip_dst.s_addr, htons(ip4->ip_p + plen - hlen));
+
+				if ((priv->conf->csum_offload & CSUM_TCP) == 0) {
+					th->th_sum = in_cksum_skip(m, l3_offset + plen, l3_offset + hlen);
+					m->m_pkthdr.csum_flags &= ~CSUM_TCP;
+				}
+
+				processed = 1;
+			}
+
+			m->m_pkthdr.csum_flags &= ~CSUM_UDP;
+			break;
+
+		case IPPROTO_UDP:
+			if (m->m_pkthdr.csum_flags & CSUM_UDP) {
+				struct udphdr *uh;
+
+				PULLUP_CHECK(m, sizeof(struct udphdr));
+				uh = (struct udphdr *) mtodo(m, l3_offset + hlen);
+
+				uh->uh_sum = in_pseudo(ip4->ip_src.s_addr,
+				    ip4->ip_dst.s_addr, htons(ip4->ip_p + plen - hlen));
+
+				if ((priv->conf->csum_offload & CSUM_UDP) == 0) {
+					uh->uh_sum = in_cksum_skip(m,
+					    l3_offset + plen, l3_offset + hlen);
+
+					if (uh->uh_sum == 0)
+						uh->uh_sum = 0xffff;
+
+					m->m_pkthdr.csum_flags &= ~CSUM_UDP;
+				}
+
+				processed = 1;
+			}
+
+			m->m_pkthdr.csum_flags &= ~CSUM_TCP;
+			break;
+
+		default:
+			m->m_pkthdr.csum_flags &= ~(CSUM_TCP|CSUM_UDP);
+			break;
+	}
+
+	m->m_pkthdr.csum_flags &= ~NG_CHECKSUM_CSUM_IPV6;
+
+	if (processed)
+		priv->stats.processed++;
+
+	return (0);
+}
+#endif /* INET */
+
+#ifdef INET6
+static int
+checksum_ipv6(priv_p priv, struct mbuf *m, int l3_offset)
+{
+	struct ip6_hdr *ip6;
+	struct ip6_ext *ip6e = NULL;
+	int pullup_len;
+	int hlen, plen;
+	int nxt;
+	int processed = 0;
+
+	pullup_len = l3_offset;
+
+	PULLUP_CHECK(m, sizeof(struct ip6_hdr));
+	ip6 = (struct ip6_hdr *) mtodo(m, l3_offset);
+
+	if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION)
+		return (EOPNOTSUPP);
+
+	hlen = sizeof(struct ip6_hdr);
+	plen = ntohs(ip6->ip6_plen) + hlen;
+
+	if (m->m_pkthdr.len < l3_offset + plen)
+		return (EINVAL);
+
+	nxt = ip6->ip6_nxt;
+
+	for (;;) {
+		switch (nxt)
+		{
+			case IPPROTO_DSTOPTS:
+			case IPPROTO_HOPOPTS:
+			case IPPROTO_ROUTING:
+				PULLUP_CHECK(m, sizeof(struct ip6_ext));
+				ip6e = (struct ip6_ext *) mtodo(m, l3_offset + hlen);
+				nxt = ip6e->ip6e_nxt;
+				hlen += (ip6e->ip6e_len + 1) << 3;
+				pullup_len = l3_offset + hlen;
+				break;
+
+			case IPPROTO_AH:
+				PULLUP_CHECK(m, sizeof(struct ip6_ext));
+				ip6e = (struct ip6_ext *) mtodo(m, l3_offset + hlen);
+				nxt = ip6e->ip6e_nxt;
+				hlen += (ip6e->ip6e_len + 2) << 2;
+				pullup_len = l3_offset + hlen;
+				break;
+
+			case IPPROTO_FRAGMENT:
+				/* We can not calculate a checksum fragmented packets */
+				m->m_pkthdr.csum_flags &= ~(CSUM_TCP_IPV6|CSUM_UDP_IPV6);
+				return (0);
+
+			default:
+				goto loopend;
+		}
+
+		if (nxt == 0)
+			return (EINVAL);
+	}
+
+loopend:
+
+	switch (nxt)
+	{
+		case IPPROTO_TCP:
+			if (m->m_pkthdr.csum_flags & CSUM_TCP_IPV6) {
+				struct tcphdr *th;
+
+				PULLUP_CHECK(m, sizeof(struct tcphdr));
+				th = (struct tcphdr *) mtodo(m, l3_offset + hlen);
+
+				th->th_sum = in6_cksum_pseudo(ip6, plen - hlen, nxt, 0);
+
+				if ((priv->conf->csum_offload & CSUM_TCP_IPV6) == 0) {
+					th->th_sum = in_cksum_skip(m, l3_offset + plen, l3_offset + hlen);
+					m->m_pkthdr.csum_flags &= ~CSUM_TCP_IPV6;
+				}
+
+				processed = 1;
+			}
+
+			m->m_pkthdr.csum_flags &= ~CSUM_UDP_IPV6;
+			break;
+
+		case IPPROTO_UDP:
+			if (m->m_pkthdr.csum_flags & CSUM_UDP_IPV6) {
+				struct udphdr *uh;
+
+				PULLUP_CHECK(m, sizeof(struct udphdr));
+				uh = (struct udphdr *) mtodo(m, l3_offset + hlen);
+
+				uh->uh_sum = in6_cksum_pseudo(ip6, plen - hlen, nxt, 0);
+
+				if ((priv->conf->csum_offload & CSUM_UDP_IPV6) == 0) {
+					uh->uh_sum = in_cksum_skip(m,
+					    l3_offset + plen, l3_offset + hlen);
+
+					if (uh->uh_sum == 0)
+						uh->uh_sum = 0xffff;
+
+					m->m_pkthdr.csum_flags &= ~CSUM_UDP_IPV6;
+				}
+
+				processed = 1;
+			}
+
+			m->m_pkthdr.csum_flags &= ~CSUM_TCP_IPV6;
+			break;
+
+		default:
+			m->m_pkthdr.csum_flags &= ~(CSUM_TCP_IPV6|CSUM_UDP_IPV6);
+			break;
+	}
+
+	m->m_pkthdr.csum_flags &= ~NG_CHECKSUM_CSUM_IPV4;
+
+	if (processed)
+		priv->stats.processed++;
+
+	return (0);
+}
+#endif /* INET6 */
+
+#undef	PULLUP_CHECK
+
+static int
+ng_checksum_rcvdata(hook_p hook, item_p item)
+{
+	const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
+	struct mbuf *m;
+	hook_p out;
+	int error = 0;
+
+	priv->stats.received++;
+
+	NGI_GET_M(item, m);
+
+#define	PULLUP_CHECK(mbuf, length) do {					\
+	pullup_len += length;						\
+	if (((mbuf)->m_pkthdr.len < pullup_len) ||			\
+	    (pullup_len > MHLEN)) {					\
+		error = EINVAL;						\
+		goto bypass;						\
+	}								\
+	if ((mbuf)->m_len < pullup_len &&				\
+	    (((mbuf) = m_pullup((mbuf), pullup_len)) == NULL)) {	\
+		error = ENOBUFS;					\
+		goto drop;						\
+	}								\
+} while (0)
+
+	if (!(priv->conf && hook == priv->in && m && (m->m_flags & M_PKTHDR)))
+		goto bypass;
+
+	m->m_pkthdr.csum_flags |= priv->conf->csum_flags;
+
+	if (m->m_pkthdr.csum_flags & (NG_CHECKSUM_CSUM_IPV4|NG_CHECKSUM_CSUM_IPV6))
+	{
+		struct ether_header *eh;
+		struct ng_checksum_vlan_header *vh;
+		int pullup_len = 0;
+		uint16_t etype;
+
+		m = m_unshare(m, M_NOWAIT);
+
+		if (m == NULL)
+			ERROUT(ENOMEM);
+
+		switch (priv->dlt)
+		{
+			case DLT_EN10MB:
+				PULLUP_CHECK(m, sizeof(struct ether_header));
+				eh = mtod(m, struct ether_header *);
+				etype = ntohs(eh->ether_type);
+
+				for (;;) {	/* QinQ support */
+					switch (etype)
+					{
+						case 0x8100:
+						case 0x88A8:
+						case 0x9100:
+							PULLUP_CHECK(m, sizeof(struct ng_checksum_vlan_header));
+							vh = (struct ng_checksum_vlan_header *) mtodo(m,
+							    pullup_len - sizeof(struct ng_checksum_vlan_header));
+							etype = ntohs(vh->etype);
+							break;
+
+						default:
+							goto loopend;
+					}
+				}
+loopend:
+#ifdef INET
+				if (etype == ETHERTYPE_IP &&
+				    (m->m_pkthdr.csum_flags & NG_CHECKSUM_CSUM_IPV4)) {
+					error = checksum_ipv4(priv, m, pullup_len);
+					if (error == ENOBUFS)
+						goto drop;
+				} else
+#endif
+#ifdef INET6
+				if (etype == ETHERTYPE_IPV6 &&
+				    (m->m_pkthdr.csum_flags & NG_CHECKSUM_CSUM_IPV6)) {
+					error = checksum_ipv6(priv, m, pullup_len);
+					if (error == ENOBUFS)
+						goto drop;
+				} else
+#endif
+				{
+					m->m_pkthdr.csum_flags &=
+					    ~(NG_CHECKSUM_CSUM_IPV4|NG_CHECKSUM_CSUM_IPV6);
+				}
+
+				break;
+
+			case DLT_RAW:
+#ifdef INET
+				if (m->m_pkthdr.csum_flags & NG_CHECKSUM_CSUM_IPV4)
+				{
+					error = checksum_ipv4(priv, m, pullup_len);
+
+					if (error == 0)
+						goto bypass;
+					else if (error == ENOBUFS)
+						goto drop;
+				}
+#endif
+#ifdef INET6
+				if (m->m_pkthdr.csum_flags & NG_CHECKSUM_CSUM_IPV6)
+				{
+					error = checksum_ipv6(priv, m, pullup_len);
+
+					if (error == 0)
+						goto bypass;
+					else if (error == ENOBUFS)
+						goto drop;
+				}
+#endif
+				if (error)
+					m->m_pkthdr.csum_flags &=
+					    ~(NG_CHECKSUM_CSUM_IPV4|NG_CHECKSUM_CSUM_IPV6);
+
+				break;
+
+			default:
+				ERROUT(EINVAL);
+		}
+	}
+
+#undef	PULLUP_CHECK
+
+bypass:
+	out = NULL;
+
+	if (hook == priv->in) {
+		/* return frames on 'in' hook if 'out' not connected */
+		out = priv->out ? priv->out : priv->in;
+	} else if (hook == priv->out && priv->in) {
+		/* pass frames on 'out' hook if 'in' connected */
+		out = priv->in;
+	}
+
+	if (out == NULL)
+		ERROUT(0);
+
+	NG_FWD_NEW_DATA(error, item, out, m);
+
+	return (error);
+
+done:
+drop:
+	NG_FREE_ITEM(item);
+	NG_FREE_M(m);
+
+	priv->stats.dropped++;
+
+	return (error);
+}
+
+static int
+ng_checksum_shutdown(node_p node)
+{
+	const priv_p priv = NG_NODE_PRIVATE(node);
+
+	NG_NODE_SET_PRIVATE(node, NULL);
+	NG_NODE_UNREF(node);
+
+	if (priv->conf)
+		free(priv->conf, M_NETGRAPH);
+
+	free(priv, M_NETGRAPH);
+
+	return (0);
+}
+
+static int
+ng_checksum_disconnect(hook_p hook)
+{
+	priv_p priv;
+
+	priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
+
+	if (hook == priv->in)
+		priv->in = NULL;
+
+	if (hook == priv->out)
+		priv->out = NULL;
+
+	if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0 &&
+	    NG_NODE_IS_VALID(NG_HOOK_NODE(hook))) /* already shutting down? */
+		ng_rmnode_self(NG_HOOK_NODE(hook));
+
+	return (0);
+}


Property changes on: trunk/sys/netgraph/ng_checksum.c
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Added: trunk/sys/netgraph/ng_checksum.h
===================================================================
--- trunk/sys/netgraph/ng_checksum.h	                        (rev 0)
+++ trunk/sys/netgraph/ng_checksum.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -0,0 +1,89 @@
+/* $MidnightBSD$ */
+/*-
+ * Copyright (c) 2015 Dmitry Vagin <daemon.hammer at ya.ru>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: stable/10/sys/netgraph/ng_checksum.h 309387 2016-12-02 05:38:25Z julian $
+ */
+
+#ifndef _NETGRAPH_NG_CHECKSUM_H_
+#define _NETGRAPH_NG_CHECKSUM_H_
+
+/* Node type name. */
+#define	NG_CHECKSUM_NODE_TYPE	"checksum"
+
+/* Node type cookie. */
+#define	NGM_CHECKSUM_COOKIE	439419912
+
+/* Hook names */
+#define	NG_CHECKSUM_HOOK_IN	"in"
+#define	NG_CHECKSUM_HOOK_OUT	"out"
+
+/* Checksum flags */
+#define NG_CHECKSUM_CSUM_IPV4	(CSUM_IP|CSUM_TCP|CSUM_UDP)
+#define NG_CHECKSUM_CSUM_IPV6	(CSUM_TCP_IPV6|CSUM_UDP_IPV6)
+
+/* Netgraph commands understood by this node type */
+enum {
+	NGM_CHECKSUM_GETDLT = 1,
+	NGM_CHECKSUM_SETDLT,
+	NGM_CHECKSUM_GETCONFIG,
+	NGM_CHECKSUM_SETCONFIG,
+	NGM_CHECKSUM_GETCLR_STATS,
+	NGM_CHECKSUM_GET_STATS,
+	NGM_CHECKSUM_CLR_STATS,
+};
+
+/* Parsing declarations */
+
+#define	NG_CHECKSUM_CONFIG_TYPE {				\
+	{ "csum_flags",		&ng_parse_uint64_type	},	\
+	{ "csum_offload",	&ng_parse_uint64_type	},	\
+	{ NULL }						\
+}
+
+#define	NG_CHECKSUM_STATS_TYPE {				\
+	{ "Received",		&ng_parse_uint64_type	},	\
+	{ "Processed",		&ng_parse_uint64_type	},	\
+	{ "Dropped",		&ng_parse_uint64_type	},	\
+	{ NULL }					\
+}
+
+struct ng_checksum_config {
+	uint64_t	csum_flags;
+	uint64_t	csum_offload;
+};
+
+struct ng_checksum_stats {
+	uint64_t	received;
+	uint64_t	processed;
+	uint64_t	dropped;
+};
+
+struct ng_checksum_vlan_header {
+	u_int16_t tag;
+	u_int16_t etype;
+};
+
+#endif /* _NETGRAPH_NG_CHECKSUM_H_ */


Property changes on: trunk/sys/netgraph/ng_checksum.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: svn:keywords
## -0,0 +1 ##
+MidnightBSD=%H
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+text/plain
\ No newline at end of property
Modified: trunk/sys/netgraph/ng_cisco.c
===================================================================
--- trunk/sys/netgraph/ng_cisco.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_cisco.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_cisco.c 243882 2012-12-05 08:04:20Z glebius $
  * $Whistle: ng_cisco.c,v 1.25 1999/11/01 09:24:51 julian Exp $
  */
 
@@ -360,12 +360,13 @@
 
 	/* OK so it came from a protocol, heading out. Prepend general data
 	   packet header. For now, IP,IPX only  */
-	m = NGI_M(item); /* still associated with item */
-	M_PREPEND(m, CISCO_HEADER_LEN, M_DONTWAIT);
+	NGI_GET_M(item, m);
+	M_PREPEND(m, CISCO_HEADER_LEN, M_NOWAIT);
 	if (!m) {
 		error = ENOBUFS;
 		goto out;
 	}
+	NGI_M(item) = m;
 	h = mtod(m, struct cisco_header *);
 	h->address = CISCO_UNICAST;
 	h->control = 0;
@@ -608,7 +609,7 @@
 
 	getmicrouptime(&time);
 
-	MGETHDR(m, M_DONTWAIT, MT_DATA);
+	MGETHDR(m, M_NOWAIT, MT_DATA);
 	if (!m)
 		return (ENOBUFS);
 

Modified: trunk/sys/netgraph/ng_cisco.h
===================================================================
--- trunk/sys/netgraph/ng_cisco.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_cisco.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_cisco.h 231543 2012-02-12 05:14:12Z fjoe $
  * $Whistle: ng_cisco.h,v 1.6 1999/01/25 01:21:48 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_deflate.c
===================================================================
--- trunk/sys/netgraph/ng_deflate.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_deflate.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_deflate.c 243882 2012-12-05 08:04:20Z glebius $
  */
 
 /*
@@ -463,7 +463,7 @@
 	}
 
 	/* We must own the mbuf chain exclusively to modify it. */
-	m = m_unshare(m, M_DONTWAIT);
+	m = m_unshare(m, M_NOWAIT);
 	if (m == NULL) {
 		priv->stats.Errors++;
 		return (ENOMEM);
@@ -557,7 +557,7 @@
 	}
 
 	/* We must own the mbuf chain exclusively to modify it. */
-	m = m_unshare(m, M_DONTWAIT);
+	m = m_unshare(m, M_NOWAIT);
 	if (m == NULL) {
 		priv->stats.Errors++;
 		return (ENOMEM);

Modified: trunk/sys/netgraph/ng_deflate.h
===================================================================
--- trunk/sys/netgraph/ng_deflate.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_deflate.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_deflate.h 165581 2006-12-28 15:44:05Z glebius $
  */
 
 #ifndef _NETGRAPH_NG_DEFLATE_H_

Modified: trunk/sys/netgraph/ng_device.c
===================================================================
--- trunk/sys/netgraph/ng_device.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_device.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -28,7 +28,7 @@
  * This node presents a /dev/ngd%d device that interfaces to an other
  * netgraph node.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_device.c 243882 2012-12-05 08:04:20Z glebius $
  *
  */
 
@@ -466,7 +466,7 @@
 	if (uio->uio_resid < 0 || uio->uio_resid > IP_MAXPACKET)
 		return (EIO);
 
-	if ((m = m_uiotombuf(uio, M_DONTWAIT, 0, 0, M_PKTHDR)) == NULL)
+	if ((m = m_uiotombuf(uio, M_NOWAIT, 0, 0, M_PKTHDR)) == NULL)
 		return (ENOBUFS);
 
 	NG_SEND_DATA_ONLY(error, priv->hook, m);

Modified: trunk/sys/netgraph/ng_device.h
===================================================================
--- trunk/sys/netgraph/ng_device.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_device.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -23,7 +23,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_device.h 139823 2005-01-07 01:45:51Z imp $
  *
  */
 

Modified: trunk/sys/netgraph/ng_echo.c
===================================================================
--- trunk/sys/netgraph/ng_echo.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_echo.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Julian Elisher <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_echo.c 145101 2005-04-15 10:14:00Z glebius $
  * $Whistle: ng_echo.c,v 1.13 1999/11/01 09:24:51 julian Exp $
  */
 

Modified: trunk/sys/netgraph/ng_echo.h
===================================================================
--- trunk/sys/netgraph/ng_echo.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_echo.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_echo.h 139823 2005-01-07 01:45:51Z imp $
  * $Whistle: ng_echo.h,v 1.3 1999/01/20 00:22:12 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_eiface.c
===================================================================
--- trunk/sys/netgraph/ng_eiface.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_eiface.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_eiface.c 241686 2012-10-18 13:57:24Z andre $
  */
 
 #include <sys/param.h>
@@ -133,12 +133,11 @@
 {
 	const priv_p priv = (priv_p)ifp->if_softc;
 	struct ifreq *const ifr = (struct ifreq *)data;
-	int s, error = 0;
+	int error = 0;
 
 #ifdef DEBUG
 	ng_eiface_print_ioctl(ifp, command, data);
 #endif
-	s = splimp();
 	switch (command) {
 
 	/* These two are mostly handled at a higher layer */
@@ -194,7 +193,6 @@
 		error = EINVAL;
 		break;
 	}
-	splx(s);
 	return (error);
 }
 
@@ -203,14 +201,9 @@
 {
 	priv_p sc = xsc;
 	struct ifnet *ifp = sc->ifp;
-	int s;
 
-	s = splimp();
-
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
-
-	splx(s);
 }
 
 /*

Modified: trunk/sys/netgraph/ng_eiface.h
===================================================================
--- trunk/sys/netgraph/ng_eiface.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_eiface.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -29,7 +29,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_eiface.h 215673 2010-11-22 12:32:19Z zec $
  */
 
 #ifndef _NETGRAPH_NG_EIFACE_H_

Modified: trunk/sys/netgraph/ng_etf.c
===================================================================
--- trunk/sys/netgraph/ng_etf.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_etf.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -31,7 +31,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_etf.c 220768 2011-04-18 09:12:27Z glebius $
  */
 
 #include <sys/param.h>

Modified: trunk/sys/netgraph/ng_etf.h
===================================================================
--- trunk/sys/netgraph/ng_etf.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_etf.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -31,7 +31,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_etf.h 139823 2005-01-07 01:45:51Z imp $
  */
 
 #ifndef _NETGRAPH_NG_ETF_H_

Modified: trunk/sys/netgraph/ng_ether.c
===================================================================
--- trunk/sys/netgraph/ng_ether.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_ether.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -40,7 +40,7 @@
  * Authors: Archie Cobbs <archie at freebsd.org>
  *	    Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_ether.c 246324 2013-02-04 17:29:13Z avg $
  */
 
 /*
@@ -241,8 +241,6 @@
 /*
  * Handle a packet that has come in on an interface. We get to
  * look at it here before any upper layer protocols do.
- *
- * NOTE: this function will get called at splimp()
  */
 static void
 ng_ether_input(struct ifnet *ifp, struct mbuf **mp)
@@ -260,8 +258,6 @@
 /*
  * Handle a packet that has come in on an interface, and which
  * does not match any of our known protocols (an ``orphan'').
- *
- * NOTE: this function will get called at splimp()
  */
 static void
 ng_ether_input_orphan(struct ifnet *ifp, struct mbuf *m)
@@ -812,9 +808,7 @@
 ng_ether_mod_event(module_t mod, int event, void *data)
 {
 	int error = 0;
-	int s;
 
-	s = splnet();
 	switch (event) {
 	case MOD_LOAD:
 
@@ -861,7 +855,6 @@
 		error = EOPNOTSUPP;
 		break;
 	}
-	splx(s);
 	return (error);
 }
 

Modified: trunk/sys/netgraph/ng_ether.h
===================================================================
--- trunk/sys/netgraph/ng_ether.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_ether.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -39,7 +39,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_ether.h 141910 2005-02-14 12:01:09Z glebius $
  * $Whistle: ng_ether.h,v 1.1 1999/02/02 03:17:22 julian Exp $
  */
 

Modified: trunk/sys/netgraph/ng_ether_echo.c
===================================================================
--- trunk/sys/netgraph/ng_ether_echo.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_ether_echo.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Julian Elisher <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_ether_echo.c 186481 2008-12-25 00:01:29Z julian $
  * $Whistle: ng_echo.c,v 1.13 1999/11/01 09:24:51 julian Exp $
  */
 

Modified: trunk/sys/netgraph/ng_ether_echo.h
===================================================================
--- trunk/sys/netgraph/ng_ether_echo.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_ether_echo.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_ether_echo.h 186481 2008-12-25 00:01:29Z julian $
  * $Whistle: ng_echo.h,v 1.3 1999/01/20 00:22:12 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_fec.c
===================================================================
--- trunk/sys/netgraph/ng_fec.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_fec.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -35,7 +35,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_fec.c 249925 2013-04-26 12:50:32Z glebius $
  */
 /*-
  * Copyright (c) 1996-1999 Whistle Communications, Inc.
@@ -166,7 +166,7 @@
 	int			fec_btype;
 	int			(*fec_if_output) (struct ifnet *,
 						  struct mbuf *,
-						  struct sockaddr *,
+						  const struct sockaddr *,
 						  struct route *);
 };
 
@@ -199,7 +199,7 @@
 static void	ng_fec_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr);
 static int	ng_fec_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
 static int	ng_fec_output(struct ifnet *ifp, struct mbuf *m0,
-			struct sockaddr *dst, struct route *ro);
+			const struct sockaddr *dst, struct route *ro);
 static void	ng_fec_tick(void *arg);
 static int	ng_fec_addport(struct ng_fec_private *priv, char *iface);
 static int	ng_fec_delport(struct ng_fec_private *priv, char *iface);
@@ -754,7 +754,7 @@
 ng_fec_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
 {
 	struct ifreq *const ifr = (struct ifreq *) data;
-	int s, error = 0;
+	int error = 0;
 	struct ng_fec_private	*priv;
 	struct ng_fec_bundle	*b;
 
@@ -764,7 +764,6 @@
 #ifdef DEBUG
 	ng_fec_print_ioctl(ifp, command, data);
 #endif
-	s = splimp();
 	switch (command) {
 
 	/* These two are mostly handled at a higher layer */
@@ -844,7 +843,6 @@
 		error = EINVAL;
 		break;
 	}
-	(void) splx(s);
 	return (error);
 }
 
@@ -926,7 +924,7 @@
 
 static int
 ng_fec_output(struct ifnet *ifp, struct mbuf *m,
-		struct sockaddr *dst, struct route *ro)
+	const struct sockaddr *dst, struct route *ro)
 {
 	const priv_p priv = (priv_p) ifp->if_softc;
 	struct ng_fec_bundle *b;
@@ -1333,7 +1331,7 @@
 	}
 
 	ether_ifdetach(priv->ifp);
-	if_free_type(priv->ifp, IFT_ETHER);
+	if_free(priv->ifp);
 	ifmedia_removeall(&priv->ifmedia);
 	ng_fec_free_unit(priv->unit);
 	free(priv, M_NETGRAPH);

Modified: trunk/sys/netgraph/ng_fec.h
===================================================================
--- trunk/sys/netgraph/ng_fec.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_fec.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -35,7 +35,7 @@
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_fec.h 139823 2005-01-07 01:45:51Z imp $
  */
 /*-
  * Copyright (c) 1996-1999 Whistle Communications, Inc.

Modified: trunk/sys/netgraph/ng_frame_relay.c
===================================================================
--- trunk/sys/netgraph/ng_frame_relay.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_frame_relay.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_frame_relay.c 243882 2012-12-05 08:04:20Z glebius $
  * $Whistle: ng_frame_relay.c,v 1.20 1999/11/01 09:24:51 julian Exp $
  */
 
@@ -361,7 +361,7 @@
 	alen = sc->addrlen;
 	if (alen == 0)
 		alen = 2;	/* default value for transmit */
-	M_PREPEND(m, alen, M_DONTWAIT);
+	M_PREPEND(m, alen, M_NOWAIT);
 	if (m == NULL) {
 		error = ENOBUFS;
 		goto bad;

Modified: trunk/sys/netgraph/ng_frame_relay.h
===================================================================
--- trunk/sys/netgraph/ng_frame_relay.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_frame_relay.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_frame_relay.h 139823 2005-01-07 01:45:51Z imp $
  * $Whistle: ng_frame_relay.h,v 1.7 1999/01/20 00:22:13 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_gif.c
===================================================================
--- trunk/sys/netgraph/ng_gif.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_gif.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -63,7 +63,7 @@
  * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
  * OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_gif.c 243882 2012-12-05 08:04:20Z glebius $
  */
 
 /*
@@ -164,8 +164,6 @@
 /*
  * Handle a packet that has come in on an interface. We get to
  * look at it here before any upper layer protocols do.
- *
- * NOTE: this function will get called at splimp()
  */
 static void
 ng_gif_input(struct ifnet *ifp, struct mbuf **mp, int af)
@@ -182,8 +180,6 @@
 /*
  * Handle a packet that has come in on an interface, and which
  * does not match any of our known protocols (an ``orphan'').
- *
- * NOTE: this function will get called at splimp()
  */
 static void
 ng_gif_input_orphan(struct ifnet *ifp, struct mbuf *m, int af)
@@ -204,8 +200,6 @@
 /*
  * Handle a packet that has come in on a gif interface.
  * Attach the address family to the mbuf for later use.
- *
- * NOTE: this function will get called at splimp()
  */
 static void
 ng_gif_input2(node_p node, struct mbuf **mp, int af)
@@ -310,7 +304,7 @@
 	 * hopefully everything after that will not
 	 * need one. So let's just use M_PREPEND.
 	 */
-	M_PREPEND(m, sizeof (tmp_af), M_DONTWAIT);
+	M_PREPEND(m, sizeof (tmp_af), M_NOWAIT);
 	if (m == NULL) {
 		error = ENOBUFS;
 		goto done;
@@ -544,9 +538,7 @@
 	VNET_ITERATOR_DECL(vnet_iter);
 	struct ifnet *ifp;
 	int error = 0;
-	int s;
 
-	s = splnet();
 	switch (event) {
 	case MOD_LOAD:
 
@@ -598,7 +590,6 @@
 		error = EOPNOTSUPP;
 		break;
 	}
-	splx(s);
 	return (error);
 }
 

Modified: trunk/sys/netgraph/ng_gif.h
===================================================================
--- trunk/sys/netgraph/ng_gif.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_gif.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -63,7 +63,7 @@
  * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
  * OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_gif.h 139823 2005-01-07 01:45:51Z imp $
  */
 
 #ifndef _NETGRAPH_NG_GIF_H_

Modified: trunk/sys/netgraph/ng_gif_demux.c
===================================================================
--- trunk/sys/netgraph/ng_gif_demux.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_gif_demux.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -63,7 +63,7 @@
  * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
  * OF SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_gif_demux.c 243882 2012-12-05 08:04:20Z glebius $
  */
 
 /*
@@ -342,7 +342,7 @@
 		 * Add address family header and set the output hook.
 		 */
 		iffam = get_iffam_from_hook(priv, hook);
-		M_PREPEND(m, sizeof (iffam->family), M_DONTWAIT);
+		M_PREPEND(m, sizeof (iffam->family), M_NOWAIT);
 		if (m == NULL) {
 			NG_FREE_M(m);
 			NG_FREE_ITEM(item);

Modified: trunk/sys/netgraph/ng_gif_demux.h
===================================================================
--- trunk/sys/netgraph/ng_gif_demux.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_gif_demux.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -30,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_gif_demux.h 139823 2005-01-07 01:45:51Z imp $
  */
 
 #ifndef _NETGRAPH_NG_GIF_DEMUX_H_

Modified: trunk/sys/netgraph/ng_hole.c
===================================================================
--- trunk/sys/netgraph/ng_hole.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_hole.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Julian Elisher <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_hole.c 184205 2008-10-23 15:53:51Z des $
  * $Whistle: ng_hole.c,v 1.10 1999/11/01 09:24:51 julian Exp $
  */
 

Modified: trunk/sys/netgraph/ng_hole.h
===================================================================
--- trunk/sys/netgraph/ng_hole.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_hole.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_hole.h 139823 2005-01-07 01:45:51Z imp $
  * $Whistle: ng_hole.h,v 1.3 1999/01/20 00:22:13 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_hub.c
===================================================================
--- trunk/sys/netgraph/ng_hub.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_hub.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_hub.c 243882 2012-12-05 08:04:20Z glebius $
  */
 
 #include <sys/param.h>
@@ -134,7 +134,7 @@
 		if (--nhooks == 1)
 			NG_FWD_ITEM_HOOK(error, item, hook2);
 		else {
-			if ((m2 = m_dup(m, M_DONTWAIT)) == NULL) {
+			if ((m2 = m_dup(m, M_NOWAIT)) == NULL) {
 				NG_FREE_ITEM(item);
 				return (ENOBUFS);
 			}

Modified: trunk/sys/netgraph/ng_hub.h
===================================================================
--- trunk/sys/netgraph/ng_hub.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_hub.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_hub.h 207680 2010-05-05 22:06:05Z zec $
  */
 
 #ifndef _NETGRAPH_NG_HUB_H_

Modified: trunk/sys/netgraph/ng_iface.c
===================================================================
--- trunk/sys/netgraph/ng_iface.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_iface.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_iface.c 324176 2017-10-01 19:40:29Z eugen $
  * $Whistle: ng_iface.c,v 1.33 1999/11/01 09:24:51 julian Exp $
  */
 
@@ -62,11 +62,13 @@
 #include <sys/systm.h>
 #include <sys/errno.h>
 #include <sys/kernel.h>
+#include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/errno.h>
 #include <sys/proc.h>
 #include <sys/random.h>
+#include <sys/rmlock.h>
 #include <sys/sockio.h>
 #include <sys/socket.h>
 #include <sys/syslog.h>
@@ -117,14 +119,20 @@
 	int	unit;			/* Interface unit number */
 	node_p	node;			/* Our netgraph node */
 	hook_p	hooks[NUM_FAMILIES];	/* Hook for each address family */
+	struct rmlock	lock;		/* Protect private data changes */
 };
 typedef struct ng_iface_private *priv_p;
 
+#define	PRIV_RLOCK(priv, t)	rm_rlock(&priv->lock, t)
+#define	PRIV_RUNLOCK(priv, t)	rm_runlock(&priv->lock, t)
+#define	PRIV_WLOCK(priv)	rm_wlock(&priv->lock)
+#define	PRIV_WUNLOCK(priv)	rm_wunlock(&priv->lock)
+
 /* Interface methods */
 static void	ng_iface_start(struct ifnet *ifp);
 static int	ng_iface_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
 static int	ng_iface_output(struct ifnet *ifp, struct mbuf *m0,
-    			struct sockaddr *dst, struct route *ro);
+    			const struct sockaddr *dst, struct route *ro);
 static void	ng_iface_bpftap(struct ifnet *ifp,
 			struct mbuf *m, sa_family_t family);
 static int	ng_iface_send(struct ifnet *ifp, struct mbuf *m,
@@ -354,7 +362,7 @@
 
 static int
 ng_iface_output(struct ifnet *ifp, struct mbuf *m,
-    		struct sockaddr *dst, struct route *ro)
+	const struct sockaddr *dst, struct route *ro)
 {
 	struct m_tag *mtag;
 	uint32_t af;
@@ -386,16 +394,16 @@
 	m_tag_prepend(m, mtag);
 
 	/* BPF writes need to be handled specially. */
-	if (dst->sa_family == AF_UNSPEC) {
+	if (dst->sa_family == AF_UNSPEC)
 		bcopy(dst->sa_data, &af, sizeof(af));
-		dst->sa_family = af;
-	}
+	else
+		af = dst->sa_family;
 
 	/* Berkeley packet filter */
-	ng_iface_bpftap(ifp, m, dst->sa_family);
+	ng_iface_bpftap(ifp, m, af);
 
 	if (ALTQ_IS_ENABLED(&ifp->if_snd)) {
-		M_PREPEND(m, sizeof(sa_family_t), M_DONTWAIT);
+		M_PREPEND(m, sizeof(sa_family_t), M_NOWAIT);
 		if (m == NULL) {
 			IFQ_LOCK(&ifp->if_snd);
 			IFQ_INC_DROPS(&ifp->if_snd);
@@ -403,10 +411,10 @@
 			ifp->if_oerrors++;
 			return (ENOBUFS);
 		}
-		*(sa_family_t *)m->m_data = dst->sa_family;
+		*(sa_family_t *)m->m_data = af;
 		error = (ifp->if_transmit)(ifp, m);
 	} else
-		error = ng_iface_send(ifp, m, dst->sa_family);
+		error = ng_iface_send(ifp, m, af);
 
 	return (error);
 }
@@ -454,8 +462,10 @@
 static int
 ng_iface_send(struct ifnet *ifp, struct mbuf *m, sa_family_t sa)
 {
+	struct rm_priotracker priv_tracker;
 	const priv_p priv = (priv_p) ifp->if_softc;
 	const iffam_p iffam = get_iffam_from_af(sa);
+	hook_p hook;
 	int error;
 	int len;
 
@@ -469,10 +479,20 @@
 	/* Copy length before the mbuf gets invalidated. */
 	len = m->m_pkthdr.len;
 
-	/* Send packet. If hook is not connected, mbuf will get freed. */
+	PRIV_RLOCK(priv, &priv_tracker);
+	hook = *get_hook_from_iffam(priv, iffam);
+	if (hook == NULL) {
+		NG_FREE_M(m);
+		PRIV_RUNLOCK(priv, &priv_tracker);
+		return ENETDOWN;
+	}
+	NG_HOOK_REF(hook);
+	PRIV_RUNLOCK(priv, &priv_tracker);
+
 	NG_OUTBOUND_THREAD_REF();
-	NG_SEND_DATA_ONLY(error, *get_hook_from_iffam(priv, iffam), m);
+	NG_SEND_DATA_ONLY(error, hook, m);
 	NG_OUTBOUND_THREAD_UNREF();
+	NG_HOOK_UNREF(hook);
 
 	/* Update stats. */
 	if (error == 0) {
@@ -539,6 +559,8 @@
 		return (ENOMEM);
 	}
 
+	rm_init(&priv->lock, "ng_iface private rmlock");
+
 	/* Link them together */
 	ifp->if_softc = priv;
 	priv->ifp = ifp;
@@ -585,16 +607,21 @@
 ng_iface_newhook(node_p node, hook_p hook, const char *name)
 {
 	const iffam_p iffam = get_iffam_from_name(name);
+	const priv_p priv = NG_NODE_PRIVATE(node);
 	hook_p *hookptr;
 
 	if (iffam == NULL)
 		return (EPFNOSUPPORT);
-	hookptr = get_hook_from_iffam(NG_NODE_PRIVATE(node), iffam);
-	if (*hookptr != NULL)
+	PRIV_WLOCK(priv);
+	hookptr = get_hook_from_iffam(priv, iffam);
+	if (*hookptr != NULL) {
+		PRIV_WUNLOCK(priv);
 		return (EISCONN);
+	}
 	*hookptr = hook;
 	NG_HOOK_HI_STACK(hook);
 	NG_HOOK_SET_TO_INBOUND(hook);
+	PRIV_WUNLOCK(priv);
 	return (0);
 }
 
@@ -775,9 +802,8 @@
 		m_freem(m);
 		return (EAFNOSUPPORT);
 	}
-	/* First chunk of an mbuf contains good junk */
 	if (harvest.point_to_point)
-		random_harvest(m, 16, 3, 0, RANDOM_NET);
+		random_harvest(&(m->m_data), 12, 2, RANDOM_NET_NG);
 	M_SETFIB(m, ifp->if_fib);
 	netisr_dispatch(isr, m);
 	return (0);
@@ -802,6 +828,7 @@
 	CURVNET_RESTORE();
 	priv->ifp = NULL;
 	free_unr(V_ng_iface_unit, priv->unit);
+	rm_destroy(&priv->lock);
 	free(priv, M_NETGRAPH_IFACE);
 	NG_NODE_SET_PRIVATE(node, NULL);
 	NG_NODE_UNREF(node);
@@ -820,7 +847,9 @@
 
 	if (iffam == NULL)
 		panic("%s", __func__);
+	PRIV_WLOCK(priv);
 	*get_hook_from_iffam(priv, iffam) = NULL;
+	PRIV_WUNLOCK(priv);
 	return (0);
 }
 

Modified: trunk/sys/netgraph/ng_iface.h
===================================================================
--- trunk/sys/netgraph/ng_iface.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_iface.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_iface.h 187495 2009-01-20 22:26:09Z mav $
  * $Whistle: ng_iface.h,v 1.5 1999/01/20 00:22:13 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_ip_input.c
===================================================================
--- trunk/sys/netgraph/ng_ip_input.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_ip_input.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -65,7 +65,7 @@
  * Author:		Brooks Davis <brooks at FreeBSD.org>
  * Derived from:	ng_hole.c
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_ip_input.c 194012 2009-06-11 16:50:49Z zec $
  */
 
 /*

Modified: trunk/sys/netgraph/ng_ip_input.h
===================================================================
--- trunk/sys/netgraph/ng_ip_input.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_ip_input.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -65,7 +65,7 @@
  * Author:		Brooks Davis <brooks at FreeBSD.org>
  * Derived from:	ng_hole.h
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_ip_input.h 139823 2005-01-07 01:45:51Z imp $
  */
 
 #ifndef _NETGRAPH_NG_IP_INPUT_H_

Modified: trunk/sys/netgraph/ng_ipfw.c
===================================================================
--- trunk/sys/netgraph/ng_ipfw.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_ipfw.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_ipfw.c 243882 2012-12-05 08:04:20Z glebius $
  */
 
 #include "opt_inet.h"
@@ -196,7 +196,7 @@
 }
 
 /* Look up hook by name */
-hook_p
+static hook_p
 ng_ipfw_findhook(node_p node, const char *name)
 {
 	u_int16_t n;	/* numeric representation of hook */
@@ -244,7 +244,7 @@
 
 	if (m->m_len < sizeof(struct ip) &&
 	    (m = m_pullup(m, sizeof(struct ip))) == NULL)
-		return (EINVAL);
+		return (ENOBUFS);
 
 	ip = mtod(m, struct ip *);
 
@@ -254,23 +254,18 @@
 #ifdef INET
 		case IPVERSION:
 			ip_input(m);
-			break;
+			return (0);
 #endif
 #ifdef INET6
 		case IPV6_VERSION >> 4:
 			ip6_input(m);
-			break;
+			return (0);
 #endif
-		default:
-			NG_FREE_M(m);
-			return (EINVAL);
 		}
-		return (0);
 	} else {
 		switch (ip->ip_v) {
 #ifdef INET
 		case IPVERSION:
-			SET_HOST_IPLEN(ip);
 			return (ip_output(m, NULL, NULL, IP_FORWARDING,
 			    NULL, NULL));
 #endif
@@ -279,10 +274,12 @@
 			return (ip6_output(m, NULL, NULL, 0, NULL,
 			    NULL, NULL));
 #endif
-		default:
-			return (EINVAL);
 		}
 	}
+
+	/* unknown IP protocol version */
+	NG_FREE_M(m);
+	return (EPROTONOSUPPORT);
 }
 
 static int
@@ -324,7 +321,7 @@
 		m_tag_prepend(m, tag);
 
 	} else
-		if ((m = m_dup(*m0, M_DONTWAIT)) == NULL)
+		if ((m = m_dup(*m0, M_NOWAIT)) == NULL)
 			return (ENOMEM);	/* which is ignored */
 
 	if (m->m_len < sizeof(struct ip) &&

Modified: trunk/sys/netgraph/ng_ipfw.h
===================================================================
--- trunk/sys/netgraph/ng_ipfw.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_ipfw.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_ipfw.h 201124 2009-12-28 12:29:13Z luigi $
  */
 
 #ifndef _NG_IPFW_H

Modified: trunk/sys/netgraph/ng_ksocket.c
===================================================================
--- trunk/sys/netgraph/ng_ksocket.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_ksocket.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_ksocket.c 260226 2014-01-03 12:28:33Z glebius $
  * $Whistle: ng_ksocket.c,v 1.1 1999/11/16 20:04:40 archie Exp $
  */
 
@@ -67,6 +67,7 @@
 #include <netgraph/ng_ksocket.h>
 
 #include <netinet/in.h>
+#include <netinet/ip.h>
 #include <netatalk/at.h>
 
 #ifdef NG_SEPARATE_MALLOC
@@ -224,7 +225,7 @@
 	/* Get socket address family followed by a slash */
 	while (isspace(s[*off]))
 		(*off)++;
-	if ((t = index(s + *off, '/')) == NULL)
+	if ((t = strchr(s + *off, '/')) == NULL)
 		return (EINVAL);
 	if ((len = t - (s + *off)) > sizeof(fambuf) - 1)
 		return (EINVAL);
@@ -525,7 +526,9 @@
 	priv_p priv;
 
 	/* Allocate private structure */
-	priv = malloc(sizeof(*priv), M_NETGRAPH_KSOCKET, M_WAITOK | M_ZERO);
+	priv = malloc(sizeof(*priv), M_NETGRAPH_KSOCKET, M_NOWAIT | M_ZERO);
+	if (priv == NULL)
+		return (ENOMEM);
 
 	LIST_INIT(&priv->embryos);
 	/* cross link them */
@@ -566,7 +569,7 @@
 		/* Extract family, type, and protocol from hook name */
 		snprintf(name, sizeof(name), "%s", name0);
 		s1 = name;
-		if ((s2 = index(s1, '/')) == NULL)
+		if ((s2 = strchr(s1, '/')) == NULL)
 			return (EINVAL);
 		*s2++ = '\0';
 		family = ng_ksocket_parse(ng_ksocket_families, s1, 0);
@@ -573,7 +576,7 @@
 		if (family == -1)
 			return (EINVAL);
 		s1 = s2;
-		if ((s2 = index(s1, '/')) == NULL)
+		if ((s2 = strchr(s1, '/')) == NULL)
 			return (EINVAL);
 		*s2++ = '\0';
 		type = ng_ksocket_parse(ng_ksocket_types, s1, 0);
@@ -646,7 +649,7 @@
 	 * This is a bad byproduct of the complicated way in which hooks
 	 * are now created (3 daisy chained async events).
 	 *
-	 * Since we are a netgraph operation 
+	 * Since we are a netgraph operation
 	 * We know that we hold a lock on this node. This forces the
 	 * request we make below to be queued rather than implemented
 	 * immediatly which will cause the upcall function to be called a bit
@@ -786,7 +789,7 @@
 			/* Get function */
 			if (msg->header.cmd == NGM_KSOCKET_GETPEERNAME) {
 				if ((so->so_state
-				    & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0) 
+				    & (SS_ISCONNECTED|SS_ISCONFIRMING)) == 0)
 					ERROUT(ENOTCONN);
 				func = so->so_proto->pr_usrreqs->pru_peeraddr;
 			} else
@@ -814,7 +817,7 @@
 
 		case NGM_KSOCKET_GETOPT:
 		    {
-			struct ng_ksocket_sockopt *ksopt = 
+			struct ng_ksocket_sockopt *ksopt =
 			    (struct ng_ksocket_sockopt *)msg->data;
 			struct sockopt sopt;
 
@@ -851,7 +854,7 @@
 
 		case NGM_KSOCKET_SETOPT:
 		    {
-			struct ng_ksocket_sockopt *const ksopt = 
+			struct ng_ksocket_sockopt *const ksopt =
 			    (struct ng_ksocket_sockopt *)msg->data;
 			const int valsize = msg->header.arglen - sizeof(*ksopt);
 			struct sockopt sopt;
@@ -996,11 +999,11 @@
 /************************************************************************
 			HELPER STUFF
  ************************************************************************/
-/* 
+/*
  * You should not "just call" a netgraph node function from an external
  * asynchronous event. This is because in doing so you are ignoring the
  * locking on the netgraph nodes. Instead call your function via ng_send_fn().
- * This will call the function you chose, but will first do all the 
+ * This will call the function you chose, but will first do all the
  * locking rigmarole. Your function MAY only be called at some distant future
  * time (several millisecs away) so don't give it any arguments
  * that may be revoked soon (e.g. on your stack).
@@ -1032,7 +1035,7 @@
 /*
  * When incoming data is appended to the socket, we get notified here.
  * This is also called whenever a significant event occurs for the socket.
- * Our original caller may have queued this even some time ago and 
+ * Our original caller may have queued this even some time ago and
  * we cannot trust that he even still exists. The node however is being
  * held with a reference by the queueing code and guarantied to be valid.
  */
@@ -1041,16 +1044,11 @@
 {
 	struct socket *so = arg1;
 	const priv_p priv = NG_NODE_PRIVATE(node);
-	struct mbuf *m;
 	struct ng_mesg *response;
-	struct uio auio;
-	int s, flags, error;
+	int error;
 
-	s = splnet();
+	KASSERT(so == priv->so, ("%s: wrong socket", __func__));
 
-	/* so = priv->so; *//* XXX could have derived this like so */
-	KASSERT(so == priv->so, ("%s: wrong socket", __func__));
-	
 	/* Allow next incoming event to be queued. */
 	atomic_store_rel_int(&priv->fn_sent, 0);
 
@@ -1067,7 +1065,7 @@
 				response->header.flags |= NGF_RESP;
 				response->header.token = priv->response_token;
 				*(int32_t *)response->data = error;
-				/* 
+				/*
 				 * send an async "response" message
 				 * to the node that set us up
 				 * (if it still exists)
@@ -1093,25 +1091,30 @@
 	 * the hook gets created and is connected, this upcall function
 	 * will be called again.
 	 */
-	if (priv->hook == NULL) {
-		splx(s);
+	if (priv->hook == NULL)
 		return;
-	}
 
-	/* Read and forward available mbuf's */
-	auio.uio_td = NULL;
-	auio.uio_resid = 1000000000;
-	flags = MSG_DONTWAIT;
+	/* Read and forward available mbufs. */
 	while (1) {
-		struct sockaddr *sa = NULL;
-		struct mbuf *n;
+		struct uio uio;
+		struct sockaddr *sa;
+		struct mbuf *m;
+		int flags;
 
-		/* Try to get next packet from socket */
+		/* Try to get next packet from socket. */
+		uio.uio_td = NULL;
+		uio.uio_resid = IP_MAXPACKET;
+		flags = MSG_DONTWAIT;
+		sa = NULL;
 		if ((error = soreceive(so, (so->so_state & SS_ISCONNECTED) ?
-		    NULL : &sa, &auio, &m, (struct mbuf **)0, &flags)) != 0)
+		    NULL : &sa, &uio, &m, NULL, &flags)) != 0)
 			break;
 
-		/* See if we got anything */
+		/* See if we got anything. */
+		if (flags & MSG_TRUNC) {
+			m_freem(m);
+			m = NULL;
+		}
 		if (m == NULL) {
 			if (sa != NULL)
 				free(sa, M_SONAME);
@@ -1118,17 +1121,28 @@
 			break;
 		}
 
+		KASSERT(m->m_nextpkt == NULL, ("%s: nextpkt", __func__));
+
 		/*
-		 * Don't trust the various socket layers to get the
-		 * packet header and length correct (e.g. kern/15175).
-		 *
-		 * Also, do not trust that soreceive() will clear m_nextpkt
-		 * for us (e.g. kern/84952, kern/82413).
+		 * Stream sockets do not have packet boundaries, so
+		 * we have to allocate a header mbuf and attach the
+		 * stream of data to it.
 		 */
-		m->m_pkthdr.csum_flags = 0;
-		for (n = m, m->m_pkthdr.len = 0; n != NULL; n = n->m_next) {
-			m->m_pkthdr.len += n->m_len;
-			n->m_nextpkt = NULL;
+		if (so->so_type == SOCK_STREAM) {
+			struct mbuf *mh;
+
+			mh = m_gethdr(M_NOWAIT, MT_DATA);
+			if (mh == NULL) {
+				m_freem(m);
+				if (sa != NULL)
+					free(sa, M_SONAME);
+				break;
+			}
+
+			mh->m_next = m;
+			for (; m; m = m->m_next)
+				mh->m_pkthdr.len += m->m_len;
+			m = mh;
 		}
 
 		/* Put peer's socket address (if any) into a tag */
@@ -1156,15 +1170,15 @@
 	 * If the peer has closed the connection, forward a 0-length mbuf
 	 * to indicate end-of-file.
 	 */
-	if (so->so_rcv.sb_state & SBS_CANTRCVMORE && !(priv->flags & KSF_EOFSEEN)) {
-		MGETHDR(m, M_NOWAIT, MT_DATA);
-		if (m != NULL) {
-			m->m_len = m->m_pkthdr.len = 0;
+	if (so->so_rcv.sb_state & SBS_CANTRCVMORE &&
+	    !(priv->flags & KSF_EOFSEEN)) {
+		struct mbuf *m;
+
+		m = m_gethdr(M_NOWAIT, MT_DATA);
+		if (m != NULL)
 			NG_SEND_DATA_ONLY(error, priv->hook, m);
-		}
 		priv->flags |= KSF_EOFSEEN;
 	}
-	splx(s);
 }
 
 /*
@@ -1241,8 +1255,8 @@
 	resp->header.token = priv->response_token;
 
 	/* Clone a ksocket node to wrap the new socket */
-        error = ng_make_node_common(&ng_ksocket_typestruct, &node);
-        if (error) {
+	error = ng_make_node_common(&ng_ksocket_typestruct, &node);
+	if (error) {
 		free(resp, M_NETGRAPH);
 		soclose(so);
 		goto out;

Modified: trunk/sys/netgraph/ng_ksocket.h
===================================================================
--- trunk/sys/netgraph/ng_ksocket.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_ksocket.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_ksocket.h 151800 2005-10-28 14:41:28Z ru $
  * $Whistle: ng_ksocket.h,v 1.1 1999/11/16 20:04:40 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_l2tp.c
===================================================================
--- trunk/sys/netgraph/ng_l2tp.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_l2tp.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -37,7 +37,7 @@
  * 
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_l2tp.c 261009 2014-01-22 09:22:39Z glebius $
  */
 
 /*
@@ -99,7 +99,7 @@
 #define L2TP_ENABLE_DSEQ	1			/* enable data seq # */
 
 /* Compare sequence numbers using circular math */
-#define L2TP_SEQ_DIFF(x, y)	((int)((int16_t)(x) - (int16_t)(y)))
+#define L2TP_SEQ_DIFF(x, y)	((int16_t)((x) - (y)))
 
 #define SESSHASHSIZE		0x0020
 #define SESSHASH(x)		(((x) ^ ((x) >> 8)) & (SESSHASHSIZE - 1))
@@ -935,7 +935,7 @@
 		mtx_unlock(&seq->mtx);
 
 		/* Prepend session ID to packet. */
-		M_PREPEND(m, 2, M_DONTWAIT);
+		M_PREPEND(m, 2, M_NOWAIT);
 		if (m == NULL) {
 			seq->inproc = 0;
 			priv->stats.memoryFailures++;
@@ -1072,7 +1072,7 @@
 	mtx_unlock(&seq->mtx);
 
 	/* Copy packet */
-	if ((m = L2TP_COPY_MBUF(m, M_DONTWAIT)) == NULL) {
+	if ((m = L2TP_COPY_MBUF(m, M_NOWAIT)) == NULL) {
 		priv->stats.memoryFailures++;
 		ERROUT(ENOBUFS);
 	}
@@ -1123,7 +1123,7 @@
 	M_PREPEND(m, 6
 	    + (2 * (hpriv->conf.include_length != 0))
 	    + (4 * (hpriv->conf.enable_dseq != 0)),
-	    M_DONTWAIT);
+	    M_NOWAIT);
 	if (m == NULL) {
 		priv->stats.memoryFailures++;
 		NG_FREE_ITEM(item);
@@ -1407,7 +1407,7 @@
 	 */
 	for (i = 0; i < j; i++) {
 		struct mbuf 	*m;
-		if ((m = L2TP_COPY_MBUF(xwin[i], M_DONTWAIT)) == NULL)
+		if ((m = L2TP_COPY_MBUF(xwin[i], M_NOWAIT)) == NULL)
 			priv->stats.memoryFailures++;
 		else
 			ng_l2tp_xmit_ctrl(priv, m, ns);
@@ -1483,7 +1483,7 @@
 	seq->acks = 0;
 
 	/* Retransmit oldest unack'd packet */
-	if ((m = L2TP_COPY_MBUF(seq->xwin[0], M_DONTWAIT)) == NULL)
+	if ((m = L2TP_COPY_MBUF(seq->xwin[0], M_NOWAIT)) == NULL)
 		priv->stats.memoryFailures++;
 	else
 		ng_l2tp_xmit_ctrl(priv, m, seq->ns++);
@@ -1522,7 +1522,7 @@
 	if (m == NULL) {
 
 		/* Create a new mbuf for ZLB packet */
-		MGETHDR(m, M_DONTWAIT, MT_DATA);
+		MGETHDR(m, M_NOWAIT, MT_DATA);
 		if (m == NULL) {
 			priv->stats.memoryFailures++;
 			return (ENOBUFS);
@@ -1540,7 +1540,7 @@
 		session_id = (mtod(m, u_int8_t *)[0] << 8) + mtod(m, u_int8_t *)[1];
 
 		/* Make room for L2TP header */
-		M_PREPEND(m, 10, M_DONTWAIT);	/* - 2 + 12 = 10 */
+		M_PREPEND(m, 10, M_NOWAIT);	/* - 2 + 12 = 10 */
 		if (m == NULL) {
 			priv->stats.memoryFailures++;
 			return (ENOBUFS);

Modified: trunk/sys/netgraph/ng_l2tp.h
===================================================================
--- trunk/sys/netgraph/ng_l2tp.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_l2tp.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -37,7 +37,7 @@
  * 
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_l2tp.h 139823 2005-01-07 01:45:51Z imp $
  */
 
 #ifndef _NETGRAPH_NG_L2TP_H_

Modified: trunk/sys/netgraph/ng_lmi.c
===================================================================
--- trunk/sys/netgraph/ng_lmi.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_lmi.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_lmi.c 243882 2012-12-05 08:04:20Z glebius $
  * $Whistle: ng_lmi.c,v 1.38 1999/11/01 09:24:52 julian Exp $
  */
 
@@ -318,7 +318,7 @@
 
 	if (sc->lmi_channel == NULL)
 		return;
-	MGETHDR(m, M_DONTWAIT, MT_DATA);
+	MGETHDR(m, M_NOWAIT, MT_DATA);
 	if (m == NULL) {
 		log(LOG_ERR, "nglmi: unable to start up LMI processing\n");
 		return;

Modified: trunk/sys/netgraph/ng_lmi.h
===================================================================
--- trunk/sys/netgraph/ng_lmi.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_lmi.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_lmi.h 139823 2005-01-07 01:45:51Z imp $
  * $Whistle: ng_lmi.h,v 1.9 1999/01/20 00:22:13 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_message.h
===================================================================
--- trunk/sys/netgraph/ng_message.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_message.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_message.h 193812 2009-06-09 07:07:20Z imp $
  * $Whistle: ng_message.h,v 1.12 1999/01/25 01:17:44 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_mppc.c
===================================================================
--- trunk/sys/netgraph/ng_mppc.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_mppc.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -39,7 +39,7 @@
  * Author: Archie Cobbs <archie at freebsd.org>
  *
  * $Whistle: ng_mppc.c,v 1.4 1999/11/25 00:10:12 archie Exp $
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_mppc.c 312657 2017-01-23 01:21:39Z pfg $
  */
 
 /*
@@ -56,6 +56,7 @@
 #include <sys/malloc.h>
 #include <sys/endian.h>
 #include <sys/errno.h>
+#include <sys/sysctl.h>
 #include <sys/syslog.h>
 
 #include <netgraph/ng_message.h>
@@ -66,7 +67,7 @@
 
 #if !defined(NETGRAPH_MPPC_COMPRESSION) && !defined(NETGRAPH_MPPC_ENCRYPTION)
 #ifdef KLD_MODULE
-/* XXX NETGRAPH_MPPC_COMPRESSION isn't functional yet */
+#define NETGRAPH_MPPC_COMPRESSION
 #define NETGRAPH_MPPC_ENCRYPTION
 #else
 /* This case is indicative of an error in sys/conf files */
@@ -81,7 +82,6 @@
 #endif
 
 #ifdef NETGRAPH_MPPC_COMPRESSION
-/* XXX this file doesn't exist yet, but hopefully someday it will... */
 #include <net/mppc.h>
 #endif
 #ifdef NETGRAPH_MPPC_ENCRYPTION
@@ -108,6 +108,23 @@
  */
 #define MPPE_MAX_REKEY		1000
 
+SYSCTL_NODE(_net_graph, OID_AUTO, mppe, CTLFLAG_RW, 0, "MPPE");
+
+static int mppe_block_on_max_rekey = 0;
+TUNABLE_INT("net.graph.mppe.block_on_max_rekey", &mppe_block_on_max_rekey);
+SYSCTL_INT(_net_graph_mppe, OID_AUTO, block_on_max_rekey, CTLFLAG_RW,
+    &mppe_block_on_max_rekey, 0, "Block node on max MPPE key re-calculations");
+
+static int mppe_log_max_rekey = 1;
+TUNABLE_INT("net.graph.mppe.log_max_rekey", &mppe_log_max_rekey);
+SYSCTL_INT(_net_graph_mppe, OID_AUTO, log_max_rekey, CTLFLAG_RW,
+    &mppe_log_max_rekey, 0, "Log max MPPE key re-calculations event");
+
+static int mppe_max_rekey = MPPE_MAX_REKEY;
+TUNABLE_INT("net.graph.mppe.max_rekey", &mppe_max_rekey);
+SYSCTL_INT(_net_graph_mppe, OID_AUTO, max_rekey, CTLFLAG_RW,
+    &mppe_max_rekey, 0, "Maximum number of MPPE key re-calculations");
+
 /* MPPC packet header bits */
 #define MPPC_FLAG_FLUSHED	0x8000		/* xmitter reset state */
 #define MPPC_FLAG_RESTART	0x4000		/* compress history restart */
@@ -468,7 +485,7 @@
 	struct mbuf *m = *datap;
 
 	/* We must own the mbuf chain exclusively to modify it. */
-	m = m_unshare(m, M_DONTWAIT);
+	m = m_unshare(m, M_NOWAIT);
 	if (m == NULL)
 		return (ENOMEM);
 
@@ -529,7 +546,7 @@
 			&destCnt, d->history, flags, 0);
 
 		/* Check return value */
-		KASSERT(rtn != MPPC_INVALID, ("%s: invalid", __func__));
+		/* KASSERT(rtn != MPPC_INVALID, ("%s: invalid", __func__)); */
 		if ((rtn & MPPC_EXPANDED) == 0
 		    && (rtn & MPPC_COMP_OK) == MPPC_COMP_OK) {
 			outlen -= destCnt;     
@@ -596,7 +613,7 @@
 	MPPC_CCOUNT_INC(d->cc);
 
 	/* Install header */
-	M_PREPEND(m, MPPC_HDRLEN, M_DONTWAIT);
+	M_PREPEND(m, MPPC_HDRLEN, M_NOWAIT);
 	if (m != NULL)
 		be16enc(mtod(m, void *), header);
 
@@ -618,7 +635,7 @@
 	struct mbuf *m = *datap;
 
 	/* We must own the mbuf chain exclusively to modify it. */
-	m = m_unshare(m, M_DONTWAIT);
+	m = m_unshare(m, M_NOWAIT);
 	if (m == NULL)
 		return (ENOMEM);
 
@@ -647,12 +664,23 @@
 			/* How many times are we going to have to re-key? */
 			rekey = ((d->cfg.bits & MPPE_STATELESS) != 0) ?
 			    numLost : (numLost / (MPPE_UPDATE_MASK + 1));
-			if (rekey > MPPE_MAX_REKEY) {
-				log(LOG_ERR, "%s: too many (%d) packets"
-				    " dropped, disabling node %p!",
-				    __func__, numLost, node);
+			if (rekey > mppe_max_rekey) {
+			    if (mppe_block_on_max_rekey) {
+				if (mppe_log_max_rekey) {
+				    log(LOG_ERR, "%s: too many (%d) packets"
+					" dropped, disabling node %p!\n",
+					__func__, numLost, node);
+				}
 				priv->recv.cfg.enable = 0;
 				goto failed;
+			    } else {
+				if (mppe_log_max_rekey) {
+				    log(LOG_ERR, "%s: %d packets"
+					" dropped, node %p\n",
+					__func__, numLost, node);
+				}
+				goto failed;
+			    }
 			}
 
 			/* Re-key as necessary to catch up to peer */
@@ -780,7 +808,7 @@
 			&sourceCnt, &destCnt, d->history, flags);
 
 		/* Check return value */
-		KASSERT(rtn != MPPC_INVALID, ("%s: invalid", __func__));
+		/* KASSERT(rtn != MPPC_INVALID, ("%s: invalid", __func__)); */
 		if ((rtn & MPPC_DEST_EXHAUSTED) != 0
 		    || (rtn & MPPC_DECOMP_OK) != MPPC_DECOMP_OK) {
 			log(LOG_ERR, "%s: decomp returned 0x%x",

Modified: trunk/sys/netgraph/ng_mppc.h
===================================================================
--- trunk/sys/netgraph/ng_mppc.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_mppc.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -39,7 +39,7 @@
  * Author: Archie Cobbs <archie at freebsd.org>
  *
  * $Whistle: ng_mppc.h,v 1.3 2000/02/12 01:17:22 archie Exp $
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_mppc.h 139823 2005-01-07 01:45:51Z imp $
  */
 
 #ifndef _NETGRAPH_NG_MPPC_H_

Modified: trunk/sys/netgraph/ng_nat.c
===================================================================
--- trunk/sys/netgraph/ng_nat.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_nat.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_nat.c 248570 2013-03-21 08:36:15Z glebius $
  */
 
 #include <sys/param.h>
@@ -146,6 +146,14 @@
 	&ng_nat_list_redirects_fields
 };
 
+/* Parse type for struct ng_nat_libalias_info. */
+static const struct ng_parse_struct_field ng_nat_libalias_info_fields[]
+	= NG_NAT_LIBALIAS_INFO;
+static const struct ng_parse_type ng_nat_libalias_info_type = {
+	&ng_parse_struct_type,
+	&ng_nat_libalias_info_fields
+};
+
 /* List of commands and how to convert arguments to/from ASCII. */
 static const struct ng_cmdlist ng_nat_cmdlist[] = {
 	{
@@ -225,6 +233,13 @@
 	  &ng_parse_string_type,
 	  NULL
 	},
+	{
+	  NGM_NAT_COOKIE,
+	  NGM_NAT_LIBALIAS_INFO,
+	  "libaliasinfo",
+	  NULL,
+	  &ng_nat_libalias_info_type
+	},
 	{ 0 }
 };
 
@@ -648,6 +663,36 @@
 				error = ENOMEM;
 		    }
 			break;
+		case NGM_NAT_LIBALIAS_INFO:
+		    {
+			struct ng_nat_libalias_info *i;
+
+			NG_MKRESPONSE(resp, msg,
+			    sizeof(struct ng_nat_libalias_info), M_NOWAIT);
+			if (resp == NULL) {
+				error = ENOMEM;
+				break;
+			}
+			i = (struct ng_nat_libalias_info *)resp->data;
+#define	COPY(F)	do {						\
+	if (priv->lib->F >= 0 && priv->lib->F < UINT32_MAX)	\
+		i->F = priv->lib->F;				\
+	else							\
+		i->F = UINT32_MAX;				\
+} while (0)
+		
+			COPY(icmpLinkCount);
+			COPY(udpLinkCount);
+			COPY(tcpLinkCount);
+			COPY(pptpLinkCount);
+			COPY(sctpLinkCount);
+			COPY(protoLinkCount);
+			COPY(fragmentIdLinkCount);
+			COPY(fragmentPtrLinkCount);
+			COPY(sockCount);
+#undef COPY
+		    }
+			break;
 		default:
 			error = EINVAL;		/* unknown command */
 			break;
@@ -757,11 +802,12 @@
 		 */
 
 		if (th->th_x2) {
+			uint16_t ip_len = ntohs(ip->ip_len);
+
 			th->th_x2 = 0;
-			ip->ip_len = ntohs(ip->ip_len);
 			th->th_sum = in_pseudo(ip->ip_src.s_addr,
 			    ip->ip_dst.s_addr, htons(IPPROTO_TCP +
-			    ip->ip_len - (ip->ip_hl << 2)));
+			    ip_len - (ip->ip_hl << 2)));
 	
 			if ((m->m_pkthdr.csum_flags & CSUM_TCP) == 0) {
 				m->m_pkthdr.csum_data = offsetof(struct tcphdr,
@@ -768,7 +814,6 @@
 				    th_sum);
 				in_delayed_cksum(m);
 			}
-			ip->ip_len = htons(ip->ip_len);
 		}
 	}
 

Modified: trunk/sys/netgraph/ng_nat.h
===================================================================
--- trunk/sys/netgraph/ng_nat.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_nat.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_nat.h 248570 2013-03-21 08:36:15Z glebius $
  */
 
 #define NG_NAT_NODE_TYPE    "nat"
@@ -173,6 +173,33 @@
 	  { NULL }						\
 }
 
+/* Structure returned by NGM_NAT_LIBALIAS_INFO */
+struct ng_nat_libalias_info {
+	uint32_t	icmpLinkCount;
+	uint32_t	udpLinkCount;
+	uint32_t	tcpLinkCount;
+	uint32_t	sctpLinkCount;
+	uint32_t	pptpLinkCount;
+	uint32_t	protoLinkCount;
+	uint32_t	fragmentIdLinkCount;
+	uint32_t	fragmentPtrLinkCount;
+	uint32_t	sockCount;
+};
+
+/* Keep this in sync with the above structure definition */
+#define NG_NAT_LIBALIAS_INFO {					\
+	  { "icmpLinkCount",	&ng_parse_uint32_type	},	\
+	  { "udpLinkCount",	&ng_parse_uint32_type	},	\
+	  { "tcpLinkCount",	&ng_parse_uint32_type	},	\
+	  { "sctpLinkCount",	&ng_parse_uint32_type	},	\
+	  { "pptpLinkCount",	&ng_parse_uint32_type	},	\
+	  { "protoLinkCount",	&ng_parse_uint32_type	},	\
+	  { "fragmentIdLinkCount", &ng_parse_uint32_type },	\
+	  { "fragmentPtrLinkCount", &ng_parse_uint32_type },	\
+	  { "sockCount",	&ng_parse_uint32_type	},	\
+	  { NULL }						\
+}
+
 enum {
 	NGM_NAT_SET_IPADDR = 1,
 	NGM_NAT_SET_MODE,
@@ -185,4 +212,5 @@
 	NGM_NAT_ADD_SERVER,
 	NGM_NAT_LIST_REDIRECTS,
 	NGM_NAT_PROXY_RULE,
+	NGM_NAT_LIBALIAS_INFO,
 };

Modified: trunk/sys/netgraph/ng_one2many.c
===================================================================
--- trunk/sys/netgraph/ng_one2many.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_one2many.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_one2many.c 243882 2012-12-05 08:04:20Z glebius $
  */
 
 /*
@@ -460,7 +460,7 @@
 				struct ng_one2many_link *mdst;
 
 				mdst = &priv->many[priv->activeMany[i]];
-				m2 = m_dup(m, M_DONTWAIT);        /* XXX m_copypacket() */
+				m2 = m_dup(m, M_NOWAIT);        /* XXX m_copypacket() */
 				if (m2 == NULL) {
 					mdst->stats.memoryFailures++;
 					NG_FREE_ITEM(item);

Modified: trunk/sys/netgraph/ng_one2many.h
===================================================================
--- trunk/sys/netgraph/ng_one2many.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_one2many.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_one2many.h 219127 2011-03-01 13:10:56Z ae $
  */
 
 #ifndef _NETGRAPH_NG_ONE2MANY_H_

Modified: trunk/sys/netgraph/ng_parse.c
===================================================================
--- trunk/sys/netgraph/ng_parse.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_parse.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -39,7 +39,7 @@
  * Author: Archie Cobbs <archie at freebsd.org>
  *
  * $Whistle: ng_parse.c,v 1.3 1999/11/29 01:43:48 archie Exp $
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_parse.c 278140 2015-02-03 07:59:33Z dim $
  */
 
 #include <sys/types.h>
@@ -1123,7 +1123,7 @@
 		struct ng_parse_type subtype;
 
 		subtype = ng_parse_bytearray_subtype;
-		*(const void **)&subtype.private = type->info;
+		subtype.private = __DECONST(void *, type->info);
 		return ng_array_parse(&subtype, s, off, start, buf, buflen);
 	}
 }
@@ -1135,7 +1135,7 @@
 	struct ng_parse_type subtype;
 
 	subtype = ng_parse_bytearray_subtype;
-	*(const void **)&subtype.private = type->info;
+	subtype.private = __DECONST(void *, type->info);
 	return ng_array_unparse(&subtype, data, off, cbuf, cbuflen);
 }
 
@@ -1146,7 +1146,7 @@
 	struct ng_parse_type subtype;
 
 	subtype = ng_parse_bytearray_subtype;
-	*(const void **)&subtype.private = type->info;
+	subtype.private = __DECONST(void *, type->info);
 	return ng_array_getDefault(&subtype, start, buf, buflen);
 }
 
@@ -1237,6 +1237,7 @@
 		   distinguish name from values by seeing if the next
 		   token is an equals sign */
 		if (ctype != CT_STRUCT) {
+			u_long ul;
 			int len2, off2;
 			char *eptr;
 
@@ -1260,11 +1261,12 @@
 			}
 
 			/* Index was specified explicitly; parse it */
-			index = (u_int)strtoul(s + *off, &eptr, 0);
-			if (index < 0 || eptr - (s + *off) != len) {
+			ul = strtoul(s + *off, &eptr, 0);
+			if (ul == ULONG_MAX || eptr - (s + *off) != len) {
 				error = EINVAL;
 				goto done;
 			}
+			index = (u_int)ul;
 			nextIndex = index + 1;
 			*off += len + len2;
 		} else {			/* a structure field */

Modified: trunk/sys/netgraph/ng_parse.h
===================================================================
--- trunk/sys/netgraph/ng_parse.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_parse.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -39,7 +39,7 @@
  * Author: Archie Cobbs <archie at freebsd.org>
  *
  * $Whistle: ng_parse.h,v 1.2 1999/11/29 01:43:48 archie Exp $
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_parse.h 151800 2005-10-28 14:41:28Z ru $
  */
 
 #ifndef _NETGRAPH_NG_PARSE_H_

Modified: trunk/sys/netgraph/ng_patch.c
===================================================================
--- trunk/sys/netgraph/ng_patch.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_patch.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -1,6 +1,6 @@
 /* $MidnightBSD$ */
 /*-
- * Copyright (C) 2010 by Maxim Ignatenko <gelraen.ua at gmail.com>
+ * Copyright (c) 2010  Maxim Ignatenko <gelraen.ua at gmail.com>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/netgraph/ng_patch.c 309389 2016-12-02 05:42:04Z julian $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -51,11 +51,12 @@
 ng_patch_config_getlen(const struct ng_parse_type *type,
     const u_char *start, const u_char *buf)
 {
-	const struct ng_patch_config *p;
+	const struct ng_patch_config *conf;
 
-	p = (const struct ng_patch_config *)(buf -
+	conf = (const struct ng_patch_config *)(buf -
 	    offsetof(struct ng_patch_config, ops));
-	return (p->count);
+
+	return (conf->count);
 }
 
 static const struct ng_parse_struct_field ng_patch_op_type_fields[]
@@ -65,13 +66,13 @@
 	&ng_patch_op_type_fields
 };
 
-static const struct ng_parse_array_info ng_patch_confarr_info = {
+static const struct ng_parse_array_info ng_patch_ops_array_info = {
 	&ng_patch_op_type,
 	&ng_patch_config_getlen
 };
-static const struct ng_parse_type ng_patch_confarr_type = {
+static const struct ng_parse_type ng_patch_ops_array_type = {
 	&ng_parse_array_type,
-	&ng_patch_confarr_info
+	&ng_patch_ops_array_info
 };
 
 static const struct ng_parse_struct_field ng_patch_config_type_fields[]
@@ -138,6 +139,7 @@
 	.disconnect =	ng_patch_disconnect,
 	.cmdlist =	ng_patch_cmdlist,
 };
+
 NETGRAPH_INIT(patch, &typestruct);
 
 union patch_val {
@@ -147,6 +149,7 @@
 	uint64_t	v8;
 };
 
+/* private data */
 struct ng_patch_priv {
 	hook_p		in;
 	hook_p		out;

Modified: trunk/sys/netgraph/ng_patch.h
===================================================================
--- trunk/sys/netgraph/ng_patch.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_patch.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_patch.h 326568 2017-12-05 14:46:12Z julian $
  */
 
 #ifndef _NETGRAPH_NG_PATCH_H_
@@ -58,7 +58,7 @@
 	NG_PATCH_MODE_DIV = 5,
 	NG_PATCH_MODE_NEG = 6,
 	NG_PATCH_MODE_AND = 7,
-	NG_PATCH_MODE_OR = 8,
+	NG_PATCH_MODE_OR  = 8,
 	NG_PATCH_MODE_XOR = 9,
 	NG_PATCH_MODE_SHL = 10,
 	NG_PATCH_MODE_SHR = 11
@@ -67,16 +67,16 @@
 struct ng_patch_op {
 	uint64_t	value;
 	uint32_t	offset;
-	uint16_t	length;	/* 1,2,4 or 8 (bytes) */
+	uint16_t	length;	/* 1, 2, 4 or 8 (bytes) */
 	uint16_t	mode;
 };
 
-#define	NG_PATCH_OP_TYPE_INFO	{	\
-		{ "value",	&ng_parse_uint64_type	},	\
-		{ "offset",	&ng_parse_uint32_type	},	\
-		{ "length",	&ng_parse_uint16_type	},	\
-		{ "mode",	&ng_parse_uint16_type	},	\
-		{ NULL } \
+#define	NG_PATCH_OP_TYPE_INFO {				\
+	{ "value",	&ng_parse_uint64_type	},	\
+	{ "offset",	&ng_parse_uint32_type	},	\
+	{ "length",	&ng_parse_uint16_type	},	\
+	{ "mode",	&ng_parse_uint16_type	},	\
+	{ NULL }					\
 }
 
 struct ng_patch_config {
@@ -85,11 +85,11 @@
 	struct ng_patch_op ops[];
 };
 
-#define	NG_PATCH_CONFIG_TYPE_INFO	{	\
-		{ "count",	&ng_parse_uint32_type	},	\
-		{ "csum_flags",	&ng_parse_uint32_type	},	\
-		{ "ops",	&ng_patch_confarr_type	},	\
-		{ NULL } \
+#define	NG_PATCH_CONFIG_TYPE_INFO {					\
+	{ "count",		&ng_parse_uint32_type		},	\
+	{ "csum_flags",		&ng_parse_uint32_type		},	\
+	{ "ops",		&ng_patch_ops_array_type		},	\
+	{ NULL }							\
 }
 
 struct ng_patch_stats {
@@ -98,11 +98,11 @@
 	uint64_t	dropped;
 };
 
-#define	NG_PATCH_STATS_TYPE_INFO {	\
-		{ "received",	&ng_parse_uint64_type	},	\
-		{ "patched",	&ng_parse_uint64_type	},	\
-		{ "dropped",	&ng_parse_uint64_type	},	\
-		{ NULL } \
+#define	NG_PATCH_STATS_TYPE_INFO {			\
+	{ "Received",	&ng_parse_uint64_type	},	\
+	{ "Patched",	&ng_parse_uint64_type	},	\
+	{ "Dropped",	&ng_parse_uint64_type	},	\
+	{ NULL }					\
 }
 
 #endif /* _NETGRAPH_NG_PATCH_H_ */

Modified: trunk/sys/netgraph/ng_pipe.c
===================================================================
--- trunk/sys/netgraph/ng_pipe.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_pipe.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -28,7 +28,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_pipe.c 222257 2011-05-24 14:36:32Z zec $
  */
 
 /*

Modified: trunk/sys/netgraph/ng_pipe.h
===================================================================
--- trunk/sys/netgraph/ng_pipe.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_pipe.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -28,7 +28,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_pipe.h 206360 2010-04-07 16:29:10Z joel $
  */
 
 #ifndef _NETGRAPH_PIPE_H_

Modified: trunk/sys/netgraph/ng_ppp.c
===================================================================
--- trunk/sys/netgraph/ng_ppp.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_ppp.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -59,7 +59,7 @@
  *
  * Authors: Archie Cobbs <archie at freebsd.org>, Alexander Motin <mav at alkar.net>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_ppp.c 243882 2012-12-05 08:04:20Z glebius $
  * $Whistle: ng_ppp.c,v 1.24 1999/11/01 09:24:52 julian Exp $
  */
 
@@ -2096,7 +2096,7 @@
 			/* Split off next fragment as "m2" */
 			m2 = m;
 			if (!lastFragment) {
-				struct mbuf *n = m_split(m, len, M_DONTWAIT);
+				struct mbuf *n = m_split(m, len, M_NOWAIT);
 
 				if (n == NULL) {
 					NG_FREE_M(m);
@@ -2104,7 +2104,7 @@
 						NG_FREE_ITEM(item);
 					return (ENOMEM);
 				}
-				m_tag_copy_chain(n, m, M_DONTWAIT);
+				m_tag_copy_chain(n, m, M_NOWAIT);
 				m = n;
 			}
 
@@ -2446,7 +2446,7 @@
 static struct mbuf *
 ng_ppp_prepend(struct mbuf *m, const void *buf, int len)
 {
-	M_PREPEND(m, len, M_DONTWAIT);
+	M_PREPEND(m, len, M_NOWAIT);
 	if (m == NULL || (m->m_len < len && (m = m_pullup(m, len)) == NULL))
 		return (NULL);
 	bcopy(buf, mtod(m, uint8_t *), len);

Modified: trunk/sys/netgraph/ng_ppp.h
===================================================================
--- trunk/sys/netgraph/ng_ppp.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_ppp.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_ppp.h 171688 2007-08-01 20:49:35Z mav $
  * $Whistle: ng_ppp.h,v 1.8 1999/01/25 02:40:02 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_pppoe.c
===================================================================
--- trunk/sys/netgraph/ng_pppoe.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_pppoe.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_pppoe.c 331059 2018-03-16 15:10:13Z eugen $
  * $Whistle: ng_pppoe.c,v 1.10 1999/11/01 09:24:52 julian Exp $
  */
 
@@ -169,6 +169,27 @@
 	  &ng_parse_enaddr_type,
 	  NULL
 	},
+	{
+	  NGM_PPPOE_COOKIE,
+	  NGM_PPPOE_SETMAXP,
+	  "setmaxp",
+	  &ng_parse_uint16_type,
+	  NULL
+	},
+        {
+	  NGM_PPPOE_COOKIE,
+	  NGM_PPPOE_SEND_HURL,
+	  "send_hurl",
+	  &ngpppoe_init_data_state_type,
+	  NULL
+        },
+        {
+	  NGM_PPPOE_COOKIE,
+	  NGM_PPPOE_SEND_MOTM,
+	  "send_motm",
+	  &ngpppoe_init_data_state_type,
+	  NULL
+        },
 	{ 0 }
 };
 
@@ -220,9 +241,11 @@
 	const struct pppoe_tag	*tags[NUMTAGS];
 	u_int			service_len;
 	u_int			ac_name_len;
+	u_int			host_uniq_len;
 
 	struct datatag		service;
 	struct datatag		ac_name;
+	struct datatag		host_uniq;
 };
 typedef struct sess_neg *negp;
 
@@ -263,6 +286,7 @@
 	struct ether_header	eh;
 	LIST_HEAD(, sess_con) listeners;
 	struct sess_hash_entry	sesshash[SESSHASHSIZE];
+	struct maxptag	max_payload;	/* PPP-Max-Payload (RFC4638) */
 };
 typedef struct PPPoE *priv_p;
 
@@ -461,7 +485,7 @@
 	LIST_FOREACH(sp, &privp->listeners, sessions) {
 		struct mbuf *m;
 
-		m = m_dup(m0, M_DONTWAIT);
+		m = m_dup(m0, M_NOWAIT);
 		if (m == NULL)
 			return (ENOMEM);
 		NG_SEND_DATA_ONLY(error, sp->hook, m);
@@ -582,22 +606,47 @@
 pppoe_finduniq(node_p node, const struct pppoe_tag *tag)
 {
 	hook_p	hook = NULL;
-	union uniq uniq;
+	sessp	sp;
 
-	bcopy(tag + 1, uniq.bytes, sizeof(void *));
 	/* Cycle through all known hooks. */
 	LIST_FOREACH(hook, &node->nd_hooks, hk_hooks) {
 		/* Skip any nonsession hook. */
 		if (NG_HOOK_PRIVATE(hook) == NULL)
 			continue;
-		if (uniq.pointer == NG_HOOK_PRIVATE(hook))
+		sp = NG_HOOK_PRIVATE(hook);
+		/* Skip already connected sessions. */
+		if (sp->neg == NULL)
+			continue;
+		if (sp->neg->host_uniq_len == ntohs(tag->tag_len) &&
+		    bcmp(sp->neg->host_uniq.data, (const char *)(tag + 1),
+		     sp->neg->host_uniq_len) == 0)
 			break;
 	}
-	CTR3(KTR_NET, "%20s: matched %p for %p", __func__, hook, uniq.pointer);
+	CTR3(KTR_NET, "%20s: matched %p for %p", __func__, hook, sp);
 
 	return (hook);
 }
 
+static hook_p
+pppoe_findcookie(node_p node, const struct pppoe_tag *tag)
+{
+	hook_p	hook = NULL;
+	union uniq cookie;
+
+	bcopy(tag + 1, cookie.bytes, sizeof(void *));
+	/* Cycle through all known hooks. */
+	LIST_FOREACH(hook, &node->nd_hooks, hk_hooks) {
+		/* Skip any nonsession hook. */
+		if (NG_HOOK_PRIVATE(hook) == NULL)
+			continue;
+		if (cookie.pointer == NG_HOOK_PRIVATE(hook))
+			break;
+	}
+	CTR3(KTR_NET, "%20s: matched %p for %p", __func__, hook, cookie.pointer);
+
+	return (hook);
+}
+
 /**************************************************************************
  * Start of Netgraph entrypoints.					  *
  **************************************************************************/
@@ -737,6 +786,8 @@
 		case NGM_PPPOE_LISTEN:
 		case NGM_PPPOE_OFFER:
 		case NGM_PPPOE_SERVICE:
+		case NGM_PPPOE_SEND_HURL:
+		case NGM_PPPOE_SEND_MOTM:
 			ourmsg = (struct ngpppoe_init_data *)msg->data;
 			if (msg->header.arglen < sizeof(*ourmsg)) {
 				log(LOG_ERR, "ng_pppoe[%x]: init data too "
@@ -743,11 +794,21 @@
 				    "small\n", node->nd_ID);
 				LEAVE(EMSGSIZE);
 			}
-			if (msg->header.arglen - sizeof(*ourmsg) >
-			    PPPOE_SERVICE_NAME_SIZE) {
-				log(LOG_ERR, "ng_pppoe[%x]: service name "
-				    "too big\n", node->nd_ID);
-				LEAVE(EMSGSIZE);
+			if (msg->header.cmd == NGM_PPPOE_SEND_HURL ||
+			    msg->header.cmd == NGM_PPPOE_SEND_MOTM) {
+				if (msg->header.arglen - sizeof(*ourmsg) >
+				    PPPOE_PADM_VALUE_SIZE) {
+					log(LOG_ERR, "ng_pppoe[%x]: message "
+					    "too big\n", node->nd_ID);
+					LEAVE(EMSGSIZE);
+				}
+			} else {
+				if (msg->header.arglen - sizeof(*ourmsg) >
+				    PPPOE_SERVICE_NAME_SIZE) {
+					log(LOG_ERR, "ng_pppoe[%x]: service name "
+					    "too big\n", node->nd_ID);
+					LEAVE(EMSGSIZE);
+				}
 			}
 			if (msg->header.arglen - sizeof(*ourmsg) <
 			    ourmsg->data_len) {
@@ -787,6 +848,20 @@
 			if (msg->header.cmd == NGM_PPPOE_SERVICE)
 				break;
 
+			/*
+			 * PADM messages are set up on active sessions.
+			 */
+			if (msg->header.cmd == NGM_PPPOE_SEND_HURL ||
+			    msg->header.cmd == NGM_PPPOE_SEND_MOTM) {
+				if (sp->state != PPPOE_NEWCONNECTED &&
+				    sp->state != PPPOE_CONNECTED) {
+					log(LOG_NOTICE, "ng_pppoe[%x]: session is not "
+					    "active\n", node->nd_ID);
+					LEAVE(EISCONN);
+				}
+				break;
+			}
+
 			if (sp->state != PPPOE_SNONE) {
 				log(LOG_NOTICE, "ng_pppoe[%x]: Session already "
 				    "active\n", node->nd_ID);
@@ -802,7 +877,7 @@
 			if (neg == NULL)
 				LEAVE(ENOMEM);
 
-			neg->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+			neg->m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
 			if (neg->m == NULL) {
 				free(neg, M_NETGRAPH_PPPOE);
 				LEAVE(ENOBUFS);
@@ -841,12 +916,15 @@
 			 * Check the hook exists and is Uninitialised.
 			 * Send a PADI request, and start the timeout logic.
 			 * Store the originator of this message so we can send
-			 * a success of fail message to them later.
+			 * a success or fail message to them later.
 			 * Move the session to SINIT.
 			 * Set up the session to the correct state and
 			 * start it.
 			 */
-			int	i, acnlen = 0, acnsep = 0, srvlen;
+			int	acnpos, acnlen = 0, acnsep = 0;
+			int	hupos, hulen = 0, husep = 0;
+			int	i, srvpos, srvlen;
+			acnpos = 0;
 			for (i = 0; i < ourmsg->data_len; i++) {
 				if (ourmsg->data[i] == '\\') {
 					acnlen = i;
@@ -854,15 +932,56 @@
 					break;
 				}
 			}
-			srvlen = ourmsg->data_len - acnlen - acnsep;
+			hupos = acnlen + acnsep;
+			for (i = hupos; i < ourmsg->data_len; i++) {
+				if (ourmsg->data[i] == '|') {
+					hulen = i - hupos;
+					husep = 1;
+					break;
+				}
+			}
+			srvpos = hupos + hulen + husep;
+			srvlen = ourmsg->data_len - srvpos;
 
-			bcopy(ourmsg->data, neg->ac_name.data, acnlen);
+			bcopy(ourmsg->data + acnpos, neg->ac_name.data, acnlen);
 			neg->ac_name_len = acnlen;
 
+			neg->host_uniq.hdr.tag_type = PTT_HOST_UNIQ;
+			if (hulen == 0) {
+				/* Not provided, generate one */
+				neg->host_uniq.hdr.tag_len = htons(sizeof(sp));
+				bcopy(&sp, neg->host_uniq.data, sizeof(sp));
+				neg->host_uniq_len = sizeof(sp);
+			} else if (hulen > 2 && ourmsg->data[hupos] == '0' &&
+			  ourmsg->data[hupos + 1] == 'x' && hulen % 2 == 0) {
+				/* Hex encoded */
+				static const char hexdig[16] = "0123456789abcdef";
+				int j;
+
+				neg->host_uniq.hdr.tag_len = htons((uint16_t)(hulen / 2 - 1));
+				for (i = 0; i < hulen - 2; i++) {
+					for (j = 0;
+					     j < 16 &&
+					     ourmsg->data[hupos + 2 + i] != hexdig[j];
+					     j++);
+					if (j == 16)
+						LEAVE(EINVAL);
+					if (i % 2 == 0)
+						neg->host_uniq.data[i / 2] = j << 4;
+					else
+						neg->host_uniq.data[i / 2] |= j;
+				}
+				neg->host_uniq_len = hulen / 2 - 1;
+			} else {
+				/* Plain string */
+				neg->host_uniq.hdr.tag_len = htons((uint16_t)hulen);
+				bcopy(ourmsg->data + hupos, neg->host_uniq.data, hulen);
+				neg->host_uniq_len = hulen;
+			}
+
 			neg->service.hdr.tag_type = PTT_SRV_NAME;
 			neg->service.hdr.tag_len = htons((uint16_t)srvlen);
-			bcopy(ourmsg->data + acnlen + acnsep,
-			    neg->service.data, srvlen);
+			bcopy(ourmsg->data + srvpos, neg->service.data, srvlen);
 			neg->service_len = srvlen;
 			pppoe_start(sp);
 			break;
@@ -872,7 +991,7 @@
 			 * Check the hook exists and is Uninitialised.
 			 * Install the service matching string.
 			 * Store the originator of this message so we can send
-			 * a success of fail message to them later.
+			 * a success or fail message to them later.
 			 * Move the hook to 'LISTENING'
 			 */
 			neg->service.hdr.tag_type = PTT_SRV_NAME;
@@ -1005,6 +1124,99 @@
 			bcopy(msg->data, &privp->eh.ether_shost,
 			    ETHER_ADDR_LEN);
 			break;
+		case NGM_PPPOE_SETMAXP:
+			if (msg->header.arglen != sizeof(uint16_t))
+				LEAVE(EINVAL);
+			privp->max_payload.hdr.tag_type = PTT_MAX_PAYL;
+			privp->max_payload.hdr.tag_len = htons(sizeof(uint16_t));
+			privp->max_payload.data = htons(*((uint16_t *)msg->data));
+			break;
+		case NGM_PPPOE_SEND_HURL:
+		    {
+			struct mbuf *m;
+
+			/* Generate a packet of that type. */
+			m = m_gethdr(M_NOWAIT, MT_DATA);
+			if (m == NULL)
+				log(LOG_NOTICE, "ng_pppoe[%x]: session out of "
+				    "mbufs\n", node->nd_ID);
+			else {
+				struct pppoe_full_hdr *wh;
+				struct pppoe_tag *tag;
+				int     error = 0;
+
+				wh = mtod(m, struct pppoe_full_hdr *);
+				bcopy(&sp->pkt_hdr, wh, sizeof(*wh));
+
+				/* Revert the stored header to DISC/PADM mode. */
+				wh->ph.code = PADM_CODE;
+				/*
+				 * Configure ethertype depending on what
+				 * was used during sessions stage.
+				 */
+				if (wh->eh.ether_type ==
+				    ETHERTYPE_PPPOE_3COM_SESS)
+					wh->eh.ether_type = ETHERTYPE_PPPOE_3COM_DISC;
+				else
+					wh->eh.ether_type = ETHERTYPE_PPPOE_DISC;
+				/*
+				 * Add PADM message and adjust sizes.
+				 */
+				tag = (void *)(&wh->ph + 1);
+				tag->tag_type = PTT_HURL;
+				tag->tag_len = htons(ourmsg->data_len);
+				strncpy((char *)(tag + 1), ourmsg->data, ourmsg->data_len);
+				m->m_pkthdr.len = m->m_len = sizeof(*wh) + sizeof(*tag) +
+				    ourmsg->data_len;
+				wh->ph.length = htons(sizeof(*tag) + ourmsg->data_len);
+				NG_SEND_DATA_ONLY(error,
+				    privp->ethernet_hook, m);
+			}
+			break;
+		    }
+		case NGM_PPPOE_SEND_MOTM:
+		    {
+			struct mbuf *m;
+
+			/* Generate a packet of that type. */
+			m = m_gethdr(M_NOWAIT, MT_DATA);
+			if (m == NULL)
+				log(LOG_NOTICE, "ng_pppoe[%x]: session out of "
+				    "mbufs\n", node->nd_ID);
+			else {
+				struct pppoe_full_hdr *wh;
+				struct pppoe_tag *tag;
+				int     error = 0;
+
+				wh = mtod(m, struct pppoe_full_hdr *);
+				bcopy(&sp->pkt_hdr, wh, sizeof(*wh));
+
+				/* Revert the stored header to DISC/PADM mode. */
+				wh->ph.code = PADM_CODE;
+				/*
+				 * Configure ethertype depending on what
+				 * was used during sessions stage.
+				 */
+				if (wh->eh.ether_type ==
+				    ETHERTYPE_PPPOE_3COM_SESS)
+					wh->eh.ether_type = ETHERTYPE_PPPOE_3COM_DISC;
+				else
+					wh->eh.ether_type = ETHERTYPE_PPPOE_DISC;
+				/*
+				 * Add PADM message and adjust sizes.
+				 */
+				tag = (void *)(&wh->ph + 1);
+				tag->tag_type = PTT_MOTM;
+				tag->tag_len = htons(ourmsg->data_len);
+				strncpy((char *)(tag + 1), ourmsg->data, ourmsg->data_len);
+				m->m_pkthdr.len = m->m_len = sizeof(*wh) + sizeof(*tag) +
+				    ourmsg->data_len;
+				wh->ph.length = htons(sizeof(*tag) + ourmsg->data_len);
+				NG_SEND_DATA_ONLY(error,
+				    privp->ethernet_hook, m);
+			}
+			break;
+		    }
 		default:
 			LEAVE(EINVAL);
 		}
@@ -1047,10 +1259,6 @@
 	node_p	node = NG_HOOK_NODE(hook);
 	priv_p	privp = NG_NODE_PRIVATE(node);
 	negp	neg = sp->neg;
-	struct {
-		struct pppoe_tag hdr;
-		union	uniq	data;
-	} __packed uniqtag;
 	struct  mbuf *m0;
 	int	error;
 
@@ -1066,12 +1274,11 @@
 	memcpy((void *)&neg->pkt->pkt_header.eh, &privp->eh,
 	    sizeof(struct ether_header));
 	neg->pkt->pkt_header.ph.code = PADI_CODE;
-	uniqtag.hdr.tag_type = PTT_HOST_UNIQ;
-	uniqtag.hdr.tag_len = htons((u_int16_t)sizeof(uniqtag.data));
-	uniqtag.data.pointer = sp;
 	init_tags(sp);
-	insert_tag(sp, &uniqtag.hdr);
+	insert_tag(sp, &neg->host_uniq.hdr);
 	insert_tag(sp, &neg->service.hdr);
+	if (privp->max_payload.data != 0)
+		insert_tag(sp, &privp->max_payload.hdr);
 	make_packet(sp);
 	/*
 	 * Send packet and prepare to retransmit it after timeout.
@@ -1079,7 +1286,7 @@
 	ng_callout(&neg->handle, node, hook, PPPOE_INITIAL_TIMEOUT * hz,
 	    pppoe_ticker, NULL, 0);
 	neg->timeout = PPPOE_INITIAL_TIMEOUT * 2;
-	m0 = m_copypacket(neg->m, M_DONTWAIT);
+	m0 = m_copypacket(neg->m, M_NOWAIT);
 	NG_SEND_DATA_ONLY(error, privp->ethernet_hook, m0);
 }
 
@@ -1125,6 +1332,74 @@
 	return (error);
 }
 
+static int
+send_maxp(sessp sp, const struct pppoe_tag *tag)
+{
+	int error;
+	struct ng_mesg *msg;
+	struct ngpppoe_maxp *maxp;
+
+	CTR2(KTR_NET, "%20s: called %d", __func__, sp->Session_ID);
+
+	NG_MKMESSAGE(msg, NGM_PPPOE_COOKIE, NGM_PPPOE_SETMAXP,
+	    sizeof(struct ngpppoe_maxp), M_NOWAIT);
+	if (msg == NULL)
+		return (ENOMEM);
+
+	maxp = (struct ngpppoe_maxp *)msg->data;
+	strncpy(maxp->hook, NG_HOOK_NAME(sp->hook), NG_HOOKSIZ);
+	maxp->data = ntohs(((const struct maxptag *)tag)->data);
+	NG_SEND_MSG_ID(error, NG_HOOK_NODE(sp->hook), msg, sp->creator, 0);
+
+	return (error);
+}
+
+static int
+send_hurl(sessp sp, const struct pppoe_tag *tag)
+{
+	int error, tlen;
+	struct ng_mesg *msg;
+	struct ngpppoe_padm *padm;
+
+	CTR2(KTR_NET, "%20s: called %d", __func__, sp->Session_ID);
+
+	NG_MKMESSAGE(msg, NGM_PPPOE_COOKIE, NGM_PPPOE_HURL,
+	    sizeof(struct ngpppoe_padm), M_NOWAIT);
+	if (msg == NULL)
+		return (ENOMEM);
+
+	padm = (struct ngpppoe_padm *)msg->data;
+	tlen = min(PPPOE_PADM_VALUE_SIZE - 1, ntohs(tag->tag_len));
+	strncpy(padm->msg, (const char *)(tag + 1), tlen);
+	padm->msg[tlen] = '\0';
+	NG_SEND_MSG_ID(error, NG_HOOK_NODE(sp->hook), msg, sp->creator, 0);
+
+	return (error);
+}
+
+static int
+send_motm(sessp sp, const struct pppoe_tag *tag)
+{
+	int error, tlen;
+	struct ng_mesg *msg;
+	struct ngpppoe_padm *padm;
+
+	CTR2(KTR_NET, "%20s: called %d", __func__, sp->Session_ID);
+
+	NG_MKMESSAGE(msg, NGM_PPPOE_COOKIE, NGM_PPPOE_MOTM,
+	    sizeof(struct ngpppoe_padm), M_NOWAIT);
+	if (msg == NULL)
+		return (ENOMEM);
+
+	padm = (struct ngpppoe_padm *)msg->data;
+	tlen = min(PPPOE_PADM_VALUE_SIZE - 1, ntohs(tag->tag_len));
+	strncpy(padm->msg, (const char *)(tag + 1), tlen);
+	padm->msg[tlen] = '\0';
+	NG_SEND_MSG_ID(error, NG_HOOK_NODE(sp->hook), msg, sp->creator, 0);
+
+	return (error);
+}
+
 /*
  * Receive data from session hook and do something with it.
  */
@@ -1162,7 +1437,7 @@
 		 * Bang in a pre-made header, and set the length up
 		 * to be correct. Then send it to the ethernet driver.
 		 */
-		M_PREPEND(m, sizeof(*wh), M_DONTWAIT);
+		M_PREPEND(m, sizeof(*wh), M_NOWAIT);
 		if (m == NULL)
 			LEAVE(ENOBUFS);
 
@@ -1252,7 +1527,7 @@
 		 */
 		ng_callout(&neg->handle, node, hook, PPPOE_OFFER_TIMEOUT * hz,
 		    pppoe_ticker, NULL, 0);
-		m0 = m_copypacket(sp->neg->m, M_DONTWAIT);
+		m0 = m_copypacket(sp->neg->m, M_NOWAIT);
 		NG_FWD_NEW_DATA(error, item, privp->ethernet_hook, m0);
 		privp->packets_out++;
 		break;
@@ -1282,6 +1557,7 @@
 	const priv_p		privp = NG_NODE_PRIVATE(node);
 	sessp			sp;
 	const struct pppoe_tag	*utag = NULL, *tag = NULL;
+	const struct pppoe_tag	sntag = { PTT_SRV_NAME, 0 };
 	const struct pppoe_full_hdr *wh;
 	const struct pppoe_hdr	*ph;
 	negp			neg = NULL;
@@ -1339,7 +1615,7 @@
 			 * Put it into a cluster.
 			 */
 			struct mbuf *n;
-			n = m_dup(m, M_DONTWAIT);
+			n = m_dup(m, M_NOWAIT);
 			m_freem(m);
 			m = n;
 			if (m) {
@@ -1371,11 +1647,8 @@
 			 * processing.
 			 */
 			tag = get_tag(ph, PTT_SRV_NAME);
-			if (tag == NULL) {
-				CTR1(KTR_NET, "%20s: PADI w/o Service-Name",
-				    __func__);
-				LEAVE(ENETUNREACH);
-			}
+			if (tag == NULL)
+				tag = &sntag;
 
 			/*
 			 * First, try to match Service-Name against our 
@@ -1400,8 +1673,7 @@
 			 * For now simply accept the first we receive.
 			 */
 			utag = get_tag(ph, PTT_HOST_UNIQ);
-			if ((utag == NULL) ||
-			    (ntohs(utag->tag_len) != sizeof(sp))) {
+			if (utag == NULL) {
 				log(LOG_NOTICE, "ng_pppoe[%x]: no host "
 				    "unique field\n", node->nd_ID);
 				LEAVE(ENETUNREACH);
@@ -1465,6 +1737,9 @@
 				insert_tag(sp, tag); 	/* return it */
 				send_acname(sp, tag);
 			}
+			if ((tag = get_tag(ph, PTT_MAX_PAYL)) &&
+			    (privp->max_payload.data != 0))
+				insert_tag(sp, tag);	/* return it */
 			insert_tag(sp, &neg->service.hdr); /* Service */
 			scan_tags(sp, ph);
 			make_packet(sp);
@@ -1473,7 +1748,7 @@
 			    PPPOE_INITIAL_TIMEOUT * hz,
 			    pppoe_ticker, NULL, 0);
 			neg->timeout = PPPOE_INITIAL_TIMEOUT * 2;
-			m0 = m_copypacket(neg->m, M_DONTWAIT);
+			m0 = m_copypacket(neg->m, M_NOWAIT);
 			NG_FWD_NEW_DATA(error, item, privp->ethernet_hook, m0);
 			break;
 		case	PADR_CODE:
@@ -1488,7 +1763,7 @@
 				LEAVE(ENETUNREACH);
 			}
 
-			sendhook = pppoe_finduniq(node, utag);
+			sendhook = pppoe_findcookie(node, utag);
 			if (sendhook == NULL)
 				LEAVE(ENETUNREACH);
 
@@ -1531,7 +1806,7 @@
 			sp->state = PPPOE_NEWCONNECTED;
 
 			/* Send the PADS without a timeout - we're now connected. */
-			m0 = m_copypacket(sp->neg->m, M_DONTWAIT);
+			m0 = m_copypacket(sp->neg->m, M_NOWAIT);
 			NG_FWD_NEW_DATA(error, item, privp->ethernet_hook, m0);
 
 			/*
@@ -1564,8 +1839,7 @@
 			 * set us into Session mode.
 			 */
 			utag = get_tag(ph, PTT_HOST_UNIQ);
-			if ((utag == NULL) ||
-			    (ntohs(utag->tag_len) != sizeof(sp))) {
+			if (utag == NULL) {
 				LEAVE (ENETUNREACH);
 			}
 			sendhook = pppoe_finduniq(node, utag);
@@ -1603,6 +1877,9 @@
 			m_freem(neg->m);
 			free(sp->neg, M_NETGRAPH_PPPOE);
 			sp->neg = NULL;
+			if ((tag = get_tag(ph, PTT_MAX_PAYL)) &&
+			    (privp->max_payload.data != 0))
+				send_maxp(sp, tag);
 			pppoe_send_event(sp, NGM_PPPOE_SUCCESS);
 			break;
 		case	PADT_CODE:
@@ -1615,6 +1892,19 @@
 			/* Disconnect that hook. */
 			ng_rmhook_self(sp->hook);
 			break;
+		case	PADM_CODE:
+			/*
+			 * We are a client:
+			 * find matching peer/session combination.
+			 */
+			sp = pppoe_findsession(privp, wh);
+			if (sp == NULL)
+				LEAVE (ENETUNREACH);
+			if ((tag = get_tag(ph, PTT_HURL)))
+				send_hurl(sp, tag);
+			if ((tag = get_tag(ph, PTT_MOTM)))
+				send_motm(sp, tag);
+			break;
 		default:
 			LEAVE(EPFNOSUPPORT);
 		}
@@ -1737,7 +2027,7 @@
 			struct mbuf *m;
 
 			/* Generate a packet of that type. */
-			MGETHDR(m, M_DONTWAIT, MT_DATA);
+			m = m_gethdr(M_NOWAIT, MT_DATA);
 			if (m == NULL)
 				log(LOG_NOTICE, "ng_pppoe[%x]: session out of "
 				    "mbufs\n", node->nd_ID);
@@ -1747,8 +2037,6 @@
 				int	msglen = strlen(SIGNOFF);
 				int	error = 0;
 
-				m->m_pkthdr.rcvif = NULL;
-				m->m_pkthdr.len = m->m_len = sizeof(*wh);
 				wh = mtod(m, struct pppoe_full_hdr *);
 				bcopy(&sp->pkt_hdr, wh, sizeof(*wh));
 
@@ -1771,8 +2059,8 @@
 				tag->tag_type = PTT_GEN_ERR;
 				tag->tag_len = htons((u_int16_t)msglen);
 				strncpy((char *)(tag + 1), SIGNOFF, msglen);
-				m->m_pkthdr.len = (m->m_len += sizeof(*tag) +
-				    msglen);
+				m->m_pkthdr.len = m->m_len = sizeof(*wh) + sizeof(*tag) +
+				    msglen;
 				wh->ph.length = htons(sizeof(*tag) + msglen);
 				NG_SEND_DATA_ONLY(error,
 					privp->ethernet_hook, m);
@@ -1824,7 +2112,7 @@
 	case	PPPOE_SINIT:
 	case	PPPOE_SREQ:
 		/* Timeouts on these produce resends. */
-		m0 = m_copypacket(sp->neg->m, M_DONTWAIT);
+		m0 = m_copypacket(sp->neg->m, M_NOWAIT);
 		NG_SEND_DATA_ONLY( error, privp->ethernet_hook, m0);
 		ng_callout(&neg->handle, node, hook, neg->timeout * hz,
 		    pppoe_ticker, NULL, 0);
@@ -1888,6 +2176,9 @@
 		case	PTT_SRV_ERR:
 		case	PTT_SYS_ERR:
 		case	PTT_GEN_ERR:
+		case	PTT_MAX_PAYL:
+		case	PTT_HURL:
+		case	PTT_MOTM:
 			break;
 		}
 		pt = (const struct pppoe_tag*)ptn;

Modified: trunk/sys/netgraph/ng_pppoe.h
===================================================================
--- trunk/sys/netgraph/ng_pppoe.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_pppoe.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_pppoe.h 331059 2018-03-16 15:10:13Z eugen $
  * $Whistle: ng_pppoe.h,v 1.7 1999/10/16 10:16:43 julian Exp $
  */
 
@@ -52,8 +52,11 @@
 #define NG_PPPOE_NODE_TYPE	"pppoe"
 
 #define NGM_PPPOE_COOKIE		1089893072
+#define NGM_PPPOE_SETMAXP_COOKIE	1441624322
+#define NGM_PPPOE_PADM_COOKIE		1488405822
 
 #define	PPPOE_SERVICE_NAME_SIZE		64 /* for now */
+#define	PPPOE_PADM_VALUE_SIZE		128 /* for now */
 
 /* Hook names */
 #define NG_PPPOE_HOOK_ETHERNET	"ethernet"
@@ -84,6 +87,11 @@
 	NGM_PPPOE_SETMODE  = 12, /* set to standard or compat modes */
 	NGM_PPPOE_GETMODE  = 13, /* see current mode */
 	NGM_PPPOE_SETENADDR = 14, /* set Ethernet address */
+	NGM_PPPOE_SETMAXP   = 15, /* Set PPP-Max-Payload value */
+	NGM_PPPOE_SEND_HURL = 16, /* Send PADM HURL message */
+	NGM_PPPOE_HURL      = 17, /* HURL for informational purposes */
+	NGM_PPPOE_SEND_MOTM = 18, /* Send PADM MOTM message */
+	NGM_PPPOE_MOTM      = 19  /* MOTM for informational purposes */
 };
 
 /***********************
@@ -148,7 +156,21 @@
 	  { NULL }					\
 }
 
+/*
+ * This structure is used to send PPP-Max-Payload value from server to client.
+ */
+struct ngpppoe_maxp {
+	char	hook[NG_HOOKSIZ];	/* hook associated with event session */
+	uint16_t	data;
+};
 
+/*
+ * This structure is used to send PADM messages from server to client.
+ */
+struct ngpppoe_padm {
+	char	msg[PPPOE_PADM_VALUE_SIZE];
+};
+
 /********************************************************************
  * Constants and definitions specific to pppoe
  ********************************************************************/
@@ -163,6 +185,7 @@
 #define PADR_CODE	0x19
 #define PADS_CODE	0x65
 #define PADT_CODE	0xa7
+#define PADM_CODE	0xd3
 
 /* Tag identifiers */
 #if BYTE_ORDER == BIG_ENDIAN
@@ -173,6 +196,9 @@
 #define PTT_AC_COOKIE	(0x0104)
 #define PTT_VENDOR 	(0x0105)
 #define PTT_RELAY_SID	(0x0110)
+#define PTT_HURL	(0x0111)	/* PPPoE Extensions (CARREL) */
+#define PTT_MOTM	(0x0112)	/* PPPoE Extensions (CARREL) */
+#define	PTT_MAX_PAYL	(0x0120)	/* PPP-Max-Payload (RFC4638) */
 #define PTT_SRV_ERR     (0x0201)
 #define PTT_SYS_ERR  	(0x0202)
 #define PTT_GEN_ERR  	(0x0203)
@@ -189,6 +215,9 @@
 #define PTT_AC_COOKIE	(0x0401)
 #define PTT_VENDOR 	(0x0501)
 #define PTT_RELAY_SID	(0x1001)
+#define PTT_HURL	(0x1101)	/* PPPoE Extensions (CARREL) */
+#define PTT_MOTM	(0x1201)	/* PPPoE Extensions (CARREL) */
+#define	PTT_MAX_PAYL	(0x2001)	/* PPP-Max-Payload (RFC4638) */
 #define PTT_SRV_ERR     (0x0102)
 #define PTT_SYS_ERR  	(0x0202)
 #define PTT_GEN_ERR  	(0x0302)
@@ -228,6 +257,10 @@
 	u_int8_t        data[PPPOE_SERVICE_NAME_SIZE];
 };     
 
+struct maxptag {
+	struct pppoe_tag hdr;
+	uint16_t	data;
+};
 
 /*
  * Define the order in which we will place tags in packets

Modified: trunk/sys/netgraph/ng_pptpgre.c
===================================================================
--- trunk/sys/netgraph/ng_pptpgre.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_pptpgre.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_pptpgre.c 243882 2012-12-05 08:04:20Z glebius $
  * $Whistle: ng_pptpgre.c,v 1.7 1999/12/08 00:10:06 archie Exp $
  */
 
@@ -599,7 +599,7 @@
 	/* Prepend GRE header to outgoing frame */
 	grelen = sizeof(*gre) + sizeof(u_int32_t) * (gre->hasSeq + gre->hasAck);
 	if (m == NULL) {
-		MGETHDR(m, M_DONTWAIT, MT_DATA);
+		MGETHDR(m, M_NOWAIT, MT_DATA);
 		if (m == NULL) {
 			priv->stats.memoryFailures++;
 			ERROUT(ENOBUFS);
@@ -607,7 +607,7 @@
 		m->m_len = m->m_pkthdr.len = grelen;
 		m->m_pkthdr.rcvif = NULL;
 	} else {
-		M_PREPEND(m, grelen, M_DONTWAIT);
+		M_PREPEND(m, grelen, M_NOWAIT);
 		if (m == NULL || (m->m_len < grelen
 		    && (m = m_pullup(m, grelen)) == NULL)) {
 			priv->stats.memoryFailures++;

Modified: trunk/sys/netgraph/ng_pptpgre.h
===================================================================
--- trunk/sys/netgraph/ng_pptpgre.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_pptpgre.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_pptpgre.h 177587 2008-03-24 22:55:22Z mav $
  * $Whistle: ng_pptpgre.h,v 1.3 1999/12/08 00:11:36 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_pred1.c
===================================================================
--- trunk/sys/netgraph/ng_pred1.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_pred1.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_pred1.c 243882 2012-12-05 08:04:20Z glebius $
  */
 
 /*
@@ -402,7 +402,7 @@
 	}
 
 	/* We must own the mbuf chain exclusively to modify it. */
-	m = m_unshare(m, M_DONTWAIT);
+	m = m_unshare(m, M_NOWAIT);
 	if (m == NULL) {
 		priv->stats.Errors++;
 		return (ENOMEM);
@@ -480,7 +480,7 @@
 	}
 
 	/* We must own the mbuf chain exclusively to modify it. */
-	m = m_unshare(m, M_DONTWAIT);
+	m = m_unshare(m, M_NOWAIT);
 	if (m == NULL) {
 		priv->stats.Errors++;
 		return (ENOMEM);

Modified: trunk/sys/netgraph/ng_pred1.h
===================================================================
--- trunk/sys/netgraph/ng_pred1.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_pred1.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_pred1.h 165619 2006-12-29 09:54:32Z glebius $
  */
 
 #ifndef _NETGRAPH_NG_PRED1_H_

Modified: trunk/sys/netgraph/ng_rfc1490.c
===================================================================
--- trunk/sys/netgraph/ng_rfc1490.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_rfc1490.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_rfc1490.c 243882 2012-12-05 08:04:20Z glebius $
  * $Whistle: ng_rfc1490.c,v 1.22 1999/11/01 09:24:52 julian Exp $
  */
 
@@ -386,7 +386,7 @@
 			break;
 		}
 	} else if (hook == priv->ppp) {
-		M_PREPEND(m, 2, M_DONTWAIT);	/* Prepend PPP NLPID */
+		M_PREPEND(m, 2, M_NOWAIT);	/* Prepend PPP NLPID */
 		if (!m)
 			ERROUT(ENOBUFS);
 		mtod(m, u_char *)[0] = HDLC_UI;
@@ -395,7 +395,7 @@
 	} else if (hook == priv->inet) {
 		switch (priv->enc->method) {
 		case NG_RFC1490_ENCAP_IETF_IP:
-			M_PREPEND(m, 2, M_DONTWAIT);	/* Prepend IP NLPID */
+			M_PREPEND(m, 2, M_NOWAIT);	/* Prepend IP NLPID */
 			if (!m)
 				ERROUT(ENOBUFS);
 			mtod(m, u_char *)[0] = HDLC_UI;
@@ -407,7 +407,7 @@
 			 *  HDLC_UI  PAD  NLIPID  OUI      PID
 			 *  03      00   80      00 00 00  08 00
 			 */
-			M_PREPEND(m, 8, M_DONTWAIT);
+			M_PREPEND(m, 8, M_NOWAIT);
 			if (!m)
 				ERROUT(ENOBUFS);
 			mtod(m, u_char *)[0] = HDLC_UI;
@@ -418,7 +418,7 @@
 			    = htons(ETHERTYPE_IP);  /* PID */
 			break;
 		case NG_RFC1490_ENCAP_CISCO:
-			M_PREPEND(m, 2, M_DONTWAIT);	/* Prepend IP ethertype */
+			M_PREPEND(m, 2, M_NOWAIT);	/* Prepend IP ethertype */
 			if (!m)
 				ERROUT(ENOBUFS);
 			*((u_int16_t *)mtod(m, u_int16_t *)) = htons(ETHERTYPE_IP);
@@ -426,7 +426,7 @@
 		}
 		NG_FWD_NEW_DATA(error, item, priv->downlink, m);
 	} else if (hook == priv->ethernet) {
-		M_PREPEND(m, 8, M_DONTWAIT);	/* Prepend NLPID, OUI, PID */
+		M_PREPEND(m, 8, M_NOWAIT);	/* Prepend NLPID, OUI, PID */
 		if (!m)
 			ERROUT(ENOBUFS);
 		mtod(m, u_char *)[0] = HDLC_UI;

Modified: trunk/sys/netgraph/ng_rfc1490.h
===================================================================
--- trunk/sys/netgraph/ng_rfc1490.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_rfc1490.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_rfc1490.h 139823 2005-01-07 01:45:51Z imp $
  * $Whistle: ng_rfc1490.h,v 1.7 1999/01/20 00:54:15 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_sample.c
===================================================================
--- trunk/sys/netgraph/ng_sample.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_sample.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_sample.c 227293 2011-11-07 06:44:47Z ed $
  * $Whistle: ng_sample.c,v 1.13 1999/11/01 09:24:52 julian Exp $
  */
 

Modified: trunk/sys/netgraph/ng_sample.h
===================================================================
--- trunk/sys/netgraph/ng_sample.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_sample.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_sample.h 139823 2005-01-07 01:45:51Z imp $
  * $Whistle: ng_sample.h,v 1.3 1999/01/20 00:22:14 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_socket.c
===================================================================
--- trunk/sys/netgraph/ng_socket.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_socket.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_socket.c 273736 2014-10-27 14:38:00Z hselasky $
  * $Whistle: ng_socket.c,v 1.28 1999/11/01 09:24:52 julian Exp $
  */
 
@@ -166,6 +166,27 @@
 #define TRAP_ERROR
 #endif
 
+struct hookpriv {
+	LIST_ENTRY(hookpriv)	next;
+	hook_p			hook;
+};
+LIST_HEAD(ngshash, hookpriv);
+
+/* Per-node private data */
+struct ngsock {
+	struct ng_node	*node;		/* the associated netgraph node */
+	struct ngpcb	*datasock;	/* optional data socket */
+	struct ngpcb	*ctlsock;	/* optional control socket */
+	struct ngshash	*hash;		/* hash for hook names */
+	u_long		hmask;		/* hash mask */
+	int	flags;
+	int	refs;
+	struct mtx	mtx;		/* mtx to wait on */
+	int		error;		/* place to store error */
+};
+
+#define	NGS_FLAG_NOLINGER	1	/* close with last hook */
+
 /***************************************************************
 	Control sockets
 ***************************************************************/
@@ -542,10 +563,8 @@
 	pcbp->sockdata = priv;
 	priv->refs++;
 	priv->node = node;
+	pcbp->node_id = node->nd_ID;	/* hint for netstat(1) */
 
-	/* Store a hint for netstat(1). */
-	priv->node_id = priv->node->nd_ID;
-
 	/* Link the node and the private data. */
 	NG_NODE_SET_PRIVATE(priv->node, priv);
 	NG_NODE_REF(priv->node);
@@ -615,6 +634,7 @@
 			panic("%s", __func__);
 		}
 		pcbp->sockdata = NULL;
+		pcbp->node_id = 0;
 
 		ng_socket_free_priv(priv);
 	}
@@ -706,6 +726,7 @@
 	mtx_lock(&priv->mtx);
 	priv->datasock = pcbp;
 	pcbp->sockdata = priv;
+	pcbp->node_id = priv->node->nd_ID;	/* hint for netstat(1) */
 	priv->refs++;
 	mtx_unlock(&priv->mtx);
 	NG_FREE_ITEM(item);	/* drop the reference to the node */
@@ -1179,9 +1200,9 @@
 
 VNET_DOMAIN_SET(ng);
 
-SYSCTL_INT(_net_graph, OID_AUTO, family, CTLFLAG_RD, 0, AF_NETGRAPH, "");
+SYSCTL_INT(_net_graph, OID_AUTO, family, CTLFLAG_RD, SYSCTL_NULL_INT_PTR, AF_NETGRAPH, "");
 static SYSCTL_NODE(_net_graph, OID_AUTO, data, CTLFLAG_RW, 0, "DATA");
-SYSCTL_INT(_net_graph_data, OID_AUTO, proto, CTLFLAG_RD, 0, NG_DATA, "");
+SYSCTL_INT(_net_graph_data, OID_AUTO, proto, CTLFLAG_RD, SYSCTL_NULL_INT_PTR, NG_DATA, "");
 static SYSCTL_NODE(_net_graph, OID_AUTO, control, CTLFLAG_RW, 0, "CONTROL");
-SYSCTL_INT(_net_graph_control, OID_AUTO, proto, CTLFLAG_RD, 0, NG_CONTROL, "");
+SYSCTL_INT(_net_graph_control, OID_AUTO, proto, CTLFLAG_RD, SYSCTL_NULL_INT_PTR, NG_CONTROL, "");
 

Modified: trunk/sys/netgraph/ng_socket.h
===================================================================
--- trunk/sys/netgraph/ng_socket.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_socket.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_socket.h 163462 2006-10-17 11:03:55Z glebius $
  * $Whistle: ng_socket.h,v 1.5 1999/01/20 00:22:14 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_socketvar.h
===================================================================
--- trunk/sys/netgraph/ng_socketvar.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_socketvar.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -38,7 +38,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_socketvar.h 230481 2012-01-23 15:39:45Z glebius $
  * $Whistle: ng_socketvar.h,v 1.1 1999/01/20 21:35:39 archie Exp $
  */
 
@@ -51,32 +51,6 @@
 	struct ngsock	 *sockdata;	/* netgraph info */
 	LIST_ENTRY(ngpcb) socks;	/* linked list of sockets */
 	int		  type;		/* NG_CONTROL or NG_DATA */
-};
-
-#ifdef _KERNEL
-struct hookpriv {
-	LIST_ENTRY(hookpriv)	next;
-	hook_p			hook;
-};
-LIST_HEAD(ngshash, hookpriv);
-#endif
-
-/* Per-node private data */
-struct ngsock {
-	struct ng_node	*node;		/* the associated netgraph node */
-	struct ngpcb	*datasock;	/* optional data socket */
-	struct ngpcb	*ctlsock;	/* optional control socket */
-	int    flags;
-	int    refs;
-	struct mtx	mtx;		/* mtx to wait on */
-	int		error;		/* place to store error */
 	ng_ID_t		node_id;	/* a hint for netstat(1) to find the node */
-#ifdef _KERNEL
-	struct ngshash	*hash;		/* hash for hook names */
-	u_long		hmask;		/* hash mask */
-#endif
 };
-#define	NGS_FLAG_NOLINGER	1	/* close with last hook */
-
 #endif /* _NETGRAPH_NG_SOCKETVAR_H_ */
-

Modified: trunk/sys/netgraph/ng_source.c
===================================================================
--- trunk/sys/netgraph/ng_source.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_source.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/netgraph/ng_source.c 243882 2012-12-05 08:04:20Z glebius $");
 
 /*
  * This node is used for high speed packet geneneration.  It queues
@@ -69,7 +69,6 @@
 #include <sys/syslog.h>
 #include <net/if.h>
 #include <net/if_var.h>
-#include <net/vnet.h>
 #include <netgraph/ng_message.h>
 #include <netgraph/netgraph.h>
 #include <netgraph/ng_parse.h>
@@ -447,7 +446,7 @@
 		    {
 			struct ng_source_embed_info *embed;
 
-			NG_MKRESPONSE(resp, msg, sizeof(*embed), M_DONTWAIT);
+			NG_MKRESPONSE(resp, msg, sizeof(*embed), M_NOWAIT);
 			if (resp == NULL) {
 				error = ENOMEM;
 				goto done;
@@ -486,7 +485,7 @@
 				error = EINVAL;
 				goto done;
 			}
-			NG_MKRESPONSE(resp, msg, sizeof(*embed), M_DONTWAIT);
+			NG_MKRESPONSE(resp, msg, sizeof(*embed), M_NOWAIT);
 			if (resp == NULL) {
 				error = ENOMEM;
 				goto done;
@@ -610,7 +609,6 @@
 ng_source_store_output_ifp(sc_p sc, char *ifname)
 {
 	struct ifnet *ifp;
-	int s;
 
 	ifp = ifunit(ifname);
 
@@ -626,13 +624,11 @@
 	 * interface with small packets.
 	 * XXX we should restore the original value at stop or disconnect
 	 */
-	s = splimp();		/* XXX is this required? */
 	if (ifp->if_snd.ifq_maxlen < NG_SOURCE_DRIVER_IFQ_MAXLEN) {
 		printf("ng_source: changing ifq_maxlen from %d to %d\n",
 		    ifp->if_snd.ifq_maxlen, NG_SOURCE_DRIVER_IFQ_MAXLEN);
 		ifp->if_snd.ifq_maxlen = NG_SOURCE_DRIVER_IFQ_MAXLEN;
 	}
-	splx(s);
 #endif
 	return (0);
 }
@@ -878,9 +874,9 @@
 
 	/* Duplicate the packet. */
 	if (modify)
-		m = m_dup(m0, M_DONTWAIT);
+		m = m_dup(m0, M_NOWAIT);
 	else
-		m = m_copypacket(m0, M_DONTWAIT);
+		m = m_copypacket(m0, M_NOWAIT);
 	if (m == NULL) {
 		error = ENOBUFS;
 		goto done;

Modified: trunk/sys/netgraph/ng_source.h
===================================================================
--- trunk/sys/netgraph/ng_source.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_source.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -37,7 +37,7 @@
  *
  * Author: Dave Chapeskie
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_source.h 209730 2010-07-06 16:55:39Z emaste $
  */
 
 #ifndef _NETGRAPH_NG_SOURCE_H_

Modified: trunk/sys/netgraph/ng_split.c
===================================================================
--- trunk/sys/netgraph/ng_split.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_split.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_split.c 220768 2011-04-18 09:12:27Z glebius $
  *
  */
 

Modified: trunk/sys/netgraph/ng_split.h
===================================================================
--- trunk/sys/netgraph/ng_split.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_split.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -26,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_split.h 151676 2005-10-25 20:56:12Z ru $
  *
  */
 

Modified: trunk/sys/netgraph/ng_sppp.c
===================================================================
--- trunk/sys/netgraph/ng_sppp.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_sppp.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -18,7 +18,7 @@
  * Cronyx Id: ng_sppp.c,v 1.1.2.10 2004/03/01 15:17:21 rik Exp $
  */
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
+__FBSDID("$FreeBSD: stable/10/sys/netgraph/ng_sppp.c 227293 2011-11-07 06:44:47Z ed $");
 
 #include <sys/param.h>
 #include <sys/systm.h>

Modified: trunk/sys/netgraph/ng_sppp.h
===================================================================
--- trunk/sys/netgraph/ng_sppp.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_sppp.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -15,7 +15,7 @@
  * as long as this message is kept with the software, all derivative
  * works or modified versions.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_sppp.h 141197 2005-02-03 13:03:31Z ru $
  * Cronyx Id: ng_sppp.h,v 1.1.2.6 2004/03/01 15:17:21 rik Exp $
  */
 

Modified: trunk/sys/netgraph/ng_tag.c
===================================================================
--- trunk/sys/netgraph/ng_tag.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_tag.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -28,7 +28,7 @@
  * Portions Copyright (c) 1999 Whistle Communications, Inc.
  * (ng_bpf by Archie Cobbs <archie at freebsd.org>)
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_tag.c 230272 2012-01-17 18:10:25Z glebius $
  */
 
 /*
@@ -304,8 +304,9 @@
 	int error;
 
 	/* Create hook private structure. */
-	hip = malloc(sizeof(*hip), M_NETGRAPH_TAG, M_WAITOK | M_ZERO);
-	/* M_WAITOK can't return NULL. */
+	hip = malloc(sizeof(*hip), M_NETGRAPH_TAG, M_NOWAIT | M_ZERO);
+	if (hip == NULL)
+		return (ENOMEM);
 	NG_HOOK_SET_PRIVATE(hook, hip);
 
 	/*

Modified: trunk/sys/netgraph/ng_tag.h
===================================================================
--- trunk/sys/netgraph/ng_tag.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_tag.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_tag.h 159979 2006-06-27 12:45:28Z glebius $
  */
 
 #ifndef _NETGRAPH_NG_TAG_H_

Modified: trunk/sys/netgraph/ng_tcpmss.c
===================================================================
--- trunk/sys/netgraph/ng_tcpmss.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_tcpmss.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -30,7 +30,7 @@
  * This software includes fragments of the following programs:
  *	tcpmssd		Ruslan Ermilov <ru at FreeBSD.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_tcpmss.c 206032 2010-04-01 10:41:01Z mav $
  */
 
 /*

Modified: trunk/sys/netgraph/ng_tcpmss.h
===================================================================
--- trunk/sys/netgraph/ng_tcpmss.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_tcpmss.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -27,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_tcpmss.h 147231 2005-06-10 08:02:34Z glebius $
  */
 
 #ifndef _NETGRAPH_TCPMSS_H_

Modified: trunk/sys/netgraph/ng_tee.c
===================================================================
--- trunk/sys/netgraph/ng_tee.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_tee.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -39,7 +39,7 @@
  *
  * Author: Julian Elischer <julian at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_tee.c 243882 2012-12-05 08:04:20Z glebius $
  * $Whistle: ng_tee.c,v 1.18 1999/11/01 09:24:52 julian Exp $
  */
 
@@ -306,7 +306,7 @@
 		struct mbuf *m2;
 
 		/* Copy packet (failure will not stop the original)*/
-		m2 = m_dup(m, M_DONTWAIT);
+		m2 = m_dup(m, M_NOWAIT);
 		if (m2) {
 			/* Deliver duplicate */
 			h = hinfo->dup;

Modified: trunk/sys/netgraph/ng_tee.h
===================================================================
--- trunk/sys/netgraph/ng_tee.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_tee.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -39,7 +39,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_tee.h 139823 2005-01-07 01:45:51Z imp $
  * $Whistle: ng_tee.h,v 1.2 1999/01/20 00:22:14 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_tty.c
===================================================================
--- trunk/sys/netgraph/ng_tty.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_tty.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -40,7 +40,7 @@
  *
  * Updated by Andrew Thompson <thompsa at FreeBSD.org> for MPSAFE TTY.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_tty.c 243882 2012-12-05 08:04:20Z glebius $
  * $Whistle: ng_tty.c,v 1.21 1999/11/01 09:24:52 julian Exp $
  */
 
@@ -419,7 +419,7 @@
 	if (sc->hook == NULL)
 		return (0);
 
-	m = m_getm2(NULL, len, M_DONTWAIT, MT_DATA, M_PKTHDR);
+	m = m_getm2(NULL, len, M_NOWAIT, MT_DATA, M_PKTHDR);
 	if (m == NULL) {
 		if (sc->flags & FLG_DEBUG)
 			log(LOG_ERR,
@@ -477,7 +477,7 @@
 
 	/* Get a new header mbuf if we need one */
 	if (!(m = sc->m)) {
-		MGETHDR(m, M_DONTWAIT, MT_DATA);
+		MGETHDR(m, M_NOWAIT, MT_DATA);
 		if (!m) {
 			if (sc->flags & FLG_DEBUG)
 				log(LOG_ERR,

Modified: trunk/sys/netgraph/ng_tty.h
===================================================================
--- trunk/sys/netgraph/ng_tty.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_tty.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -39,7 +39,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_tty.h 184760 2008-11-08 02:05:41Z mav $
  * $Whistle: ng_tty.h,v 1.7 1999/01/20 00:22:15 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_vjc.c
===================================================================
--- trunk/sys/netgraph/ng_vjc.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_vjc.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -39,7 +39,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_vjc.c 243882 2012-12-05 08:04:20Z glebius $
  * $Whistle: ng_vjc.c,v 1.17 1999/11/01 09:24:52 julian Exp $
  */
 
@@ -475,7 +475,7 @@
 		m_adj(m, vjlen);
 
 		/* Copy the reconstructed TCP/IP headers into a new mbuf */
-		MGETHDR(hm, M_DONTWAIT, MT_DATA);
+		MGETHDR(hm, M_NOWAIT, MT_DATA);
 		if (hm == NULL) {
 			priv->slc.sls_errorin++;
 			NG_FREE_M(m);
@@ -485,7 +485,7 @@
 		hm->m_len = 0;
 		hm->m_pkthdr.rcvif = NULL;
 		if (hlen > MHLEN) {		/* unlikely, but can happen */
-			MCLGET(hm, M_DONTWAIT);
+			MCLGET(hm, M_NOWAIT);
 			if ((hm->m_flags & M_EXT) == 0) {
 				m_freem(hm);
 				priv->slc.sls_errorin++;

Modified: trunk/sys/netgraph/ng_vjc.h
===================================================================
--- trunk/sys/netgraph/ng_vjc.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_vjc.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -39,7 +39,7 @@
  *
  * Author: Archie Cobbs <archie at freebsd.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_vjc.h 139823 2005-01-07 01:45:51Z imp $
  * $Whistle: ng_vjc.h,v 1.6 1999/01/25 02:40:22 archie Exp $
  */
 

Modified: trunk/sys/netgraph/ng_vlan.c
===================================================================
--- trunk/sys/netgraph/ng_vlan.c	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_vlan.c	2018-05-25 20:03:57 UTC (rev 9936)
@@ -1,6 +1,7 @@
 /* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003 IPNET Internet Communication Company
+ * Copyright (c) 2011 - 2012 Rozhuk Ivan <rozhuk.im at gmail.com>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,7 +27,7 @@
  *
  * Author: Ruslan Ermilov <ru at FreeBSD.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_vlan.c 243882 2012-12-05 08:04:20Z glebius $
  */
 
 #include <sys/param.h>
@@ -47,6 +48,22 @@
 #include <netgraph/ng_vlan.h>
 #include <netgraph/netgraph.h>
 
+struct ng_vlan_private {
+	hook_p		downstream_hook;
+	hook_p		nomatch_hook;
+	uint32_t	decap_enable;
+	uint32_t	encap_enable;
+	uint16_t	encap_proto;
+	hook_p		vlan_hook[(EVL_VLID_MASK + 1)];
+};
+typedef struct ng_vlan_private *priv_p;
+
+#define	ETHER_VLAN_HDR_LEN (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN)
+#define	VLAN_TAG_MASK	0xFFFF
+#define	HOOK_VLAN_TAG_SET_MASK ((uintptr_t)((~0) & ~(VLAN_TAG_MASK)))
+#define	IS_HOOK_VLAN_SET(hdata) \
+	    ((((uintptr_t)hdata) & HOOK_VLAN_TAG_SET_MASK) == HOOK_VLAN_TAG_SET_MASK)
+
 static ng_constructor_t	ng_vlan_constructor;
 static ng_rcvmsg_t	ng_vlan_rcvmsg;
 static ng_shutdown_t	ng_vlan_shutdown;
@@ -111,6 +128,55 @@
 	  NULL,
 	  &ng_vlan_table_type
 	},
+	{
+	  NGM_VLAN_COOKIE,
+	  NGM_VLAN_DEL_VID_FLT,
+	  "delvidflt",
+	  &ng_parse_uint16_type,
+	  NULL
+	},
+	{
+	  NGM_VLAN_COOKIE,
+	  NGM_VLAN_GET_DECAP,
+	  "getdecap",
+	  NULL,
+	  &ng_parse_hint32_type
+	},
+	{
+	  NGM_VLAN_COOKIE,
+	  NGM_VLAN_SET_DECAP,
+	  "setdecap",
+	  &ng_parse_hint32_type,
+	  NULL
+	},
+	{
+	  NGM_VLAN_COOKIE,
+	  NGM_VLAN_GET_ENCAP,
+	  "getencap",
+	  NULL,
+	  &ng_parse_hint32_type
+	},
+	{
+	  NGM_VLAN_COOKIE,
+	  NGM_VLAN_SET_ENCAP,
+	  "setencap",
+	  &ng_parse_hint32_type,
+	  NULL
+	},
+	{
+	  NGM_VLAN_COOKIE,
+	  NGM_VLAN_GET_ENCAP_PROTO,
+	  "getencapproto",
+	  NULL,
+	  &ng_parse_hint16_type
+	},
+	{
+	  NGM_VLAN_COOKIE,
+	  NGM_VLAN_SET_ENCAP_PROTO,
+	  "setencapproto",
+	  &ng_parse_hint16_type,
+	  NULL
+	},
 	{ 0 }
 };
 
@@ -127,44 +193,40 @@
 };
 NETGRAPH_INIT(vlan, &ng_vlan_typestruct);
 
-struct filter {
-	LIST_ENTRY(filter) next;
-	u_int16_t	vlan;
-	hook_p		hook;
-};
 
-#define	HASHSIZE	16
-#define	HASH(id)	((((id) >> 8) ^ ((id) >> 4) ^ (id)) & 0x0f)
-LIST_HEAD(filterhead, filter);
+/*
+ * Helper functions.
+ */
 
-typedef struct {
-	hook_p		downstream_hook;
-	hook_p		nomatch_hook;
-	struct filterhead hashtable[HASHSIZE];
-	u_int32_t	nent;
-} *priv_p;
-
-static struct filter *
-ng_vlan_findentry(priv_p priv, u_int16_t vlan)
+static __inline int
+m_chk(struct mbuf **mp, int len)
 {
-	struct filterhead *chain = &priv->hashtable[HASH(vlan)];
-	struct filter *f;
 
-	LIST_FOREACH(f, chain, next)
-		if (f->vlan == vlan)
-			return (f);
-	return (NULL);
+	if ((*mp)->m_pkthdr.len < len) {
+		m_freem((*mp));
+		(*mp) = NULL;
+		return (EINVAL);
+	}
+	if ((*mp)->m_len < len && ((*mp) = m_pullup((*mp), len)) == NULL)
+		return (ENOBUFS);
+
+	return (0);
 }
 
+
+/*
+ * Netgraph node functions.
+ */
+
 static int
 ng_vlan_constructor(node_p node)
 {
 	priv_p priv;
-	int i;
 
 	priv = malloc(sizeof(*priv), M_NETGRAPH, M_WAITOK | M_ZERO);
-	for (i = 0; i < HASHSIZE; i++)
-		LIST_INIT(&priv->hashtable[i]);
+	priv->decap_enable = 0;
+	priv->encap_enable = VLAN_ENCAP_FROM_FILTER;
+	priv->encap_proto = htons(ETHERTYPE_VLAN);
 	NG_NODE_SET_PRIVATE(node, priv);
 	return (0);
 }
@@ -192,13 +254,14 @@
 ng_vlan_rcvmsg(node_p node, item_p item, hook_p lasthook)
 {
 	const priv_p priv = NG_NODE_PRIVATE(node);
-	int error = 0;
 	struct ng_mesg *msg, *resp = NULL;
 	struct ng_vlan_filter *vf;
-	struct filter *f;
 	hook_p hook;
 	struct ng_vlan_table *t;
-	int i;
+	uintptr_t hook_data;
+	int i, vlan_count;
+	uint16_t vid;
+	int error = 0;
 
 	NGI_GET_MSG(item, msg);
 	/* Deal with message according to cookie and command. */
@@ -213,12 +276,23 @@
 			}
 			vf = (struct ng_vlan_filter *)msg->data;
 			/* Sanity check the VLAN ID value. */
-			if (vf->vlan & ~EVL_VLID_MASK) {
+#ifdef	NG_VLAN_USE_OLD_VLAN_NAME
+			if (vf->vid == 0 && vf->vid != vf->vlan) {
+				vf->vid = vf->vlan;
+			} else if (vf->vid != 0 && vf->vlan != 0 &&
+			    vf->vid != vf->vlan) {
 				error = EINVAL;
 				break;
 			}
+#endif
+			if (vf->vid & ~EVL_VLID_MASK ||
+			    vf->pcp & ~7 ||
+			    vf->cfi & ~1) {
+				error = EINVAL;
+				break;
+			}
 			/* Check that a referenced hook exists. */
-			hook = ng_findhook(node, vf->hook);
+			hook = ng_findhook(node, vf->hook_name);
 			if (hook == NULL) {
 				error = ENOENT;
 				break;
@@ -230,30 +304,20 @@
 				break;
 			}
 			/* And is not already in service. */
-			if (NG_HOOK_PRIVATE(hook) != NULL) {
+			if (IS_HOOK_VLAN_SET(NG_HOOK_PRIVATE(hook))) {
 				error = EEXIST;
 				break;
 			}
 			/* Check we don't already trap this VLAN. */
-			if (ng_vlan_findentry(priv, vf->vlan)) {
+			if (priv->vlan_hook[vf->vid] != NULL) {
 				error = EEXIST;
 				break;
 			}
-			/* Create filter. */
-			f = malloc(sizeof(*f),
-			    M_NETGRAPH, M_NOWAIT | M_ZERO);
-			if (f == NULL) {
-				error = ENOMEM;
-				break;
-			}
-			/* Link filter and hook together. */
-			f->hook = hook;
-			f->vlan = vf->vlan;
-			NG_HOOK_SET_PRIVATE(hook, f);
-			/* Register filter in a hash table. */
-			LIST_INSERT_HEAD(
-			    &priv->hashtable[HASH(f->vlan)], f, next);
-			priv->nent++;
+			/* Link vlan and hook together. */
+			NG_HOOK_SET_PRIVATE(hook,
+			    (void *)(HOOK_VLAN_TAG_SET_MASK |
+			    EVL_MAKETAG(vf->vid, vf->pcp, vf->cfi)));
+			priv->vlan_hook[vf->vid] = hook;
 			break;
 		case NGM_VLAN_DEL_FILTER:
 			/* Check that message is long enough. */
@@ -263,37 +327,151 @@
 			}
 			/* Check that hook exists and is active. */
 			hook = ng_findhook(node, (char *)msg->data);
-			if (hook == NULL ||
-			    (f = NG_HOOK_PRIVATE(hook)) == NULL) {
+			if (hook == NULL) {
 				error = ENOENT;
 				break;
 			}
+			hook_data = (uintptr_t)NG_HOOK_PRIVATE(hook);
+			if (IS_HOOK_VLAN_SET(hook_data) == 0) {
+				error = ENOENT;
+				break;
+			}
+
+			KASSERT(priv->vlan_hook[EVL_VLANOFTAG(hook_data)] == hook,
+			    ("%s: NGM_VLAN_DEL_FILTER: Invalid VID for Hook = %s\n",
+			    __func__, (char *)msg->data));
+
 			/* Purge a rule that refers to this hook. */
+			priv->vlan_hook[EVL_VLANOFTAG(hook_data)] = NULL;
 			NG_HOOK_SET_PRIVATE(hook, NULL);
-			LIST_REMOVE(f, next);
-			priv->nent--;
-			free(f, M_NETGRAPH);
 			break;
+		case NGM_VLAN_DEL_VID_FLT:
+			/* Check that message is long enough. */
+			if (msg->header.arglen != sizeof(uint16_t)) {
+				error = EINVAL;
+				break;
+			}
+			vid = (*((uint16_t *)msg->data));
+			/* Sanity check the VLAN ID value. */
+			if (vid & ~EVL_VLID_MASK) {
+				error = EINVAL;
+				break;
+			}
+			/* Check that hook exists and is active. */
+			hook = priv->vlan_hook[vid];
+			if (hook == NULL) {
+				error = ENOENT;
+				break;
+			}
+			hook_data = (uintptr_t)NG_HOOK_PRIVATE(hook);
+			if (IS_HOOK_VLAN_SET(hook_data) == 0) {
+				error = ENOENT;
+				break;
+			}
+
+			KASSERT(EVL_VLANOFTAG(hook_data) == vid,
+			    ("%s: NGM_VLAN_DEL_VID_FLT:"
+			    " Invalid VID Hook = %us, must be: %us\n",
+			    __func__, (uint16_t )EVL_VLANOFTAG(hook_data),
+			    vid));
+
+			/* Purge a rule that refers to this hook. */
+			priv->vlan_hook[vid] = NULL;
+			NG_HOOK_SET_PRIVATE(hook, NULL);
+			break;
 		case NGM_VLAN_GET_TABLE:
+			/* Calculate vlans. */
+			vlan_count = 0;
+			for (i = 0; i < (EVL_VLID_MASK + 1); i ++) {
+				if (priv->vlan_hook[i] != NULL &&
+				    NG_HOOK_IS_VALID(priv->vlan_hook[i]))
+					vlan_count ++;
+			}
+
+			/* Allocate memory for responce. */
 			NG_MKRESPONSE(resp, msg, sizeof(*t) +
-			    priv->nent * sizeof(*t->filter), M_NOWAIT);
+			    vlan_count * sizeof(*t->filter), M_NOWAIT);
 			if (resp == NULL) {
 				error = ENOMEM;
 				break;
 			}
+
+			/* Pack data to responce. */
 			t = (struct ng_vlan_table *)resp->data;
-			t->n = priv->nent;
+			t->n = 0;
 			vf = &t->filter[0];
-			for (i = 0; i < HASHSIZE; i++) {
-				LIST_FOREACH(f, &priv->hashtable[i], next) {
-					vf->vlan = f->vlan;
-					strncpy(vf->hook, NG_HOOK_NAME(f->hook),
-					    NG_HOOKSIZ);
-					vf++;
-				}
+			for (i = 0; i < (EVL_VLID_MASK + 1); i ++) {
+				hook = priv->vlan_hook[i];
+				if (hook == NULL || NG_HOOK_NOT_VALID(hook))
+					continue;
+				hook_data = (uintptr_t)NG_HOOK_PRIVATE(hook);
+				if (IS_HOOK_VLAN_SET(hook_data) == 0)
+					continue;
+
+				KASSERT(EVL_VLANOFTAG(hook_data) == i,
+				    ("%s: NGM_VLAN_GET_TABLE:"
+				    " hook %s VID = %us, must be: %i\n",
+				    __func__, NG_HOOK_NAME(hook),
+				    (uint16_t)EVL_VLANOFTAG(hook_data), i));
+
+#ifdef	NG_VLAN_USE_OLD_VLAN_NAME
+				vf->vlan = i;
+#endif
+				vf->vid = i;
+				vf->pcp = EVL_PRIOFTAG(hook_data);
+				vf->cfi = EVL_CFIOFTAG(hook_data);
+				strncpy(vf->hook_name,
+				    NG_HOOK_NAME(hook), NG_HOOKSIZ);
+				vf ++;
+				t->n ++;
 			}
 			break;
-		default:		/* Unknown command. */
+		case NGM_VLAN_GET_DECAP:
+			NG_MKRESPONSE(resp, msg, sizeof(uint32_t), M_NOWAIT);
+			if (resp == NULL) {
+				error = ENOMEM;
+				break;
+			}
+			(*((uint32_t *)resp->data)) = priv->decap_enable;
+			break;
+		case NGM_VLAN_SET_DECAP:
+			if (msg->header.arglen != sizeof(uint32_t)) {
+				error = EINVAL;
+				break;
+			}
+			priv->decap_enable = (*((uint32_t *)msg->data));
+			break;
+		case NGM_VLAN_GET_ENCAP:
+			NG_MKRESPONSE(resp, msg, sizeof(uint32_t), M_NOWAIT);
+			if (resp == NULL) {
+				error = ENOMEM;
+				break;
+			}
+			(*((uint32_t *)resp->data)) = priv->encap_enable;
+			break;
+		case NGM_VLAN_SET_ENCAP:
+			if (msg->header.arglen != sizeof(uint32_t)) {
+				error = EINVAL;
+				break;
+			}
+			priv->encap_enable = (*((uint32_t *)msg->data));
+			break;
+		case NGM_VLAN_GET_ENCAP_PROTO:
+			NG_MKRESPONSE(resp, msg, sizeof(uint16_t), M_NOWAIT);
+			if (resp == NULL) {
+				error = ENOMEM;
+				break;
+			}
+			(*((uint16_t *)resp->data)) = ntohs(priv->encap_proto);
+			break;
+		case NGM_VLAN_SET_ENCAP_PROTO:
+			if (msg->header.arglen != sizeof(uint16_t)) {
+				error = EINVAL;
+				break;
+			}
+			priv->encap_proto = htons((*((uint16_t *)msg->data)));
+			break;
+		default: /* Unknown command. */
 			error = EINVAL;
 			break;
 		}
@@ -301,8 +479,6 @@
 	case NGM_FLOW_COOKIE:
 	    {
 		struct ng_mesg *copy;
-		struct filterhead *chain;
-		struct filter *f;
 
 		/*
 		 * Flow control messages should come only
@@ -313,20 +489,20 @@
 			break;
 		if (lasthook != priv->downstream_hook)
 			break;
+		/* Broadcast the event to all uplinks. */
+		for (i = 0; i < (EVL_VLID_MASK + 1); i ++) {
+			if (priv->vlan_hook[i] == NULL)
+				continue;
 
-		/* Broadcast the event to all uplinks. */
-		for (i = 0, chain = priv->hashtable; i < HASHSIZE;
-		    i++, chain++)
-		LIST_FOREACH(f, chain, next) {
 			NG_COPYMESSAGE(copy, msg, M_NOWAIT);
 			if (copy == NULL)
 				continue;
-			NG_SEND_MSG_HOOK(error, node, copy, f->hook, 0);
+			NG_SEND_MSG_HOOK(error, node, copy,
+			    priv->vlan_hook[i], 0);
 		}
-
 		break;
 	    }
-	default:			/* Unknown type cookie. */
+	default: /* Unknown type cookie. */
 		error = EINVAL;
 		break;
 	}
@@ -340,19 +516,21 @@
 {
 	const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
 	struct ether_header *eh;
-	struct ether_vlan_header *evl = NULL;
+	struct ether_vlan_header *evl;
 	int error;
-	u_int16_t vlan;
+	uintptr_t hook_data;
+	uint16_t vid, eth_vtag;
 	struct mbuf *m;
-	struct filter *f;
+	hook_p dst_hook;
 
+
+	NGI_GET_M(item, m);
+
 	/* Make sure we have an entire header. */
-	NGI_GET_M(item, m);
-	if (m->m_len < sizeof(*eh) &&
-	    (m = m_pullup(m, sizeof(*eh))) == NULL) {
-		NG_FREE_ITEM(item);
-		return (EINVAL);
-	}
+	error = m_chk(&m, ETHER_HDR_LEN);
+	if (error != 0)
+		goto mchk_err;
+
 	eh = mtod(m, struct ether_header *);
 	if (hook == priv->downstream_hook) {
 		/*
@@ -359,42 +537,68 @@
 		 * If from downstream, select between a match hook
 		 * or the nomatch hook.
 		 */
-		if (m->m_flags & M_VLANTAG ||
-		    eh->ether_type == htons(ETHERTYPE_VLAN)) {
-			if (m->m_flags & M_VLANTAG) {
-				/*
-				 * Packet is tagged, m contains a normal
-				 * Ethernet frame; tag is stored out-of-band.
-				 */
-				vlan = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag);
-			} else {
-				if (m->m_len < sizeof(*evl) &&
-				    (m = m_pullup(m, sizeof(*evl))) == NULL) {
-					NG_FREE_ITEM(item);
-					return (EINVAL);
-				}
-				evl = mtod(m, struct ether_vlan_header *);
-				vlan = EVL_VLANOFTAG(ntohs(evl->evl_tag));
+
+		dst_hook = priv->nomatch_hook;
+
+		/* Skip packets without tag. */
+		if ((m->m_flags & M_VLANTAG) == 0 &&
+		    eh->ether_type != priv->encap_proto) {
+			if (dst_hook == NULL)
+				goto net_down;
+			goto send_packet;
+		}
+
+		/* Process packets with tag. */
+		if (m->m_flags & M_VLANTAG) {
+			/*
+			 * Packet is tagged, m contains a normal
+			 * Ethernet frame; tag is stored out-of-band.
+			 */
+			evl = NULL;
+			vid = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag);
+		} else { /* eh->ether_type == priv->encap_proto */
+			error = m_chk(&m, ETHER_VLAN_HDR_LEN);
+			if (error != 0)
+				goto mchk_err;
+			evl = mtod(m, struct ether_vlan_header *);
+			vid = EVL_VLANOFTAG(ntohs(evl->evl_tag));
+		}
+
+		if (priv->vlan_hook[vid] != NULL) {
+			/*
+			 * VLAN filter: allways remove vlan tags and
+			 * decapsulate packet.
+			 */
+			dst_hook = priv->vlan_hook[vid];
+			if (evl == NULL) { /* m->m_flags & M_VLANTAG */
+				m->m_pkthdr.ether_vtag = 0;
+				m->m_flags &= ~M_VLANTAG;
+				goto send_packet;
 			}
-			if ((f = ng_vlan_findentry(priv, vlan)) != NULL) {
-				if (m->m_flags & M_VLANTAG) {
-					m->m_pkthdr.ether_vtag = 0;
-					m->m_flags &= ~M_VLANTAG;
-				} else {
-					evl->evl_encap_proto = evl->evl_proto;
-					bcopy(mtod(m, caddr_t),
-					    mtod(m, caddr_t) +
-					    ETHER_VLAN_ENCAP_LEN,
-					    ETHER_HDR_LEN);
-					m_adj(m, ETHER_VLAN_ENCAP_LEN);
-				}
-			}
-		} else
-			f = NULL;
-		if (f != NULL)
-			NG_FWD_NEW_DATA(error, item, f->hook, m);
-		else
-			NG_FWD_NEW_DATA(error, item, priv->nomatch_hook, m);
+		} else { /* nomatch_hook */
+			if (dst_hook == NULL)
+				goto net_down;
+			if (evl == NULL || priv->decap_enable == 0)
+				goto send_packet;
+			/* Save tag out-of-band. */
+			m->m_pkthdr.ether_vtag = ntohs(evl->evl_tag);
+			m->m_flags |= M_VLANTAG;
+		}
+
+		/*
+		 * Decapsulate:
+		 * TPID = ether type encap
+		 * Move DstMAC and SrcMAC to ETHER_TYPE.
+		 * Before:
+		 *  [dmac] [smac] [TPID] [PCP/CFI/VID] [ether_type] [payload]
+		 *  |-----------| >>>>>>>>>>>>>>>>>>>> |--------------------|
+		 * After:
+		 *  [free space ] [dmac] [smac] [ether_type] [payload]
+		 *                |-----------| |--------------------|
+		 */
+		bcopy((char *)evl, ((char *)evl + ETHER_VLAN_ENCAP_LEN),
+		    (ETHER_ADDR_LEN * 2));
+		m_adj(m, ETHER_VLAN_ENCAP_LEN);
 	} else {
 		/*
 		 * It is heading towards the downstream.
@@ -401,33 +605,75 @@
 		 * If from nomatch, pass it unmodified.
 		 * Otherwise, do the VLAN encapsulation.
 		 */
-		if (hook != priv->nomatch_hook) {
-			if ((f = NG_HOOK_PRIVATE(hook)) == NULL) {
-				NG_FREE_ITEM(item);
-				NG_FREE_M(m);
-				return (EOPNOTSUPP);
+		dst_hook = priv->downstream_hook;
+		if (dst_hook == NULL)
+			goto net_down;
+		if (hook != priv->nomatch_hook) {/* Filter hook. */
+			hook_data = (uintptr_t)NG_HOOK_PRIVATE(hook);
+			if (IS_HOOK_VLAN_SET(hook_data) == 0) {
+				/*
+				 * Packet from hook not in filter
+				 * call addfilter for this hook to fix.
+				 */
+				error = EOPNOTSUPP;
+				goto drop;
 			}
-			M_PREPEND(m, ETHER_VLAN_ENCAP_LEN, M_DONTWAIT);
-			/* M_PREPEND takes care of m_len and m_pkthdr.len. */
-			if (m == NULL || (m->m_len < sizeof(*evl) &&
-			    (m = m_pullup(m, sizeof(*evl))) == NULL)) {
-				NG_FREE_ITEM(item);
-				return (ENOMEM);
+			eth_vtag = (hook_data & VLAN_TAG_MASK);
+			if ((priv->encap_enable & VLAN_ENCAP_FROM_FILTER) == 0) {
+				/* Just set packet header tag and send. */
+				m->m_flags |= M_VLANTAG;
+				m->m_pkthdr.ether_vtag = eth_vtag;
+				goto send_packet;
 			}
-			/*
-			 * Transform the Ethernet header into an Ethernet header
-			 * with 802.1Q encapsulation.
-			 */
-			bcopy(mtod(m, char *) + ETHER_VLAN_ENCAP_LEN,
-			    mtod(m, char *), ETHER_HDR_LEN);
-			evl = mtod(m, struct ether_vlan_header *);
-			evl->evl_proto = evl->evl_encap_proto;
-			evl->evl_encap_proto = htons(ETHERTYPE_VLAN);
-			evl->evl_tag = htons(f->vlan);
+		} else { /* nomatch_hook */
+			if ((priv->encap_enable & VLAN_ENCAP_FROM_NOMATCH) == 0 ||
+			    (m->m_flags & M_VLANTAG) == 0)
+				goto send_packet;
+			/* Encapsulate tagged packet. */
+			eth_vtag = m->m_pkthdr.ether_vtag;
+			m->m_pkthdr.ether_vtag = 0;
+			m->m_flags &= ~M_VLANTAG;
 		}
-		NG_FWD_NEW_DATA(error, item, priv->downstream_hook, m);
+
+		/*
+		 * Transform the Ethernet header into an Ethernet header
+		 * with 802.1Q encapsulation.
+		 * Mod of: ether_vlanencap.
+		 *
+		 * TPID = ether type encap
+		 * Move DstMAC and SrcMAC from ETHER_TYPE.
+		 * Before:
+		 *  [free space ] [dmac] [smac] [ether_type] [payload]
+		 *  <<<<<<<<<<<<< |-----------| |--------------------|
+		 * After:
+		 *  [dmac] [smac] [TPID] [PCP/CFI/VID] [ether_type] [payload]
+		 *  |-----------| |-- inserted tag --| |--------------------|
+		 */
+		M_PREPEND(m, ETHER_VLAN_ENCAP_LEN, M_NOWAIT);
+		if (m == NULL)
+			error = ENOMEM;
+		else
+			error = m_chk(&m, ETHER_VLAN_HDR_LEN);
+		if (error != 0)
+			goto mchk_err;
+
+		evl = mtod(m, struct ether_vlan_header *);
+		bcopy(((char *)evl + ETHER_VLAN_ENCAP_LEN),
+		    (char *)evl, (ETHER_ADDR_LEN * 2));
+		evl->evl_encap_proto = priv->encap_proto;
+		evl->evl_tag = htons(eth_vtag);
 	}
+
+send_packet:
+	NG_FWD_NEW_DATA(error, item, dst_hook, m);
 	return (error);
+net_down:
+	error = ENETDOWN;
+drop:
+	m_freem(m);
+mchk_err:
+	NG_FREE_ITEM(item);
+	return (error);
 }
 
 static int
@@ -445,7 +691,7 @@
 ng_vlan_disconnect(hook_p hook)
 {
 	const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
-	struct filter *f;
+	uintptr_t hook_data;
 
 	if (hook == priv->downstream_hook)
 		priv->downstream_hook = NULL;
@@ -453,11 +699,9 @@
 		priv->nomatch_hook = NULL;
 	else {
 		/* Purge a rule that refers to this hook. */
-		if ((f = NG_HOOK_PRIVATE(hook)) != NULL) {
-			LIST_REMOVE(f, next);
-			priv->nent--;
-			free(f, M_NETGRAPH);
-		}
+		hook_data = (uintptr_t)NG_HOOK_PRIVATE(hook);
+		if (IS_HOOK_VLAN_SET(hook_data))
+			priv->vlan_hook[EVL_VLANOFTAG(hook_data)] = NULL;
 	}
 	NG_HOOK_SET_PRIVATE(hook, NULL);
 	if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) &&

Modified: trunk/sys/netgraph/ng_vlan.h
===================================================================
--- trunk/sys/netgraph/ng_vlan.h	2018-05-25 20:03:52 UTC (rev 9935)
+++ trunk/sys/netgraph/ng_vlan.h	2018-05-25 20:03:57 UTC (rev 9936)
@@ -1,6 +1,7 @@
 /* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003 IPNET Internet Communication Company
+ * Copyright (c) 2011 - 2012 Rozhuk Ivan <rozhuk.im at gmail.com>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,12 +27,15 @@
  *
  * Author: Ruslan Ermilov <ru at FreeBSD.org>
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/sys/netgraph/ng_vlan.h 232825 2012-03-11 19:08:56Z adrian $
  */
 
 #ifndef _NETGRAPH_NG_VLAN_H_
 #define	_NETGRAPH_NG_VLAN_H_
 
+/* Using "vlan" in addfilter and gettable messages. 2012.01 */
+#define	NG_VLAN_USE_OLD_VLAN_NAME 1
+
 /* Node type name and magic cookie. */
 #define	NG_VLAN_NODE_TYPE	"vlan"
 #define	NGM_VLAN_COOKIE		1068486472
@@ -44,22 +48,51 @@
 enum {
 	NGM_VLAN_ADD_FILTER = 1,
 	NGM_VLAN_DEL_FILTER,
-	NGM_VLAN_GET_TABLE
+	NGM_VLAN_GET_TABLE,
+	NGM_VLAN_DEL_VID_FLT,
+	NGM_VLAN_GET_DECAP,
+	NGM_VLAN_SET_DECAP,
+	NGM_VLAN_GET_ENCAP,
+	NGM_VLAN_SET_ENCAP,
+	NGM_VLAN_GET_ENCAP_PROTO,
+	NGM_VLAN_SET_ENCAP_PROTO,
 };
 
+#define	VLAN_ENCAP_FROM_FILTER	0x00000001
+#define	VLAN_ENCAP_FROM_NOMATCH	0x00000002
+
 /* For NGM_VLAN_ADD_FILTER control message. */
 struct ng_vlan_filter {
-	char		hook[NG_HOOKSIZ];
-	u_int16_t	vlan;
-};	
+	char		hook_name[NG_HOOKSIZ];
+#ifdef	NG_VLAN_USE_OLD_VLAN_NAME
+	uint16_t	vlan;	/* VLAN - same as vid, oldname, deprecated. */
+#endif
+	uint16_t	vid;	/* VID - VLAN Identifier. */
+	uint8_t		pcp;	/* PCP - Priority Code Point. */
+	uint8_t		cfi;	/* CFI - Canonical Format Indicator. */
+};
 
 /* Keep this in sync with the above structure definition.  */
+#ifdef	NG_VLAN_USE_OLD_VLAN_NAME
 #define	NG_VLAN_FILTER_FIELDS	{				\
-	{ "hook",	&ng_parse_hookbuf_type  },		\
-	{ "vlan",	&ng_parse_uint16_type   },		\
+	{ "hook",	&ng_parse_hookbuf_type	},		\
+	{ "vlan",	&ng_parse_uint16_type	},		\
+	{ "vid",	&ng_parse_uint16_type	},		\
+	{ "pcp",	&ng_parse_uint8_type	},		\
+	{ "cfi",	&ng_parse_uint8_type	},		\
 	{ NULL }						\
 }
+#else
+#define	NG_VLAN_FILTER_FIELDS	{				\
+	{ "hook",	&ng_parse_hookbuf_type	},		\
+	{ "vid",	&ng_parse_uint16_type	},		\
+	{ "pcp",	&ng_parse_uint8_type	},		\
+	{ "cfi",	&ng_parse_uint8_type	},		\
+	{ NULL }						\
+}
+#endif
 
+
 /* Structure returned by NGM_VLAN_GET_TABLE. */
 struct ng_vlan_table {
 	u_int32_t	n;



More information about the Midnightbsd-cvs mailing list