]>
Commit | Line | Data |
---|---|---|
064af421 | 1 | /* |
67b732e8 | 2 | * Copyright (c) 2008, 2009, 2010 Nicira Networks. |
064af421 | 3 | * |
a14bc59f BP |
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: | |
064af421 | 7 | * |
a14bc59f BP |
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. | |
064af421 BP |
15 | */ |
16 | ||
17 | #include <config.h> | |
18 | #include <assert.h> | |
19 | #include <errno.h> | |
20 | #include <getopt.h> | |
21 | #include <inttypes.h> | |
22 | #include <netinet/in.h> | |
23 | #include <stdlib.h> | |
24 | #include <signal.h> | |
25 | #include <string.h> | |
26 | ||
27 | #include "command-line.h" | |
28 | #include "compiler.h" | |
29 | #include "daemon.h" | |
30 | #include "dirs.h" | |
064af421 | 31 | #include "dpif.h" |
064af421 BP |
32 | #include "leak-checker.h" |
33 | #include "list.h" | |
34 | #include "netdev.h" | |
35 | #include "ofpbuf.h" | |
8cd4882f | 36 | #include "ofproto/ofproto.h" |
064af421 BP |
37 | #include "openflow/openflow.h" |
38 | #include "packets.h" | |
39 | #include "poll-loop.h" | |
40 | #include "rconn.h" | |
fe55ad15 | 41 | #include "stream-ssl.h" |
064af421 BP |
42 | #include "svec.h" |
43 | #include "timeval.h" | |
44 | #include "unixctl.h" | |
45 | #include "util.h" | |
064af421 | 46 | #include "vconn.h" |
064af421 | 47 | #include "vlog.h" |
5136ce49 BP |
48 | |
49 | VLOG_DEFINE_THIS_MODULE(openflowd) | |
064af421 | 50 | |
064af421 BP |
51 | /* Settings that may be configured by the user. */ |
52 | struct ofsettings { | |
79c9f2ee | 53 | /* Controller configuration. */ |
76ce9432 BP |
54 | struct ofproto_controller *controllers; |
55 | size_t n_controllers; | |
31681a5d | 56 | enum ofproto_fail_mode fail_mode; |
064af421 BP |
57 | |
58 | /* Datapath. */ | |
59 | uint64_t datapath_id; /* Datapath ID. */ | |
0e17074a JG |
60 | char *dp_name; /* Name of local datapath. */ |
61 | char *dp_type; /* Type of local datapath. */ | |
e3e9370b | 62 | struct svec ports; /* Set of ports to add to datapath (if any). */ |
064af421 BP |
63 | |
64 | /* Description strings. */ | |
65 | const char *mfr_desc; /* Manufacturer. */ | |
66 | const char *hw_desc; /* Hardware. */ | |
67 | const char *sw_desc; /* Software version. */ | |
68 | const char *serial_desc; /* Serial number. */ | |
ce640333 | 69 | const char *dp_desc; /* Datapath description. */ |
064af421 BP |
70 | |
71 | /* Related vconns and network devices. */ | |
064af421 BP |
72 | struct svec snoops; /* Listen for controller snooping conns. */ |
73 | ||
74 | /* Failure behavior. */ | |
064af421 | 75 | int max_idle; /* Idle time for flows in fail-open mode. */ |
064af421 | 76 | |
064af421 BP |
77 | /* NetFlow. */ |
78 | struct svec netflow; /* NetFlow targets. */ | |
79 | }; | |
80 | ||
81 | static void parse_options(int argc, char *argv[], struct ofsettings *); | |
82 | static void usage(void) NO_RETURN; | |
83 | ||
84 | int | |
85 | main(int argc, char *argv[]) | |
86 | { | |
87 | struct unixctl_server *unixctl; | |
88 | struct ofproto *ofproto; | |
89 | struct ofsettings s; | |
90 | int error; | |
0e17074a | 91 | struct dpif *dpif; |
0193b2af | 92 | struct netflow_options nf_options; |
064af421 | 93 | |
40f0707c | 94 | proctitle_init(argc, argv); |
064af421 | 95 | set_program_name(argv[0]); |
064af421 BP |
96 | parse_options(argc, argv, &s); |
97 | signal(SIGPIPE, SIG_IGN); | |
98 | ||
99 | die_if_already_running(); | |
95440284 | 100 | daemonize_start(); |
064af421 BP |
101 | |
102 | /* Start listening for ovs-appctl requests. */ | |
103 | error = unixctl_server_create(NULL, &unixctl); | |
104 | if (error) { | |
4d12270a | 105 | exit(EXIT_FAILURE); |
064af421 BP |
106 | } |
107 | ||
108 | VLOG_INFO("Open vSwitch version %s", VERSION BUILDNR); | |
109 | VLOG_INFO("OpenFlow protocol version 0x%02x", OFP_VERSION); | |
110 | ||
0e17074a JG |
111 | error = dpif_create_and_open(s.dp_name, s.dp_type, &dpif); |
112 | if (error) { | |
113 | ovs_fatal(error, "could not create datapath"); | |
114 | } | |
115 | ||
116 | /* Add ports to the datapath if requested by the user. */ | |
e3e9370b | 117 | if (s.ports.n) { |
e3e9370b BP |
118 | const char *port; |
119 | size_t i; | |
e3e9370b BP |
120 | |
121 | SVEC_FOR_EACH (i, port, &s.ports) { | |
122 | error = dpif_port_add(dpif, port, 0, NULL); | |
123 | if (error) { | |
124 | ovs_fatal(error, "failed to add %s as a port", port); | |
125 | } | |
126 | } | |
e3e9370b BP |
127 | } |
128 | ||
064af421 | 129 | /* Start OpenFlow processing. */ |
0e17074a | 130 | error = ofproto_create(s.dp_name, s.dp_type, NULL, NULL, &ofproto); |
064af421 BP |
131 | if (error) { |
132 | ovs_fatal(error, "could not initialize openflow switch"); | |
133 | } | |
064af421 BP |
134 | if (s.datapath_id) { |
135 | ofproto_set_datapath_id(ofproto, s.datapath_id); | |
136 | } | |
8abc4ed7 JP |
137 | ofproto_set_desc(ofproto, s.mfr_desc, s.hw_desc, s.sw_desc, |
138 | s.serial_desc, s.dp_desc); | |
064af421 BP |
139 | error = ofproto_set_snoops(ofproto, &s.snoops); |
140 | if (error) { | |
141 | ovs_fatal(error, | |
142 | "failed to configure controller snooping connections"); | |
143 | } | |
0193b2af JG |
144 | memset(&nf_options, 0, sizeof nf_options); |
145 | nf_options.collectors = s.netflow; | |
146 | error = ofproto_set_netflow(ofproto, &nf_options); | |
064af421 BP |
147 | if (error) { |
148 | ovs_fatal(error, "failed to configure NetFlow collectors"); | |
149 | } | |
76ce9432 | 150 | ofproto_set_controllers(ofproto, s.controllers, s.n_controllers); |
31681a5d | 151 | ofproto_set_fail_mode(ofproto, s.fail_mode); |
064af421 | 152 | |
95440284 BP |
153 | daemonize_complete(); |
154 | ||
064af421 BP |
155 | while (ofproto_is_alive(ofproto)) { |
156 | error = ofproto_run(ofproto); | |
157 | if (error) { | |
158 | ovs_fatal(error, "unrecoverable datapath error"); | |
159 | } | |
160 | unixctl_server_run(unixctl); | |
5792c5c6 | 161 | dp_run(); |
8b61709d | 162 | netdev_run(); |
064af421 BP |
163 | |
164 | ofproto_wait(ofproto); | |
165 | unixctl_server_wait(unixctl); | |
5792c5c6 | 166 | dp_wait(); |
8b61709d | 167 | netdev_wait(); |
064af421 BP |
168 | poll_block(); |
169 | } | |
170 | ||
0e17074a JG |
171 | dpif_close(dpif); |
172 | ||
064af421 BP |
173 | return 0; |
174 | } | |
175 | \f | |
176 | /* User interface. */ | |
177 | ||
178 | static void | |
179 | parse_options(int argc, char *argv[], struct ofsettings *s) | |
180 | { | |
181 | enum { | |
182 | OPT_DATAPATH_ID = UCHAR_MAX + 1, | |
0c30c8f1 JP |
183 | OPT_MFR_DESC, |
184 | OPT_HW_DESC, | |
185 | OPT_SW_DESC, | |
186 | OPT_SERIAL_DESC, | |
8abc4ed7 | 187 | OPT_DP_DESC, |
064af421 BP |
188 | OPT_ACCEPT_VCONN, |
189 | OPT_NO_RESOLV_CONF, | |
190 | OPT_BR_NAME, | |
191 | OPT_FAIL_MODE, | |
192 | OPT_INACTIVITY_PROBE, | |
193 | OPT_MAX_IDLE, | |
194 | OPT_MAX_BACKOFF, | |
195 | OPT_SNOOP, | |
196 | OPT_RATE_LIMIT, | |
197 | OPT_BURST_LIMIT, | |
198 | OPT_BOOTSTRAP_CA_CERT, | |
064af421 BP |
199 | OPT_OUT_OF_BAND, |
200 | OPT_IN_BAND, | |
064af421 | 201 | OPT_NETFLOW, |
e3e9370b | 202 | OPT_PORTS, |
064af421 BP |
203 | VLOG_OPTION_ENUMS, |
204 | LEAK_CHECKER_OPTION_ENUMS | |
205 | }; | |
206 | static struct option long_options[] = { | |
207 | {"datapath-id", required_argument, 0, OPT_DATAPATH_ID}, | |
0c30c8f1 JP |
208 | {"mfr-desc", required_argument, 0, OPT_MFR_DESC}, |
209 | {"hw-desc", required_argument, 0, OPT_HW_DESC}, | |
210 | {"sw-desc", required_argument, 0, OPT_SW_DESC}, | |
211 | {"serial-desc", required_argument, 0, OPT_SERIAL_DESC}, | |
212 | {"dp-desc", required_argument, 0, OPT_DP_DESC}, | |
064af421 BP |
213 | {"accept-vconn", required_argument, 0, OPT_ACCEPT_VCONN}, |
214 | {"no-resolv-conf", no_argument, 0, OPT_NO_RESOLV_CONF}, | |
215 | {"config", required_argument, 0, 'F'}, | |
216 | {"br-name", required_argument, 0, OPT_BR_NAME}, | |
217 | {"fail", required_argument, 0, OPT_FAIL_MODE}, | |
218 | {"inactivity-probe", required_argument, 0, OPT_INACTIVITY_PROBE}, | |
219 | {"max-idle", required_argument, 0, OPT_MAX_IDLE}, | |
220 | {"max-backoff", required_argument, 0, OPT_MAX_BACKOFF}, | |
221 | {"listen", required_argument, 0, 'l'}, | |
222 | {"snoop", required_argument, 0, OPT_SNOOP}, | |
223 | {"rate-limit", optional_argument, 0, OPT_RATE_LIMIT}, | |
224 | {"burst-limit", required_argument, 0, OPT_BURST_LIMIT}, | |
064af421 BP |
225 | {"out-of-band", no_argument, 0, OPT_OUT_OF_BAND}, |
226 | {"in-band", no_argument, 0, OPT_IN_BAND}, | |
064af421 | 227 | {"netflow", required_argument, 0, OPT_NETFLOW}, |
e3e9370b | 228 | {"ports", required_argument, 0, OPT_PORTS}, |
064af421 BP |
229 | {"verbose", optional_argument, 0, 'v'}, |
230 | {"help", no_argument, 0, 'h'}, | |
231 | {"version", no_argument, 0, 'V'}, | |
232 | DAEMON_LONG_OPTIONS, | |
233 | VLOG_LONG_OPTIONS, | |
234 | LEAK_CHECKER_LONG_OPTIONS, | |
235 | #ifdef HAVE_OPENSSL | |
fe55ad15 | 236 | STREAM_SSL_LONG_OPTIONS |
064af421 BP |
237 | {"bootstrap-ca-cert", required_argument, 0, OPT_BOOTSTRAP_CA_CERT}, |
238 | #endif | |
239 | {0, 0, 0, 0}, | |
240 | }; | |
241 | char *short_options = long_options_to_short_options(long_options); | |
76ce9432 | 242 | struct ofproto_controller controller_opts; |
7d674866 BP |
243 | struct svec controllers; |
244 | int i; | |
064af421 BP |
245 | |
246 | /* Set defaults that we can figure out before parsing options. */ | |
76ce9432 BP |
247 | controller_opts.target = NULL; |
248 | controller_opts.max_backoff = 8; | |
249 | controller_opts.probe_interval = 5; | |
76ce9432 BP |
250 | controller_opts.band = OFPROTO_IN_BAND; |
251 | controller_opts.accept_re = NULL; | |
252 | controller_opts.update_resolv_conf = true; | |
253 | controller_opts.rate_limit = 0; | |
254 | controller_opts.burst_limit = 0; | |
31681a5d | 255 | s->fail_mode = OFPROTO_FAIL_STANDALONE; |
064af421 BP |
256 | s->datapath_id = 0; |
257 | s->mfr_desc = NULL; | |
258 | s->hw_desc = NULL; | |
259 | s->sw_desc = NULL; | |
260 | s->serial_desc = NULL; | |
8abc4ed7 | 261 | s->dp_desc = NULL; |
7d674866 | 262 | svec_init(&controllers); |
064af421 | 263 | svec_init(&s->snoops); |
064af421 | 264 | s->max_idle = 0; |
064af421 | 265 | svec_init(&s->netflow); |
e3e9370b | 266 | svec_init(&s->ports); |
064af421 BP |
267 | for (;;) { |
268 | int c; | |
269 | ||
270 | c = getopt_long(argc, argv, short_options, long_options, NULL); | |
271 | if (c == -1) { | |
272 | break; | |
273 | } | |
274 | ||
275 | switch (c) { | |
276 | case OPT_DATAPATH_ID: | |
76343538 | 277 | if (!dpid_from_string(optarg, &s->datapath_id)) { |
064af421 | 278 | ovs_fatal(0, "argument to --datapath-id must be " |
b123cc3c | 279 | "exactly 16 hex digits and may not be all-zero"); |
064af421 BP |
280 | } |
281 | break; | |
282 | ||
0c30c8f1 | 283 | case OPT_MFR_DESC: |
064af421 BP |
284 | s->mfr_desc = optarg; |
285 | break; | |
286 | ||
0c30c8f1 | 287 | case OPT_HW_DESC: |
064af421 BP |
288 | s->hw_desc = optarg; |
289 | break; | |
290 | ||
0c30c8f1 | 291 | case OPT_SW_DESC: |
064af421 BP |
292 | s->sw_desc = optarg; |
293 | break; | |
294 | ||
0c30c8f1 | 295 | case OPT_SERIAL_DESC: |
064af421 BP |
296 | s->serial_desc = optarg; |
297 | break; | |
298 | ||
8abc4ed7 JP |
299 | case OPT_DP_DESC: |
300 | s->dp_desc = optarg; | |
301 | break; | |
302 | ||
064af421 | 303 | case OPT_ACCEPT_VCONN: |
76ce9432 | 304 | controller_opts.accept_re = optarg; |
064af421 BP |
305 | break; |
306 | ||
307 | case OPT_NO_RESOLV_CONF: | |
76ce9432 | 308 | controller_opts.update_resolv_conf = false; |
064af421 BP |
309 | break; |
310 | ||
311 | case OPT_FAIL_MODE: | |
33e01d3a | 312 | if (!strcmp(optarg, "open") || !strcmp(optarg, "standalone")) { |
31681a5d | 313 | s->fail_mode = OFPROTO_FAIL_STANDALONE; |
33e01d3a BP |
314 | } else if (!strcmp(optarg, "closed") |
315 | || !strcmp(optarg, "secure")) { | |
31681a5d | 316 | s->fail_mode = OFPROTO_FAIL_SECURE; |
064af421 | 317 | } else { |
33e01d3a BP |
318 | ovs_fatal(0, "--fail argument must be \"standalone\" " |
319 | "or \"secure\""); | |
064af421 BP |
320 | } |
321 | break; | |
322 | ||
323 | case OPT_INACTIVITY_PROBE: | |
76ce9432 BP |
324 | controller_opts.probe_interval = atoi(optarg); |
325 | if (controller_opts.probe_interval < 5) { | |
064af421 BP |
326 | ovs_fatal(0, "--inactivity-probe argument must be at least 5"); |
327 | } | |
328 | break; | |
329 | ||
330 | case OPT_MAX_IDLE: | |
331 | if (!strcmp(optarg, "permanent")) { | |
332 | s->max_idle = OFP_FLOW_PERMANENT; | |
333 | } else { | |
334 | s->max_idle = atoi(optarg); | |
335 | if (s->max_idle < 1 || s->max_idle > 65535) { | |
336 | ovs_fatal(0, "--max-idle argument must be between 1 and " | |
337 | "65535 or the word 'permanent'"); | |
338 | } | |
339 | } | |
340 | break; | |
341 | ||
342 | case OPT_MAX_BACKOFF: | |
76ce9432 BP |
343 | controller_opts.max_backoff = atoi(optarg); |
344 | if (controller_opts.max_backoff < 1) { | |
064af421 | 345 | ovs_fatal(0, "--max-backoff argument must be at least 1"); |
76ce9432 BP |
346 | } else if (controller_opts.max_backoff > 3600) { |
347 | controller_opts.max_backoff = 3600; | |
064af421 BP |
348 | } |
349 | break; | |
350 | ||
351 | case OPT_RATE_LIMIT: | |
352 | if (optarg) { | |
76ce9432 BP |
353 | controller_opts.rate_limit = atoi(optarg); |
354 | if (controller_opts.rate_limit < 1) { | |
064af421 BP |
355 | ovs_fatal(0, "--rate-limit argument must be at least 1"); |
356 | } | |
357 | } else { | |
76ce9432 | 358 | controller_opts.rate_limit = 1000; |
064af421 BP |
359 | } |
360 | break; | |
361 | ||
362 | case OPT_BURST_LIMIT: | |
76ce9432 BP |
363 | controller_opts.burst_limit = atoi(optarg); |
364 | if (controller_opts.burst_limit < 1) { | |
064af421 BP |
365 | ovs_fatal(0, "--burst-limit argument must be at least 1"); |
366 | } | |
367 | break; | |
368 | ||
064af421 | 369 | case OPT_OUT_OF_BAND: |
76ce9432 | 370 | controller_opts.band = OFPROTO_OUT_OF_BAND; |
064af421 BP |
371 | break; |
372 | ||
373 | case OPT_IN_BAND: | |
76ce9432 | 374 | controller_opts.band = OFPROTO_IN_BAND; |
064af421 BP |
375 | break; |
376 | ||
064af421 BP |
377 | case OPT_NETFLOW: |
378 | svec_add(&s->netflow, optarg); | |
379 | break; | |
380 | ||
064af421 | 381 | case 'l': |
7d674866 | 382 | svec_add(&controllers, optarg); |
064af421 BP |
383 | break; |
384 | ||
385 | case OPT_SNOOP: | |
386 | svec_add(&s->snoops, optarg); | |
387 | break; | |
388 | ||
e3e9370b BP |
389 | case OPT_PORTS: |
390 | svec_split(&s->ports, optarg, ","); | |
391 | break; | |
392 | ||
064af421 BP |
393 | case 'h': |
394 | usage(); | |
395 | ||
396 | case 'V': | |
397 | OVS_PRINT_VERSION(OFP_VERSION, OFP_VERSION); | |
398 | exit(EXIT_SUCCESS); | |
399 | ||
400 | DAEMON_OPTION_HANDLERS | |
401 | ||
402 | VLOG_OPTION_HANDLERS | |
403 | ||
404 | LEAK_CHECKER_OPTION_HANDLERS | |
405 | ||
406 | #ifdef HAVE_OPENSSL | |
fe55ad15 | 407 | STREAM_SSL_OPTION_HANDLERS |
064af421 BP |
408 | |
409 | case OPT_BOOTSTRAP_CA_CERT: | |
fe55ad15 | 410 | stream_ssl_set_ca_cert_file(optarg, true); |
064af421 BP |
411 | break; |
412 | #endif | |
413 | ||
414 | case '?': | |
415 | exit(EXIT_FAILURE); | |
416 | ||
417 | default: | |
418 | abort(); | |
419 | } | |
420 | } | |
421 | free(short_options); | |
422 | ||
423 | argc -= optind; | |
424 | argv += optind; | |
67f6bdd7 BP |
425 | if (argc < 1) { |
426 | ovs_fatal(0, "need at least one non-option arguments; " | |
064af421 BP |
427 | "use --help for usage"); |
428 | } | |
429 | ||
064af421 | 430 | /* Set accept_controller_regex. */ |
76ce9432 BP |
431 | if (!controller_opts.accept_re) { |
432 | controller_opts.accept_re | |
fe55ad15 | 433 | = stream_ssl_is_configured() ? "^ssl:.*" : "^tcp:.*"; |
064af421 BP |
434 | } |
435 | ||
064af421 | 436 | /* Rate limiting. */ |
76ce9432 | 437 | if (controller_opts.rate_limit && controller_opts.rate_limit < 100) { |
79c9f2ee | 438 | VLOG_WARN("Rate limit set to unusually low value %d", |
76ce9432 BP |
439 | controller_opts.rate_limit); |
440 | } | |
441 | ||
442 | /* Local vconns. */ | |
443 | dp_parse_name(argv[0], &s->dp_name, &s->dp_type); | |
444 | ||
7d674866 BP |
445 | /* Figure out controller names. */ |
446 | if (!controllers.n) { | |
447 | svec_add_nocopy(&controllers, | |
448 | xasprintf("punix:%s/%s.mgmt", ovs_rundir, s->dp_name)); | |
449 | } | |
450 | for (i = 1; i < argc; i++) { | |
451 | svec_add(&controllers, argv[i]); | |
452 | } | |
453 | if (argc < 2) { | |
454 | svec_add(&controllers, "discover"); | |
455 | } | |
456 | ||
457 | /* Set up controllers. */ | |
458 | s->n_controllers = controllers.n; | |
76ce9432 BP |
459 | s->controllers = xmalloc(s->n_controllers * sizeof *s->controllers); |
460 | if (argc > 1) { | |
76ce9432 BP |
461 | for (i = 0; i < s->n_controllers; i++) { |
462 | s->controllers[i] = controller_opts; | |
7d674866 | 463 | s->controllers[i].target = controllers.names[i]; |
76ce9432 | 464 | } |
76ce9432 BP |
465 | } |
466 | ||
467 | /* Sanity check. */ | |
468 | if (controller_opts.band == OFPROTO_OUT_OF_BAND) { | |
76ce9432 BP |
469 | for (i = 0; i < s->n_controllers; i++) { |
470 | if (!strcmp(s->controllers[i].target, "discover")) { | |
471 | ovs_fatal(0, "Cannot perform discovery with out-of-band " | |
472 | "control"); | |
473 | } | |
474 | } | |
064af421 BP |
475 | } |
476 | } | |
477 | ||
478 | static void | |
479 | usage(void) | |
480 | { | |
481 | printf("%s: an OpenFlow switch implementation.\n" | |
76ce9432 | 482 | "usage: %s [OPTIONS] DATAPATH [CONTROLLER...]\n" |
064af421 | 483 | "DATAPATH is a local datapath (e.g. \"dp0\").\n" |
76ce9432 BP |
484 | "Each CONTROLLER is an active OpenFlow connection method. If\n" |
485 | "none is given, ovs-openflowd performs controller discovery.\n", | |
064af421 BP |
486 | program_name, program_name); |
487 | vconn_usage(true, true, true); | |
488 | printf("\nOpenFlow options:\n" | |
489 | " -d, --datapath-id=ID Use ID as the OpenFlow switch ID\n" | |
b123cc3c | 490 | " (ID must consist of 16 hex digits)\n" |
0c30c8f1 JP |
491 | " --mfr-desc=MFR Identify manufacturer as MFR\n" |
492 | " --hw-desc=HW Identify hardware as HW\n" | |
493 | " --sw-desc=SW Identify software as SW\n" | |
494 | " --serial-desc=SERIAL Identify serial number as SERIAL\n" | |
495 | " --dp-desc=DP_DESC Identify dp description as DP_DESC\n" | |
064af421 BP |
496 | "\nController discovery options:\n" |
497 | " --accept-vconn=REGEX accept matching discovered controllers\n" | |
498 | " --no-resolv-conf do not update /etc/resolv.conf\n" | |
499 | "\nNetworking options:\n" | |
500 | " --fail=open|closed when controller connection fails:\n" | |
501 | " closed: drop all packets\n" | |
502 | " open (default): act as learning switch\n" | |
503 | " --inactivity-probe=SECS time between inactivity probes\n" | |
8cd4882f | 504 | " --max-idle=SECS max idle for flows set up by switch\n" |
064af421 | 505 | " --max-backoff=SECS max time between controller connection\n" |
c9aaa877 | 506 | " attempts (default: 8 seconds)\n" |
064af421 BP |
507 | " -l, --listen=METHOD allow management connections on METHOD\n" |
508 | " (a passive OpenFlow connection method)\n" | |
509 | " --snoop=METHOD allow controller snooping on METHOD\n" | |
510 | " (a passive OpenFlow connection method)\n" | |
511 | " --out-of-band controller connection is out-of-band\n" | |
512 | " --netflow=HOST:PORT configure NetFlow output target\n" | |
513 | "\nRate-limiting of \"packet-in\" messages to the controller:\n" | |
514 | " --rate-limit[=PACKETS] max rate, in packets/s (default: 1000)\n" | |
67b732e8 | 515 | " --burst-limit=BURST limit on packet credit for idle time\n"); |
064af421 BP |
516 | daemon_usage(); |
517 | vlog_usage(); | |
518 | printf("\nOther options:\n" | |
519 | " -h, --help display this help message\n" | |
520 | " -V, --version display version information\n"); | |
521 | leak_checker_usage(); | |
522 | exit(EXIT_SUCCESS); | |
523 | } |