191 lines
4.5 KiB
C
191 lines
4.5 KiB
C
/* wrnad_svlan.c - NAD 802.1ad VLAN stacking netlink message handler */
|
|
|
|
/*
|
|
* Copyright (c) 2010 Wind River Systems, Inc.
|
|
*
|
|
* The right to copy, distribute or otherwise make use of this software
|
|
* may be licensed only pursuant to the terms of an applicable Wind River
|
|
* license agreement. No license to Wind River intellectual property rights
|
|
* is granted herein. All rights not licensed by Wind River are reserved
|
|
* by Wind River.
|
|
*/
|
|
|
|
/*
|
|
modification history
|
|
--------------------
|
|
01c,14oct10,tlu Restore for Linux mgnt OS
|
|
01b,17aug10,kxr Modified for VxWorks Mgmt OS
|
|
01a,26jan10,tlu Created.
|
|
*/
|
|
|
|
/* includes */
|
|
|
|
#ifndef IP_PORT_VXWORKS
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <net/if.h>
|
|
#endif
|
|
|
|
#include <syslog.h>
|
|
|
|
#include "wrnad_svconfig.h"
|
|
|
|
/* defines */
|
|
|
|
/* typedefs */
|
|
|
|
/* imports */
|
|
extern void wrnad_log(int priority, const char *format, /* args*/ ...);
|
|
extern char *wrnad_rtnl_check_proxy_interface(int ifindex);
|
|
extern const char *wrnad_rtnl_typestr(int type);
|
|
|
|
|
|
/* globals */
|
|
|
|
/* locals */
|
|
|
|
|
|
|
|
/********************************************************************************
|
|
* wrnad_rtnl_svlan_typestr - find netlink VLAN stacking type in string format
|
|
*
|
|
* This routine returns the netlink VLAN stacking type as a string
|
|
*
|
|
* RETURNS: string representation of netlink VLAN stacking type.
|
|
*
|
|
* ERRNO: N/A
|
|
*/
|
|
|
|
static const char *
|
|
wrnad_rtnl_svlan_typestr(int type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case RTM_SET_SVLAN:
|
|
return "RTM_SET_SVLAN";
|
|
case RTM_DEL_SVLAN:
|
|
return "RTM_DEL_SVLAN";
|
|
default:
|
|
return "RTM_UNKNOWN";
|
|
}
|
|
}
|
|
|
|
|
|
/********************************************************************************
|
|
* wrnad_rtnl_svlan_cmdstr - find netlink VLAN stacking cmd in string format
|
|
*
|
|
* This routine returns the netlink VLAN stacking cmd as a string
|
|
*
|
|
* RETURNS: string representation of netlink VLAN stacking cmd.
|
|
*
|
|
* ERRNO: N/A
|
|
*/
|
|
|
|
static const char *
|
|
wrnad_rtnl_svlan_cmdstr(int cmd)
|
|
{
|
|
switch (cmd)
|
|
{
|
|
case VLAN_SET_STPID:
|
|
return "VLAN_SET_STPID";
|
|
case VLAN_SET_SVLAN:
|
|
return "VLAN_SET_SVLAN";
|
|
case VLAN_SET_PVID:
|
|
return "VLAN_SET_PVID";
|
|
case VLAN_SET_PRI_MAP:
|
|
return "VLAN_SET_PRI_MAP";
|
|
case VLAN_SET_INGRESS:
|
|
return "VLAN_SET_INGRESS";
|
|
case VLAN_SET_EGRESS:
|
|
return "VLAN_SET_EGRESS";
|
|
default:
|
|
return "CMD_UNKNOWN";
|
|
}
|
|
}
|
|
|
|
|
|
/********************************************************************************
|
|
* wrnad_rtnl_svlan_ptypestr - netlink VLAN stacking port type in string format
|
|
*
|
|
* This routine returns the netlink VLAN stacking port type as a string
|
|
*
|
|
* RETURNS: string representation of netlink VLAN stacking port type.
|
|
*
|
|
* ERRNO: N/A
|
|
*/
|
|
|
|
static const char *
|
|
wrnad_rtnl_svlan_ptypestr(int type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case VLAN_CS_VLAN:
|
|
return "VLAN_CS_VLAN";
|
|
case VLAN_SC_VLAN:
|
|
return "VLAN_SC_VLAN";
|
|
case VLAN_S_VLAN:
|
|
return "VLAN_S_VLAN";
|
|
default:
|
|
return "PTYPE_UNKNOWN";
|
|
}
|
|
}
|
|
|
|
|
|
/*******************************************************************************
|
|
*
|
|
* wrnad_rtnl_svlan_handler - netlink handler for vlan stacking messages
|
|
*
|
|
* This routine handles netlink vlan stacking messages.
|
|
*
|
|
* RETURNS: -1 = failed
|
|
* 0 = skip
|
|
* 1 = action
|
|
*
|
|
* ERRNO: N/A
|
|
*/
|
|
|
|
int
|
|
wrnad_rtnl_svlan_handler(struct nlmsghdr *nlh)
|
|
{
|
|
vlannetreq *vlan;
|
|
int len;
|
|
unsigned long int ifindex;
|
|
|
|
|
|
vlan = NLMSG_DATA(nlh);
|
|
len = nlh->nlmsg_len - NLMSG_LENGTH(sizeof(vlannetreq));
|
|
|
|
if (len < 0)
|
|
{
|
|
wrnad_log(LOG_WARNING, "Netlink message type %s has wrong nlmsg length %d!",
|
|
wrnad_rtnl_svlan_typestr(nlh->nlmsg_type), nlh->nlmsg_len);
|
|
return -1;
|
|
}
|
|
|
|
if (nlh->nlmsg_type == RTM_SET_SVLAN)
|
|
wrnad_log(LOG_DEBUG, "Netlink VLAN stacking msg(RTM_SET_VLAN): ifindex=%lu, cmd=%s.",
|
|
vlan->ifindex,
|
|
wrnad_rtnl_svlan_cmdstr(vlan->cmd));
|
|
else
|
|
wrnad_log(LOG_DEBUG, "Netlink VLAN stacking msg(RTM_DEL_VLAN): ifindex=%lu, port type=%s.",
|
|
vlan->ifindex,
|
|
wrnad_rtnl_svlan_ptypestr(vlan->type));
|
|
|
|
if (vlan->cmd != VLAN_SET_STPID)
|
|
{
|
|
/* Not a set TPID cmd, must have interface */
|
|
ifindex = vlan->ifindex;
|
|
if (ifindex == 0 || wrnad_rtnl_check_proxy_interface(ifindex) == NULL)
|
|
{
|
|
wrnad_log(LOG_DEBUG, "Netlink message type %s skipped on interface %lu",
|
|
wrnad_rtnl_typestr(nlh->nlmsg_type), vlan->ifindex);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|