36#include <sys/kernel.h>
37#include <sys/malloc.h>
40#include <sys/socket.h>
43#include <net/ethernet.h>
45#include <net/if_vlan_var.h>
62#define ETHER_VLAN_HDR_LEN (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN)
63#define VLAN_TAG_MASK 0xFFFF
64#define HOOK_VLAN_TAG_SET_MASK ((uintptr_t)((~0) & ~(VLAN_TAG_MASK)))
65#define IS_HOOK_VLAN_SET(hdata) \
66 ((((uintptr_t)hdata) & HOOK_VLAN_TAG_SET_MASK) == HOOK_VLAN_TAG_SET_MASK)
85 const u_char *start,
const u_char *buf)
205 if ((*mp)->m_pkthdr.len < len) {
210 if ((*mp)->m_len < len && ((*mp) = m_pullup((*mp), len)) == NULL)
225 priv = malloc(
sizeof(*
priv), M_NETGRAPH, M_WAITOK | M_ZERO);
226 priv->decap_enable = 0;
228 priv->encap_proto = htons(ETHERTYPE_VLAN);
239 priv->downstream_hook = hook;
241 priv->nomatch_hook = hook;
256 struct ng_mesg *msg, *resp = NULL;
281 }
else if (vf->
vid != 0 && vf->
vlan != 0 &&
287 if (vf->
vid & ~EVL_VLID_MASK ||
300 if (hook ==
priv->downstream_hook ||
301 hook ==
priv->nomatch_hook) {
311 if (
priv->vlan_hook[vf->
vid] != NULL) {
318 EVL_MAKETAG(vf->
vid, vf->
pcp, vf->
cfi)));
319 priv->vlan_hook[vf->
vid] = hook;
339 KASSERT(
priv->vlan_hook[EVL_VLANOFTAG(hook_data)] == hook,
340 (
"%s: NGM_VLAN_DEL_FILTER: Invalid VID for Hook = %s\n",
341 __func__, (
char *)msg->
data));
344 priv->vlan_hook[EVL_VLANOFTAG(hook_data)] = NULL;
353 vid = (*((uint16_t *)msg->
data));
355 if (
vid & ~EVL_VLID_MASK) {
371 KASSERT(EVL_VLANOFTAG(hook_data) ==
vid,
372 (
"%s: NGM_VLAN_DEL_VID_FLT:"
373 " Invalid VID Hook = %us, must be: %us\n",
374 __func__, (uint16_t )EVL_VLANOFTAG(hook_data),
384 for (i = 0; i < (EVL_VLID_MASK + 1); i ++) {
385 if (
priv->vlan_hook[i] != NULL &&
392 vlan_count *
sizeof(*t->
filter), M_NOWAIT);
402 for (i = 0; i < (EVL_VLID_MASK + 1); i ++) {
403 hook =
priv->vlan_hook[i];
410 KASSERT(EVL_VLANOFTAG(hook_data) == i,
411 (
"%s: NGM_VLAN_GET_TABLE:"
412 " hook %s VID = %us, must be: %i\n",
414 (uint16_t)EVL_VLANOFTAG(hook_data), i));
416#ifdef NG_VLAN_USE_OLD_VLAN_NAME
420 vf->
pcp = EVL_PRIOFTAG(hook_data);
421 vf->
cfi = EVL_CFIOFTAG(hook_data);
434 (*((uint32_t *)resp->
data)) =
priv->decap_enable;
441 priv->decap_enable = (*((uint32_t *)msg->
data));
449 (*((uint32_t *)resp->
data)) =
priv->encap_enable;
456 priv->encap_enable = (*((uint32_t *)msg->
data));
464 (*((uint16_t *)resp->
data)) = ntohs(
priv->encap_proto);
471 priv->encap_proto = htons((*((uint16_t *)msg->
data)));
487 if (lasthook == NULL)
489 if (lasthook !=
priv->downstream_hook)
492 for (i = 0; i < (EVL_VLID_MASK + 1); i ++) {
493 if (
priv->vlan_hook[i] == NULL)
500 priv->vlan_hook[i], 0);
517 struct ether_header *eh;
518 struct ether_vlan_header *evl;
521 uint16_t vid, eth_vtag;
528 error =
m_chk(&m, ETHER_HDR_LEN);
532 eh = mtod(m,
struct ether_header *);
533 if (hook ==
priv->downstream_hook) {
539 dst_hook =
priv->nomatch_hook;
542 if ((m->m_flags & M_VLANTAG) == 0 &&
543 eh->ether_type !=
priv->encap_proto) {
544 if (dst_hook == NULL)
550 if (m->m_flags & M_VLANTAG) {
556 vid = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag);
561 evl = mtod(m,
struct ether_vlan_header *);
562 vid = EVL_VLANOFTAG(ntohs(evl->evl_tag));
565 if (
priv->vlan_hook[vid] != NULL) {
570 dst_hook =
priv->vlan_hook[vid];
572 m->m_pkthdr.ether_vtag = 0;
573 m->m_flags &= ~M_VLANTAG;
577 if (dst_hook == NULL)
579 if (evl == NULL ||
priv->decap_enable == 0)
582 m->m_pkthdr.ether_vtag = ntohs(evl->evl_tag);
583 m->m_flags |= M_VLANTAG;
597 bcopy((
char *)evl, ((
char *)evl + ETHER_VLAN_ENCAP_LEN),
598 (ETHER_ADDR_LEN * 2));
599 m_adj(m, ETHER_VLAN_ENCAP_LEN);
606 dst_hook =
priv->downstream_hook;
607 if (dst_hook == NULL)
609 if (hook !=
priv->nomatch_hook) {
622 m->m_flags |= M_VLANTAG;
623 m->m_pkthdr.ether_vtag = eth_vtag;
628 (m->m_flags & M_VLANTAG) == 0)
631 eth_vtag = m->m_pkthdr.ether_vtag;
632 m->m_pkthdr.ether_vtag = 0;
633 m->m_flags &= ~M_VLANTAG;
650 M_PREPEND(m, ETHER_VLAN_ENCAP_LEN, M_NOWAIT);
658 evl = mtod(m,
struct ether_vlan_header *);
659 bcopy(((
char *)evl + ETHER_VLAN_ENCAP_LEN),
660 (
char *)evl, (ETHER_ADDR_LEN * 2));
661 evl->evl_encap_proto =
priv->encap_proto;
662 evl->evl_tag = htons(eth_vtag);
684 free(
priv, M_NETGRAPH);
694 if (hook ==
priv->downstream_hook)
695 priv->downstream_hook = NULL;
696 else if (hook ==
priv->nomatch_hook)
697 priv->nomatch_hook = NULL;
702 priv->vlan_hook[EVL_VLANOFTAG(hook_data)] = NULL;
#define NG_HOOK_NODE(hook)
#define NG_HOOK_NOT_VALID(hook)
int ng_rcvmsg_t(node_p node, item_p item, hook_p lasthook)
int ng_disconnect_t(hook_p hook)
#define NG_NODE_SET_PRIVATE(node, val)
#define NG_RESPOND_MSG(error, here, item, resp)
#define NG_NODE_IS_VALID(node)
#define NG_NODE_UNREF(node)
#define NG_HOOK_SET_PRIVATE(hook, val)
int ng_rmnode_self(node_p here)
#define NG_FWD_NEW_DATA(error, item, hook, m)
int ng_rcvdata_t(hook_p hook, item_p item)
int ng_shutdown_t(node_p node)
#define NG_HOOK_NAME(hook)
#define NG_FREE_ITEM(item)
int ng_constructor_t(node_p node)
#define NG_HOOK_IS_VALID(hook)
#define NG_NODE_NUMHOOKS(node)
#define NGI_GET_MSG(i, m)
#define NG_NODE_PRIVATE(node)
#define NG_SEND_MSG_HOOK(error, here, msg, hook, retaddr)
int ng_newhook_t(node_p node, hook_p hook, const char *name)
hook_p ng_findhook(node_p node, const char *name)
#define NG_HOOK_PRIVATE(hook)
#define NG_MKRESPONSE(rsp, msg, len, how)
#define NG_COPYMESSAGE(copy, msg, how)
const struct ng_parse_type ng_parse_uint16_type
const struct ng_parse_type ng_parse_array_type
const struct ng_parse_type ng_parse_struct_type
const struct ng_parse_type ng_parse_hookbuf_type
const struct ng_parse_type ng_parse_hint16_type
const struct ng_parse_type ng_parse_hint32_type
#define ETHER_VLAN_HDR_LEN
static ng_disconnect_t ng_vlan_disconnect
static int ng_vlan_getTableLength(const struct ng_parse_type *type, const u_char *start, const u_char *buf)
#define HOOK_VLAN_TAG_SET_MASK
static const struct ng_parse_type ng_vlan_table_type
static ng_shutdown_t ng_vlan_shutdown
static const struct ng_parse_array_info ng_vlan_table_array_info
static ng_rcvmsg_t ng_vlan_rcvmsg
NETGRAPH_INIT(vlan, &ng_vlan_typestruct)
static const struct ng_cmdlist ng_vlan_cmdlist[]
static __inline int m_chk(struct mbuf **mp, int len)
static const struct ng_parse_type ng_vlan_filter_type
static const struct ng_parse_type ng_vlan_table_array_type
static ng_newhook_t ng_vlan_newhook
static const struct ng_parse_struct_field ng_vlan_filter_fields[]
static ng_constructor_t ng_vlan_constructor
static struct ng_type ng_vlan_typestruct
#define IS_HOOK_VLAN_SET(hdata)
struct ng_vlan_private * priv_p
static ng_rcvdata_t ng_vlan_rcvdata
static const struct ng_parse_struct_field ng_vlan_table_fields[]
#define VLAN_ENCAP_FROM_NOMATCH
#define VLAN_ENCAP_FROM_FILTER
#define NG_VLAN_HOOK_DOWNSTREAM
#define NG_VLAN_NODE_TYPE
#define NG_VLAN_USE_OLD_VLAN_NAME
#define NG_VLAN_TABLE_FIELDS
@ NGM_VLAN_GET_ENCAP_PROTO
@ NGM_VLAN_SET_ENCAP_PROTO
#define NG_VLAN_FILTER_FIELDS
#define NG_VLAN_HOOK_NOMATCH
struct ng_mesg::ng_msghdr header
char hook_name[NG_HOOKSIZ]
hook_p vlan_hook[(EVL_VLID_MASK+1)]
struct ng_vlan_filter filter[]