netdev-dpdk: fix mbuf leaks
[cascardo/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 = ovs_cmdl_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 }