Revision 337283

Date:
2018/08/03 15:03:56
Author:
sduo
Revision Log:
Updated vale-vlan-ctl.
Files:

Legend:

 
Added
 
Removed
 
Modified
  • soc2018/sduo/head/tools/tools/vale_vlan/Makefile

     
    1 PROGS=vale-vlan-ctl
    2 CLEANFILES = $(PROGS) *.o
    3 CFLAGS += -Werror -Wall
    4 CFLAGS += -Wextra
    5 SRCS=vale-vlan-ctl.c
    6 MAN=
    7 .include <bsd.prog.mk>
    8
    9 all: $(PROGS)
    10
    11 vale-vlan-ctl: vale-vlan-ctl.o
    12 $(CC) $(CFLAGS) vale-vlan-ctl.c -o vale-vlan-ctl
  • soc2018/sduo/head/tools/tools/vale_vlan/vale-vlan-ctl.c

     
    1 #include <errno.h>
    2 #include <fcntl.h>
    3 #include <getopt.h>
    4 #include <inttypes.h>
    5 #include <net/if.h>
    6 #include <stdint.h>
    7 #include <stdio.h>
    8 #include <stdlib.h>
    9 #include <string.h>
    10 #include <sys/ioctl.h>
    11 #include <sys/stat.h>
    12 #include <sys/time.h>
    13 #include <sys/types.h>
    14 #include <unistd.h>
    15
    16 #include <net/vale_vlan_user.h>
    17
    18 #define DEVICE_NAME "/dev/vale_vlan"
    19
    20 static int
    21 str_to_uint16(const char *str, uint16_t *res)
    22 {
    23 intmax_t val;
    24 char *end;
    25 errno = 0;
    26
    27 val = strtoimax(str, &end, 10);
    28 if (errno == ERANGE || val < 0 || val > UINT16_MAX || end == str ||
    29 *end != '\0') {
    30 return -1;
    31 }
    32 *res = (uint16_t)val;
    33 return 0;
    34 }
    35
    36 static int
    37 vlan_ioctl(int fd, const char *conf_name, uint16_t req_type)
    38 {
    39 struct vlanreq_header hdr;
    40
    41 memset(&hdr, 0, sizeof(hdr));
    42 hdr.vr_req_type = req_type;
    43 snprintf(hdr.vr_conf_name, sizeof(hdr.vr_conf_name), "%s", conf_name);
    44
    45 return ioctl(fd, VV_IOCCTRL, &hdr);
    46 }
    47
    48 static ssize_t
    49 vlan_write(int fd, const char *port_name, uint8_t port_type, uint8_t action,
    50 uint16_t vlan_id)
    51 {
    52 struct vlan_conf_entry entry;
    53
    54 memset(&entry, 0, sizeof(entry));
    55 if (port_name) {
    56 snprintf(entry.port_name, sizeof(entry.port_name), "%s",
    57 port_name);
    58 }
    59 entry.port_type = port_type;
    60 entry.vlan_id = vlan_id;
    61 entry.action = action;
    62
    63 return write(fd, &entry, sizeof(entry));
    64 }
    65
    66 #define MAX_LIST_ENTRIES 256
    67
    68 static void
    69 list_conf(int fd)
    70 {
    71 struct port *port_entries = NULL;
    72 int ret;
    73 int i;
    74
    75 port_entries = malloc(sizeof(struct port) * MAX_LIST_ENTRIES);
    76 if (!port_entries) {
    77 exit(EXIT_FAILURE);
    78 }
    79
    80 ret = read(fd, port_entries, sizeof(struct port) * MAX_LIST_ENTRIES);
    81 if (ret < 0) {
    82 perror("read()");
    83 exit(EXIT_FAILURE);
    84 }
    85 for (i = 0; i < ret / (int)sizeof(struct port); ++i) {
    86 printf("%s%s, type:", port_entries[i].bdg_name,
    87 port_entries[i].port_name);
    88 if (port_entries[i].port_type == TRUNK_PORT) {
    89 printf("trunk port\n");
    90 } else {
    91 printf("access port, vlan id:%d\n",
    92 port_entries[i].vlan_id);
    93 }
    94 }
    95
    96 free(port_entries);
    97 }
    98
    99 static int
    100 valid_port_name(const char *conf_name)
    101 {
    102
    103 return (strlen(conf_name) + 1) <= NETMAP_REQ_IFNAMSIZ;
    104 }
    105
    106 static void
    107 attach_access_port(int fd, char *port_and_vlan, int create)
    108 {
    109 char port_name[NETMAP_REQ_IFNAMSIZ];
    110 uint16_t vlan_id = 0;
    111 uint8_t action;
    112 ssize_t ret;
    113 char *token;
    114
    115 token = strtok(port_and_vlan, "=");
    116 if (!token) {
    117 /* cannot happen (?) */
    118 fprintf(stderr, "You must specify a vlan id\n");
    119 exit(EXIT_FAILURE);
    120 }
    121 if (!valid_port_name(token)) {
    122 fprintf(stderr, "Max port name length = %d\n",
    123 NETMAP_REQ_IFNAMSIZ);
    124 exit(EXIT_FAILURE);
    125 }
    126 snprintf(port_name, sizeof(port_name), "%s", token);
    127
    128 token = strtok(NULL, "=");
    129 if (!token) {
    130 fprintf(stderr, "You must specify a vlan id\n");
    131 exit(EXIT_FAILURE);
    132 }
    133 if (str_to_uint16(token, &vlan_id) == -1 || vlan_id >= 4095) {
    134 fprintf(stderr, "Invalid vlan id: %u\n", vlan_id);
    135 exit(EXIT_FAILURE);
    136 }
    137
    138 action = create ? CREATE_AND_ATTACH_PORT : ATTACH_PORT;
    139 ret = vlan_write(fd, port_name, ACCESS_PORT, action, vlan_id);
    140 if (ret < 0) {
    141 perror(port_name);
    142 exit(EXIT_FAILURE);
    143 }
    144 }
    145
    146 static void
    147 detach_access_port(int fd, const char *port_name, int destroy)
    148 {
    149 uint8_t action;
    150 ssize_t ret;
    151
    152 action = destroy ? DETACH_AND_DESTROY_PORT : DETACH_PORT;
    153 ret = vlan_write(fd, port_name, ACCESS_PORT, action, 0xFFF);
    154 if (ret < 0) {
    155 perror(port_name);
    156 exit(EXIT_FAILURE);
    157 }
    158 }
    159
    160 static void
    161 attach_trunk_port(int fd, const char *port_name, int create)
    162 {
    163 uint8_t action;
    164 ssize_t ret;
    165
    166 if (!valid_port_name(port_name)) {
    167 fprintf(stderr, "Max port name length = %d\n",
    168 NETMAP_REQ_IFNAMSIZ);
    169 exit(EXIT_FAILURE);
    170 }
    171
    172 action = create ? CREATE_AND_ATTACH_PORT : ATTACH_PORT;
    173 ret = vlan_write(fd, port_name, TRUNK_PORT, action, 0xFFF);
    174 if (ret < 0) {
    175 perror(port_name);
    176 exit(EXIT_FAILURE);
    177 }
    178 }
    179
    180 static void
    181 detach_trunk_port(int fd, int destroy)
    182 {
    183 uint8_t action;
    184 ssize_t ret;
    185
    186 action = destroy ? DETACH_AND_DESTROY_PORT : DETACH_PORT;
    187 ret = vlan_write(fd, NULL, TRUNK_PORT, action, 0xFFF);
    188 if (ret < 0) {
    189 exit(EXIT_FAILURE);
    190 }
    191 }
    192
    193 static int
    194 valid_conf_name(const char *conf_name)
    195 {
    196
    197 return (strlen(conf_name) + 1) <= VV_CONF_NAME_LENGTH;
    198 }
    199
    200 static void
    201 create_conf(int fd, const char *conf_name)
    202 {
    203 int ret;
    204
    205 if (!valid_conf_name(conf_name)) {
    206 fprintf(stderr, "Max conf name length = %d\n",
    207 VV_CONF_NAME_LENGTH - 1);
    208 exit(EXIT_FAILURE);
    209 }
    210
    211 ret = vlan_ioctl(fd, conf_name, VV_REQ_CREATE_CONF);
    212 if (ret < 0) {
    213 perror(conf_name);
    214 exit(EXIT_FAILURE);
    215 }
    216 }
    217
    218 static void
    219 delete_conf(int fd, const char *conf_name)
    220 {
    221 int ret;
    222
    223 if (!valid_conf_name(conf_name)) {
    224 fprintf(stderr, "Max conf name length = %d\n",
    225 VV_CONF_NAME_LENGTH - 1);
    226 exit(EXIT_FAILURE);
    227 }
    228
    229 ret = vlan_ioctl(fd, conf_name, VV_REQ_DELETE_CONF);
    230 if (ret < 0) {
    231 perror(conf_name);
    232 exit(EXIT_FAILURE);
    233 }
    234 }
    235
    236 static void
    237 select_conf(int fd, const char *conf_name)
    238 {
    239 int ret;
    240
    241 if (!valid_conf_name(conf_name)) {
    242 fprintf(stderr, "Max conf name length = %d\n",
    243 VV_CONF_NAME_LENGTH - 1);
    244 exit(EXIT_FAILURE);
    245 }
    246
    247 ret = vlan_ioctl(fd, conf_name, VV_REQ_SELECT_CONF);
    248 if (ret < 0) {
    249 perror(conf_name);
    250 exit(EXIT_FAILURE);
    251 }
    252 }
    253
    254 static void
    255 usage(const char *file_name, FILE *std_stream)
    256 {
    257
    258 fprintf(std_stream,
    259 "Usage:\n"
    260 "%s arguments\n"
    261 "\t-n conf_name create (and select) configuration "
    262 "conf_name\n"
    263 "\t-r conf_name delete configuration conf_name\n"
    264 "\t-s conf_name select configuration conf_name\n"
    265 "\t-t interface attach interface as trunk port\n"
    266 "\t-T detach trunk port\n"
    267 "\t-p interfaces create persistent VALE port "
    268 "and attach it as trunk port\n"
    269 "\t-P detach trunk port and destroy it (must "
    270 "have been created through -p)\n"
    271 "\t-a interface=vlan_id attach interface as vlan port with id "
    272 "vlan_id\n"
    273 "\t-A interface detach vlan port interface\n"
    274 "\t-c interface=vlan_id create persistent VALE port and attach "
    275 "it as vlan port with id vlan_id\n"
    276 "\t-C interface detach vlan port interface and destroy "
    277 "it (must have been created through -c)\n"
    278 "\t-l list attached interfaces\n",
    279 file_name);
    280 }
    281
    282 int
    283 main(int argc, char **argv)
    284 {
    285 int fd;
    286 char c;
    287
    288 if (argc == 1) {
    289 usage(argv[0], stderr);
    290 exit(EXIT_FAILURE);
    291 }
    292
    293 fd = open(DEVICE_NAME, O_RDWR);
    294 if (fd < 0) {
    295 perror(DEVICE_NAME);
    296 exit(EXIT_FAILURE);
    297 }
    298
    299 while ((c = getopt(argc, argv, "n:s:r:t:Tp:Pc:C:a:A:hl")) != -1) {
    300 switch (c) {
    301 case 't': /* attach trunk port */
    302 attach_trunk_port(fd, optarg, 0 /* don't create */);
    303 break;
    304 case 'T': /* detach trunk port */
    305 detach_trunk_port(fd, 0 /* don't destroy */);
    306 break;
    307 case 'p': /* create and attach trunk port */
    308 attach_trunk_port(fd, optarg, 1 /* create */);
    309 break;
    310 case 'P': /* detach and destroy trunk port */
    311 detach_trunk_port(fd, 1 /* destroy */);
    312 break;
    313 case 'a': /* attach vlan port */
    314 attach_access_port(fd, optarg, 0 /* don't create */);
    315 break;
    316 case 'A': /* detach vlan port */
    317 detach_access_port(fd, optarg, 0 /* don't destroy */);
    318 break;
    319 case 'c': /* create and attach vlan port */
    320 attach_access_port(fd, optarg, 1 /* create */);
    321 break;
    322 case 'C': /* detach and destroy vlan port */
    323 detach_access_port(fd, optarg, 1 /* destroy */);
    324 break;
    325 case 'n': /* create new configuration */
    326 create_conf(fd, optarg);
    327 break;
    328 case 'r': /* destroy existing configuration */
    329 delete_conf(fd, optarg);
    330 break;
    331 case 's': /* select existing configuration */
    332 select_conf(fd, optarg);
    333 break;
    334 case 'l': /* list existing configuration */
    335 list_conf(fd);
    336 break;
    337 case 'h': /* help */
    338 usage(argv[0], stdout);
    339 exit(0);
    340 default: /* error, unknown option or missing parameter */
    341 usage(argv[0], stdout);
    342 exit(EXIT_FAILURE);
    343 }
    344 }
    345 return 0;
    346 }
  • soc2018/sduo/vale_vlan_utils/Makefile

     
    1 CFLAGS = -Wall -g -I$(PWD)/../head/sys
    2
    3 all:
    4 $(CC) $(CFLAGS) vale-vlan-ctl.c -o vale-vlan-ctl
    5
    6 clean:
    7 rm -f *.o vale-vlan-ctl
  • soc2018/sduo/vale_vlan_utils/vale-vlan-ctl.c

     
    1 #include <errno.h>
    2 #include <fcntl.h>
    3 #include <getopt.h>
    4 #include <inttypes.h>
    5 #include <net/if.h>
    6 #include <stdint.h>
    7 #include <stdio.h>
    8 #include <stdlib.h>
    9 #include <string.h>
    10 #include <sys/ioctl.h>
    11 #include <sys/stat.h>
    12 #include <sys/time.h>
    13 #include <sys/types.h>
    14 #include <unistd.h>
    15
    16 #include <net/vale_vlan_user.h>
    17
    18 #define DEVICE_NAME "/dev/vale_vlan"
    19
    20 static int
    21 vlan_ioctl(int fd, const char *conf_name, uint16_t req_type)
    22 {
    23 struct vlanreq_header hdr;
    24
    25 memset(&hdr, 0, sizeof(hdr));
    26 hdr.vr_req_type = req_type;
    27 snprintf(hdr.vr_conf_name, sizeof(hdr.vr_conf_name), "%s", conf_name);
    28
    29 return ioctl(fd, VV_IOCCTRL, &hdr);
    30 }
    31
    32 #define MAX_LIST_ENTRIES 256
    33
    34 static void
    35 list_conf(int fd)
    36 {
    37 struct port *port_entries = NULL;
    38 int ret;
    39 int i;
    40
    41 port_entries = malloc(sizeof(struct port) * MAX_LIST_ENTRIES);
    42 if (!port_entries) {
    43 perror("");
    44 exit(EXIT_FAILURE);
    45 }
    46
    47 ret = read(fd, port_entries, sizeof(struct port) * MAX_LIST_ENTRIES);
    48 if (ret < 0) {
    49 perror("Error reading the configuration");
    50 exit(EXIT_FAILURE);
    51 }
    52
    53 for (i = 0; i < ret / (int)sizeof(struct port); ++i) {
    54 printf("%s%s, type:", port_entries[i].bdg_name,
    55 port_entries[i].port_name);
    56 if (port_entries[i].port_type == TRUNK_PORT) {
    57 printf("trunk port\n");
    58 } else {
    59 printf("access port, vlan id:%d\n",
    60 port_entries[i].vlan_id);
    61 }
    62 }
    63
    64 free(port_entries);
    65 }
    66
    67 static int
    68 parse_attach_argument(const char *arg, char *port_name, int len,
    69 uint16_t *vlan_id, const char *arg_name)
    70 {
    71 int ret = 0;
    72 char *token;
    73 char *buf;
    74
    75 buf = strdup(arg);
    76 if (buf == NULL) {
    77 perror("strdup()");
    78 exit(EXIT_FAILURE);
    79 }
    80
    81 token = strtok(buf, "=");
    82 if (token == NULL) {
    83 fprintf(stderr, "%s %s: missing IF_NAME\n", arg_name, arg);
    84 ret = 1;
    85 goto free_buf;
    86 }
    87 snprintf(port_name, len, "%s", token);
    88
    89 token = strtok(NULL, "=");
    90 if (token == NULL) {
    91 fprintf(stderr, "%s %s: missing VLAN_ID\n", arg_name, arg);
    92 ret = 1;
    93 goto free_buf;
    94 }
    95
    96 *vlan_id = atoi(token);
    97 if (*vlan_id >= 4095) {
    98 fprintf(stderr, "%s %s: invalid VLAN_ID\n", arg_name, arg);
    99 ret = 1;
    100 goto free_buf;
    101 }
    102
    103 free_buf:
    104 free(buf);
    105 return ret;
    106 }
    107
    108 static void
    109 usage(const char *file_name, FILE *std_stream)
    110 {
    111 fprintf(std_stream,
    112 "Usage:\n"
    113 "%s {-c, -s, -d} CONF_NAME ...\n"
    114 "\t-n CONF_NAME create (and select) configuration "
    115 "conf_name\n"
    116 "\t-s CONF_NAME select configuration conf_name\n"
    117 "\t-r CONF_NAME delete configuration conf_name\n"
    118
    119 "\t[-t IF_NAME] attach interface as trunk port\n"
    120 "\t[-T] detach trunk port\n"
    121 "\t[-p IF_NAME] create persistent VALE port "
    122 "and attach it as trunk port\n"
    123 "\t[-P] detach trunk port and destroy it (must "
    124 "have been created through -p)\n"
    125 "\t[-a IF_NAME=VLAN_ID] attach interface as an access "
    126 "port with "
    127 "id VLAN_ID\n"
    128 "\t[-A IF_NAME] detach vlan port interface\n"
    129 "\t[-c IF_NAME=VLAN_ID] create a VALE port and attach "
    130 "it as an access port with id VLAN_ID\n"
    131 "\t[-C IF_NAME] detach access port and destroy "
    132 "it (must "
    133 "have been created through -c)\n"
    134 "\t[-l] list attached interfaces "
    135 "(always executed "
    136 " last)\n",
    137 file_name);
    138 }
    139
    140 #define MAX_ACTIONS 128
    141
    142 struct cli_arguments {
    143 char conf_name[VV_CONF_NAME_LENGTH];
    144 uint16_t req_type;
    145
    146 struct vlan_conf_entry actions[MAX_ACTIONS];
    147 unsigned int action_num;
    148
    149 unsigned int read_conf;
    150 };
    151
    152 /* Debugging.
    153 static void
    154 print_parsed_arguments(struct cli_arguments *args)
    155 {
    156 int i;
    157
    158 if (args->conf_name) {
    159 printf("conf name: %s\n", args->conf_name);
    160 }
    161
    162 printf("\n");
    163 for (i = 0; i < args->action_num; ++i) {
    164 struct vlan_conf_entry *entry = &args->actions[i];
    165
    166 printf("port name: %s\n", entry->port_name);
    167 printf("port type: %s\n", entry->port_type == TRUNK_PORT ?
    168 "TRUNK_PORT" : "ACCESS_PORT");
    169 printf("action: ");
    170 if (entry->action == ATTACH_PORT)
    171 printf("ATTACH_PORT\n");
    172 else if (entry->action == DETACH_PORT)
    173 printf("DETACH_PORT\n");
    174 else if (entry->action == CREATE_AND_ATTACH_PORT)
    175 printf("CREATE_AND_ATTACH_PORT\n");
    176 else
    177 printf("DETACH_AND_DESTROY_PORT\n");
    178 printf("vlan id: %" PRIu16 "\n", entry->vlan_id);
    179 printf("\n");
    180 }
    181 }
    182 */
    183
    184 int
    185 main(int argc, char **argv)
    186 {
    187 struct vlan_conf_entry *entry;
    188 struct cli_arguments args;
    189 ssize_t size;
    190 int ret;
    191 char c;
    192 int fd;
    193
    194 if (argc == 1) {
    195 usage(argv[0], stderr);
    196 exit(EXIT_FAILURE);
    197 }
    198
    199 fd = open(DEVICE_NAME, O_RDWR);
    200 if (fd < 0) {
    201 perror(DEVICE_NAME);
    202 exit(EXIT_FAILURE);
    203 }
    204
    205 memset(&args, 0, sizeof(args));
    206 while ((c = getopt(argc, argv, "n:s:r:t:Tp:Pc:C:a:A:hl")) != -1) {
    207 switch (c) {
    208 case 'n': /* create new configuration */
    209 if (args.req_type != 0) {
    210 fprintf(stderr,
    211 "One configuration at a time\n");
    212 usage(argv[0], stderr);
    213 exit(EXIT_FAILURE);
    214 }
    215
    216 snprintf(args.conf_name, sizeof(args.conf_name), "%s",
    217 optarg);
    218 args.req_type = VV_REQ_CREATE_CONF;
    219 break;
    220
    221 case 'r': /* destroy existing configuration */
    222 if (args.req_type != 0) {
    223 fprintf(stderr,
    224 "One configuration at a time\n");
    225 usage(argv[0], stderr);
    226 exit(EXIT_FAILURE);
    227 }
    228
    229 snprintf(args.conf_name, sizeof(args.conf_name), "%s",
    230 optarg);
    231 args.req_type = VV_REQ_DELETE_CONF;
    232 break;
    233
    234 case 's': /* select existing configuration */
    235 if (args.req_type != 0) {
    236 fprintf(stderr,
    237 "One configuration at a time\n");
    238 usage(argv[0], stderr);
    239 exit(EXIT_FAILURE);
    240 }
    241
    242 snprintf(args.conf_name, sizeof(args.conf_name), "%s",
    243 optarg);
    244 args.req_type = VV_REQ_SELECT_CONF;
    245 break;
    246
    247 case 't': /* attach trunk port */
    248 if (args.action_num >= MAX_ACTIONS) {
    249 fprintf(stderr,
    250 "Max actions number %d reached\n",
    251 MAX_ACTIONS);
    252 exit(EXIT_FAILURE);
    253 }
    254
    255 entry = &args.actions[args.action_num++];
    256 snprintf(entry->port_name, sizeof(entry->port_name),
    257 "%s", optarg);
    258 entry->port_type = TRUNK_PORT;
    259 entry->action = ATTACH_PORT;
    260 break;
    261
    262 case 'T': /* detach trunk port */
    263 if (args.action_num >= MAX_ACTIONS) {
    264 fprintf(stderr,
    265 "Max actions number %d reached\n",
    266 MAX_ACTIONS);
    267 exit(EXIT_FAILURE);
    268 }
    269
    270 entry = &args.actions[args.action_num++];
    271 entry->port_type = TRUNK_PORT;
    272 entry->action = DETACH_PORT;
    273 break;
    274
    275 case 'p': /* create and attach trunk port */
    276 if (args.action_num >= MAX_ACTIONS) {
    277 fprintf(stderr,
    278 "Max actions number %d reached\n",
    279 MAX_ACTIONS);
    280 exit(EXIT_FAILURE);
    281 }
    282
    283 entry = &args.actions[args.action_num++];
    284 snprintf(entry->port_name, sizeof(entry->port_name),
    285 "%s", optarg);
    286 entry->action = CREATE_AND_ATTACH_PORT;
    287 entry->port_type = TRUNK_PORT;
    288 break;
    289
    290 case 'P': /* detach and destroy trunk port */
    291 if (args.action_num >= MAX_ACTIONS) {
    292 fprintf(stderr,
    293 "Max actions number %d reached\n",
    294 MAX_ACTIONS);
    295 exit(EXIT_FAILURE);
    296 }
    297
    298 entry = &args.actions[args.action_num++];
    299 entry->port_type = TRUNK_PORT;
    300 entry->action = DETACH_AND_DESTROY_PORT;
    301 break;
    302
    303 case 'a': /* attach vlan port */
    304 if (args.action_num >= MAX_ACTIONS) {
    305 fprintf(stderr,
    306 "Max actions number %d reached\n",
    307 MAX_ACTIONS);
    308 exit(EXIT_FAILURE);
    309 }
    310
    311 entry = &args.actions[args.action_num++];
    312 if (parse_attach_argument(optarg, entry->port_name,
    313 sizeof(entry->port_name), &entry->vlan_id, "-a")) {
    314 usage(argv[0], stderr);
    315 exit(EXIT_FAILURE);
    316 }
    317
    318 entry->port_type = ACCESS_PORT;
    319 entry->action = ATTACH_PORT;
    320 break;
    321
    322 case 'A': /* detach vlan port */
    323 if (args.action_num >= MAX_ACTIONS) {
    324 fprintf(stderr,
    325 "Max actions number %d reached\n",
    326 MAX_ACTIONS);
    327 exit(EXIT_FAILURE);
    328 }
    329
    330 entry = &args.actions[args.action_num++];
    331 snprintf(entry->port_name, sizeof(entry->port_name),
    332 "%s", optarg);
    333 entry->port_type = ACCESS_PORT;
    334 entry->action = DETACH_PORT;
    335 break;
    336
    337 case 'c': /* create and attach vlan port */
    338 if (args.action_num >= MAX_ACTIONS) {
    339 fprintf(stderr,
    340 "Max actions number %d reached\n",
    341 MAX_ACTIONS);
    342 exit(EXIT_FAILURE);
    343 }
    344
    345 entry = &args.actions[args.action_num++];
    346 if (parse_attach_argument(optarg, entry->port_name,
    347 sizeof(entry->port_name), &entry->vlan_id, "-c")) {
    348 usage(argv[0], stderr);
    349 exit(EXIT_FAILURE);
    350 }
    351
    352 entry->action = CREATE_AND_ATTACH_PORT;
    353 entry->port_type = ACCESS_PORT;
    354 break;
    355
    356 case 'C': /* detach and destroy vlan port */
    357 if (args.action_num >= MAX_ACTIONS) {
    358 fprintf(stderr,
    359 "Max actions number %d reached\n",
    360 MAX_ACTIONS);
    361 exit(EXIT_FAILURE);
    362 }
    363
    364 entry = &args.actions[args.action_num++];
    365 snprintf(entry->port_name, sizeof(entry->port_name),
    366 "%s", optarg);
    367 entry->port_type = ACCESS_PORT;
    368 entry->action = DETACH_AND_DESTROY_PORT;
    369 break;
    370
    371 case 'l': /* list existing configuration */
    372 args.read_conf = 1;
    373 break;
    374
    375 case 'h': /* help */
    376 usage(argv[0], stdout);
    377 exit(0);
    378
    379 default: /* error, unknown option or missing parameter */
    380 usage(argv[0], stdout);
    381 exit(EXIT_FAILURE);
    382 }
    383 }
    384
    385 //print_parsed_arguments(&args);
    386
    387 if (args.req_type == 0) {
    388 fprintf(stderr,
    389 "You must select/create/delete a configuration\n");
    390 exit(EXIT_FAILURE);
    391 }
    392
    393 if (args.req_type == VV_REQ_DELETE_CONF && args.action_num != 0) {
    394 fprintf(stderr, "You can't specify actions after deleting a "
    395 "configuration\n");
    396 exit(EXIT_FAILURE);
    397 }
    398
    399 ret = vlan_ioctl(fd, args.conf_name, args.req_type);
    400 if (ret != 0) {
    401 perror(args.conf_name);
    402 exit(EXIT_FAILURE);
    403 }
    404
    405 size = args.action_num * sizeof(args.actions[0]);
    406 ret = write(fd, args.actions, size);
    407 if (ret != size) {
    408 perror("Error executing actions");
    409 exit(EXIT_FAILURE);
    410 }
    411
    412 if (args.read_conf != 0) {
    413 list_conf(fd);
    414 }
    415
    416 return 0;
    417 }