]> git.proxmox.com Git - mirror_ovs.git/blob - utilities/ovs-vlan-bug-workaround.c
Rename NOT_REACHED to OVS_NOT_REACHED
[mirror_ovs.git] / utilities / ovs-vlan-bug-workaround.c
1 /*
2 * Copyright (c) 2011 Nicira, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <config.h>
18
19 #include <errno.h>
20 #include <getopt.h>
21 #include <linux/if_vlan.h>
22 #include <linux/sockios.h>
23 #include <net/if.h>
24 #include <stdlib.h>
25 #include <sys/ioctl.h>
26 #include <sys/socket.h>
27 #include <stdio.h>
28 #include <string.h>
29 #include <unistd.h>
30
31 #include "command-line.h"
32 #include "util.h"
33
34 #define ADD_ALL_VLANS_CMD 10
35 #define DEL_ALL_VLANS_CMD 11
36
37 static void usage(void);
38 static void parse_options(int argc, char *argv[]);
39
40 int
41 main(int argc, char *argv[])
42 {
43 struct vlan_ioctl_args vlan_args;
44 const char *netdev, *setting;
45 int fd;
46
47 set_program_name(argv[0]);
48
49 parse_options(argc, argv);
50 if (argc - optind != 2) {
51 ovs_fatal(0, "exactly two non-option arguments are required "
52 "(use --help for help)");
53 }
54
55 memset(&vlan_args, 0, sizeof vlan_args);
56
57 /* Get command. */
58 setting = argv[optind + 1];
59 if (!strcmp(setting, "on")) {
60 vlan_args.cmd = ADD_ALL_VLANS_CMD;
61 } else if (!strcmp(setting, "off")) {
62 vlan_args.cmd = DEL_ALL_VLANS_CMD;
63 } else {
64 ovs_fatal(0, "second command line argument must be \"on\" or \"off\" "
65 "(not \"%s\")", setting);
66 }
67
68 /* Get network device name. */
69 netdev = argv[optind];
70 if (strlen(netdev) >= IFNAMSIZ) {
71 ovs_fatal(0, "%s: network device name too long", netdev);
72 }
73 strcpy(vlan_args.device1, netdev);
74
75 /* Execute operation. */
76 fd = socket(AF_INET, SOCK_STREAM, 0);
77 if (fd < 0) {
78 ovs_fatal(errno, "socket creation failed");
79 }
80 if (ioctl(fd, SIOCSIFVLAN, &vlan_args) < 0) {
81 if (errno == ENOPKG) {
82 ovs_fatal(0, "operation failed (8021q module not loaded)");
83 } else if (errno == EOPNOTSUPP) {
84 ovs_fatal(0, "operation failed (kernel does not support the "
85 "VLAN bug workaround)");
86 } else {
87 ovs_fatal(errno, "operation failed");
88 }
89 }
90 close(fd);
91
92 return 0;
93 }
94
95 static void
96 usage(void)
97 {
98 printf("\
99 %s, for enabling or disabling the kernel VLAN bug workaround\n\
100 usage: %s NETDEV SETTING\n\
101 where NETDEV is a network device (e.g. \"eth0\")\n\
102 and SETTING is \"on\" to enable the workaround or \"off\" to disable it.\n\
103 \n\
104 Options:\n\
105 -h, --help Print this helpful information\n\
106 -V, --version Display version information\n",
107 program_name, program_name);
108 exit(EXIT_SUCCESS);
109 }
110
111 static void
112 parse_options(int argc, char *argv[])
113 {
114 static const struct option long_options[] = {
115 {"help", no_argument, NULL, 'h'},
116 {"version", no_argument, NULL, 'V'},
117 {NULL, 0, NULL, 0},
118 };
119 char *short_options = long_options_to_short_options(long_options);
120
121 for (;;) {
122 int option;
123
124 option = getopt_long(argc, argv, "+t:hVe", long_options, NULL);
125 if (option == -1) {
126 break;
127 }
128 switch (option) {
129 case 'h':
130 usage();
131 break;
132
133 case 'V':
134 ovs_print_version(0, 0);
135 exit(EXIT_SUCCESS);
136
137 case '?':
138 exit(EXIT_FAILURE);
139
140 default:
141 OVS_NOT_REACHED();
142 }
143 }
144 free(short_options);
145 }