10f66f451Sopenharmony_ci/* vconfig.c - Creates virtual ethernet devices.
20f66f451Sopenharmony_ci *
30f66f451Sopenharmony_ci * Copyright 2012 Sandeep Sharma <sandeep.jack2756@gmail.com>
40f66f451Sopenharmony_ci * Copyright 2012 Kyungwan Han <asura321@gmail.com>
50f66f451Sopenharmony_ci *
60f66f451Sopenharmony_ci * No standard
70f66f451Sopenharmony_ci
80f66f451Sopenharmony_ciUSE_VCONFIG(NEWTOY(vconfig, "<2>4", TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
90f66f451Sopenharmony_ci
100f66f451Sopenharmony_ciconfig VCONFIG
110f66f451Sopenharmony_ci  bool "vconfig"
120f66f451Sopenharmony_ci  default y
130f66f451Sopenharmony_ci  help
140f66f451Sopenharmony_ci    usage: vconfig COMMAND [OPTIONS]
150f66f451Sopenharmony_ci
160f66f451Sopenharmony_ci    Create and remove virtual ethernet devices
170f66f451Sopenharmony_ci
180f66f451Sopenharmony_ci    add             [interface-name] [vlan_id]
190f66f451Sopenharmony_ci    rem             [vlan-name]
200f66f451Sopenharmony_ci    set_flag        [interface-name] [flag-num]       [0 | 1]
210f66f451Sopenharmony_ci    set_egress_map  [vlan-name]      [skb_priority]   [vlan_qos]
220f66f451Sopenharmony_ci    set_ingress_map [vlan-name]      [skb_priority]   [vlan_qos]
230f66f451Sopenharmony_ci    set_name_type   [name-type]
240f66f451Sopenharmony_ci*/
250f66f451Sopenharmony_ci
260f66f451Sopenharmony_ci#include "toys.h"
270f66f451Sopenharmony_ci#include <linux/if_vlan.h>
280f66f451Sopenharmony_ci#include <linux/sockios.h>
290f66f451Sopenharmony_ci
300f66f451Sopenharmony_civoid vconfig_main(void)
310f66f451Sopenharmony_ci{
320f66f451Sopenharmony_ci  struct vlan_ioctl_args request;
330f66f451Sopenharmony_ci  char *cmd = *toys.optargs;
340f66f451Sopenharmony_ci  int fd = xsocket(AF_INET, SOCK_STREAM, 0);
350f66f451Sopenharmony_ci
360f66f451Sopenharmony_ci  memset(&request, 0, sizeof(struct vlan_ioctl_args));
370f66f451Sopenharmony_ci
380f66f451Sopenharmony_ci  if (!strcmp(cmd, "set_name_type")) {
390f66f451Sopenharmony_ci    char *types[] = {"VLAN_PLUS_VID", "DEV_PLUS_VID", "VLAN_PLUS_VID_NO_PAD",
400f66f451Sopenharmony_ci                     "DEV_PLUS_VID_NO_PAD"};
410f66f451Sopenharmony_ci    int i, j = ARRAY_LEN(types);
420f66f451Sopenharmony_ci
430f66f451Sopenharmony_ci    for (i=0; i<j; i++) if (!strcmp(toys.optargs[1], types[i])) break;
440f66f451Sopenharmony_ci    if (i == j) {
450f66f451Sopenharmony_ci      for (i=0; i<j; i++) puts(types[i]);
460f66f451Sopenharmony_ci      error_exit("%s: unknown '%s'", cmd, toys.optargs[1]);
470f66f451Sopenharmony_ci    }
480f66f451Sopenharmony_ci
490f66f451Sopenharmony_ci    request.u.name_type = i;
500f66f451Sopenharmony_ci    request.cmd = SET_VLAN_NAME_TYPE_CMD;
510f66f451Sopenharmony_ci    xioctl(fd, SIOCSIFVLAN, &request);
520f66f451Sopenharmony_ci
530f66f451Sopenharmony_ci    return;
540f66f451Sopenharmony_ci  }
550f66f451Sopenharmony_ci
560f66f451Sopenharmony_ci  // Store interface name
570f66f451Sopenharmony_ci  xstrncpy(request.device1, toys.optargs[1], sizeof(request.device1));
580f66f451Sopenharmony_ci
590f66f451Sopenharmony_ci  if (!strcmp(cmd, "add")) {
600f66f451Sopenharmony_ci    request.cmd = ADD_VLAN_CMD;
610f66f451Sopenharmony_ci    if (toys.optargs[2]) request.u.VID = atolx_range(toys.optargs[2], 0, 4094);
620f66f451Sopenharmony_ci    if (request.u.VID == 1)
630f66f451Sopenharmony_ci      xprintf("WARNING: VLAN 1 does not work with many switches.\n");
640f66f451Sopenharmony_ci  } else if (!strcmp(cmd, "rem")) request.cmd = DEL_VLAN_CMD;
650f66f451Sopenharmony_ci  else if (!strcmp(cmd, "set_flag")) {
660f66f451Sopenharmony_ci    request.cmd = SET_VLAN_FLAG_CMD;
670f66f451Sopenharmony_ci    if (toys.optargs[2]) request.u.flag = atolx_range(toys.optargs[2], 0, 1);
680f66f451Sopenharmony_ci    if (toys.optargs[3]) request.vlan_qos = atolx_range(toys.optargs[3], 0, 7);
690f66f451Sopenharmony_ci  } else if(strcmp(cmd, "set_egress_map") == 0) {
700f66f451Sopenharmony_ci    request.cmd = SET_VLAN_EGRESS_PRIORITY_CMD;
710f66f451Sopenharmony_ci    if (toys.optargs[2])
720f66f451Sopenharmony_ci      request.u.skb_priority = atolx_range(toys.optargs[2], 0, INT_MAX);
730f66f451Sopenharmony_ci    if (toys.optargs[3]) request.vlan_qos = atolx_range(toys.optargs[3], 0, 7);
740f66f451Sopenharmony_ci  } else if(strcmp(cmd, "set_ingress_map") == 0) {
750f66f451Sopenharmony_ci    request.cmd = SET_VLAN_INGRESS_PRIORITY_CMD;
760f66f451Sopenharmony_ci    if (toys.optargs[2])
770f66f451Sopenharmony_ci      request.u.skb_priority = atolx_range(toys.optargs[2], 0, INT_MAX);
780f66f451Sopenharmony_ci    //To set flag we must have to set vlan_qos
790f66f451Sopenharmony_ci    if (toys.optargs[3]) request.vlan_qos = atolx_range(toys.optargs[3], 0, 7);
800f66f451Sopenharmony_ci  } else {
810f66f451Sopenharmony_ci    xclose(fd);
820f66f451Sopenharmony_ci    perror_exit("Unknown command %s", cmd);
830f66f451Sopenharmony_ci  }
840f66f451Sopenharmony_ci
850f66f451Sopenharmony_ci  xioctl(fd, SIOCSIFVLAN, &request);
860f66f451Sopenharmony_ci  xprintf("Successful %s on device %s\n", cmd, toys.optargs[1]);
870f66f451Sopenharmony_ci}
88