/* 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 #include #include #include #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 " IP_LF); ipcom_printf(" vconfig vlantype cvid svid " IP_LF); ipcom_printf(" vconfig pvid " IP_LF); ipcom_printf(" vconfig ingress " IP_LF); ipcom_printf(" vconfig egress " IP_LF); ipcom_printf(" vconfig cvid inpri spri "IP_LF); ipcom_printf(" vconfig remove "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 \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 \t\tThe port VID (1-4094)."IP_LF); ipcom_printf(" cvid \t\tThe customer VID (1-4094)."IP_LF); ipcom_printf(" svid \t\tThe service VID (1-4094)."IP_LF); ipcom_printf(" remove \tDelete a VLAN stacking VID (1-4094)."IP_LF); ipcom_printf(" ingress \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 \tThe VLAN egress rule. "IP_LF); ipcom_printf(" \t(0 = Tagged, 1 = Untagged)."IP_LF); ipcom_printf(" inpri \tThe priority bits in a receiving VLAN frame."IP_LF); ipcom_printf(" spri \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 and vlantype 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 **************************************************************************** */