/* 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 #include #include #include #include #endif #include #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; }