863 lines
27 KiB
C
863 lines
27 KiB
C
/* ipnet_cmd_vlan.c - Shell command of 802.1ad VLAN */
|
|
|
|
/*
|
|
* 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,02dec10,tlu Add default case for parsing cmd
|
|
01b,17mar10,tlu Diable configuration part in NAE
|
|
01a,23sep09,tlu Created.
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 1 DESCRIPTION
|
|
****************************************************************************
|
|
* Shell command to configure 802.1ad VLAN.
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 CONFIGURATION
|
|
****************************************************************************
|
|
*/
|
|
|
|
#ifdef IPCOM_KERNEL
|
|
#undef IPCOM_KERNEL
|
|
#endif
|
|
#include "ipnet_config.h"
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#ifdef IPNET_USE_VLAN_STACKING
|
|
|
|
#define IPCOM_USE_CLIB_PROTO
|
|
#include <ipcom_clib.h>
|
|
#include <ipcom_cstyle.h>
|
|
#include <ipcom_getopt.h>
|
|
#include <ipcom_type.h>
|
|
|
|
#include "ipnet_cmd.h"
|
|
|
|
#include "ipnet.h"
|
|
#include "ipnet_h.h"
|
|
#include "ipnet_eth.h"
|
|
#include "ipnet_svlan.h"
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#define IPNET_VCONFIG_CMD_HELP 0 /* Display help message */
|
|
#define IPNET_VCONFIG_CMD_SHOW 1 /* Show service TPID */
|
|
#define IPNET_VCONFIG_CMD_SET_STPID 2 /* Set service TPID */
|
|
#define IPNET_VCONFIG_CMD_CONF 3 /* Configure VLAN stacking */
|
|
#define IPNET_VCONFIG_CMD_DEL 4 /* Delete VLAN stacking */
|
|
#define IPNET_VCONFIG_CMD_PVID_CONF 5 /* Configure PVID */
|
|
#define IPNET_VCONFIG_CMD_IN_CONF 6 /* Configure ingress rule */
|
|
#define IPNET_VCONFIG_CMD_OUT_CONF 7 /* Configure egress rule */
|
|
#define IPNET_VCONFIG_CMD_PRI_MAP_CONF 8 /* Configure priority mapping */
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 7 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 DATA
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_STATIC Ipcom_cmd_int_str_map ipnet_vconfig_cmd_op[] = {
|
|
{ IPNET_VCONFIG_CMD_SET_STPID, "stpid" },
|
|
{ IPNET_VCONFIG_CMD_CONF, "vlantype" },
|
|
{ IPNET_VCONFIG_CMD_PRI_MAP_CONF, "cvid" },
|
|
{ IPNET_VCONFIG_CMD_CONF, "svid" },
|
|
{ IPNET_VCONFIG_CMD_DEL, "remove" },
|
|
{ IPNET_VCONFIG_CMD_PVID_CONF, "pvid" },
|
|
{ IPNET_VCONFIG_CMD_IN_CONF, "ingress" },
|
|
{ IPNET_VCONFIG_CMD_OUT_CONF, "egress" },
|
|
{ IPNET_VCONFIG_CMD_PRI_MAP_CONF, "inpri" },
|
|
{ IPNET_VCONFIG_CMD_PRI_MAP_CONF, "spri" },
|
|
{ -1, IP_NULL }
|
|
};
|
|
|
|
IP_STATIC Ipcom_cmd_int_str_map ipnet_vconfig_switch_map[] =
|
|
{
|
|
{ IPNET_VCONFIG_CMD_HELP, "-h" },
|
|
{ IPNET_VCONFIG_CMD_SHOW, "-l" },
|
|
{ -1, IP_NULL }
|
|
};
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 9 STATIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_vconfig_print_stpid
|
|
*===========================================================================
|
|
* Description: Print the service VLAN Tag Protocol ID value.
|
|
* Parameters: sock - A socket.
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC void
|
|
ipnet_vconfig_print_stpid(Ip_fd fd)
|
|
{
|
|
struct Ip_vlanreq vlanreq;
|
|
|
|
ipcom_memset(&vlanreq, 0, sizeof(struct Ip_vlanreq));
|
|
if (ipcom_socketioctl(fd, IP_SIOCGETSTPID, &vlanreq) < 0)
|
|
{
|
|
ipcom_printf("Get service TPID failed: %s\n",
|
|
ipcom_strerror(ipcom_errno));
|
|
return;
|
|
}
|
|
|
|
ipcom_printf("\tVLAN service Tag Protocol ID: 0x%x\n", vlanreq.vlr_stpid);
|
|
}
|
|
|
|
|
|
#ifndef IPCOM_USE_FORWARDER_VLAN_STACKING
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_vconfig_stpid_conf
|
|
*===========================================================================
|
|
* Description: Configures the service VLAN Tag Protocol ID value.
|
|
* Parameters: sock - A socket.
|
|
* stpid - Service TPID.
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipnet_vconfig_stpid_conf(Ip_fd fd, Ip_u16 stpid)
|
|
{
|
|
struct Ip_vlanreq vlanreq;
|
|
|
|
vlanreq.vlr_stpid = stpid;
|
|
if (ipcom_socketioctl(fd, IP_SIOCSETSTPID, &vlanreq) < 0)
|
|
{
|
|
ipcom_printf("Setting service TPID to %x failed: %s\n",
|
|
stpid,
|
|
ipcom_strerror(ipcom_errno));
|
|
return -ipcom_errno;
|
|
}
|
|
|
|
ipcom_printf("Service TPID is set to 0x%x\n", stpid);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_vconfig_conf
|
|
*===========================================================================
|
|
* Description: Configures the VLAN stacking.
|
|
* Parameters: sock - A socket.
|
|
* ifindex - interface index
|
|
* vlanreq - VLAN IOCTL request structure
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipnet_vconfig_conf(Ip_fd sock, Ip_u32 ifindex, struct Ip_vlanreq *vlanreq)
|
|
{
|
|
struct Ip_ifreq ifreq;
|
|
|
|
(void)ipcom_if_indextoname(ifindex, ifreq.ifr_name);
|
|
ifreq.ip_ifr_data = vlanreq;
|
|
if (ipcom_socketioctl(sock, IP_SIOCSETVLANP, &ifreq) < 0)
|
|
{
|
|
ipcom_printf("Setting VLAN stacking for %s failed: %s\n",
|
|
ifreq.ifr_name,
|
|
ipcom_strerror(ipcom_errno));
|
|
return -ipcom_errno;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_vconfig_pvid_conf
|
|
*===========================================================================
|
|
* Description: Configures the (optional) default port VID.
|
|
* The default value is 1.
|
|
* Parameters: sock - A socket.
|
|
* ifindex - interface index
|
|
* vlanreq - VLAN IOCTL request structure
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipnet_vconfig_pvid_conf(Ip_fd sock, Ip_u32 ifindex, struct Ip_vlanreq *vlanreq)
|
|
{
|
|
struct Ip_ifreq ifreq;
|
|
|
|
(void)ipcom_if_indextoname(ifindex, ifreq.ifr_name);
|
|
ifreq.ip_ifr_data = vlanreq;
|
|
if (ipcom_socketioctl(sock, IP_SIOCSETVLANPVID, &ifreq) < 0) {
|
|
ipcom_printf("Setting default PVID for %s failed: %s" IP_LF,
|
|
ifreq.ifr_name,
|
|
ipcom_strerror(ipcom_errno));
|
|
return -ipcom_errno;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_vconfig_del
|
|
*===========================================================================
|
|
* Description: Delete a stacking VLAN.
|
|
* Parameters: sock - A socket.
|
|
* ifindex - interface index
|
|
* vlanreq - VLAN IOCTL request structure
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipnet_vconfig_del(Ip_fd sock, Ip_u32 ifindex, struct Ip_vlanreq *vlanreq)
|
|
{
|
|
struct Ip_ifreq ifreq;
|
|
|
|
(void)ipcom_if_indextoname(ifindex, ifreq.ifr_name);
|
|
ifreq.ip_ifr_data = vlanreq;
|
|
if (ipcom_socketioctl(sock, IP_SIOCDELVLANP, &ifreq) < 0)
|
|
{
|
|
ipcom_printf("Delete VLAN %d for %s failed: %s\n",
|
|
vlanreq->vlr_tag,
|
|
ifreq.ifr_name,
|
|
ipcom_strerror(ipcom_errno));
|
|
return -ipcom_errno;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_vconfig_pri_map_conf
|
|
*===========================================================================
|
|
* Description: Configures the VLAN priority map from incoming priority to
|
|
* S-VLAN priority for a customer edge/network port.
|
|
* Parameters: sock - A socket.
|
|
* ifindex - interface index
|
|
* vlanreq - VLAN IOCTL request structure
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipnet_vconfig_pri_map_conf(Ip_fd sock, Ip_u32 ifindex, struct Ip_vlanreq *vlanreq)
|
|
{
|
|
struct Ip_ifreq ifreq;
|
|
|
|
(void)ipcom_if_indextoname(ifindex, ifreq.ifr_name);
|
|
ifreq.ip_ifr_data = vlanreq;
|
|
if (ipcom_socketioctl(sock, IP_SIOCSETVLANPRIMAP, &ifreq) < 0)
|
|
{
|
|
ipcom_printf("Setting VALN priority map for %s failed: %s\n",
|
|
ifreq.ifr_name,
|
|
ipcom_strerror(ipcom_errno));
|
|
return -ipcom_errno;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_vconfig_in_conf
|
|
*===========================================================================
|
|
* Description: Configures the (optional) vlan ingress rule for a VLAN
|
|
* stacking. The default value is Admit-all.
|
|
* Parameters: sock - A socket.
|
|
* ifindex - interface index
|
|
* vlanreq - VLAN IOCTL request structure
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipnet_vconfig_in_conf(Ip_fd sock, Ip_u32 ifindex, struct Ip_vlanreq *vlanreq)
|
|
{
|
|
struct Ip_ifreq ifreq;
|
|
|
|
(void)ipcom_if_indextoname(ifindex, ifreq.ifr_name);
|
|
ifreq.ip_ifr_data = vlanreq;
|
|
if (ipcom_socketioctl(sock, IP_SIOCSETVLANINRULE, &ifreq) < 0)
|
|
{
|
|
ipcom_printf("Setting VLAN ingress rule for %s failed: %s\n",
|
|
ifreq.ifr_name,
|
|
ipcom_strerror(ipcom_errno));
|
|
return -ipcom_errno;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_vconfig_out_conf
|
|
*===========================================================================
|
|
* Description: Configures the (optional) vlan egress rule for a VLAN
|
|
* stacking. The default value is tagged.
|
|
* Parameters: sock - A socket.
|
|
* ifindex - interface index
|
|
* vlanreq - VLAN IOCTL request structure
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipnet_vconfig_out_conf(Ip_fd sock, Ip_u32 ifindex, struct Ip_vlanreq *vlanreq)
|
|
{
|
|
struct Ip_ifreq ifreq;
|
|
|
|
(void)ipcom_if_indextoname(ifindex, ifreq.ifr_name);
|
|
ifreq.ip_ifr_data = vlanreq;
|
|
if (ipcom_socketioctl(sock, IP_SIOCSETVLANOUTRULE, &ifreq) < 0)
|
|
{
|
|
ipcom_printf("Setting VLAN egress rule for %s failed: %s\n",
|
|
ifreq.ifr_name,
|
|
ipcom_strerror(ipcom_errno));
|
|
return -ipcom_errno;
|
|
}
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_cmd_vconfig_print_usage
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC void
|
|
ipnet_cmd_vconfig_print_usage(void)
|
|
{
|
|
ipcom_printf(IP_LF);
|
|
ipcom_printf("NAME" IP_LF);
|
|
ipcom_printf(" vconfig - VLAN stacking configuration" IP_LF);
|
|
ipcom_printf(IP_LF);
|
|
ipcom_printf("SYNOPSIS" IP_LF);
|
|
ipcom_printf(" vconfig [ options ]" IP_LF);
|
|
#ifndef IPCOM_USE_FORWARDER_VLAN_STACKING
|
|
ipcom_printf(" vconfig stpid <value>" IP_LF);
|
|
ipcom_printf(" vconfig <interface> vlantype <value> cvid <tag> svid <tag> " IP_LF);
|
|
ipcom_printf(" vconfig <interface> pvid <tag>" IP_LF);
|
|
ipcom_printf(" vconfig <interface> ingress <rule>" IP_LF);
|
|
ipcom_printf(" vconfig <interface> egress <rule>" IP_LF);
|
|
ipcom_printf(" vconfig <interface> cvid <tag> inpri <value> spri <value>"IP_LF);
|
|
ipcom_printf(" vconfig <interface> remove <tag>"IP_LF);
|
|
#endif
|
|
ipcom_printf(IP_LF);
|
|
ipcom_printf("DESCRIPTION" IP_LF);
|
|
ipcom_printf(" vconfig configures VLAN stacking parameters."IP_LF);
|
|
ipcom_printf(IP_LF);
|
|
ipcom_printf("COMMANDS"IP_LF);
|
|
ipcom_printf(" -h\t\t\tDisplay usage help message."IP_LF);
|
|
ipcom_printf(" -l\t\t\tDisplay service VLAN tag protocol ID."IP_LF);
|
|
#ifndef IPCOM_USE_FORWARDER_VLAN_STACKING
|
|
ipcom_printf(" stpid\t\tSet service VLAN tag protocol ID."IP_LF);
|
|
ipcom_printf(" \t(1-33023,33025-65535)."IP_LF);
|
|
ipcom_printf(" vlantype <value>\tThe VLAN stacking type."IP_LF);
|
|
ipcom_printf(" \t(1 = customer edge/network port,"IP_LF);
|
|
ipcom_printf(" \t 2 = provider network port on provider edge node,"IP_LF);
|
|
ipcom_printf(" \t 3 = provider network port on S-VLAN node)."IP_LF);
|
|
ipcom_printf(" pvid <tag>\t\tThe port VID (1-4094)."IP_LF);
|
|
ipcom_printf(" cvid <tag>\t\tThe customer VID (1-4094)."IP_LF);
|
|
ipcom_printf(" svid <tag>\t\tThe service VID (1-4094)."IP_LF);
|
|
ipcom_printf(" remove <tag>\tDelete a VLAN stacking VID (1-4094)."IP_LF);
|
|
ipcom_printf(" ingress <rule>\tThe VLAN ingress rule."IP_LF);
|
|
ipcom_printf(" \t(0 = Admit-All,"IP_LF);
|
|
ipcom_printf(" \t 1 = Admit-Tag,"IP_LF);
|
|
ipcom_printf(" \t 2 = Admit-Untag+PriorityTag)."IP_LF);
|
|
ipcom_printf(" egress <rule>\tThe VLAN egress rule. "IP_LF);
|
|
ipcom_printf(" \t(0 = Tagged, 1 = Untagged)."IP_LF);
|
|
ipcom_printf(" inpri <value>\tThe priority bits in a receiving VLAN frame."IP_LF);
|
|
ipcom_printf(" spri <value>\tThe priority bits mapped from a receiving"IP_LF);
|
|
ipcom_printf(" \tVLAN frame, and is inserted to the S-VLAN tag"IP_LF);
|
|
ipcom_printf(" \tin a transmitting VLAN frame on a customer"IP_LF);
|
|
ipcom_printf(" \tedge/network port."IP_LF);
|
|
#endif
|
|
ipcom_printf(IP_LF);
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 10 GLOBAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 11 PUBLIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipnet_cmd_vconfig
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_PUBLIC int
|
|
ipnet_cmd_vconfig(int argc, char **argv)
|
|
{
|
|
int i = 0, next_arg = 1, err = 0;
|
|
Ip_fd fd;
|
|
#ifndef IPCOM_USE_FORWARDER_VLAN_STACKING
|
|
int tmp_stpid;
|
|
Ip_u16 stpid;
|
|
#endif
|
|
IP_CONST char *ifname = IP_NULL;
|
|
Ip_u32 ifindex;
|
|
struct Ip_vlanreq vlan;
|
|
|
|
|
|
#ifdef IPCOM_USE_INET
|
|
fd = ipcom_socket(IP_AF_INET, IP_SOCK_DGRAM, 0);
|
|
#else
|
|
fd = ipcom_socket(IP_AF_INET6, IP_SOCK_DGRAM, 0);
|
|
#endif
|
|
if (fd == IP_SOCKERR)
|
|
{
|
|
ipcom_printf("vconfig: ipcom_socket() failed: %s"IP_LF, ipcom_strerror(ipcom_errno));
|
|
goto errout;
|
|
}
|
|
|
|
/* Process all switches */
|
|
while (argc > next_arg && i != -1)
|
|
{
|
|
i = ipcom_cmd_str_to_key(ipnet_vconfig_switch_map, argv[next_arg]);
|
|
switch (i)
|
|
{
|
|
case IPNET_VCONFIG_CMD_SHOW:
|
|
ipnet_vconfig_print_stpid(fd);
|
|
goto cleanup;
|
|
case IPNET_VCONFIG_CMD_HELP:
|
|
goto usage;
|
|
default:
|
|
if (argv[next_arg][0] == '-' && i == -1)
|
|
{
|
|
ipcom_printf("'%s' is a unknown switch"IP_LF, argv[next_arg]);
|
|
goto usage;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (argc == next_arg)
|
|
goto usage;
|
|
|
|
i = 0;
|
|
/* Process all global commands */
|
|
while (argc > next_arg && i != -1)
|
|
{
|
|
i = ipcom_cmd_str_to_key(ipnet_vconfig_cmd_op, argv[next_arg]);
|
|
switch (i)
|
|
{
|
|
case IPNET_VCONFIG_CMD_SET_STPID:
|
|
#ifdef IPCOM_USE_FORWARDER_VLAN_STACKING
|
|
goto usage;
|
|
#else
|
|
tmp_stpid = ipcom_atoi(argv[++next_arg]);
|
|
if (tmp_stpid < 1 || tmp_stpid == 0x8100 || tmp_stpid > 65535)
|
|
{
|
|
ipcom_printf("S-TPID must be 1 - 33023, 33025 - 65535\n");
|
|
goto errout;
|
|
}
|
|
stpid = (Ip_u16)tmp_stpid;
|
|
err = ipnet_vconfig_stpid_conf(fd, stpid);
|
|
goto cleanup;
|
|
#endif
|
|
default:
|
|
if (i != -1)
|
|
{
|
|
ipcom_printf("The first parameter must be an interface name\n");
|
|
goto usage;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
ip_assert(argc > next_arg);
|
|
|
|
/* next parameter must be an interface name */
|
|
ifname = argv[next_arg];
|
|
ifindex = ipcom_if_nametoindex(ifname);
|
|
if (ifindex == 0)
|
|
{
|
|
ipcom_printf("vconfig: interface %s not found.\n", ifname);
|
|
goto errout;
|
|
}
|
|
|
|
i = 0;
|
|
next_arg ++;
|
|
ipcom_memset(&vlan, 0, sizeof(vlan));
|
|
/* Process all interface commands */
|
|
while (argc > next_arg && i != -1)
|
|
{
|
|
i = ipcom_cmd_str_to_key(ipnet_vconfig_cmd_op, argv[next_arg]);
|
|
switch (i)
|
|
{
|
|
case IPNET_VCONFIG_CMD_CONF:
|
|
#ifdef IPCOM_USE_FORWARDER_VLAN_STACKING
|
|
goto usage;
|
|
#else
|
|
if (argc - next_arg < 3)
|
|
goto vlan_conf_parse_error;
|
|
|
|
if (ipcom_strcmp(argv[next_arg], "vlantype") == 0)
|
|
{
|
|
vlan.vlr_type = (Ip_u16)ipcom_atoi(argv[++next_arg]);
|
|
if (vlan.vlr_type < 1 || vlan.vlr_type > 3)
|
|
{
|
|
ipcom_printf("vlan type must be 1 - 3\n");
|
|
goto errout;
|
|
}
|
|
++next_arg;
|
|
}
|
|
|
|
if (ipcom_strcmp(argv[next_arg], "cvid") &&
|
|
ipcom_strcmp(argv[next_arg], "svid"))
|
|
goto vlan_conf_parse_error;
|
|
else
|
|
{
|
|
if (ipcom_strcmp(argv[next_arg], "cvid") == 0)
|
|
{
|
|
vlan.vlr_tag = (Ip_u16)ipcom_atoi(argv[++next_arg]);
|
|
if (vlan.vlr_tag < 1 || vlan.vlr_tag > 4094)
|
|
{
|
|
ipcom_printf("vlan ID must be 1 - 4094\n");
|
|
goto errout;
|
|
}
|
|
++next_arg;
|
|
}
|
|
else
|
|
{
|
|
vlan.vlr_stag = (Ip_u16)ipcom_atoi(argv[++next_arg]);
|
|
if (vlan.vlr_stag < 1 || vlan.vlr_stag > 4094)
|
|
{
|
|
ipcom_printf("vlan ID must be 1 - 4094\n");
|
|
goto errout;
|
|
|
|
}
|
|
++next_arg;
|
|
}
|
|
}
|
|
|
|
if ((argc - next_arg > 1) &&
|
|
(ipcom_strcmp(argv[next_arg], "vlantype") == 0))
|
|
{
|
|
vlan.vlr_type = (Ip_u16)ipcom_atoi(argv[++next_arg]);
|
|
if (vlan.vlr_type < 1 || vlan.vlr_type > 3)
|
|
{
|
|
ipcom_printf("vlan type must be 1 - 3\n");
|
|
goto errout;
|
|
}
|
|
}
|
|
|
|
if ((argc - next_arg > 1) &&
|
|
(ipcom_strcmp(argv[next_arg], "cvid") == 0))
|
|
{
|
|
vlan.vlr_tag = (Ip_u16)ipcom_atoi(argv[++next_arg]);
|
|
if (vlan.vlr_tag < 1 || vlan.vlr_tag > 4094)
|
|
{
|
|
ipcom_printf("vlan ID must be 1 - 4094\n");
|
|
goto errout;
|
|
}
|
|
}
|
|
|
|
if ((argc - next_arg > 1) &&
|
|
(ipcom_strcmp(argv[next_arg], "svid") == 0))
|
|
{
|
|
vlan.vlr_stag = (Ip_u16)ipcom_atoi(argv[++next_arg]);
|
|
if (vlan.vlr_stag < 1 || vlan.vlr_stag > 4094)
|
|
{
|
|
ipcom_printf("vlan ID must be 1 - 4094\n");
|
|
goto errout;
|
|
}
|
|
}
|
|
|
|
if (vlan.vlr_type == 0)
|
|
{
|
|
if ((argc - next_arg > 1) &&
|
|
(ipcom_strcmp(argv[++next_arg], "vlantype") == 0))
|
|
{
|
|
vlan.vlr_type = (Ip_u16)ipcom_atoi(argv[++next_arg]);
|
|
if (vlan.vlr_type < 1 || vlan.vlr_type > 3)
|
|
{
|
|
ipcom_printf("vlan type must be 1 - 3\n");
|
|
goto errout;
|
|
}
|
|
}
|
|
else
|
|
goto vlan_conf_parse_error;
|
|
}
|
|
|
|
if (vlan.vlr_type == 1)
|
|
{
|
|
/* customer edge/network port */
|
|
if ((vlan.vlr_tag == 0) || (vlan.vlr_stag == 0))
|
|
{
|
|
ipcom_printf("C-VID and S-VID must be both configured\n");
|
|
goto errout;
|
|
}
|
|
}
|
|
else if ((vlan.vlr_type == 2) || (vlan.vlr_type == 3))
|
|
{
|
|
/* provider network port */
|
|
if ((vlan.vlr_tag != 0) || (vlan.vlr_stag == 0))
|
|
{
|
|
ipcom_printf("C-VID must not be configured and S-VID must be configured\n");
|
|
goto errout;
|
|
}
|
|
}
|
|
|
|
err = ipnet_vconfig_conf(fd, ifindex, &vlan);
|
|
++next_arg;
|
|
break;
|
|
|
|
vlan_conf_parse_error:
|
|
ipcom_printf("cvid/svid <vid> and vlantype <value> must be set at the same time\n");
|
|
goto errout;
|
|
#endif
|
|
|
|
case IPNET_VCONFIG_CMD_PVID_CONF:
|
|
#ifdef IPCOM_USE_FORWARDER_VLAN_STACKING
|
|
goto usage;
|
|
#else
|
|
vlan.vlr_tag = (Ip_u16)ipcom_atoi(argv[++next_arg]);
|
|
if (vlan.vlr_tag < 1 || vlan.vlr_tag > 4094)
|
|
{
|
|
ipcom_printf("VID must be 1 - 4094\n");
|
|
goto errout;
|
|
}
|
|
|
|
err = ipnet_vconfig_pvid_conf(fd, ifindex, &vlan);
|
|
++next_arg;
|
|
break;
|
|
#endif
|
|
|
|
case IPNET_VCONFIG_CMD_DEL:
|
|
#ifdef IPCOM_USE_FORWARDER_VLAN_STACKING
|
|
goto usage;
|
|
#else
|
|
vlan.vlr_tag = (Ip_u16)ipcom_atoi(argv[++next_arg]);
|
|
if (vlan.vlr_tag < 1 || vlan.vlr_tag > 4094)
|
|
{
|
|
ipcom_printf("VID must be 1 - 4094\n");
|
|
goto errout;
|
|
}
|
|
|
|
err = ipnet_vconfig_del(fd, ifindex, &vlan);
|
|
++next_arg;
|
|
break;
|
|
#endif
|
|
|
|
case IPNET_VCONFIG_CMD_PRI_MAP_CONF:
|
|
#ifdef IPCOM_USE_FORWARDER_VLAN_STACKING
|
|
goto usage;
|
|
#else
|
|
if (argc - next_arg < 3)
|
|
goto vlan_conf_pri_map_parse_error;
|
|
|
|
if (ipcom_strcmp(argv[next_arg], "cvid") == 0)
|
|
{
|
|
vlan.vlr_tag = (Ip_u16)ipcom_atoi(argv[++next_arg]);
|
|
if (vlan.vlr_tag < 1 || vlan.vlr_tag > 4094)
|
|
{
|
|
ipcom_printf("vlan ID must be 1 - 4094\n");
|
|
goto errout;
|
|
}
|
|
++next_arg;
|
|
}
|
|
|
|
/* init pri values */
|
|
vlan.vlr_pri = 10;
|
|
vlan.vlr_spri = 10;
|
|
|
|
if (ipcom_strcmp(argv[next_arg], "inpri") &&
|
|
ipcom_strcmp(argv[next_arg], "spri"))
|
|
goto vlan_conf_pri_map_parse_error;
|
|
else
|
|
{
|
|
if (ipcom_strcmp(argv[next_arg], "inpri") == 0)
|
|
{
|
|
vlan.vlr_pri = (Ip_u16)ipcom_atoi(argv[++next_arg]);
|
|
if (vlan.vlr_pri > 7)
|
|
{
|
|
ipcom_printf("vlan priority must be 0 - 7\n");
|
|
goto errout;
|
|
}
|
|
++next_arg;
|
|
}
|
|
else
|
|
{
|
|
vlan.vlr_spri = (Ip_u16)ipcom_atoi(argv[++next_arg]);
|
|
if (vlan.vlr_spri > 7)
|
|
{
|
|
ipcom_printf("vlan priority must be 0 - 7\n");
|
|
goto errout;
|
|
}
|
|
++next_arg;
|
|
}
|
|
|
|
if ((argc - next_arg > 1) &&
|
|
(ipcom_strcmp(argv[next_arg], "inpri") == 0))
|
|
{
|
|
|
|
vlan.vlr_pri = (Ip_u16)ipcom_atoi(argv[++next_arg]);
|
|
if (vlan.vlr_pri > 7)
|
|
{
|
|
ipcom_printf("vlan priority must be 0 - 7\n");
|
|
goto errout;
|
|
}
|
|
}
|
|
|
|
if ((argc - next_arg > 1) &&
|
|
(ipcom_strcmp(argv[next_arg], "spri") == 0))
|
|
{
|
|
|
|
vlan.vlr_spri = (Ip_u16)ipcom_atoi(argv[++next_arg]);
|
|
if (vlan.vlr_spri > 7)
|
|
{
|
|
ipcom_printf("vlan priority must be 0 - 7\n");
|
|
goto errout;
|
|
}
|
|
}
|
|
|
|
if ((argc - next_arg > 1) &&
|
|
ipcom_strcmp(argv[next_arg], "cvid") == 0)
|
|
{
|
|
vlan.vlr_tag = (Ip_u16)ipcom_atoi(argv[++next_arg]);
|
|
if (vlan.vlr_tag < 1 || vlan.vlr_tag > 4094)
|
|
{
|
|
ipcom_printf("vlan ID must be 1 - 4094\n");
|
|
goto errout;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (vlan.vlr_tag == 0 || vlan.vlr_pri == 10 || vlan.vlr_spri == 10)
|
|
goto vlan_conf_pri_map_parse_error;
|
|
|
|
err = ipnet_vconfig_pri_map_conf(fd, ifindex, &vlan);
|
|
++next_arg;
|
|
break;
|
|
|
|
vlan_conf_pri_map_parse_error:
|
|
ipcom_printf("cvid, inpri, and spri must be set at the same time\n");
|
|
goto errout;
|
|
#endif
|
|
|
|
case IPNET_VCONFIG_CMD_IN_CONF:
|
|
#ifdef IPCOM_USE_FORWARDER_VLAN_STACKING
|
|
goto usage;
|
|
#else
|
|
vlan.vlr_inrule = (Ip_u16)ipcom_atoi(argv[++next_arg]);
|
|
if (vlan.vlr_inrule > 2)
|
|
{
|
|
ipcom_printf("vlan ingress rule must be 0(Admit-all)/1(Admit-tag)/2(Admit-untag+Priority)\n");
|
|
goto errout;
|
|
}
|
|
|
|
err = ipnet_vconfig_in_conf(fd, ifindex, &vlan);
|
|
++next_arg;
|
|
break;
|
|
#endif
|
|
|
|
case IPNET_VCONFIG_CMD_OUT_CONF:
|
|
#ifdef IPCOM_USE_FORWARDER_VLAN_STACKING
|
|
goto usage;
|
|
#else
|
|
vlan.vlr_outrule = (Ip_u16)ipcom_atoi(argv[++next_arg]);
|
|
if (vlan.vlr_outrule > 1)
|
|
{
|
|
ipcom_printf("vlan egress rule must be 0(tagged)/1(untagged)\n");
|
|
goto errout;
|
|
}
|
|
err = ipnet_vconfig_out_conf(fd, ifindex, &vlan);
|
|
++next_arg;
|
|
break;
|
|
#endif
|
|
|
|
default:
|
|
goto usage;
|
|
}
|
|
}
|
|
|
|
|
|
cleanup:
|
|
if (fd != IP_INVALID_SOCKET)
|
|
(void)ipcom_socketclose(fd);
|
|
return err;
|
|
|
|
usage:
|
|
ipnet_cmd_vconfig_print_usage();
|
|
|
|
errout:
|
|
err = -1;
|
|
goto cleanup;
|
|
}
|
|
|
|
#endif /* IPNET_USE_VLAN_STACKING */
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|
|
|