Date: Fri, 3 Aug 2018 15:04:01 GMT From: sduo@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r337283 - in soc2018/sduo: head/tools/tools/vale_vlan vale_vlan_utils Message-ID: <201808031504.w73F41vM062387@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: sduo Date: Fri Aug 3 15:03:56 2018 New Revision: 337283 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=337283 Log: Updated vale-vlan-ctl. Added: soc2018/sduo/vale_vlan_utils/ soc2018/sduo/vale_vlan_utils/Makefile soc2018/sduo/vale_vlan_utils/vale-vlan-ctl.c Deleted: soc2018/sduo/head/tools/tools/vale_vlan/ Added: soc2018/sduo/vale_vlan_utils/Makefile ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2018/sduo/vale_vlan_utils/Makefile Fri Aug 3 15:03:56 2018 (r337283) @@ -0,0 +1,7 @@ +CFLAGS = -Wall -g -I$(PWD)/../head/sys + +all: + $(CC) $(CFLAGS) vale-vlan-ctl.c -o vale-vlan-ctl + +clean: + rm -f *.o vale-vlan-ctl Added: soc2018/sduo/vale_vlan_utils/vale-vlan-ctl.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ soc2018/sduo/vale_vlan_utils/vale-vlan-ctl.c Fri Aug 3 15:03:56 2018 (r337283) @@ -0,0 +1,417 @@ +#include <errno.h> +#include <fcntl.h> +#include <getopt.h> +#include <inttypes.h> +#include <net/if.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/types.h> +#include <unistd.h> + +#include <net/vale_vlan_user.h> + +#define DEVICE_NAME "/dev/vale_vlan" + +static int +vlan_ioctl(int fd, const char *conf_name, uint16_t req_type) +{ + struct vlanreq_header hdr; + + memset(&hdr, 0, sizeof(hdr)); + hdr.vr_req_type = req_type; + snprintf(hdr.vr_conf_name, sizeof(hdr.vr_conf_name), "%s", conf_name); + + return ioctl(fd, VV_IOCCTRL, &hdr); +} + +#define MAX_LIST_ENTRIES 256 + +static void +list_conf(int fd) +{ + struct port *port_entries = NULL; + int ret; + int i; + + port_entries = malloc(sizeof(struct port) * MAX_LIST_ENTRIES); + if (!port_entries) { + perror(""); + exit(EXIT_FAILURE); + } + + ret = read(fd, port_entries, sizeof(struct port) * MAX_LIST_ENTRIES); + if (ret < 0) { + perror("Error reading the configuration"); + exit(EXIT_FAILURE); + } + + for (i = 0; i < ret / (int)sizeof(struct port); ++i) { + printf("%s%s, type:", port_entries[i].bdg_name, + port_entries[i].port_name); + if (port_entries[i].port_type == TRUNK_PORT) { + printf("trunk port\n"); + } else { + printf("access port, vlan id:%d\n", + port_entries[i].vlan_id); + } + } + + free(port_entries); +} + +static int +parse_attach_argument(const char *arg, char *port_name, int len, + uint16_t *vlan_id, const char *arg_name) +{ + int ret = 0; + char *token; + char *buf; + + buf = strdup(arg); + if (buf == NULL) { + perror("strdup()"); + exit(EXIT_FAILURE); + } + + token = strtok(buf, "="); + if (token == NULL) { + fprintf(stderr, "%s %s: missing IF_NAME\n", arg_name, arg); + ret = 1; + goto free_buf; + } + snprintf(port_name, len, "%s", token); + + token = strtok(NULL, "="); + if (token == NULL) { + fprintf(stderr, "%s %s: missing VLAN_ID\n", arg_name, arg); + ret = 1; + goto free_buf; + } + + *vlan_id = atoi(token); + if (*vlan_id >= 4095) { + fprintf(stderr, "%s %s: invalid VLAN_ID\n", arg_name, arg); + ret = 1; + goto free_buf; + } + +free_buf: + free(buf); + return ret; +} + +static void +usage(const char *file_name, FILE *std_stream) +{ + fprintf(std_stream, + "Usage:\n" + "%s {-c, -s, -d} CONF_NAME ...\n" + "\t-n CONF_NAME create (and select) configuration " + "conf_name\n" + "\t-s CONF_NAME select configuration conf_name\n" + "\t-r CONF_NAME delete configuration conf_name\n" + + "\t[-t IF_NAME] attach interface as trunk port\n" + "\t[-T] detach trunk port\n" + "\t[-p IF_NAME] create persistent VALE port " + "and attach it as trunk port\n" + "\t[-P] detach trunk port and destroy it (must " + "have been created through -p)\n" + "\t[-a IF_NAME=VLAN_ID] attach interface as an access " + "port with " + "id VLAN_ID\n" + "\t[-A IF_NAME] detach vlan port interface\n" + "\t[-c IF_NAME=VLAN_ID] create a VALE port and attach " + "it as an access port with id VLAN_ID\n" + "\t[-C IF_NAME] detach access port and destroy " + "it (must " + "have been created through -c)\n" + "\t[-l] list attached interfaces " + "(always executed " + " last)\n", + file_name); +} + +#define MAX_ACTIONS 128 + +struct cli_arguments { + char conf_name[VV_CONF_NAME_LENGTH]; + uint16_t req_type; + + struct vlan_conf_entry actions[MAX_ACTIONS]; + unsigned int action_num; + + unsigned int read_conf; +}; + +/* Debugging. +static void +print_parsed_arguments(struct cli_arguments *args) +{ + int i; + + if (args->conf_name) { + printf("conf name: %s\n", args->conf_name); + } + + printf("\n"); + for (i = 0; i < args->action_num; ++i) { + struct vlan_conf_entry *entry = &args->actions[i]; + + printf("port name: %s\n", entry->port_name); + printf("port type: %s\n", entry->port_type == TRUNK_PORT ? + "TRUNK_PORT" : "ACCESS_PORT"); + printf("action: "); + if (entry->action == ATTACH_PORT) + printf("ATTACH_PORT\n"); + else if (entry->action == DETACH_PORT) + printf("DETACH_PORT\n"); + else if (entry->action == CREATE_AND_ATTACH_PORT) + printf("CREATE_AND_ATTACH_PORT\n"); + else + printf("DETACH_AND_DESTROY_PORT\n"); + printf("vlan id: %" PRIu16 "\n", entry->vlan_id); + printf("\n"); + } +} +*/ + +int +main(int argc, char **argv) +{ + struct vlan_conf_entry *entry; + struct cli_arguments args; + ssize_t size; + int ret; + char c; + int fd; + + if (argc == 1) { + usage(argv[0], stderr); + exit(EXIT_FAILURE); + } + + fd = open(DEVICE_NAME, O_RDWR); + if (fd < 0) { + perror(DEVICE_NAME); + exit(EXIT_FAILURE); + } + + memset(&args, 0, sizeof(args)); + while ((c = getopt(argc, argv, "n:s:r:t:Tp:Pc:C:a:A:hl")) != -1) { + switch (c) { + case 'n': /* create new configuration */ + if (args.req_type != 0) { + fprintf(stderr, + "One configuration at a time\n"); + usage(argv[0], stderr); + exit(EXIT_FAILURE); + } + + snprintf(args.conf_name, sizeof(args.conf_name), "%s", + optarg); + args.req_type = VV_REQ_CREATE_CONF; + break; + + case 'r': /* destroy existing configuration */ + if (args.req_type != 0) { + fprintf(stderr, + "One configuration at a time\n"); + usage(argv[0], stderr); + exit(EXIT_FAILURE); + } + + snprintf(args.conf_name, sizeof(args.conf_name), "%s", + optarg); + args.req_type = VV_REQ_DELETE_CONF; + break; + + case 's': /* select existing configuration */ + if (args.req_type != 0) { + fprintf(stderr, + "One configuration at a time\n"); + usage(argv[0], stderr); + exit(EXIT_FAILURE); + } + + snprintf(args.conf_name, sizeof(args.conf_name), "%s", + optarg); + args.req_type = VV_REQ_SELECT_CONF; + break; + + case 't': /* attach trunk port */ + if (args.action_num >= MAX_ACTIONS) { + fprintf(stderr, + "Max actions number %d reached\n", + MAX_ACTIONS); + exit(EXIT_FAILURE); + } + + entry = &args.actions[args.action_num++]; + snprintf(entry->port_name, sizeof(entry->port_name), + "%s", optarg); + entry->port_type = TRUNK_PORT; + entry->action = ATTACH_PORT; + break; + + case 'T': /* detach trunk port */ + if (args.action_num >= MAX_ACTIONS) { + fprintf(stderr, + "Max actions number %d reached\n", + MAX_ACTIONS); + exit(EXIT_FAILURE); + } + + entry = &args.actions[args.action_num++]; + entry->port_type = TRUNK_PORT; + entry->action = DETACH_PORT; + break; + + case 'p': /* create and attach trunk port */ + if (args.action_num >= MAX_ACTIONS) { + fprintf(stderr, + "Max actions number %d reached\n", + MAX_ACTIONS); + exit(EXIT_FAILURE); + } + + entry = &args.actions[args.action_num++]; + snprintf(entry->port_name, sizeof(entry->port_name), + "%s", optarg); + entry->action = CREATE_AND_ATTACH_PORT; + entry->port_type = TRUNK_PORT; + break; + + case 'P': /* detach and destroy trunk port */ + if (args.action_num >= MAX_ACTIONS) { + fprintf(stderr, + "Max actions number %d reached\n", + MAX_ACTIONS); + exit(EXIT_FAILURE); + } + + entry = &args.actions[args.action_num++]; + entry->port_type = TRUNK_PORT; + entry->action = DETACH_AND_DESTROY_PORT; + break; + + case 'a': /* attach vlan port */ + if (args.action_num >= MAX_ACTIONS) { + fprintf(stderr, + "Max actions number %d reached\n", + MAX_ACTIONS); + exit(EXIT_FAILURE); + } + + entry = &args.actions[args.action_num++]; + if (parse_attach_argument(optarg, entry->port_name, + sizeof(entry->port_name), &entry->vlan_id, "-a")) { + usage(argv[0], stderr); + exit(EXIT_FAILURE); + } + + entry->port_type = ACCESS_PORT; + entry->action = ATTACH_PORT; + break; + + case 'A': /* detach vlan port */ + if (args.action_num >= MAX_ACTIONS) { + fprintf(stderr, + "Max actions number %d reached\n", + MAX_ACTIONS); + exit(EXIT_FAILURE); + } + + entry = &args.actions[args.action_num++]; + snprintf(entry->port_name, sizeof(entry->port_name), + "%s", optarg); + entry->port_type = ACCESS_PORT; + entry->action = DETACH_PORT; + break; + + case 'c': /* create and attach vlan port */ + if (args.action_num >= MAX_ACTIONS) { + fprintf(stderr, + "Max actions number %d reached\n", + MAX_ACTIONS); + exit(EXIT_FAILURE); + } + + entry = &args.actions[args.action_num++]; + if (parse_attach_argument(optarg, entry->port_name, + sizeof(entry->port_name), &entry->vlan_id, "-c")) { + usage(argv[0], stderr); + exit(EXIT_FAILURE); + } + + entry->action = CREATE_AND_ATTACH_PORT; + entry->port_type = ACCESS_PORT; + break; + + case 'C': /* detach and destroy vlan port */ + if (args.action_num >= MAX_ACTIONS) { + fprintf(stderr, + "Max actions number %d reached\n", + MAX_ACTIONS); + exit(EXIT_FAILURE); + } + + entry = &args.actions[args.action_num++]; + snprintf(entry->port_name, sizeof(entry->port_name), + "%s", optarg); + entry->port_type = ACCESS_PORT; + entry->action = DETACH_AND_DESTROY_PORT; + break; + + case 'l': /* list existing configuration */ + args.read_conf = 1; + break; + + case 'h': /* help */ + usage(argv[0], stdout); + exit(0); + + default: /* error, unknown option or missing parameter */ + usage(argv[0], stdout); + exit(EXIT_FAILURE); + } + } + + //print_parsed_arguments(&args); + + if (args.req_type == 0) { + fprintf(stderr, + "You must select/create/delete a configuration\n"); + exit(EXIT_FAILURE); + } + + if (args.req_type == VV_REQ_DELETE_CONF && args.action_num != 0) { + fprintf(stderr, "You can't specify actions after deleting a " + "configuration\n"); + exit(EXIT_FAILURE); + } + + ret = vlan_ioctl(fd, args.conf_name, args.req_type); + if (ret != 0) { + perror(args.conf_name); + exit(EXIT_FAILURE); + } + + size = args.action_num * sizeof(args.actions[0]); + ret = write(fd, args.actions, size); + if (ret != size) { + perror("Error executing actions"); + exit(EXIT_FAILURE); + } + + if (args.read_conf != 0) { + list_conf(fd); + } + + return 0; +}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201808031504.w73F41vM062387>