meta-flow: Correctly set destination MAC in mf_set_flow_value().
[sliver-openvswitch.git] / utilities / ovs-appctl.c
1 /*
2  * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
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 <stdio.h>
22 #include <string.h>
23 #include <stdlib.h>
24
25 #include "command-line.h"
26 #include "daemon.h"
27 #include "dirs.h"
28 #include "dynamic-string.h"
29 #include "process.h"
30 #include "timeval.h"
31 #include "unixctl.h"
32 #include "util.h"
33
34 static void usage(void);
35 static const char *parse_command_line(int argc, char *argv[]);
36 static struct unixctl_client *connect_to_target(const char *target);
37
38 int
39 main(int argc, char *argv[])
40 {
41     struct unixctl_client *client;
42     const char *target;
43     int code, error;
44     char *request;
45     char *reply;
46
47     set_program_name(argv[0]);
48
49     /* Parse command line and connect to target. */
50     target = parse_command_line(argc, argv);
51     client = connect_to_target(target);
52
53     /* Transact request and process reply. */
54     request = process_escape_args(argv + optind);
55     error = unixctl_client_transact(client, request, &code, &reply);
56     free(request);
57     if (error) {
58         ovs_fatal(error, "%s: transaction error", target);
59     }
60     if (code / 100 != 2) {
61         fputs(reply, stderr);
62         ovs_error(0, "%s: server returned reply code %03d", target, code);
63         exit(2);
64     }
65     fputs(reply, stdout);
66
67     unixctl_client_destroy(client);
68     free(reply);
69
70     return 0;
71 }
72
73 static void
74 usage(void)
75 {
76     printf("\
77 %s, for querying and controlling Open vSwitch daemon\n\
78 usage: %s [TARGET] COMMAND [ARG...]\n\
79 Targets:\n\
80   -t, --target=TARGET  pidfile or socket to contact\n\
81 Common commands:\n\
82   help               List commands supported by the target\n\
83   version            Print version of the target\n\
84   vlog/list          List current logging levels\n\
85   vlog/set MODULE[:FACILITY[:LEVEL]]\n\
86       Set MODULE and FACILITY log level to LEVEL\n\
87       MODULE may be any valid module name or 'ANY'\n\
88       FACILITY may be 'syslog', 'console', 'file', or 'ANY' (default)\n\
89       LEVEL may be 'off', 'emer', 'err', 'warn', 'info', or 'dbg' (default)\n\
90   vlog/reopen        Make the program reopen its log file\n\
91 Other options:\n\
92   -h, --help         Print this helpful information\n\
93   -V, --version      Display ovs-appctl version information\n",
94            program_name, program_name);
95     exit(EXIT_SUCCESS);
96 }
97
98 static const char *
99 parse_command_line(int argc, char *argv[])
100 {
101     static const struct option long_options[] = {
102         {"target", required_argument, NULL, 't'},
103         {"execute", no_argument, NULL, 'e'},
104         {"help", no_argument, NULL, 'h'},
105         {"version", no_argument, NULL, 'V'},
106         {NULL, 0, NULL, 0},
107     };
108     const char *target;
109     int e_options;
110
111     target = NULL;
112     e_options = 0;
113     for (;;) {
114         int option;
115
116         option = getopt_long(argc, argv, "+t:hVe", long_options, NULL);
117         if (option == -1) {
118             break;
119         }
120         switch (option) {
121         case 't':
122             if (target) {
123                 ovs_fatal(0, "-t or --target may be specified only once");
124             }
125             target = optarg;
126             break;
127
128         case 'e':
129             /* We ignore -e for compatibility.  Older versions specified the
130              * command as the argument to -e.  Since the current version takes
131              * the command as non-option arguments and we say that -e has no
132              * arguments, this just works in the common case. */
133             if (e_options++) {
134                 ovs_fatal(0, "-e or --execute may be speciifed only once");
135             }
136             break;
137
138         case 'h':
139             usage();
140             break;
141
142         case 'V':
143             ovs_print_version(0, 0);
144             exit(EXIT_SUCCESS);
145
146         case '?':
147             exit(EXIT_FAILURE);
148
149         default:
150             NOT_REACHED();
151         }
152     }
153
154     if (optind >= argc) {
155         ovs_fatal(0, "at least one non-option argument is required "
156                   "(use --help for help)");
157     }
158
159     return target ? target : "ovs-vswitchd";
160 }
161
162 static struct unixctl_client *
163 connect_to_target(const char *target)
164 {
165     struct unixctl_client *client;
166     char *socket_name;
167     int error;
168
169     if (target[0] != '/') {
170         char *pidfile_name;
171         pid_t pid;
172
173         pidfile_name = xasprintf("%s/%s.pid", ovs_rundir(), target);
174         pid = read_pidfile(pidfile_name);
175         if (pid < 0) {
176             ovs_fatal(-pid, "cannot read pidfile \"%s\"", pidfile_name);
177         }
178         free(pidfile_name);
179         socket_name = xasprintf("%s/%s.%ld.ctl",
180                                 ovs_rundir(), target, (long int) pid);
181     } else {
182         socket_name = xstrdup(target);
183     }
184
185     error = unixctl_client_create(socket_name, &client);
186     if (error) {
187         ovs_fatal(error, "cannot connect to \"%s\"", socket_name);
188     }
189     free(socket_name);
190
191     return client;
192 }
193