Date: Fri, 24 Jun 2011 07:03:40 +0900 From: rozhuk.im@gmail.com To: <freebsd-net@FreeBSD.org> Subject: ng_vlan improvements Message-ID: <4e03b840.d899cc0a.2527.3041@mx.google.com>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format. ------=_NextPart_000_00C0_01CC323C.DAE3A3C0 Content-Type: text/plain; charset="windows-1251" Content-Transfer-Encoding: quoted-printable Hi! Changes: 1. list + hash was replaced by array of hooks: its simple and faster 2. added encap setting. "getencap" and "setencap" messages for control it: Default =3D 1 (do the VLAN encapsulation) 0: no encapsulation, just: m->m_flags |=3D M_VLANTAG; m->m_pkthdr.ether_vtag =3D (vlan & EVL_VLID_MASK); Who can test? =A0 -- Rozhuk Ivan =A0=20 ------=_NextPart_000_00C0_01CC323C.DAE3A3C0 Content-Type: text/plain; name="ng_vlan.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="ng_vlan.c" /*-=0A= * Copyright (c) 2003 IPNET Internet Communication Company=0A= * All rights reserved.=0A= *=0A= * Redistribution and use in source and binary forms, with or without=0A= * modification, are permitted provided that the following conditions=0A= * are met:=0A= * 1. Redistributions of source code must retain the above copyright=0A= * notice, this list of conditions and the following disclaimer.=0A= * 2. Redistributions in binary form must reproduce the above copyright=0A= * notice, this list of conditions and the following disclaimer in the=0A= * documentation and/or other materials provided with the = distribution.=0A= *=0A= * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND=0A= * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE=0A= * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR = PURPOSE=0A= * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE = LIABLE=0A= * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR = CONSEQUENTIAL=0A= * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE = GOODS=0A= * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)=0A= * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, = STRICT=0A= * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY = WAY=0A= * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF=0A= * SUCH DAMAGE.=0A= *=0A= * Author: Ruslan Ermilov <ru@FreeBSD.org>=0A= *=0A= * $FreeBSD: src/sys/netgraph/ng_vlan.c,v 1.6.2.1 2009/08/03 08:13:06 = kensmith Exp $=0A= */=0A= =0A= #include <sys/param.h>=0A= #include <sys/errno.h>=0A= #include <sys/kernel.h>=0A= #include <sys/malloc.h>=0A= #include <sys/mbuf.h>=0A= #include <sys/queue.h>=0A= #include <sys/socket.h>=0A= #include <sys/systm.h>=0A= =0A= #include <net/ethernet.h>=0A= #include <net/if.h>=0A= #include <net/if_vlan_var.h>=0A= =0A= #include <netgraph/ng_message.h>=0A= #include <netgraph/ng_parse.h>=0A= #include <netgraph/ng_vlan.h>=0A= #include <netgraph/netgraph.h>=0A= =0A= static ng_constructor_t ng_vlan_constructor;=0A= static ng_rcvmsg_t ng_vlan_rcvmsg;=0A= static ng_shutdown_t ng_vlan_shutdown;=0A= static ng_newhook_t ng_vlan_newhook;=0A= static ng_rcvdata_t ng_vlan_rcvdata;=0A= static ng_disconnect_t ng_vlan_disconnect;=0A= =0A= /* Parse type for struct ng_vlan_filter. */=0A= static const struct ng_parse_struct_field ng_vlan_filter_fields[] =3D=0A= NG_VLAN_FILTER_FIELDS;=0A= static const struct ng_parse_type ng_vlan_filter_type =3D {=0A= &ng_parse_struct_type,=0A= &ng_vlan_filter_fields=0A= };=0A= =0A= static int=0A= ng_vlan_getTableLength(const struct ng_parse_type *type,=0A= const u_char *start, const u_char *buf)=0A= {=0A= const struct ng_vlan_table *const table =3D=0A= (const struct ng_vlan_table *)(buf - sizeof(u_int32_t));=0A= =0A= return table->n;=0A= }=0A= =0A= /* Parse type for struct ng_vlan_table. */=0A= static const struct ng_parse_array_info ng_vlan_table_array_info =3D {=0A= &ng_vlan_filter_type,=0A= ng_vlan_getTableLength=0A= };=0A= static const struct ng_parse_type ng_vlan_table_array_type =3D {=0A= &ng_parse_array_type,=0A= &ng_vlan_table_array_info=0A= };=0A= static const struct ng_parse_struct_field ng_vlan_table_fields[] =3D=0A= NG_VLAN_TABLE_FIELDS;=0A= static const struct ng_parse_type ng_vlan_table_type =3D {=0A= &ng_parse_struct_type,=0A= &ng_vlan_table_fields=0A= };=0A= =0A= /* List of commands and how to convert arguments to/from ASCII. */=0A= static const struct ng_cmdlist ng_vlan_cmdlist[] =3D {=0A= {=0A= NGM_VLAN_COOKIE,=0A= NGM_VLAN_ADD_FILTER,=0A= "addfilter",=0A= &ng_vlan_filter_type,=0A= NULL=0A= },=0A= {=0A= NGM_VLAN_COOKIE,=0A= NGM_VLAN_DEL_FILTER,=0A= "delfilter",=0A= &ng_parse_hookbuf_type,=0A= NULL=0A= },=0A= {=0A= NGM_VLAN_COOKIE,=0A= NGM_VLAN_GET_TABLE,=0A= "gettable",=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= static struct ng_type ng_vlan_typestruct =3D {=0A= .version =3D NG_ABI_VERSION,=0A= .name =3D NG_VLAN_NODE_TYPE,=0A= .constructor =3D ng_vlan_constructor,=0A= .rcvmsg =3D ng_vlan_rcvmsg,=0A= .shutdown =3D ng_vlan_shutdown,=0A= .newhook =3D ng_vlan_newhook,=0A= .rcvdata =3D ng_vlan_rcvdata,=0A= .disconnect =3D ng_vlan_disconnect,=0A= .cmdlist =3D ng_vlan_cmdlist,=0A= };=0A= NETGRAPH_INIT(vlan, &ng_vlan_typestruct);=0A= =0A= =0A= =0A= typedef struct {=0A= hook_p downstream_hook;=0A= hook_p nomatch_hook;=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= =0A= static int=0A= ng_vlan_constructor(node_p node)=0A= {=0A= priv_p priv;=0A= =0A= priv =3D malloc(sizeof(*priv), M_NETGRAPH, M_NOWAIT | M_ZERO);=0A= if (priv =3D=3D NULL)=0A= return (ENOMEM);=0A= priv->vlan_encap =3D 1;=0A= =0A= return (0);=0A= }=0A= =0A= static int=0A= ng_vlan_newhook(node_p node, hook_p hook, const char *name)=0A= {=0A= const priv_p priv =3D NG_NODE_PRIVATE(node);=0A= =0A= if (strcmp(name, NG_VLAN_HOOK_DOWNSTREAM) =3D=3D 0)=0A= priv->downstream_hook =3D hook;=0A= else if (strcmp(name, NG_VLAN_HOOK_NOMATCH) =3D=3D 0)=0A= priv->nomatch_hook =3D hook;=0A= else {=0A= /*=0A= * Any other hook name is valid and can=0A= * later be associated with a filter rule.=0A= */=0A= }=0A= NG_HOOK_SET_PRIVATE(hook, NULL);=0A= return (0);=0A= }=0A= =0A= static int=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= struct ng_mesg *msg, *resp =3D NULL;=0A= struct ng_vlan_filter *vf;=0A= hook_p hook;=0A= struct ng_vlan_table *t;=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= switch (msg->header.typecookie) {=0A= case NGM_VLAN_COOKIE:=0A= switch (msg->header.cmd) {=0A= case NGM_VLAN_ADD_FILTER:=0A= /* Check that message is long enough. */=0A= if (msg->header.arglen !=3D sizeof(*vf)) {=0A= error =3D EINVAL;=0A= break;=0A= }=0A= vf =3D (struct ng_vlan_filter *)msg->data;=0A= /* Sanity check the VLAN ID value. */=0A= if (vf->vlan & ~EVL_VLID_MASK) {=0A= error =3D EINVAL;=0A= break;=0A= }=0A= /* Check that a referenced hook exists. */=0A= hook =3D ng_findhook(node, vf->hook);=0A= if (hook =3D=3D NULL) {=0A= error =3D ENOENT;=0A= break;=0A= }=0A= /* And is not one of the special hooks. */=0A= if (hook =3D=3D priv->downstream_hook ||=0A= hook =3D=3D priv->nomatch_hook) {=0A= error =3D EINVAL;=0A= break;=0A= }=0A= /* And is not already in service. */=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 (priv->vlan_hook[vf->vlan] !=3D NULL) {=0A= error =3D EEXIST;=0A= break;=0A= }=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= if (msg->header.arglen !=3D NG_HOOKSIZ) {=0A= error =3D EINVAL;=0A= break;=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= 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= /* Purge a rule that refers to this hook. */=0A= NG_HOOK_SET_PRIVATE(hook, NULL);=0A= priv->vlan_hook[(vlan & EVL_VLID_MASK)] =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= 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 vlan_count;=0A= vf =3D &t->filter[0];=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= 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= break;=0A= }=0A= break;=0A= case NGM_FLOW_COOKIE:=0A= {=0A= struct ng_mesg *copy;=0A= =0A= /*=0A= * Flow control messages should come only=0A= * from downstream.=0A= */=0A= =0A= if (lasthook =3D=3D NULL)=0A= break;=0A= if (lasthook !=3D priv->downstream_hook)=0A= break;=0A= =0A= /* Broadcast the event to all uplinks. */=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, priv->vlan_hook[vlan], 0);=0A= }=0A= break;=0A= }=0A= default: /* Unknown type cookie. */=0A= error =3D EINVAL;=0A= break;=0A= }=0A= NG_RESPOND_MSG(error, node, item, resp);=0A= NG_FREE_MSG(msg);=0A= return (error);=0A= }=0A= =0A= static int=0A= ng_vlan_rcvdata(hook_p hook, item_p item)=0A= {=0A= const priv_p priv =3D NG_NODE_PRIVATE(NG_HOOK_NODE(hook));=0A= struct ether_header *eh;=0A= struct ether_vlan_header *evl =3D NULL;=0A= int error;=0A= uintptr_t vlan;=0A= struct mbuf *m;=0A= hook_p vlan_hook;=0A= =0A= /* Make sure we have an entire header. */=0A= NGI_GET_M(item, m);=0A= if (m->m_len < sizeof(*eh) &&=0A= (m =3D m_pullup(m, sizeof(*eh))) =3D=3D NULL) {=0A= NG_FREE_ITEM(item);=0A= return (EINVAL);=0A= }=0A= eh =3D mtod(m, struct ether_header *);=0A= if (hook =3D=3D priv->downstream_hook) {=0A= /*=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= /*=0A= * Packet is tagged, m contains a normal=0A= * Ethernet frame; tag is stored out-of-band.=0A= */=0A= vlan =3D EVL_VLANOFTAG(m->m_pkthdr.ether_vtag);=0A= } else {=0A= if (m->m_len < sizeof(*evl) &&=0A= (m =3D m_pullup(m, sizeof(*evl))) =3D=3D NULL) {=0A= NG_FREE_ITEM(item);=0A= return (EINVAL);=0A= }=0A= evl =3D mtod(m, struct ether_vlan_header *);=0A= vlan =3D EVL_VLANOFTAG(ntohs(evl->evl_tag));=0A= }=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= m_adj(m, ETHER_VLAN_ENCAP_LEN);=0A= }=0A= }=0A= }=0A= NG_FWD_NEW_DATA(error, item, vlan_hook, m);=0A= } else {=0A= /*=0A= * It is heading towards the downstream.=0A= * If from nomatch, pass it unmodified.=0A= * Otherwise, do the VLAN encapsulation.=0A= */=0A= if (hook !=3D priv->nomatch_hook) {=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= =0A= if (priv->vlan_encap =3D=3D 0) {=0A= m->m_flags |=3D M_VLANTAG;=0A= m->m_pkthdr.ether_vtag =3D (vlan & EVL_VLID_MASK);=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 & EVL_VLID_MASK));=0A= }=0A= }=0A= NG_FWD_NEW_DATA(error, item, priv->downstream_hook, m);=0A= }=0A= return (error);=0A= }=0A= =0A= static int=0A= ng_vlan_shutdown(node_p node)=0A= {=0A= const priv_p priv =3D NG_NODE_PRIVATE(node);=0A= =0A= NG_NODE_SET_PRIVATE(node, NULL);=0A= NG_NODE_UNREF(node);=0A= free(priv, M_NETGRAPH);=0A= return (0);=0A= }=0A= =0A= static int=0A= ng_vlan_disconnect(hook_p hook)=0A= {=0A= const priv_p priv =3D NG_NODE_PRIVATE(NG_HOOK_NODE(hook));=0A= uintptr_t vlan;=0A= =0A= if (hook =3D=3D priv->downstream_hook)=0A= priv->downstream_hook =3D NULL;=0A= else if (hook =3D=3D priv->nomatch_hook)=0A= priv->nomatch_hook =3D NULL;=0A= else {=0A= /* Purge a rule that refers to this hook. */=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= (NG_NODE_IS_VALID(NG_HOOK_NODE(hook))))=0A= ng_rmnode_self(NG_HOOK_NODE(hook));=0A= return (0);=0A= }=0A= ------=_NextPart_000_00C0_01CC323C.DAE3A3C0 Content-Type: text/plain; name="ng_vlan.h" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="ng_vlan.h" /*-=0A= * Copyright (c) 2003 IPNET Internet Communication Company=0A= * All rights reserved.=0A= *=0A= * Redistribution and use in source and binary forms, with or without=0A= * modification, are permitted provided that the following conditions=0A= * are met:=0A= * 1. Redistributions of source code must retain the above copyright=0A= * notice, this list of conditions and the following disclaimer.=0A= * 2. Redistributions in binary form must reproduce the above copyright=0A= * notice, this list of conditions and the following disclaimer in the=0A= * documentation and/or other materials provided with the = distribution.=0A= *=0A= * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND=0A= * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE=0A= * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR = PURPOSE=0A= * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE = LIABLE=0A= * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR = CONSEQUENTIAL=0A= * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE = GOODS=0A= * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)=0A= * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, = STRICT=0A= * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY = WAY=0A= * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF=0A= * SUCH DAMAGE.=0A= *=0A= * Author: Ruslan Ermilov <ru@FreeBSD.org>=0A= *=0A= * $FreeBSD: src/sys/netgraph/ng_vlan.h,v 1.2.10.1 2009/08/03 08:13:06 = kensmith Exp $=0A= */=0A= =0A= #ifndef _NETGRAPH_NG_VLAN_H_=0A= #define _NETGRAPH_NG_VLAN_H_=0A= =0A= /* Node type name and magic cookie. */=0A= #define NG_VLAN_NODE_TYPE "vlan"=0A= #define NGM_VLAN_COOKIE 1068486472=0A= =0A= /* Hook names. */=0A= #define NG_VLAN_HOOK_DOWNSTREAM "downstream"=0A= #define NG_VLAN_HOOK_NOMATCH "nomatch"=0A= =0A= /* Netgraph commands. */=0A= enum {=0A= NGM_VLAN_ADD_FILTER =3D 1,=0A= NGM_VLAN_DEL_FILTER,=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= struct ng_vlan_filter {=0A= char hook[NG_HOOKSIZ];=0A= u_int16_t vlan;=0A= }; =0A= =0A= /* Keep this in sync with the above structure definition. */=0A= #define NG_VLAN_FILTER_FIELDS { \=0A= { "hook", &ng_parse_hookbuf_type }, \=0A= { "vlan", &ng_parse_uint16_type }, \=0A= { NULL } \=0A= }=0A= =0A= /* Structure returned by NGM_VLAN_GET_TABLE. */=0A= struct ng_vlan_table {=0A= u_int32_t n;=0A= struct ng_vlan_filter filter[];=0A= };=0A= =0A= /* Keep this in sync with the above structure definition. */=0A= #define NG_VLAN_TABLE_FIELDS { \=0A= { "n", &ng_parse_uint32_type }, \=0A= { "filter", &ng_vlan_table_array_type }, \=0A= { NULL } \=0A= }=0A= =0A= #endif /* _NETGRAPH_NG_VLAN_H_ */=0A= ------=_NextPart_000_00C0_01CC323C.DAE3A3C0--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4e03b840.d899cc0a.2527.3041>