~ubuntu-branches/ubuntu/wily/openvswitch/wily

« back to all changes in this revision

Viewing changes to lib/dpctl.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2015-08-10 11:35:15 UTC
  • mfrom: (1.1.30)
  • Revision ID: package-import@ubuntu.com-20150810113515-575vj06oq29emxsn
Tags: 2.4.0~git20150810.97bab95-0ubuntu1
* New upstream snapshot from 2.4 branch:
  - d/*: Align any relevant packaging changes with upstream.
* d/*: wrap-and-sort.
* d/openvswitch-{common,vswitch}.install: Correct install location for
  bash completion files.
* d/tests/openflow.py: Explicitly use ovs-testcontroller as provided
  by 2.4.0 release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015 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
#include <arpa/inet.h>
 
19
#include <errno.h>
 
20
#include <inttypes.h>
 
21
#include <sys/socket.h>
 
22
#include <net/if.h>
 
23
#include <netinet/in.h>
 
24
#include <stdarg.h>
 
25
#include <stdlib.h>
 
26
#include <string.h>
 
27
#include <unistd.h>
 
28
 
 
29
#include "command-line.h"
 
30
#include "compiler.h"
 
31
#include "dirs.h"
 
32
#include "dpctl.h"
 
33
#include "dpif.h"
 
34
#include "dynamic-string.h"
 
35
#include "flow.h"
 
36
#include "match.h"
 
37
#include "netdev.h"
 
38
#include "netdev-dpdk.h"
 
39
#include "netlink.h"
 
40
#include "odp-util.h"
 
41
#include "ofp-parse.h"
 
42
#include "ofpbuf.h"
 
43
#include "ovs-numa.h"
 
44
#include "packets.h"
 
45
#include "shash.h"
 
46
#include "simap.h"
 
47
#include "smap.h"
 
48
#include "sset.h"
 
49
#include "timeval.h"
 
50
#include "unixctl.h"
 
51
#include "util.h"
 
52
 
 
53
typedef int dpctl_command_handler(int argc, const char *argv[],
 
54
                                  struct dpctl_params *);
 
55
struct dpctl_command {
 
56
    const char *name;
 
57
    const char *usage;
 
58
    int min_args;
 
59
    int max_args;
 
60
    dpctl_command_handler *handler;
 
61
};
 
62
static const struct dpctl_command *get_all_dpctl_commands(void);
 
63
static void dpctl_print(struct dpctl_params *dpctl_p, const char *fmt, ...)
 
64
    OVS_PRINTF_FORMAT(2, 3);
 
65
static void dpctl_error(struct dpctl_params* dpctl_p, int err_no,
 
66
                        const char *fmt, ...)
 
67
    OVS_PRINTF_FORMAT(3, 4);
 
68
 
 
69
static void
 
70
dpctl_puts(struct dpctl_params *dpctl_p, bool error, const char *string)
 
71
{
 
72
    dpctl_p->output(dpctl_p->aux, error, string);
 
73
}
 
74
 
 
75
static void
 
76
dpctl_print(struct dpctl_params *dpctl_p, const char *fmt, ...)
 
77
{
 
78
    char *string;
 
79
    va_list args;
 
80
 
 
81
    va_start(args, fmt);
 
82
    string = xvasprintf(fmt, args);
 
83
    va_end(args);
 
84
 
 
85
    dpctl_puts(dpctl_p, false, string);
 
86
    free(string);
 
87
}
 
88
 
 
89
static void
 
90
dpctl_error(struct dpctl_params* dpctl_p, int err_no, const char *fmt, ...)
 
91
{
 
92
    const char *subprogram_name = get_subprogram_name();
 
93
    struct ds ds = DS_EMPTY_INITIALIZER;
 
94
    int save_errno = errno;
 
95
    va_list args;
 
96
 
 
97
 
 
98
    if (subprogram_name[0]) {
 
99
        ds_put_format(&ds, "%s(%s): ", program_name,subprogram_name);
 
100
    } else {
 
101
        ds_put_format(&ds, "%s: ", program_name);
 
102
    }
 
103
 
 
104
    va_start(args, fmt);
 
105
    ds_put_format_valist(&ds, fmt, args);
 
106
    va_end(args);
 
107
 
 
108
    if (err_no != 0) {
 
109
        ds_put_format(&ds, " (%s)", ovs_retval_to_string(err_no));
 
110
    }
 
111
    ds_put_cstr(&ds, "\n");
 
112
 
 
113
    dpctl_puts(dpctl_p, true, ds_cstr(&ds));
 
114
 
 
115
    ds_destroy(&ds);
 
116
 
 
117
    errno = save_errno;
 
118
}
 
119
 
 
120
static int dpctl_add_if(int argc, const char *argv[], struct dpctl_params *);
 
121
 
 
122
static int
 
123
if_up(struct netdev *netdev)
 
124
{
 
125
    return netdev_turn_flags_on(netdev, NETDEV_UP, NULL);
 
126
}
 
127
 
 
128
/* Retrieve the name of the datapath if exactly one exists.  The caller
 
129
 * is responsible for freeing the returned string.  If there is not one
 
130
 * datapath, aborts with an error message. */
 
131
static char *
 
132
get_one_dp(struct dpctl_params *dpctl_p)
 
133
{
 
134
    struct sset types;
 
135
    const char *type;
 
136
    char *dp_name = NULL;
 
137
    size_t count = 0;
 
138
 
 
139
    sset_init(&types);
 
140
    dp_enumerate_types(&types);
 
141
    SSET_FOR_EACH (type, &types) {
 
142
        struct sset names;
 
143
 
 
144
        sset_init(&names);
 
145
        if (!dp_enumerate_names(type, &names)) {
 
146
            count += sset_count(&names);
 
147
            if (!dp_name && count == 1) {
 
148
                dp_name = xasprintf("%s@%s", type, SSET_FIRST(&names));
 
149
            }
 
150
        }
 
151
        sset_destroy(&names);
 
152
    }
 
153
    sset_destroy(&types);
 
154
 
 
155
    if (!count) {
 
156
        dpctl_error(dpctl_p, 0, "no datapaths exist");
 
157
    } else if (count > 1) {
 
158
        dpctl_error(dpctl_p, 0, "multiple datapaths, specify one");
 
159
        free(dp_name);
 
160
        dp_name = NULL;
 
161
    }
 
162
 
 
163
    return dp_name;
 
164
}
 
165
 
 
166
static int
 
167
parsed_dpif_open(const char *arg_, bool create, struct dpif **dpifp)
 
168
{
 
169
    int result;
 
170
    char *name, *type;
 
171
 
 
172
    dp_parse_name(arg_, &name, &type);
 
173
 
 
174
    if (create) {
 
175
        result = dpif_create(name, type, dpifp);
 
176
    } else {
 
177
        result = dpif_open(name, type, dpifp);
 
178
    }
 
179
 
 
180
    free(name);
 
181
    free(type);
 
182
    return result;
 
183
}
 
184
 
 
185
static int
 
186
dpctl_add_dp(int argc, const char *argv[],
 
187
             struct dpctl_params *dpctl_p)
 
188
{
 
189
    struct dpif *dpif;
 
190
    int error;
 
191
 
 
192
    error = parsed_dpif_open(argv[1], true, &dpif);
 
193
    if (error) {
 
194
        dpctl_error(dpctl_p, error, "add_dp");
 
195
        return error;
 
196
    }
 
197
    dpif_close(dpif);
 
198
    if (argc > 2) {
 
199
        error = dpctl_add_if(argc, argv, dpctl_p);
 
200
    }
 
201
    return error;
 
202
}
 
203
 
 
204
static int
 
205
dpctl_del_dp(int argc OVS_UNUSED, const char *argv[],
 
206
             struct dpctl_params *dpctl_p)
 
207
{
 
208
    struct dpif *dpif;
 
209
    int error;
 
210
 
 
211
    error = parsed_dpif_open(argv[1], false, &dpif);
 
212
    if (error) {
 
213
        dpctl_error(dpctl_p, error, "opening datapath");
 
214
        return error;
 
215
    }
 
216
    error = dpif_delete(dpif);
 
217
    if (error) {
 
218
        dpctl_error(dpctl_p, error, "del_dp");
 
219
    }
 
220
 
 
221
    dpif_close(dpif);
 
222
    return error;
 
223
}
 
224
 
 
225
static int
 
226
dpctl_add_if(int argc OVS_UNUSED, const char *argv[],
 
227
             struct dpctl_params *dpctl_p)
 
228
{
 
229
    struct dpif *dpif;
 
230
    int i, error, lasterror = 0;
 
231
 
 
232
    error = parsed_dpif_open(argv[1], false, &dpif);
 
233
    if (error) {
 
234
        dpctl_error(dpctl_p, error, "opening datapath");
 
235
        return error;
 
236
    }
 
237
    for (i = 2; i < argc; i++) {
 
238
        const char *name, *type;
 
239
        char *save_ptr = NULL, *argcopy;
 
240
        struct netdev *netdev = NULL;
 
241
        struct smap args;
 
242
        odp_port_t port_no = ODPP_NONE;
 
243
        char *option;
 
244
 
 
245
        argcopy = xstrdup(argv[i]);
 
246
        name = strtok_r(argcopy, ",", &save_ptr);
 
247
        type = "system";
 
248
 
 
249
        if (!name) {
 
250
            dpctl_error(dpctl_p, 0, "%s is not a valid network device name",
 
251
                        argv[i]);
 
252
            error = EINVAL;
 
253
            goto next;
 
254
        }
 
255
 
 
256
        smap_init(&args);
 
257
        while ((option = strtok_r(NULL, ",", &save_ptr)) != NULL) {
 
258
            char *save_ptr_2 = NULL;
 
259
            char *key, *value;
 
260
 
 
261
            key = strtok_r(option, "=", &save_ptr_2);
 
262
            value = strtok_r(NULL, "", &save_ptr_2);
 
263
            if (!value) {
 
264
                value = "";
 
265
            }
 
266
 
 
267
            if (!strcmp(key, "type")) {
 
268
                type = value;
 
269
            } else if (!strcmp(key, "port_no")) {
 
270
                port_no = u32_to_odp(atoi(value));
 
271
            } else if (!smap_add_once(&args, key, value)) {
 
272
                dpctl_error(dpctl_p, 0, "duplicate \"%s\" option", key);
 
273
            }
 
274
        }
 
275
 
 
276
        error = netdev_open(name, type, &netdev);
 
277
        if (error) {
 
278
            dpctl_error(dpctl_p, error, "%s: failed to open network device",
 
279
                        name);
 
280
            goto next_destroy_args;
 
281
        }
 
282
 
 
283
        error = netdev_set_config(netdev, &args, NULL);
 
284
        if (error) {
 
285
            goto next_destroy_args;
 
286
        }
 
287
 
 
288
        error = dpif_port_add(dpif, netdev, &port_no);
 
289
        if (error) {
 
290
            dpctl_error(dpctl_p, error, "adding %s to %s failed", name,
 
291
                        argv[1]);
 
292
            goto next_destroy_args;
 
293
        }
 
294
 
 
295
        error = if_up(netdev);
 
296
        if (error) {
 
297
            dpctl_error(dpctl_p, error, "%s: failed bringing interface up",
 
298
                        name);
 
299
        }
 
300
 
 
301
next_destroy_args:
 
302
        netdev_close(netdev);
 
303
        smap_destroy(&args);
 
304
next:
 
305
        free(argcopy);
 
306
        if (error) {
 
307
            lasterror = error;
 
308
        }
 
309
    }
 
310
    dpif_close(dpif);
 
311
 
 
312
    return lasterror;
 
313
}
 
314
 
 
315
static int
 
316
dpctl_set_if(int argc, const char *argv[], struct dpctl_params *dpctl_p)
 
317
{
 
318
    struct dpif *dpif;
 
319
    int i, error, lasterror = 0;
 
320
 
 
321
    error = parsed_dpif_open(argv[1], false, &dpif);
 
322
    if (error) {
 
323
        dpctl_error(dpctl_p, error, "opening datapath");
 
324
        return error;
 
325
    }
 
326
    for (i = 2; i < argc; i++) {
 
327
        struct netdev *netdev = NULL;
 
328
        struct dpif_port dpif_port;
 
329
        char *save_ptr = NULL;
 
330
        char *type = NULL;
 
331
        char *argcopy;
 
332
        const char *name;
 
333
        struct smap args;
 
334
        odp_port_t port_no;
 
335
        char *option;
 
336
        int error = 0;
 
337
 
 
338
        argcopy = xstrdup(argv[i]);
 
339
        name = strtok_r(argcopy, ",", &save_ptr);
 
340
        if (!name) {
 
341
            dpctl_error(dpctl_p, 0, "%s is not a valid network device name",
 
342
                        argv[i]);
 
343
            goto next;
 
344
        }
 
345
 
 
346
        /* Get the port's type from the datapath. */
 
347
        error = dpif_port_query_by_name(dpif, name, &dpif_port);
 
348
        if (error) {
 
349
            dpctl_error(dpctl_p, error, "%s: failed to query port in %s", name,
 
350
                        argv[1]);
 
351
            goto next;
 
352
        }
 
353
        type = xstrdup(dpif_port.type);
 
354
        port_no = dpif_port.port_no;
 
355
        dpif_port_destroy(&dpif_port);
 
356
 
 
357
        /* Retrieve its existing configuration. */
 
358
        error = netdev_open(name, type, &netdev);
 
359
        if (error) {
 
360
            dpctl_error(dpctl_p, error, "%s: failed to open network device",
 
361
                        name);
 
362
            goto next;
 
363
        }
 
364
 
 
365
        smap_init(&args);
 
366
        error = netdev_get_config(netdev, &args);
 
367
        if (error) {
 
368
            dpctl_error(dpctl_p, error, "%s: failed to fetch configuration",
 
369
                        name);
 
370
            goto next_destroy_args;
 
371
        }
 
372
 
 
373
        /* Parse changes to configuration. */
 
374
        while ((option = strtok_r(NULL, ",", &save_ptr)) != NULL) {
 
375
            char *save_ptr_2 = NULL;
 
376
            char *key, *value;
 
377
 
 
378
            key = strtok_r(option, "=", &save_ptr_2);
 
379
            value = strtok_r(NULL, "", &save_ptr_2);
 
380
            if (!value) {
 
381
                value = "";
 
382
            }
 
383
 
 
384
            if (!strcmp(key, "type")) {
 
385
                if (strcmp(value, type)) {
 
386
                    dpctl_error(dpctl_p, 0,
 
387
                                "%s: can't change type from %s to %s",
 
388
                                 name, type, value);
 
389
                    error = EINVAL;
 
390
                    goto next_destroy_args;
 
391
                }
 
392
            } else if (!strcmp(key, "port_no")) {
 
393
                if (port_no != u32_to_odp(atoi(value))) {
 
394
                    dpctl_error(dpctl_p, 0, "%s: can't change port number from"
 
395
                              " %"PRIu32" to %d", name, port_no, atoi(value));
 
396
                    error = EINVAL;
 
397
                    goto next_destroy_args;
 
398
                }
 
399
            } else if (value[0] == '\0') {
 
400
                smap_remove(&args, key);
 
401
            } else {
 
402
                smap_replace(&args, key, value);
 
403
            }
 
404
        }
 
405
 
 
406
        /* Update configuration. */
 
407
        char *err_s = NULL;
 
408
        error = netdev_set_config(netdev, &args, &err_s);
 
409
        if (err_s || error) {
 
410
            dpctl_error(dpctl_p, error, "%s",
 
411
                        err_s ? err_s : "Error updating configuration");
 
412
            free(err_s);
 
413
        }
 
414
        if (error) {
 
415
            goto next_destroy_args;
 
416
        }
 
417
 
 
418
next_destroy_args:
 
419
        smap_destroy(&args);
 
420
next:
 
421
        netdev_close(netdev);
 
422
        free(type);
 
423
        free(argcopy);
 
424
        if (error) {
 
425
            lasterror = error;
 
426
        }
 
427
    }
 
428
    dpif_close(dpif);
 
429
 
 
430
    return lasterror;
 
431
}
 
432
 
 
433
static bool
 
434
get_port_number(struct dpif *dpif, const char *name, odp_port_t *port,
 
435
                struct dpctl_params *dpctl_p)
 
436
{
 
437
    struct dpif_port dpif_port;
 
438
 
 
439
    if (!dpif_port_query_by_name(dpif, name, &dpif_port)) {
 
440
        *port = dpif_port.port_no;
 
441
        dpif_port_destroy(&dpif_port);
 
442
        return true;
 
443
    } else {
 
444
        dpctl_error(dpctl_p, 0, "no port named %s", name);
 
445
        return false;
 
446
    }
 
447
}
 
448
 
 
449
static int
 
450
dpctl_del_if(int argc, const char *argv[], struct dpctl_params *dpctl_p)
 
451
{
 
452
    struct dpif *dpif;
 
453
    int i, error, lasterror = 0;
 
454
 
 
455
    error = parsed_dpif_open(argv[1], false, &dpif);
 
456
    if (error) {
 
457
        dpctl_error(dpctl_p, error, "opening datapath");
 
458
        return error;
 
459
    }
 
460
    for (i = 2; i < argc; i++) {
 
461
        const char *name = argv[i];
 
462
        odp_port_t port;
 
463
 
 
464
        if (!name[strspn(name, "0123456789")]) {
 
465
            port = u32_to_odp(atoi(name));
 
466
        } else if (!get_port_number(dpif, name, &port, dpctl_p)) {
 
467
            lasterror = ENOENT;
 
468
            continue;
 
469
        }
 
470
 
 
471
        error = dpif_port_del(dpif, port);
 
472
        if (error) {
 
473
            dpctl_error(dpctl_p, error, "deleting port %s from %s failed",
 
474
                        name, argv[1]);
 
475
            lasterror = error;
 
476
        }
 
477
    }
 
478
    dpif_close(dpif);
 
479
    return lasterror;
 
480
}
 
481
 
 
482
static void
 
483
print_stat(struct dpctl_params *dpctl_p, const char *leader, uint64_t value)
 
484
{
 
485
    dpctl_print(dpctl_p, "%s", leader);
 
486
    if (value != UINT64_MAX) {
 
487
        dpctl_print(dpctl_p, "%"PRIu64, value);
 
488
    } else {
 
489
        dpctl_print(dpctl_p, "?");
 
490
    }
 
491
}
 
492
 
 
493
static void
 
494
print_human_size(struct dpctl_params *dpctl_p, uint64_t value)
 
495
{
 
496
    if (value == UINT64_MAX) {
 
497
        /* Nothing to do. */
 
498
    } else if (value >= 1024ULL * 1024 * 1024 * 1024) {
 
499
        dpctl_print(dpctl_p, " (%.1f TiB)",
 
500
                    value / (1024.0 * 1024 * 1024 * 1024));
 
501
    } else if (value >= 1024ULL * 1024 * 1024) {
 
502
        dpctl_print(dpctl_p, " (%.1f GiB)", value / (1024.0 * 1024 * 1024));
 
503
    } else if (value >= 1024ULL * 1024) {
 
504
        dpctl_print(dpctl_p, " (%.1f MiB)", value / (1024.0 * 1024));
 
505
    } else if (value >= 1024) {
 
506
        dpctl_print(dpctl_p, " (%.1f KiB)", value / 1024.0);
 
507
    }
 
508
}
 
509
 
 
510
static void
 
511
show_dpif(struct dpif *dpif, struct dpctl_params *dpctl_p)
 
512
{
 
513
    struct dpif_port_dump dump;
 
514
    struct dpif_port dpif_port;
 
515
    struct dpif_dp_stats stats;
 
516
    struct netdev *netdev;
 
517
 
 
518
    dpctl_print(dpctl_p, "%s:\n", dpif_name(dpif));
 
519
    if (!dpif_get_dp_stats(dpif, &stats)) {
 
520
        dpctl_print(dpctl_p, "\tlookups: hit:%"PRIu64" missed:%"PRIu64
 
521
                             " lost:%"PRIu64"\n\tflows: %"PRIu64"\n",
 
522
                    stats.n_hit, stats.n_missed, stats.n_lost, stats.n_flows);
 
523
        if (stats.n_masks != UINT32_MAX) {
 
524
            uint64_t n_pkts = stats.n_hit + stats.n_missed;
 
525
            double avg = n_pkts ? (double) stats.n_mask_hit / n_pkts : 0.0;
 
526
 
 
527
            dpctl_print(dpctl_p, "\tmasks: hit:%"PRIu64" total:%"PRIu32
 
528
                                 " hit/pkt:%.2f\n",
 
529
                        stats.n_mask_hit, stats.n_masks, avg);
 
530
        }
 
531
    }
 
532
 
 
533
    DPIF_PORT_FOR_EACH (&dpif_port, &dump, dpif) {
 
534
        dpctl_print(dpctl_p, "\tport %u: %s",
 
535
                    dpif_port.port_no, dpif_port.name);
 
536
 
 
537
        if (strcmp(dpif_port.type, "system")) {
 
538
            int error;
 
539
 
 
540
            dpctl_print(dpctl_p, " (%s", dpif_port.type);
 
541
 
 
542
            error = netdev_open(dpif_port.name, dpif_port.type, &netdev);
 
543
            if (!error) {
 
544
                struct smap config;
 
545
 
 
546
                smap_init(&config);
 
547
                error = netdev_get_config(netdev, &config);
 
548
                if (!error) {
 
549
                    const struct smap_node **nodes;
 
550
                    size_t i;
 
551
 
 
552
                    nodes = smap_sort(&config);
 
553
                    for (i = 0; i < smap_count(&config); i++) {
 
554
                        const struct smap_node *node = nodes[i];
 
555
                        dpctl_print(dpctl_p, "%c %s=%s", i ? ',' : ':',
 
556
                                    node->key, node->value);
 
557
                    }
 
558
                    free(nodes);
 
559
                } else {
 
560
                    dpctl_print(dpctl_p, ", could not retrieve configuration "
 
561
                                         "(%s)",  ovs_strerror(error));
 
562
                }
 
563
                smap_destroy(&config);
 
564
 
 
565
                netdev_close(netdev);
 
566
            } else {
 
567
                dpctl_print(dpctl_p, ": open failed (%s)",
 
568
                            ovs_strerror(error));
 
569
            }
 
570
            dpctl_print(dpctl_p, ")");
 
571
        }
 
572
        dpctl_print(dpctl_p, "\n");
 
573
 
 
574
        if (dpctl_p->print_statistics) {
 
575
            struct netdev_stats s;
 
576
            int error;
 
577
 
 
578
            error = netdev_open(dpif_port.name, dpif_port.type, &netdev);
 
579
            if (error) {
 
580
                dpctl_print(dpctl_p, ", open failed (%s)",
 
581
                            ovs_strerror(error));
 
582
                continue;
 
583
            }
 
584
            error = netdev_get_stats(netdev, &s);
 
585
            if (!error) {
 
586
                netdev_close(netdev);
 
587
                print_stat(dpctl_p, "\t\tRX packets:", s.rx_packets);
 
588
                print_stat(dpctl_p, " errors:", s.rx_errors);
 
589
                print_stat(dpctl_p, " dropped:", s.rx_dropped);
 
590
                print_stat(dpctl_p, " overruns:", s.rx_over_errors);
 
591
                print_stat(dpctl_p, " frame:", s.rx_frame_errors);
 
592
                dpctl_print(dpctl_p, "\n");
 
593
 
 
594
                print_stat(dpctl_p, "\t\tTX packets:", s.tx_packets);
 
595
                print_stat(dpctl_p, " errors:", s.tx_errors);
 
596
                print_stat(dpctl_p, " dropped:", s.tx_dropped);
 
597
                print_stat(dpctl_p, " aborted:", s.tx_aborted_errors);
 
598
                print_stat(dpctl_p, " carrier:", s.tx_carrier_errors);
 
599
                dpctl_print(dpctl_p, "\n");
 
600
 
 
601
                print_stat(dpctl_p, "\t\tcollisions:", s.collisions);
 
602
                dpctl_print(dpctl_p, "\n");
 
603
 
 
604
                print_stat(dpctl_p, "\t\tRX bytes:", s.rx_bytes);
 
605
                print_human_size(dpctl_p, s.rx_bytes);
 
606
                print_stat(dpctl_p, "  TX bytes:", s.tx_bytes);
 
607
                print_human_size(dpctl_p, s.tx_bytes);
 
608
                dpctl_print(dpctl_p, "\n");
 
609
            } else {
 
610
                dpctl_print(dpctl_p, ", could not retrieve stats (%s)",
 
611
                            ovs_strerror(error));
 
612
            }
 
613
        }
 
614
    }
 
615
}
 
616
 
 
617
typedef void (*dps_for_each_cb)(struct dpif *, struct dpctl_params *);
 
618
 
 
619
static int
 
620
dps_for_each(struct dpctl_params *dpctl_p, dps_for_each_cb cb)
 
621
{
 
622
    struct sset dpif_names = SSET_INITIALIZER(&dpif_names),
 
623
                dpif_types = SSET_INITIALIZER(&dpif_types);
 
624
    int error, openerror = 0, enumerror = 0;
 
625
    const char *type, *name;
 
626
    bool at_least_one = false;
 
627
 
 
628
    dp_enumerate_types(&dpif_types);
 
629
 
 
630
    SSET_FOR_EACH (type, &dpif_types) {
 
631
        error = dp_enumerate_names(type, &dpif_names);
 
632
        if (error) {
 
633
            enumerror = error;
 
634
        }
 
635
 
 
636
        SSET_FOR_EACH (name, &dpif_names) {
 
637
            struct dpif *dpif;
 
638
 
 
639
            at_least_one = true;
 
640
            error = dpif_open(name, type, &dpif);
 
641
            if (!error) {
 
642
                cb(dpif, dpctl_p);
 
643
                dpif_close(dpif);
 
644
            } else {
 
645
                openerror = error;
 
646
                dpctl_error(dpctl_p, error, "opening datapath %s failed",
 
647
                            name);
 
648
            }
 
649
        }
 
650
    }
 
651
 
 
652
    sset_destroy(&dpif_names);
 
653
    sset_destroy(&dpif_types);
 
654
 
 
655
    /* If there has been an error while opening a datapath it should be
 
656
     * reported.  Otherwise, we want to ignore the errors generated by
 
657
     * dp_enumerate_names() if at least one datapath has been discovered,
 
658
     * because they're not interesting for the user.  This happens, for
 
659
     * example, if OVS is using a userspace datapath and the kernel module
 
660
     * is not loaded. */
 
661
    if (openerror) {
 
662
        return openerror;
 
663
    } else {
 
664
        return at_least_one ? 0 : enumerror;
 
665
    }
 
666
}
 
667
 
 
668
static int
 
669
dpctl_show(int argc, const char *argv[], struct dpctl_params *dpctl_p)
 
670
{
 
671
    int error, lasterror = 0;
 
672
    if (argc > 1) {
 
673
        int i;
 
674
        for (i = 1; i < argc; i++) {
 
675
            const char *name = argv[i];
 
676
            struct dpif *dpif;
 
677
 
 
678
            error = parsed_dpif_open(name, false, &dpif);
 
679
            if (!error) {
 
680
                show_dpif(dpif, dpctl_p);
 
681
                dpif_close(dpif);
 
682
            } else {
 
683
                dpctl_error(dpctl_p, error, "opening datapath %s failed",
 
684
                            name);
 
685
                lasterror = error;
 
686
            }
 
687
        }
 
688
    } else {
 
689
        lasterror = dps_for_each(dpctl_p, show_dpif);
 
690
    }
 
691
 
 
692
    return lasterror;
 
693
}
 
694
 
 
695
static void
 
696
dump_cb(struct dpif *dpif, struct dpctl_params *dpctl_p)
 
697
{
 
698
    dpctl_print(dpctl_p, "%s\n", dpif_name(dpif));
 
699
}
 
700
 
 
701
static int
 
702
dpctl_dump_dps(int argc OVS_UNUSED, const char *argv[] OVS_UNUSED,
 
703
               struct dpctl_params *dpctl_p)
 
704
{
 
705
    return dps_for_each(dpctl_p, dump_cb);
 
706
}
 
707
 
 
708
static void
 
709
format_dpif_flow(struct ds *ds, const struct dpif_flow *f, struct hmap *ports,
 
710
                 struct dpctl_params *dpctl_p)
 
711
{
 
712
    if (dpctl_p->verbosity && f->ufid_present) {
 
713
        odp_format_ufid(&f->ufid, ds);
 
714
        ds_put_cstr(ds, ", ");
 
715
    }
 
716
    odp_flow_format(f->key, f->key_len, f->mask, f->mask_len, ports, ds,
 
717
                    dpctl_p->verbosity);
 
718
    ds_put_cstr(ds, ", ");
 
719
 
 
720
    dpif_flow_stats_format(&f->stats, ds);
 
721
    ds_put_cstr(ds, ", actions:");
 
722
    format_odp_actions(ds, f->actions, f->actions_len);
 
723
}
 
724
 
 
725
static int
 
726
dpctl_dump_flows(int argc, const char *argv[], struct dpctl_params *dpctl_p)
 
727
{
 
728
    struct dpif *dpif;
 
729
    struct ds ds;
 
730
    char *name;
 
731
 
 
732
    char *filter = NULL;
 
733
    struct flow flow_filter;
 
734
    struct flow_wildcards wc_filter;
 
735
 
 
736
    struct dpif_port_dump port_dump;
 
737
    struct dpif_port dpif_port;
 
738
    struct hmap portno_names;
 
739
    struct simap names_portno;
 
740
 
 
741
    struct dpif_flow_dump_thread *flow_dump_thread;
 
742
    struct dpif_flow_dump *flow_dump;
 
743
    struct dpif_flow f;
 
744
    int pmd_id = PMD_ID_NULL;
 
745
    int error;
 
746
 
 
747
    if (argc > 1 && !strncmp(argv[argc - 1], "filter=", 7)) {
 
748
        filter = xstrdup(argv[--argc] + 7);
 
749
    }
 
750
    name = (argc == 2) ? xstrdup(argv[1]) : get_one_dp(dpctl_p);
 
751
    if (!name) {
 
752
        error = EINVAL;
 
753
        goto out_freefilter;
 
754
    }
 
755
 
 
756
    error = parsed_dpif_open(name, false, &dpif);
 
757
    free(name);
 
758
    if (error) {
 
759
        dpctl_error(dpctl_p, error, "opening datapath");
 
760
        goto out_freefilter;
 
761
    }
 
762
 
 
763
 
 
764
    hmap_init(&portno_names);
 
765
    simap_init(&names_portno);
 
766
    DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) {
 
767
        odp_portno_names_set(&portno_names, dpif_port.port_no, dpif_port.name);
 
768
        simap_put(&names_portno, dpif_port.name,
 
769
                  odp_to_u32(dpif_port.port_no));
 
770
    }
 
771
 
 
772
    if (filter) {
 
773
        char *err = parse_ofp_exact_flow(&flow_filter, &wc_filter.masks,
 
774
                                         filter, &names_portno);
 
775
        if (err) {
 
776
            dpctl_error(dpctl_p, 0, "Failed to parse filter (%s)", err);
 
777
            error = EINVAL;
 
778
            goto out_dpifclose;
 
779
        }
 
780
    }
 
781
 
 
782
    /* Make sure that these values are different. PMD_ID_NULL means that the
 
783
     * pmd is unspecified (e.g. because the datapath doesn't have different
 
784
     * pmd threads), while NON_PMD_CORE_ID refers to every non pmd threads
 
785
     * in the userspace datapath */
 
786
    BUILD_ASSERT(PMD_ID_NULL != NON_PMD_CORE_ID);
 
787
 
 
788
    ds_init(&ds);
 
789
    flow_dump = dpif_flow_dump_create(dpif, false);
 
790
    flow_dump_thread = dpif_flow_dump_thread_create(flow_dump);
 
791
    while (dpif_flow_dump_next(flow_dump_thread, &f, 1)) {
 
792
        if (filter) {
 
793
            struct flow flow;
 
794
            struct flow_wildcards wc;
 
795
            struct match match, match_filter;
 
796
            struct minimatch minimatch;
 
797
 
 
798
            odp_flow_key_to_flow(f.key, f.key_len, &flow);
 
799
            odp_flow_key_to_mask(f.mask, f.mask_len, &wc.masks, &flow);
 
800
            match_init(&match, &flow, &wc);
 
801
 
 
802
            match_init(&match_filter, &flow_filter, &wc);
 
803
            match_init(&match_filter, &match_filter.flow, &wc_filter);
 
804
            minimatch_init(&minimatch, &match_filter);
 
805
 
 
806
            if (!minimatch_matches_flow(&minimatch, &match.flow)) {
 
807
                minimatch_destroy(&minimatch);
 
808
                continue;
 
809
            }
 
810
            minimatch_destroy(&minimatch);
 
811
        }
 
812
        ds_clear(&ds);
 
813
        /* If 'pmd_id' is specified, overlapping flows could be dumped from
 
814
         * different pmd threads.  So, separates dumps from different pmds
 
815
         * by printing a title line. */
 
816
        if (pmd_id != f.pmd_id) {
 
817
            if (f.pmd_id == NON_PMD_CORE_ID) {
 
818
                ds_put_format(&ds, "flow-dump from non-dpdk interfaces:\n");
 
819
            } else {
 
820
                ds_put_format(&ds, "flow-dump from pmd on cpu core: %d\n",
 
821
                              f.pmd_id);
 
822
            }
 
823
            pmd_id = f.pmd_id;
 
824
        }
 
825
        format_dpif_flow(&ds, &f, &portno_names, dpctl_p);
 
826
        dpctl_print(dpctl_p, "%s\n", ds_cstr(&ds));
 
827
    }
 
828
    dpif_flow_dump_thread_destroy(flow_dump_thread);
 
829
    error = dpif_flow_dump_destroy(flow_dump);
 
830
 
 
831
    if (error) {
 
832
        dpctl_error(dpctl_p, error, "Failed to dump flows from datapath");
 
833
    }
 
834
    ds_destroy(&ds);
 
835
 
 
836
out_dpifclose:
 
837
    odp_portno_names_destroy(&portno_names);
 
838
    simap_destroy(&names_portno);
 
839
    hmap_destroy(&portno_names);
 
840
    dpif_close(dpif);
 
841
out_freefilter:
 
842
    free(filter);
 
843
    return error;
 
844
}
 
845
 
 
846
/* Extracts the in_port from the parsed keys, and returns the reference
 
847
 * to the 'struct netdev *' of the dpif port.  On error, returns NULL.
 
848
 * Users must call 'netdev_close()' after finish using the returned
 
849
 * reference. */
 
850
static struct netdev *
 
851
get_in_port_netdev_from_key(struct dpif *dpif, const struct ofpbuf *key)
 
852
{
 
853
    const struct nlattr *in_port_nla;
 
854
    struct netdev *dev = NULL;
 
855
 
 
856
    in_port_nla = nl_attr_find(key, 0, OVS_KEY_ATTR_IN_PORT);
 
857
    if (in_port_nla) {
 
858
        struct dpif_port dpif_port;
 
859
        odp_port_t port_no;
 
860
        int error;
 
861
 
 
862
        port_no = ODP_PORT_C(nl_attr_get_u32(in_port_nla));
 
863
        error = dpif_port_query_by_number(dpif, port_no, &dpif_port);
 
864
        if (error) {
 
865
            goto out;
 
866
        }
 
867
 
 
868
        netdev_open(dpif_port.name, dpif_port.type, &dev);
 
869
        dpif_port_destroy(&dpif_port);
 
870
    }
 
871
 
 
872
out:
 
873
    return dev;
 
874
}
 
875
 
 
876
static int
 
877
dpctl_put_flow(int argc, const char *argv[], enum dpif_flow_put_flags flags,
 
878
               struct dpctl_params *dpctl_p)
 
879
{
 
880
    const char *key_s = argv[argc - 2];
 
881
    const char *actions_s = argv[argc - 1];
 
882
    struct netdev *in_port_netdev = NULL;
 
883
    struct dpif_flow_stats stats;
 
884
    struct dpif_port dpif_port;
 
885
    struct dpif_port_dump port_dump;
 
886
    struct ofpbuf actions;
 
887
    struct ofpbuf key;
 
888
    struct ofpbuf mask;
 
889
    struct dpif *dpif;
 
890
    ovs_u128 ufid;
 
891
    bool ufid_present;
 
892
    char *dp_name;
 
893
    struct simap port_names;
 
894
    int n, error;
 
895
 
 
896
    dp_name = argc == 4 ? xstrdup(argv[1]) : get_one_dp(dpctl_p);
 
897
    if (!dp_name) {
 
898
        return EINVAL;
 
899
    }
 
900
    error = parsed_dpif_open(dp_name, false, &dpif);
 
901
    free(dp_name);
 
902
    if (error) {
 
903
        dpctl_error(dpctl_p, error, "opening datapath");
 
904
        return error;
 
905
    }
 
906
 
 
907
    ufid_present = false;
 
908
    n = odp_ufid_from_string(key_s, &ufid);
 
909
    if (n < 0) {
 
910
        dpctl_error(dpctl_p, -n, "parsing flow ufid");
 
911
        return -n;
 
912
    } else if (n) {
 
913
        key_s += n;
 
914
        ufid_present = true;
 
915
    }
 
916
 
 
917
    simap_init(&port_names);
 
918
    DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) {
 
919
        simap_put(&port_names, dpif_port.name, odp_to_u32(dpif_port.port_no));
 
920
    }
 
921
 
 
922
    ofpbuf_init(&key, 0);
 
923
    ofpbuf_init(&mask, 0);
 
924
    error = odp_flow_from_string(key_s, &port_names, &key, &mask);
 
925
    simap_destroy(&port_names);
 
926
    if (error) {
 
927
        dpctl_error(dpctl_p, error, "parsing flow key");
 
928
        goto out_freekeymask;
 
929
    }
 
930
 
 
931
    ofpbuf_init(&actions, 0);
 
932
    error = odp_actions_from_string(actions_s, NULL, &actions);
 
933
    if (error) {
 
934
        dpctl_error(dpctl_p, error, "parsing actions");
 
935
        goto out_freeactions;
 
936
    }
 
937
 
 
938
    /* For DPDK interface, applies the operation to all pmd threads
 
939
     * on the same numa node. */
 
940
    in_port_netdev = get_in_port_netdev_from_key(dpif, &key);
 
941
    if (in_port_netdev && netdev_is_pmd(in_port_netdev)) {
 
942
        int numa_id;
 
943
 
 
944
        numa_id = netdev_get_numa_id(in_port_netdev);
 
945
        if (ovs_numa_numa_id_is_valid(numa_id)) {
 
946
            struct ovs_numa_dump *dump = ovs_numa_dump_cores_on_numa(numa_id);
 
947
            struct ovs_numa_info *iter;
 
948
 
 
949
            FOR_EACH_CORE_ON_NUMA (iter, dump) {
 
950
                if (ovs_numa_core_is_pinned(iter->core_id)) {
 
951
                    error = dpif_flow_put(dpif, flags,
 
952
                                          key.data, key.size,
 
953
                                          mask.size == 0 ? NULL : mask.data,
 
954
                                          mask.size, actions.data,
 
955
                                          actions.size, ufid_present ? &ufid : NULL,
 
956
                                          iter->core_id, dpctl_p->print_statistics ? &stats : NULL);
 
957
                }
 
958
            }
 
959
            ovs_numa_dump_destroy(dump);
 
960
        } else {
 
961
            error = EINVAL;
 
962
        }
 
963
    } else {
 
964
        error = dpif_flow_put(dpif, flags,
 
965
                              key.data, key.size,
 
966
                              mask.size == 0 ? NULL : mask.data,
 
967
                              mask.size, actions.data,
 
968
                              actions.size, ufid_present ? &ufid : NULL,
 
969
                              PMD_ID_NULL, dpctl_p->print_statistics ? &stats : NULL);
 
970
    }
 
971
    if (error) {
 
972
        dpctl_error(dpctl_p, error, "updating flow table");
 
973
        goto out_freeactions;
 
974
    }
 
975
 
 
976
    if (dpctl_p->print_statistics) {
 
977
        struct ds s;
 
978
 
 
979
        ds_init(&s);
 
980
        dpif_flow_stats_format(&stats, &s);
 
981
        dpctl_print(dpctl_p, "%s\n", ds_cstr(&s));
 
982
        ds_destroy(&s);
 
983
    }
 
984
 
 
985
out_freeactions:
 
986
    ofpbuf_uninit(&actions);
 
987
out_freekeymask:
 
988
    ofpbuf_uninit(&mask);
 
989
    ofpbuf_uninit(&key);
 
990
    dpif_close(dpif);
 
991
    netdev_close(in_port_netdev);
 
992
    return error;
 
993
}
 
994
 
 
995
static int
 
996
dpctl_add_flow(int argc, const char *argv[], struct dpctl_params *dpctl_p)
 
997
{
 
998
    return dpctl_put_flow(argc, argv, DPIF_FP_CREATE, dpctl_p);
 
999
}
 
1000
 
 
1001
static int
 
1002
dpctl_mod_flow(int argc, const char *argv[], struct dpctl_params *dpctl_p)
 
1003
{
 
1004
    enum dpif_flow_put_flags flags;
 
1005
 
 
1006
    flags = DPIF_FP_MODIFY;
 
1007
    if (dpctl_p->may_create) {
 
1008
        flags |= DPIF_FP_CREATE;
 
1009
    }
 
1010
    if (dpctl_p->zero_statistics) {
 
1011
        flags |= DPIF_FP_ZERO_STATS;
 
1012
    }
 
1013
 
 
1014
    return dpctl_put_flow(argc, argv, flags, dpctl_p);
 
1015
}
 
1016
 
 
1017
static int
 
1018
dpctl_get_flow(int argc, const char *argv[], struct dpctl_params *dpctl_p)
 
1019
{
 
1020
    const char *key_s = argv[argc - 1];
 
1021
    struct dpif_flow flow;
 
1022
    struct dpif_port dpif_port;
 
1023
    struct dpif_port_dump port_dump;
 
1024
    struct dpif *dpif;
 
1025
    char *dp_name;
 
1026
    struct hmap portno_names;
 
1027
    ovs_u128 ufid;
 
1028
    struct ofpbuf buf;
 
1029
    uint64_t stub[DPIF_FLOW_BUFSIZE / 8];
 
1030
    struct ds ds;
 
1031
    int n, error;
 
1032
 
 
1033
    dp_name = argc == 3 ? xstrdup(argv[1]) : get_one_dp(dpctl_p);
 
1034
    if (!dp_name) {
 
1035
        return EINVAL;
 
1036
    }
 
1037
    error = parsed_dpif_open(dp_name, false, &dpif);
 
1038
    free(dp_name);
 
1039
    if (error) {
 
1040
        dpctl_error(dpctl_p, error, "opening datapath");
 
1041
        return error;
 
1042
    }
 
1043
 
 
1044
    ofpbuf_use_stub(&buf, &stub, sizeof stub);
 
1045
    hmap_init(&portno_names);
 
1046
    DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) {
 
1047
        odp_portno_names_set(&portno_names, dpif_port.port_no, dpif_port.name);
 
1048
    }
 
1049
 
 
1050
    n = odp_ufid_from_string(key_s, &ufid);
 
1051
    if (n <= 0) {
 
1052
        dpctl_error(dpctl_p, -n, "parsing flow ufid");
 
1053
        goto out;
 
1054
    }
 
1055
 
 
1056
    /* Does not work for DPDK, since do not know which 'pmd' to apply the
 
1057
     * operation.  So, just uses PMD_ID_NULL. */
 
1058
    error = dpif_flow_get(dpif, NULL, 0, &ufid, PMD_ID_NULL, &buf, &flow);
 
1059
    if (error) {
 
1060
        dpctl_error(dpctl_p, error, "getting flow");
 
1061
        goto out;
 
1062
    }
 
1063
 
 
1064
    ds_init(&ds);
 
1065
    format_dpif_flow(&ds, &flow, &portno_names, dpctl_p);
 
1066
    dpctl_print(dpctl_p, "%s\n", ds_cstr(&ds));
 
1067
    ds_destroy(&ds);
 
1068
 
 
1069
out:
 
1070
    odp_portno_names_destroy(&portno_names);
 
1071
    hmap_destroy(&portno_names);
 
1072
    ofpbuf_uninit(&buf);
 
1073
    dpif_close(dpif);
 
1074
    return error;
 
1075
}
 
1076
 
 
1077
static int
 
1078
dpctl_del_flow(int argc, const char *argv[], struct dpctl_params *dpctl_p)
 
1079
{
 
1080
    const char *key_s = argv[argc - 1];
 
1081
    struct netdev *in_port_netdev = NULL;
 
1082
    struct dpif_flow_stats stats;
 
1083
    struct dpif_port dpif_port;
 
1084
    struct dpif_port_dump port_dump;
 
1085
    struct ofpbuf key;
 
1086
    struct ofpbuf mask; /* To be ignored. */
 
1087
    struct dpif *dpif;
 
1088
    ovs_u128 ufid;
 
1089
    bool ufid_present;
 
1090
    char *dp_name;
 
1091
    struct simap port_names;
 
1092
    int n, error;
 
1093
 
 
1094
    dp_name = argc == 3 ? xstrdup(argv[1]) : get_one_dp(dpctl_p);
 
1095
    if (!dp_name) {
 
1096
        return EINVAL;
 
1097
    }
 
1098
    error = parsed_dpif_open(dp_name, false, &dpif);
 
1099
    free(dp_name);
 
1100
    if (error) {
 
1101
        dpctl_error(dpctl_p, error, "opening datapath");
 
1102
        return error;
 
1103
    }
 
1104
 
 
1105
    ufid_present = false;
 
1106
    n = odp_ufid_from_string(key_s, &ufid);
 
1107
    if (n < 0) {
 
1108
        dpctl_error(dpctl_p, -n, "parsing flow ufid");
 
1109
        return -n;
 
1110
    } else if (n) {
 
1111
        key_s += n;
 
1112
        ufid_present = true;
 
1113
    }
 
1114
 
 
1115
    simap_init(&port_names);
 
1116
    DPIF_PORT_FOR_EACH (&dpif_port, &port_dump, dpif) {
 
1117
        simap_put(&port_names, dpif_port.name, odp_to_u32(dpif_port.port_no));
 
1118
    }
 
1119
 
 
1120
    ofpbuf_init(&key, 0);
 
1121
    ofpbuf_init(&mask, 0);
 
1122
 
 
1123
    error = odp_flow_from_string(key_s, &port_names, &key, &mask);
 
1124
    if (error) {
 
1125
        dpctl_error(dpctl_p, error, "parsing flow key");
 
1126
        goto out;
 
1127
    }
 
1128
 
 
1129
    /* For DPDK interface, applies the operation to all pmd threads
 
1130
     * on the same numa node. */
 
1131
    in_port_netdev = get_in_port_netdev_from_key(dpif, &key);
 
1132
    if (in_port_netdev && netdev_is_pmd(in_port_netdev)) {
 
1133
        int numa_id;
 
1134
 
 
1135
        numa_id = netdev_get_numa_id(in_port_netdev);
 
1136
        if (ovs_numa_numa_id_is_valid(numa_id)) {
 
1137
            struct ovs_numa_dump *dump = ovs_numa_dump_cores_on_numa(numa_id);
 
1138
            struct ovs_numa_info *iter;
 
1139
 
 
1140
            FOR_EACH_CORE_ON_NUMA (iter, dump) {
 
1141
                if (ovs_numa_core_is_pinned(iter->core_id)) {
 
1142
                    error = dpif_flow_del(dpif, key.data,
 
1143
                                          key.size, ufid_present ? &ufid : NULL,
 
1144
                                          iter->core_id, dpctl_p->print_statistics ? &stats : NULL);
 
1145
                }
 
1146
            }
 
1147
            ovs_numa_dump_destroy(dump);
 
1148
        } else {
 
1149
            error = EINVAL;
 
1150
        }
 
1151
    } else {
 
1152
        error = dpif_flow_del(dpif, key.data, key.size,
 
1153
                              ufid_present ? &ufid : NULL, PMD_ID_NULL,
 
1154
                              dpctl_p->print_statistics ? &stats : NULL);
 
1155
    }
 
1156
    if (error) {
 
1157
        dpctl_error(dpctl_p, error, "deleting flow");
 
1158
        if (error == ENOENT && !ufid_present) {
 
1159
            struct ds s;
 
1160
 
 
1161
            ds_init(&s);
 
1162
            ds_put_format(&s, "Perhaps you need to specify a UFID?");
 
1163
            dpctl_print(dpctl_p, "%s\n", ds_cstr(&s));
 
1164
            ds_destroy(&s);
 
1165
        }
 
1166
        goto out;
 
1167
    }
 
1168
 
 
1169
    if (dpctl_p->print_statistics) {
 
1170
        struct ds s;
 
1171
 
 
1172
        ds_init(&s);
 
1173
        dpif_flow_stats_format(&stats, &s);
 
1174
        dpctl_print(dpctl_p, "%s\n", ds_cstr(&s));
 
1175
        ds_destroy(&s);
 
1176
    }
 
1177
 
 
1178
out:
 
1179
    ofpbuf_uninit(&mask);
 
1180
    ofpbuf_uninit(&key);
 
1181
    simap_destroy(&port_names);
 
1182
    dpif_close(dpif);
 
1183
    netdev_close(in_port_netdev);
 
1184
    return error;
 
1185
}
 
1186
 
 
1187
static int
 
1188
dpctl_del_flows(int argc, const char *argv[], struct dpctl_params *dpctl_p)
 
1189
{
 
1190
    struct dpif *dpif;
 
1191
    char *name;
 
1192
    int error;
 
1193
 
 
1194
    name = (argc == 2) ? xstrdup(argv[1]) : get_one_dp(dpctl_p);
 
1195
    if (!name) {
 
1196
        return EINVAL;
 
1197
    }
 
1198
    error = parsed_dpif_open(name, false, &dpif);
 
1199
    free(name);
 
1200
    if (error) {
 
1201
        dpctl_error(dpctl_p, error, "opening datapath");
 
1202
        return error;
 
1203
    }
 
1204
 
 
1205
    error = dpif_flow_flush(dpif);
 
1206
    if (error) {
 
1207
        dpctl_error(dpctl_p, error, "deleting all flows");
 
1208
    }
 
1209
    dpif_close(dpif);
 
1210
    return error;
 
1211
}
 
1212
 
 
1213
static int
 
1214
dpctl_help(int argc OVS_UNUSED, const char *argv[] OVS_UNUSED,
 
1215
           struct dpctl_params *dpctl_p)
 
1216
{
 
1217
    if (dpctl_p->usage) {
 
1218
        dpctl_p->usage(dpctl_p->aux);
 
1219
    }
 
1220
 
 
1221
    return 0;
 
1222
}
 
1223
 
 
1224
static int
 
1225
dpctl_list_commands(int argc OVS_UNUSED, const char *argv[] OVS_UNUSED,
 
1226
                    struct dpctl_params *dpctl_p)
 
1227
{
 
1228
    struct ds ds = DS_EMPTY_INITIALIZER;
 
1229
    const struct dpctl_command *commands = get_all_dpctl_commands();
 
1230
 
 
1231
    ds_put_cstr(&ds, "The available commands are:\n");
 
1232
    for (; commands->name; commands++) {
 
1233
        const struct dpctl_command *c = commands;
 
1234
 
 
1235
        ds_put_format(&ds, "  %s%-23s %s\n", dpctl_p->is_appctl ? "dpctl/" : "",
 
1236
                      c->name, c->usage);
 
1237
    }
 
1238
    dpctl_puts(dpctl_p, false, ds.string);
 
1239
    ds_destroy(&ds);
 
1240
 
 
1241
    return 0;
 
1242
}
 
1243
 
 
1244
/* Undocumented commands for unit testing. */
 
1245
 
 
1246
static int
 
1247
dpctl_parse_actions(int argc, const char *argv[], struct dpctl_params* dpctl_p)
 
1248
{
 
1249
    int i, error = 0;
 
1250
 
 
1251
    for (i = 1; i < argc; i++) {
 
1252
        struct ofpbuf actions;
 
1253
        struct ds s;
 
1254
 
 
1255
        ofpbuf_init(&actions, 0);
 
1256
        error = odp_actions_from_string(argv[i], NULL, &actions);
 
1257
 
 
1258
        if (error) {
 
1259
            ofpbuf_uninit(&actions);
 
1260
            dpctl_error(dpctl_p, error, "odp_actions_from_string");
 
1261
            return error;
 
1262
        }
 
1263
 
 
1264
        ds_init(&s);
 
1265
        format_odp_actions(&s, actions.data, actions.size);
 
1266
        dpctl_print(dpctl_p, "%s\n", ds_cstr(&s));
 
1267
        ds_destroy(&s);
 
1268
 
 
1269
        ofpbuf_uninit(&actions);
 
1270
    }
 
1271
 
 
1272
    return error;
 
1273
}
 
1274
 
 
1275
struct actions_for_flow {
 
1276
    struct hmap_node hmap_node;
 
1277
    struct flow flow;
 
1278
    struct ofpbuf actions;
 
1279
};
 
1280
 
 
1281
static struct actions_for_flow *
 
1282
get_actions_for_flow(struct hmap *actions_per_flow, const struct flow *flow)
 
1283
{
 
1284
    uint32_t hash = flow_hash(flow, 0);
 
1285
    struct actions_for_flow *af;
 
1286
 
 
1287
    HMAP_FOR_EACH_WITH_HASH (af, hmap_node, hash, actions_per_flow) {
 
1288
        if (flow_equal(&af->flow, flow)) {
 
1289
            return af;
 
1290
        }
 
1291
    }
 
1292
 
 
1293
    af = xmalloc(sizeof *af);
 
1294
    af->flow = *flow;
 
1295
    ofpbuf_init(&af->actions, 0);
 
1296
    hmap_insert(actions_per_flow, &af->hmap_node, hash);
 
1297
    return af;
 
1298
}
 
1299
 
 
1300
static int
 
1301
compare_actions_for_flow(const void *a_, const void *b_)
 
1302
{
 
1303
    struct actions_for_flow *const *a = a_;
 
1304
    struct actions_for_flow *const *b = b_;
 
1305
 
 
1306
    return flow_compare_3way(&(*a)->flow, &(*b)->flow);
 
1307
}
 
1308
 
 
1309
static int
 
1310
compare_output_actions(const void *a_, const void *b_)
 
1311
{
 
1312
    const struct nlattr *a = a_;
 
1313
    const struct nlattr *b = b_;
 
1314
    uint32_t a_port = nl_attr_get_u32(a);
 
1315
    uint32_t b_port = nl_attr_get_u32(b);
 
1316
 
 
1317
    return a_port < b_port ? -1 : a_port > b_port;
 
1318
}
 
1319
 
 
1320
static void
 
1321
sort_output_actions__(struct nlattr *first, struct nlattr *end)
 
1322
{
 
1323
    size_t bytes = (uint8_t *) end - (uint8_t *) first;
 
1324
    size_t n = bytes / NL_A_U32_SIZE;
 
1325
 
 
1326
    ovs_assert(bytes % NL_A_U32_SIZE == 0);
 
1327
    qsort(first, n, NL_A_U32_SIZE, compare_output_actions);
 
1328
}
 
1329
 
 
1330
static void
 
1331
sort_output_actions(struct nlattr *actions, size_t length)
 
1332
{
 
1333
    struct nlattr *first_output = NULL;
 
1334
    struct nlattr *a;
 
1335
    int left;
 
1336
 
 
1337
    NL_ATTR_FOR_EACH (a, left, actions, length) {
 
1338
        if (nl_attr_type(a) == OVS_ACTION_ATTR_OUTPUT) {
 
1339
            if (!first_output) {
 
1340
                first_output = a;
 
1341
            }
 
1342
        } else {
 
1343
            if (first_output) {
 
1344
                sort_output_actions__(first_output, a);
 
1345
                first_output = NULL;
 
1346
            }
 
1347
        }
 
1348
    }
 
1349
    if (first_output) {
 
1350
        uint8_t *end = (uint8_t *) actions + length;
 
1351
        sort_output_actions__(first_output,
 
1352
                              ALIGNED_CAST(struct nlattr *, end));
 
1353
    }
 
1354
}
 
1355
 
 
1356
/* usage: "ovs-dpctl normalize-actions FLOW ACTIONS" where FLOW and ACTIONS
 
1357
 * have the syntax used by "ovs-dpctl dump-flows".
 
1358
 *
 
1359
 * This command prints ACTIONS in a format that shows what happens for each
 
1360
 * VLAN, independent of the order of the ACTIONS.  For example, there is more
 
1361
 * than one way to output a packet on VLANs 9 and 11, but this command will
 
1362
 * print the same output for any form.
 
1363
 *
 
1364
 * The idea here generalizes beyond VLANs (e.g. to setting other fields) but
 
1365
 * so far the implementation only covers VLANs. */
 
1366
static int
 
1367
dpctl_normalize_actions(int argc, const char *argv[],
 
1368
                        struct dpctl_params *dpctl_p)
 
1369
{
 
1370
    struct simap port_names;
 
1371
    struct ofpbuf keybuf;
 
1372
    struct flow flow;
 
1373
    struct ofpbuf odp_actions;
 
1374
    struct hmap actions_per_flow;
 
1375
    struct actions_for_flow **afs;
 
1376
    struct actions_for_flow *af;
 
1377
    struct nlattr *a;
 
1378
    size_t n_afs;
 
1379
    struct ds s;
 
1380
    int left;
 
1381
    int i, error;
 
1382
 
 
1383
    ds_init(&s);
 
1384
 
 
1385
    simap_init(&port_names);
 
1386
    for (i = 3; i < argc; i++) {
 
1387
        char name[16];
 
1388
        int number;
 
1389
 
 
1390
        if (ovs_scan(argv[i], "%15[^=]=%d", name, &number)) {
 
1391
            uintptr_t n = number;
 
1392
            simap_put(&port_names, name, n);
 
1393
        } else {
 
1394
            dpctl_error(dpctl_p, 0, "%s: expected NAME=NUMBER", argv[i]);
 
1395
            error = EINVAL;
 
1396
            goto out;
 
1397
        }
 
1398
    }
 
1399
 
 
1400
    /* Parse flow key. */
 
1401
    ofpbuf_init(&keybuf, 0);
 
1402
    error = odp_flow_from_string(argv[1], &port_names, &keybuf, NULL);
 
1403
    if (error) {
 
1404
        dpctl_error(dpctl_p, error, "odp_flow_key_from_string");
 
1405
        goto out_freekeybuf;
 
1406
    }
 
1407
 
 
1408
    ds_clear(&s);
 
1409
    odp_flow_format(keybuf.data, keybuf.size, NULL, 0, NULL,
 
1410
                    &s, dpctl_p->verbosity);
 
1411
    dpctl_print(dpctl_p, "input flow: %s\n", ds_cstr(&s));
 
1412
 
 
1413
    error = odp_flow_key_to_flow(keybuf.data, keybuf.size, &flow);
 
1414
    if (error) {
 
1415
        dpctl_error(dpctl_p, error, "odp_flow_key_to_flow");
 
1416
        goto out_freekeybuf;
 
1417
    }
 
1418
 
 
1419
    /* Parse actions. */
 
1420
    ofpbuf_init(&odp_actions, 0);
 
1421
    error = odp_actions_from_string(argv[2], &port_names, &odp_actions);
 
1422
    if (error) {
 
1423
        dpctl_error(dpctl_p, error, "odp_actions_from_string");
 
1424
        goto out_freeactions;
 
1425
    }
 
1426
 
 
1427
    if (dpctl_p->verbosity) {
 
1428
        ds_clear(&s);
 
1429
        format_odp_actions(&s, odp_actions.data, odp_actions.size);
 
1430
        dpctl_print(dpctl_p, "input actions: %s\n", ds_cstr(&s));
 
1431
    }
 
1432
 
 
1433
    hmap_init(&actions_per_flow);
 
1434
    NL_ATTR_FOR_EACH (a, left, odp_actions.data, odp_actions.size) {
 
1435
        const struct ovs_action_push_vlan *push;
 
1436
        switch(nl_attr_type(a)) {
 
1437
        case OVS_ACTION_ATTR_POP_VLAN:
 
1438
            flow.vlan_tci = htons(0);
 
1439
            continue;
 
1440
 
 
1441
        case OVS_ACTION_ATTR_PUSH_VLAN:
 
1442
            push = nl_attr_get_unspec(a, sizeof *push);
 
1443
            flow.vlan_tci = push->vlan_tci;
 
1444
            continue;
 
1445
        }
 
1446
 
 
1447
        af = get_actions_for_flow(&actions_per_flow, &flow);
 
1448
        nl_msg_put_unspec(&af->actions, nl_attr_type(a),
 
1449
                          nl_attr_get(a), nl_attr_get_size(a));
 
1450
    }
 
1451
 
 
1452
    n_afs = hmap_count(&actions_per_flow);
 
1453
    afs = xmalloc(n_afs * sizeof *afs);
 
1454
    i = 0;
 
1455
    HMAP_FOR_EACH (af, hmap_node, &actions_per_flow) {
 
1456
        afs[i++] = af;
 
1457
    }
 
1458
 
 
1459
    ovs_assert(i == n_afs);
 
1460
    hmap_destroy(&actions_per_flow);
 
1461
 
 
1462
    qsort(afs, n_afs, sizeof *afs, compare_actions_for_flow);
 
1463
 
 
1464
    for (i = 0; i < n_afs; i++) {
 
1465
        struct actions_for_flow *af = afs[i];
 
1466
 
 
1467
        sort_output_actions(af->actions.data, af->actions.size);
 
1468
 
 
1469
        if (af->flow.vlan_tci != htons(0)) {
 
1470
            dpctl_print(dpctl_p, "vlan(vid=%"PRIu16",pcp=%d): ",
 
1471
                        vlan_tci_to_vid(af->flow.vlan_tci),
 
1472
                        vlan_tci_to_pcp(af->flow.vlan_tci));
 
1473
        } else {
 
1474
            dpctl_print(dpctl_p, "no vlan: ");
 
1475
        }
 
1476
 
 
1477
        if (eth_type_mpls(af->flow.dl_type)) {
 
1478
            dpctl_print(dpctl_p, "mpls(label=%"PRIu32",tc=%d,ttl=%d): ",
 
1479
                        mpls_lse_to_label(af->flow.mpls_lse[0]),
 
1480
                        mpls_lse_to_tc(af->flow.mpls_lse[0]),
 
1481
                        mpls_lse_to_ttl(af->flow.mpls_lse[0]));
 
1482
        } else {
 
1483
            dpctl_print(dpctl_p, "no mpls: ");
 
1484
        }
 
1485
 
 
1486
        ds_clear(&s);
 
1487
        format_odp_actions(&s, af->actions.data, af->actions.size);
 
1488
        dpctl_puts(dpctl_p, false, ds_cstr(&s));
 
1489
 
 
1490
        ofpbuf_uninit(&af->actions);
 
1491
        free(af);
 
1492
    }
 
1493
    free(afs);
 
1494
 
 
1495
 
 
1496
out_freeactions:
 
1497
    ofpbuf_uninit(&odp_actions);
 
1498
out_freekeybuf:
 
1499
    ofpbuf_uninit(&keybuf);
 
1500
out:
 
1501
    simap_destroy(&port_names);
 
1502
    ds_destroy(&s);
 
1503
 
 
1504
    return error;
 
1505
}
 
1506
 
 
1507
static const struct dpctl_command all_commands[] = {
 
1508
    { "add-dp", "add-dp dp [iface...]", 1, INT_MAX, dpctl_add_dp },
 
1509
    { "del-dp", "del-dp dp", 1, 1, dpctl_del_dp },
 
1510
    { "add-if", "add-if dp iface...", 2, INT_MAX, dpctl_add_if },
 
1511
    { "del-if", "del-if dp iface...", 2, INT_MAX, dpctl_del_if },
 
1512
    { "set-if", "set-if dp iface...", 2, INT_MAX, dpctl_set_if },
 
1513
    { "dump-dps", "", 0, 0, dpctl_dump_dps },
 
1514
    { "show", "[dp...]", 0, INT_MAX, dpctl_show },
 
1515
    { "dump-flows", "[dp]", 0, 2, dpctl_dump_flows },
 
1516
    { "add-flow", "add-flow [dp] flow actions", 2, 3, dpctl_add_flow },
 
1517
    { "mod-flow", "mod-flow [dp] flow actions", 2, 3, dpctl_mod_flow },
 
1518
    { "get-flow", "get-flow [dp] ufid", 1, 2, dpctl_get_flow },
 
1519
    { "del-flow", "del-flow [dp] flow", 1, 2, dpctl_del_flow },
 
1520
    { "del-flows", "[dp]", 0, 1, dpctl_del_flows },
 
1521
    { "help", "", 0, INT_MAX, dpctl_help },
 
1522
    { "list-commands", "", 0, INT_MAX, dpctl_list_commands },
 
1523
 
 
1524
    /* Undocumented commands for testing. */
 
1525
    { "parse-actions", "actions", 1, INT_MAX, dpctl_parse_actions },
 
1526
    { "normalize-actions", "actions", 2, INT_MAX, dpctl_normalize_actions },
 
1527
 
 
1528
    { NULL, NULL, 0, 0, NULL },
 
1529
};
 
1530
 
 
1531
static const struct dpctl_command *get_all_dpctl_commands(void)
 
1532
{
 
1533
    return all_commands;
 
1534
}
 
1535
 
 
1536
/* Runs the command designated by argv[0] within the command table specified by
 
1537
 * 'commands', which must be terminated by a command whose 'name' member is a
 
1538
 * null pointer. */
 
1539
int
 
1540
dpctl_run_command(int argc, const char *argv[], struct dpctl_params *dpctl_p)
 
1541
{
 
1542
    const struct dpctl_command *p;
 
1543
 
 
1544
    if (argc < 1) {
 
1545
        dpctl_error(dpctl_p, 0, "missing command name; use --help for help");
 
1546
        return EINVAL;
 
1547
    }
 
1548
 
 
1549
    for (p = all_commands; p->name != NULL; p++) {
 
1550
        if (!strcmp(p->name, argv[0])) {
 
1551
            int n_arg = argc - 1;
 
1552
            if (n_arg < p->min_args) {
 
1553
                dpctl_error(dpctl_p, 0,
 
1554
                            "'%s' command requires at least %d arguments",
 
1555
                            p->name, p->min_args);
 
1556
                return EINVAL;
 
1557
            } else if (n_arg > p->max_args) {
 
1558
                dpctl_error(dpctl_p, 0,
 
1559
                            "'%s' command takes at most %d arguments",
 
1560
                            p->name, p->max_args);
 
1561
                return EINVAL;
 
1562
            } else {
 
1563
                return p->handler(argc, argv, dpctl_p);
 
1564
            }
 
1565
        }
 
1566
    }
 
1567
 
 
1568
    dpctl_error(dpctl_p, 0, "unknown command '%s'; use --help for help",
 
1569
                argv[0]);
 
1570
    return EINVAL;
 
1571
}
 
1572
 
 
1573
static void
 
1574
dpctl_unixctl_print(void *userdata, bool error OVS_UNUSED, const char *msg)
 
1575
{
 
1576
    struct ds *ds = userdata;
 
1577
    ds_put_cstr(ds, msg);
 
1578
}
 
1579
 
 
1580
static void
 
1581
dpctl_unixctl_handler(struct unixctl_conn *conn, int argc, const char *argv[],
 
1582
                      void *aux)
 
1583
{
 
1584
    struct ds ds = DS_EMPTY_INITIALIZER;
 
1585
    struct dpctl_params dpctl_p;
 
1586
    bool error = false;
 
1587
 
 
1588
    dpctl_command_handler *handler = (dpctl_command_handler *) aux;
 
1589
 
 
1590
    dpctl_p.print_statistics = false;
 
1591
    dpctl_p.zero_statistics = false;
 
1592
    dpctl_p.may_create = false;
 
1593
    dpctl_p.verbosity = 0;
 
1594
 
 
1595
    /* Parse options (like getopt). Unfortunately it does
 
1596
     * not seem a good idea to call getopt_long() here, since it uses global
 
1597
     * variables */
 
1598
    while (argc > 1 && !error) {
 
1599
        const char *arg = argv[1];
 
1600
        if (!strncmp(arg, "--", 2)) {
 
1601
            /* Long option */
 
1602
            if (!strcmp(arg, "--statistics")) {
 
1603
                dpctl_p.print_statistics = true;
 
1604
            } else if (!strcmp(arg, "--clear")) {
 
1605
                dpctl_p.zero_statistics = true;
 
1606
            } else if (!strcmp(arg, "--may-create")) {
 
1607
                dpctl_p.may_create = true;
 
1608
            } else if (!strcmp(arg, "--more")) {
 
1609
                dpctl_p.verbosity++;
 
1610
            } else {
 
1611
                ds_put_format(&ds, "Unrecognized option %s", argv[1]);
 
1612
                error = true;
 
1613
            }
 
1614
        } else if (arg[0] == '-' && arg[1] != '\0') {
 
1615
            /* Short option[s] */
 
1616
            const char *opt = &arg[1];
 
1617
 
 
1618
            while (*opt && !error) {
 
1619
                switch (*opt) {
 
1620
                case 'm':
 
1621
                    dpctl_p.verbosity++;
 
1622
                    break;
 
1623
                case 's':
 
1624
                    dpctl_p.print_statistics = true;
 
1625
                    break;
 
1626
                default:
 
1627
                    ds_put_format(&ds, "Unrecognized option -%c", *opt);
 
1628
                    error = true;
 
1629
                    break;
 
1630
                }
 
1631
                opt++;
 
1632
            }
 
1633
        } else {
 
1634
            /* Doesn't start with -, not an option */
 
1635
            break;
 
1636
        }
 
1637
 
 
1638
        if (error) {
 
1639
            break;
 
1640
        }
 
1641
        argv++;
 
1642
        argc--;
 
1643
    }
 
1644
 
 
1645
    if (!error) {
 
1646
        dpctl_p.is_appctl = true;
 
1647
        dpctl_p.output = dpctl_unixctl_print;
 
1648
        dpctl_p.aux = &ds;
 
1649
 
 
1650
        error = handler(argc, argv, &dpctl_p) != 0;
 
1651
    }
 
1652
 
 
1653
    if (error) {
 
1654
        unixctl_command_reply_error(conn, ds_cstr(&ds));
 
1655
    } else {
 
1656
        unixctl_command_reply(conn, ds_cstr(&ds));
 
1657
    }
 
1658
 
 
1659
    ds_destroy(&ds);
 
1660
}
 
1661
 
 
1662
void
 
1663
dpctl_unixctl_register(void)
 
1664
{
 
1665
    const struct dpctl_command *p;
 
1666
 
 
1667
    for (p = all_commands; p->name != NULL; p++) {
 
1668
        char *cmd_name = xasprintf("dpctl/%s", p->name);
 
1669
        unixctl_command_register(cmd_name, "", p->min_args, p->max_args,
 
1670
                                 dpctl_unixctl_handler, p->handler);
 
1671
        free(cmd_name);
 
1672
    }
 
1673
}