Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 25 Jun 2011 02:08:17 +0900
From:      rozhuk.im@gmail.com
To:        <freebsd-net@freebsd.org>
Subject:   ng_vlan improvements
Message-ID:  <4e04c489.d899cc0a.43e4.4ad6@mx.google.com>

next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.

------=_NextPart_000_0001_01CC32DC.C33B2950
Content-Type: text/plain;
	charset="windows-1251"
Content-Transfer-Encoding: quoted-printable


Diffs

=A0
--
Rozhuk Ivan
=A0=20



------=_NextPart_000_0001_01CC32DC.C33B2950
Content-Type: application/octet-stream;
	name="ng_vlan.h.orig.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="ng_vlan.h.orig.patch"

--- ng_vlan.h.orig	2009-08-03 17:13:06.000000000 +0900=0A=
+++ ng_vlan.h	2011-06-24 05:35:05.000000000 +0900=0A=
@@ -43,7 +43,9 @@=0A=
 enum {=0A=
 	NGM_VLAN_ADD_FILTER =3D 1,=0A=
 	NGM_VLAN_DEL_FILTER,=0A=
-	NGM_VLAN_GET_TABLE=0A=
+	NGM_VLAN_GET_TABLE,=0A=
+	NGM_VLAN_GET_ENCAP,=0A=
+	NGM_VLAN_SET_ENCAP=0A=
 };=0A=
 =0A=
 /* For NGM_VLAN_ADD_FILTER control message. */=0A=

------=_NextPart_000_0001_01CC32DC.C33B2950
Content-Type: application/octet-stream;
	name="ng_vlan.c.orig.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="ng_vlan.c.orig.patch"

--- ng_vlan.c.orig	2009-08-03 17:13:06.000000000 +0900=0A=
+++ ng_vlan.c	2011-06-24 21:00:22.000000000 +0900=0A=
@@ -110,6 +110,20 @@=0A=
 	  NULL,=0A=
 	  &ng_vlan_table_type=0A=
 	},=0A=
+	{=0A=
+	  NGM_VLAN_COOKIE,=0A=
+	  NGM_VLAN_GET_ENCAP,=0A=
+	  "getencap",=0A=
+	  NULL,=0A=
+	  &ng_parse_int32_type=0A=
+	},=0A=
+	{=0A=
+	  NGM_VLAN_COOKIE,=0A=
+	  NGM_VLAN_SET_ENCAP,=0A=
+	  "setencap",=0A=
+	  &ng_parse_int32_type,=0A=
+	  NULL=0A=
+	},=0A=
 	{ 0 }=0A=
 };=0A=
 =0A=
@@ -126,47 +140,27 @@=0A=
 };=0A=
 NETGRAPH_INIT(vlan, &ng_vlan_typestruct);=0A=
 =0A=
-struct filter {=0A=
-	LIST_ENTRY(filter) next;=0A=
-	u_int16_t	vlan;=0A=
-	hook_p		hook;=0A=
-};=0A=
 =0A=
-#define	HASHSIZE	16=0A=
-#define	HASH(id)	((((id) >> 8) ^ ((id) >> 4) ^ (id)) & 0x0f)=0A=
-LIST_HEAD(filterhead, filter);=0A=
 =0A=
 typedef struct {=0A=
 	hook_p		downstream_hook;=0A=
 	hook_p		nomatch_hook;=0A=
-	struct filterhead hashtable[HASHSIZE];=0A=
-	u_int32_t	nent;=0A=
+	hook_p		vlan_hook[(EVL_VLID_MASK + 1)];=0A=
+	int		vlan_encap;=0A=
 } *priv_p;=0A=
+#define HOOK_VLAN_SET_MASK ((uintptr_t)((~0) & ~(EVL_VLID_MASK)))=0A=
 =0A=
-static struct filter *=0A=
-ng_vlan_findentry(priv_p priv, u_int16_t vlan)=0A=
-{=0A=
-	struct filterhead *chain =3D &priv->hashtable[HASH(vlan)];=0A=
-	struct filter *f;=0A=
-=0A=
-	LIST_FOREACH(f, chain, next)=0A=
-		if (f->vlan =3D=3D vlan)=0A=
-			return (f);=0A=
-	return (NULL);=0A=
-}=0A=
 =0A=
 static int=0A=
 ng_vlan_constructor(node_p node)=0A=
 {=0A=
 	priv_p priv;=0A=
-	int i;=0A=
 =0A=
 	priv =3D malloc(sizeof(*priv), M_NETGRAPH, M_NOWAIT | M_ZERO);=0A=
 	if (priv =3D=3D NULL)=0A=
 		return (ENOMEM);=0A=
-	for (i =3D 0; i < HASHSIZE; i++)=0A=
-		LIST_INIT(&priv->hashtable[i]);=0A=
-	NG_NODE_SET_PRIVATE(node, priv);=0A=
+	priv->vlan_encap =3D 1;=0A=
+=0A=
 	return (0);=0A=
 }=0A=
 =0A=
@@ -193,13 +187,12 @@=0A=
 ng_vlan_rcvmsg(node_p node, item_p item, hook_p lasthook)=0A=
 {=0A=
 	const priv_p priv =3D NG_NODE_PRIVATE(node);=0A=
-	int error =3D 0;=0A=
 	struct ng_mesg *msg, *resp =3D NULL;=0A=
 	struct ng_vlan_filter *vf;=0A=
-	struct filter *f;=0A=
 	hook_p hook;=0A=
 	struct ng_vlan_table *t;=0A=
-	int i;=0A=
+	uintptr_t vlan, vlan_count;=0A=
+	int error =3D 0;=0A=
 =0A=
 	NGI_GET_MSG(item, msg);=0A=
 	/* Deal with message according to cookie and command. */=0A=
@@ -231,30 +224,18 @@=0A=
 				break;=0A=
 			}=0A=
 			/* And is not already in service. */=0A=
-			if (NG_HOOK_PRIVATE(hook) !=3D NULL) {=0A=
+			if (((uintptr_t)NG_HOOK_PRIVATE(hook) & HOOK_VLAN_SET_MASK) =3D=3D =
HOOK_VLAN_SET_MASK) {=0A=
 				error =3D EEXIST;=0A=
 				break;=0A=
 			}=0A=
 			/* Check we don't already trap this VLAN. */=0A=
-			if (ng_vlan_findentry(priv, vf->vlan)) {=0A=
+			if (priv->vlan_hook[vf->vlan] !=3D NULL) {=0A=
 				error =3D EEXIST;=0A=
 				break;=0A=
 			}=0A=
-			/* Create filter. */=0A=
-			f =3D malloc(sizeof(*f),=0A=
-			    M_NETGRAPH, M_NOWAIT | M_ZERO);=0A=
-			if (f =3D=3D NULL) {=0A=
-				error =3D ENOMEM;=0A=
-				break;=0A=
-			}=0A=
-			/* Link filter and hook together. */=0A=
-			f->hook =3D hook;=0A=
-			f->vlan =3D vf->vlan;=0A=
-			NG_HOOK_SET_PRIVATE(hook, f);=0A=
-			/* Register filter in a hash table. */=0A=
-			LIST_INSERT_HEAD(=0A=
-			    &priv->hashtable[HASH(f->vlan)], f, next);=0A=
-			priv->nent++;=0A=
+			/* Link vlan and hook together. */=0A=
+			priv->vlan_hook[vf->vlan] =3D hook;=0A=
+			NG_HOOK_SET_PRIVATE(hook, (void *)(HOOK_VLAN_SET_MASK | vf->vlan));=0A=
 			break;=0A=
 		case NGM_VLAN_DEL_FILTER:=0A=
 			/* Check that message is long enough. */=0A=
@@ -264,35 +245,64 @@=0A=
 			}=0A=
 			/* Check that hook exists and is active. */=0A=
 			hook =3D ng_findhook(node, (char *)msg->data);=0A=
-			if (hook =3D=3D NULL ||=0A=
-			    (f =3D NG_HOOK_PRIVATE(hook)) =3D=3D NULL) {=0A=
+			if (hook =3D=3D NULL)=0A=
+				error =3D ENOENT;=0A=
+				break;=0A=
+			vlan =3D (uintptr_t)NG_HOOK_PRIVATE(hook);=0A=
+			if ((vlan & HOOK_VLAN_SET_MASK) !=3D HOOK_VLAN_SET_MASK) {=0A=
 				error =3D ENOENT;=0A=
 				break;=0A=
 			}=0A=
+			vlan &=3D EVL_VLID_MASK; /* remove HOOK_VLAN_SET_MASK from vlan num =
*/=0A=
+=0A=
 			/* Purge a rule that refers to this hook. */=0A=
 			NG_HOOK_SET_PRIVATE(hook, NULL);=0A=
-			LIST_REMOVE(f, next);=0A=
-			priv->nent--;=0A=
-			free(f, M_NETGRAPH);=0A=
+			priv->vlan_hook[vlan] =3D NULL;=0A=
 			break;=0A=
 		case NGM_VLAN_GET_TABLE:=0A=
+			/* calculate vlans */=0A=
+			vlan_count =3D 0;=0A=
+			for (vlan =3D 0; vlan < (EVL_VLID_MASK + 1); vlan ++) {=0A=
+				if (priv->vlan_hook[vlan] !=3D NULL)=0A=
+					vlan_count ++;=0A=
+			}=0A=
+=0A=
+			/* allocate memory for responce */=0A=
 			NG_MKRESPONSE(resp, msg, sizeof(*t) +=0A=
-			    priv->nent * sizeof(*t->filter), M_NOWAIT);=0A=
+			    vlan_count * sizeof(*t->filter), M_NOWAIT);=0A=
 			if (resp =3D=3D NULL) {=0A=
 				error =3D ENOMEM;=0A=
 				break;=0A=
 			}=0A=
+=0A=
+			/* pack data to responce */=0A=
 			t =3D (struct ng_vlan_table *)resp->data;=0A=
-			t->n =3D priv->nent;=0A=
+			t->n =3D vlan_count;=0A=
 			vf =3D &t->filter[0];=0A=
-			for (i =3D 0; i < HASHSIZE; i++) {=0A=
-				LIST_FOREACH(f, &priv->hashtable[i], next) {=0A=
-					vf->vlan =3D f->vlan;=0A=
-					strncpy(vf->hook, NG_HOOK_NAME(f->hook),=0A=
+			for (vlan =3D 0; vlan < (EVL_VLID_MASK + 1); vlan ++) {=0A=
+				if (priv->vlan_hook[vlan] =3D=3D NULL)=0A=
+					continue;=0A=
+=0A=
+				vf->vlan =3D vlan;=0A=
+				strncpy(vf->hook, NG_HOOK_NAME(priv->vlan_hook[vlan]),=0A=
 					    NG_HOOKSIZ);=0A=
-					vf++;=0A=
-				}=0A=
+				vf ++;=0A=
+			}=0A=
+			break;=0A=
+		case NGM_VLAN_GET_ENCAP:=0A=
+			NG_MKRESPONSE(resp, msg, sizeof(u_int32_t), M_NOWAIT);=0A=
+			if (resp =3D=3D NULL) {=0A=
+				error =3D ENOMEM;=0A=
+				break;=0A=
 			}=0A=
+			(*((u_int32_t *)resp->data)) =3D priv->vlan_encap;=0A=
+			break;=0A=
+		case NGM_VLAN_SET_ENCAP:=0A=
+			if (msg->header.arglen !=3D sizeof(u_int32_t)) {=0A=
+				error =3D EINVAL;=0A=
+				break;=0A=
+			}=0A=
+			priv->vlan_encap =3D ((*((u_int32_t *)msg->data)) !=3D 0);=0A=
 			break;=0A=
 		default:		/* Unknown command. */=0A=
 			error =3D EINVAL;=0A=
@@ -302,8 +312,6 @@=0A=
 	case NGM_FLOW_COOKIE:=0A=
 	    {=0A=
 		struct ng_mesg *copy;=0A=
-		struct filterhead *chain;=0A=
-		struct filter *f;=0A=
 =0A=
 		/*=0A=
 		 * Flow control messages should come only=0A=
@@ -316,15 +324,15 @@=0A=
 			break;=0A=
 =0A=
 		/* Broadcast the event to all uplinks. */=0A=
-		for (i =3D 0, chain =3D priv->hashtable; i < HASHSIZE;=0A=
-		    i++, chain++)=0A=
-		LIST_FOREACH(f, chain, next) {=0A=
+		for (vlan =3D 0; vlan < (EVL_VLID_MASK + 1); vlan ++) {=0A=
+			if (priv->vlan_hook[vlan] =3D=3D NULL)=0A=
+				continue;=0A=
+=0A=
 			NG_COPYMESSAGE(copy, msg, M_NOWAIT);=0A=
 			if (copy =3D=3D NULL)=0A=
-				continue;=0A=
-			NG_SEND_MSG_HOOK(error, node, copy, f->hook, 0);=0A=
+					continue;=0A=
+			NG_SEND_MSG_HOOK(error, node, copy, priv->vlan_hook[vlan], 0);=0A=
 		}=0A=
-=0A=
 		break;=0A=
 	    }=0A=
 	default:			/* Unknown type cookie. */=0A=
@@ -343,9 +351,9 @@=0A=
 	struct ether_header *eh;=0A=
 	struct ether_vlan_header *evl =3D NULL;=0A=
 	int error;=0A=
-	u_int16_t vlan;=0A=
+	uintptr_t vlan;=0A=
 	struct mbuf *m;=0A=
-	struct filter *f;=0A=
+	hook_p vlan_hook;=0A=
 =0A=
 	/* Make sure we have an entire header. */=0A=
 	NGI_GET_M(item, m);=0A=
@@ -360,6 +368,7 @@=0A=
 		 * If from downstream, select between a match hook=0A=
 		 * or the nomatch hook.=0A=
 		 */=0A=
+		vlan_hook =3D priv->nomatch_hook;=0A=
 		if (m->m_flags & M_VLANTAG ||=0A=
 		    eh->ether_type =3D=3D htons(ETHERTYPE_VLAN)) {=0A=
 			if (m->m_flags & M_VLANTAG) {=0A=
@@ -377,25 +386,20 @@=0A=
 				evl =3D mtod(m, struct ether_vlan_header *);=0A=
 				vlan =3D EVL_VLANOFTAG(ntohs(evl->evl_tag));=0A=
 			}=0A=
-			if ((f =3D ng_vlan_findentry(priv, vlan)) !=3D NULL) {=0A=
+=0A=
+			if (priv->vlan_hook[vlan] !=3D NULL) {=0A=
+				vlan_hook =3D priv->vlan_hook[vlan];=0A=
 				if (m->m_flags & M_VLANTAG) {=0A=
 					m->m_pkthdr.ether_vtag =3D 0;=0A=
 					m->m_flags &=3D ~M_VLANTAG;=0A=
 				} else {=0A=
-					evl->evl_encap_proto =3D evl->evl_proto;=0A=
-					bcopy(mtod(m, caddr_t),=0A=
-					    mtod(m, caddr_t) +=0A=
-					    ETHER_VLAN_ENCAP_LEN,=0A=
-					    ETHER_HDR_LEN);=0A=
+					bcopy((char *)evl, (char *)evl + ETHER_VLAN_ENCAP_LEN,=0A=
+						(ETHER_HDR_LEN - ETHER_TYPE_LEN));=0A=
 					m_adj(m, ETHER_VLAN_ENCAP_LEN);=0A=
 				}=0A=
 			}=0A=
-		} else=0A=
-			f =3D NULL;=0A=
-		if (f !=3D NULL)=0A=
-			NG_FWD_NEW_DATA(error, item, f->hook, m);=0A=
-		else=0A=
-			NG_FWD_NEW_DATA(error, item, priv->nomatch_hook, m);=0A=
+		}=0A=
+		NG_FWD_NEW_DATA(error, item, vlan_hook, m);=0A=
 	} else {=0A=
 		/*=0A=
 		 * It is heading towards the downstream.=0A=
@@ -403,28 +407,35 @@=0A=
 		 * Otherwise, do the VLAN encapsulation.=0A=
 		 */=0A=
 		if (hook !=3D priv->nomatch_hook) {=0A=
-			if ((f =3D NG_HOOK_PRIVATE(hook)) =3D=3D NULL) {=0A=
+			vlan =3D (uintptr_t)NG_HOOK_PRIVATE(hook);=0A=
+			if ((vlan & HOOK_VLAN_SET_MASK) !=3D HOOK_VLAN_SET_MASK) {=0A=
 				NG_FREE_ITEM(item);=0A=
 				NG_FREE_M(m);=0A=
 				return (EOPNOTSUPP);=0A=
 			}=0A=
-			M_PREPEND(m, ETHER_VLAN_ENCAP_LEN, M_DONTWAIT);=0A=
-			/* M_PREPEND takes care of m_len and m_pkthdr.len. */=0A=
-			if (m =3D=3D NULL || (m->m_len < sizeof(*evl) &&=0A=
-			    (m =3D m_pullup(m, sizeof(*evl))) =3D=3D NULL)) {=0A=
-				NG_FREE_ITEM(item);=0A=
-				return (ENOMEM);=0A=
+			vlan &=3D EVL_VLID_MASK; /* remove HOOK_VLAN_SET_MASK from vlan num =
*/=0A=
+			=0A=
+			if (priv->vlan_encap =3D=3D 0) {=0A=
+				m->m_flags |=3D M_VLANTAG;=0A=
+				m->m_pkthdr.ether_vtag =3D vlan;=0A=
+			} else {=0A=
+				M_PREPEND(m, ETHER_VLAN_ENCAP_LEN, M_DONTWAIT);=0A=
+				/* M_PREPEND takes care of m_len and m_pkthdr.len. */=0A=
+				if (m =3D=3D NULL || (m->m_len < sizeof(*evl) &&=0A=
+				    (m =3D m_pullup(m, sizeof(*evl))) =3D=3D NULL)) {=0A=
+					NG_FREE_ITEM(item);=0A=
+					return (ENOMEM);=0A=
+				}=0A=
+				/*=0A=
+				 * Transform the Ethernet header into an Ethernet header=0A=
+				 * with 802.1Q encapsulation.=0A=
+				 */=0A=
+				evl =3D mtod(m, struct ether_vlan_header *);=0A=
+				bcopy((char *)evl + ETHER_VLAN_ENCAP_LEN,=0A=
+					(char *)evl, (ETHER_HDR_LEN - ETHER_TYPE_LEN));=0A=
+				evl->evl_encap_proto =3D htons(ETHERTYPE_VLAN);=0A=
+				evl->evl_tag =3D htons(vlan);=0A=
 			}=0A=
-			/*=0A=
-			 * Transform the Ethernet header into an Ethernet header=0A=
-			 * with 802.1Q encapsulation.=0A=
-			 */=0A=
-			bcopy(mtod(m, char *) + ETHER_VLAN_ENCAP_LEN,=0A=
-			    mtod(m, char *), ETHER_HDR_LEN);=0A=
-			evl =3D mtod(m, struct ether_vlan_header *);=0A=
-			evl->evl_proto =3D evl->evl_encap_proto;=0A=
-			evl->evl_encap_proto =3D htons(ETHERTYPE_VLAN);=0A=
-			evl->evl_tag =3D htons(f->vlan);=0A=
 		}=0A=
 		NG_FWD_NEW_DATA(error, item, priv->downstream_hook, m);=0A=
 	}=0A=
@@ -446,7 +457,7 @@=0A=
 ng_vlan_disconnect(hook_p hook)=0A=
 {=0A=
 	const priv_p priv =3D NG_NODE_PRIVATE(NG_HOOK_NODE(hook));=0A=
-	struct filter *f;=0A=
+	uintptr_t vlan;=0A=
 =0A=
 	if (hook =3D=3D priv->downstream_hook)=0A=
 		priv->downstream_hook =3D NULL;=0A=
@@ -454,11 +465,9 @@=0A=
 		priv->nomatch_hook =3D NULL;=0A=
 	else {=0A=
 		/* Purge a rule that refers to this hook. */=0A=
-		if ((f =3D NG_HOOK_PRIVATE(hook)) !=3D NULL) {=0A=
-			LIST_REMOVE(f, next);=0A=
-			priv->nent--;=0A=
-			free(f, M_NETGRAPH);=0A=
-		}=0A=
+		vlan =3D (uintptr_t)NG_HOOK_PRIVATE(hook);=0A=
+		if ((vlan & HOOK_VLAN_SET_MASK) =3D=3D HOOK_VLAN_SET_MASK)=0A=
+			priv->vlan_hook[(vlan & EVL_VLID_MASK)] =3D NULL;=0A=
 	}=0A=
 	NG_HOOK_SET_PRIVATE(hook, NULL);=0A=
 	if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) =3D=3D 0) &&=0A=

------=_NextPart_000_0001_01CC32DC.C33B2950--




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4e04c489.d899cc0a.43e4.4ad6>