Coverage Report

Created: 2026-07-16 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openvswitch/lib/dpif-netlink.c
Line
Count
Source
1
/*
2
 * Copyright (c) 2008-2018 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 "dpif-netlink.h"
20
21
#include <ctype.h>
22
#include <errno.h>
23
#include <fcntl.h>
24
#include <inttypes.h>
25
#include <net/if.h>
26
#include <linux/types.h>
27
#include <linux/pkt_sched.h>
28
#include <poll.h>
29
#include <stdlib.h>
30
#include <strings.h>
31
#include <sys/epoll.h>
32
#include <sys/stat.h>
33
#include <unistd.h>
34
35
#include "bitmap.h"
36
#include "dpif-netlink-rtnl.h"
37
#include "dpif-offload.h"
38
#include "dpif-provider.h"
39
#include "fat-rwlock.h"
40
#include "flow.h"
41
#include "netdev-linux.h"
42
#include "netdev-provider.h"
43
#include "netdev-vport.h"
44
#include "netdev.h"
45
#include "netlink-conntrack.h"
46
#include "netlink-notifier.h"
47
#include "netlink-socket.h"
48
#include "netlink.h"
49
#include "netnsid.h"
50
#include "odp-util.h"
51
#include "openvswitch/dynamic-string.h"
52
#include "openvswitch/flow.h"
53
#include "openvswitch/hmap.h"
54
#include "openvswitch/match.h"
55
#include "openvswitch/ofpbuf.h"
56
#include "openvswitch/poll-loop.h"
57
#include "openvswitch/shash.h"
58
#include "openvswitch/thread.h"
59
#include "openvswitch/usdt-probes.h"
60
#include "openvswitch/vlog.h"
61
#include "packets.h"
62
#include "random.h"
63
#include "sset.h"
64
#include "timeval.h"
65
#include "unaligned.h"
66
#include "util.h"
67
68
VLOG_DEFINE_THIS_MODULE(dpif_netlink);
69
70
enum { MAX_PORTS = USHRT_MAX };
71
72
/* This ethtool flag was introduced in Linux 2.6.24, so it might be
73
 * missing if we have old headers. */
74
0
#define ETH_FLAG_LRO      (1 << 15)    /* LRO is enabled */
75
76
#define OPERATE_MAX_OPS 50
77
78
#ifndef EPOLLEXCLUSIVE
79
#define EPOLLEXCLUSIVE (1u << 28)
80
#endif
81
82
0
#define OVS_DP_F_UNSUPPORTED (1u << 31);
83
84
/* This PID is not used by the kernel datapath when using dispatch per CPU,
85
 * but it is required to be set (not zero). */
86
0
#define DPIF_NETLINK_PER_CPU_PID UINT32_MAX
87
struct dpif_netlink_dp {
88
    /* Generic Netlink header. */
89
    uint8_t cmd;
90
91
    /* struct ovs_header. */
92
    int dp_ifindex;
93
94
    /* Attributes. */
95
    const char *name;                  /* OVS_DP_ATTR_NAME. */
96
    const uint32_t *upcall_pid;        /* OVS_DP_ATTR_UPCALL_PID. */
97
    uint32_t user_features;            /* OVS_DP_ATTR_USER_FEATURES */
98
    uint32_t cache_size;               /* OVS_DP_ATTR_MASKS_CACHE_SIZE */
99
    const struct ovs_dp_stats *stats;  /* OVS_DP_ATTR_STATS. */
100
    const struct ovs_dp_megaflow_stats *megaflow_stats;
101
                                       /* OVS_DP_ATTR_MEGAFLOW_STATS.*/
102
    const uint32_t *upcall_pids;       /* OVS_DP_ATTR_PER_CPU_PIDS */
103
    uint32_t n_upcall_pids;
104
};
105
106
static void dpif_netlink_dp_init(struct dpif_netlink_dp *);
107
static int dpif_netlink_dp_from_ofpbuf(struct dpif_netlink_dp *,
108
                                       const struct ofpbuf *);
109
static void dpif_netlink_dp_dump_start(struct nl_dump *);
110
static int dpif_netlink_dp_transact(const struct dpif_netlink_dp *request,
111
                                    struct dpif_netlink_dp *reply,
112
                                    struct ofpbuf **bufp);
113
static int dpif_netlink_dp_get(const struct dpif *,
114
                               struct dpif_netlink_dp *reply,
115
                               struct ofpbuf **bufp);
116
static int
117
dpif_netlink_set_features(struct dpif *dpif_, uint32_t new_features);
118
static uint32_t
119
dpif_netlink_get_features(struct dpif *dpif_);
120
121
static void
122
dpif_netlink_unixctl_dispatch_mode(struct unixctl_conn *conn, int argc,
123
                                   const char *argv[], void *aux);
124
125
struct dpif_netlink_flow {
126
    /* Generic Netlink header. */
127
    uint8_t cmd;
128
129
    /* struct ovs_header. */
130
    unsigned int nlmsg_flags;
131
    int dp_ifindex;
132
133
    /* Attributes.
134
     *
135
     * The 'stats' member points to 64-bit data that might only be aligned on
136
     * 32-bit boundaries, so get_unaligned_u64() should be used to access its
137
     * values.
138
     *
139
     * If 'actions' is nonnull then OVS_FLOW_ATTR_ACTIONS will be included in
140
     * the Netlink version of the command, even if actions_len is zero. */
141
    const struct nlattr *key;           /* OVS_FLOW_ATTR_KEY. */
142
    size_t key_len;
143
    const struct nlattr *mask;          /* OVS_FLOW_ATTR_MASK. */
144
    size_t mask_len;
145
    const struct nlattr *actions;       /* OVS_FLOW_ATTR_ACTIONS. */
146
    size_t actions_len;
147
    ovs_u128 ufid;                      /* OVS_FLOW_ATTR_FLOW_ID. */
148
    bool ufid_present;                  /* Is there a UFID? */
149
    bool ufid_terse;                    /* Skip serializing key/mask/acts? */
150
    const struct ovs_flow_stats *stats; /* OVS_FLOW_ATTR_STATS. */
151
    const uint8_t *tcp_flags;           /* OVS_FLOW_ATTR_TCP_FLAGS. */
152
    const ovs_32aligned_u64 *used;      /* OVS_FLOW_ATTR_USED. */
153
    bool clear;                         /* OVS_FLOW_ATTR_CLEAR. */
154
    bool probe;                         /* OVS_FLOW_ATTR_PROBE. */
155
};
156
157
static void dpif_netlink_flow_init(struct dpif_netlink_flow *);
158
static int dpif_netlink_flow_from_ofpbuf(struct dpif_netlink_flow *,
159
                                         const struct ofpbuf *);
160
static void dpif_netlink_flow_to_ofpbuf(const struct dpif_netlink_flow *,
161
                                        struct ofpbuf *);
162
static int dpif_netlink_flow_transact(struct dpif_netlink_flow *request,
163
                                      struct dpif_netlink_flow *reply,
164
                                      struct ofpbuf **bufp);
165
static void dpif_netlink_flow_get_stats(const struct dpif_netlink_flow *,
166
                                        struct dpif_flow_stats *);
167
static void dpif_netlink_flow_to_dpif_flow(struct dpif_flow *,
168
                                           const struct dpif_netlink_flow *);
169
170
/* One of the dpif channels between the kernel and userspace. */
171
struct dpif_channel {
172
    struct nl_sock *sock;       /* Netlink socket. */
173
    long long int last_poll;    /* Last time this channel was polled. */
174
};
175
176
struct dpif_handler {
177
    /* per-vport dispatch mode. */
178
    struct epoll_event *epoll_events;
179
    int epoll_fd;                 /* epoll fd that includes channel socks. */
180
    int n_events;                 /* Num events returned by epoll_wait(). */
181
    int event_offset;             /* Offset into 'epoll_events'. */
182
183
    /* per-cpu dispatch mode. */
184
    struct nl_sock *sock;         /* Each handler thread holds one netlink
185
                                     socket. */
186
};
187
188
/* Datapath interface for the openvswitch Linux kernel module. */
189
struct dpif_netlink {
190
    struct dpif dpif;
191
    int dp_ifindex;
192
    uint32_t user_features;
193
194
    /* Upcall messages. */
195
    struct fat_rwlock upcall_lock;
196
    struct dpif_handler *handlers;
197
    uint32_t n_handlers;           /* Num of upcall handlers. */
198
199
    /* Per-vport dispatch mode. */
200
    struct dpif_channel *channels; /* Array of channels for each port. */
201
    int uc_array_size;             /* Size of 'handler->channels' and */
202
                                   /* 'handler->epoll_events'. */
203
204
    /* Change notification. */
205
    struct nl_sock *port_notifier; /* vport multicast group subscriber. */
206
    bool refresh_channels;
207
};
208
209
static void report_loss(struct dpif_netlink *, struct dpif_channel *,
210
                        uint32_t ch_idx, uint32_t handler_id);
211
212
static struct vlog_rate_limit error_rl = VLOG_RATE_LIMIT_INIT(9999, 5);
213
214
/* Generic Netlink family numbers for OVS.
215
 *
216
 * Initialized by dpif_netlink_init(). */
217
static int ovs_datapath_family;
218
static int ovs_vport_family;
219
static int ovs_flow_family;
220
static int ovs_packet_family;
221
static int ovs_meter_family;
222
static int ovs_ct_limit_family;
223
224
/* Generic Netlink multicast groups for OVS.
225
 *
226
 * Initialized by dpif_netlink_init(). */
227
static unsigned int ovs_vport_mcgroup;
228
229
static int dpif_netlink_init(void);
230
static int open_dpif(const struct dpif_netlink_dp *, struct dpif **);
231
static uint32_t dpif_netlink_port_get_pid(const struct dpif *,
232
                                          odp_port_t port_no);
233
static void dpif_netlink_handler_uninit(struct dpif_handler *handler);
234
static int dpif_netlink_refresh_handlers_vport_dispatch(struct dpif_netlink *,
235
                                                        uint32_t n_handlers);
236
static void destroy_all_channels(struct dpif_netlink *);
237
static int dpif_netlink_refresh_handlers_cpu_dispatch(struct dpif_netlink *);
238
static void destroy_all_handlers(struct dpif_netlink *);
239
240
static void dpif_netlink_vport_to_ofpbuf(const struct dpif_netlink_vport *,
241
                                         struct ofpbuf *);
242
static int dpif_netlink_vport_from_ofpbuf(struct dpif_netlink_vport *,
243
                                          const struct ofpbuf *);
244
static int dpif_netlink_port_query__(const struct dpif_netlink *dpif,
245
                                     odp_port_t port_no, const char *port_name,
246
                                     struct dpif_port *dpif_port);
247
static void vport_del_channels(struct dpif_netlink *, odp_port_t);
248
249
static int
250
create_nl_sock(struct dpif_netlink *dpif OVS_UNUSED, struct nl_sock **sockp)
251
    OVS_REQ_WRLOCK(dpif->upcall_lock)
252
0
{
253
0
    return nl_sock_create(NETLINK_GENERIC, sockp);
254
0
}
255
256
static void
257
close_nl_sock(struct nl_sock *sock)
258
0
{
259
0
    nl_sock_destroy(sock);
260
0
}
261
262
static struct dpif_netlink *
263
dpif_netlink_cast(const struct dpif *dpif)
264
0
{
265
0
    dpif_assert_class(dpif, &dpif_netlink_class);
266
0
    return CONTAINER_OF(dpif, struct dpif_netlink, dpif);
267
0
}
268
269
static inline bool
270
0
dpif_netlink_upcall_per_cpu(const struct dpif_netlink *dpif) {
271
0
    return !!((dpif)->user_features & OVS_DP_F_DISPATCH_UPCALL_PER_CPU);
272
0
}
273
274
static int
275
dpif_netlink_enumerate(struct sset *all_dps,
276
                       const struct dpif_class *dpif_class OVS_UNUSED)
277
0
{
278
0
    struct nl_dump dump;
279
0
    uint64_t reply_stub[NL_DUMP_BUFSIZE / 8];
280
0
    struct ofpbuf msg, buf;
281
0
    int error;
282
283
0
    error = dpif_netlink_init();
284
0
    if (error) {
285
0
        return error;
286
0
    }
287
288
0
    ofpbuf_use_stub(&buf, reply_stub, sizeof reply_stub);
289
0
    dpif_netlink_dp_dump_start(&dump);
290
0
    while (nl_dump_next(&dump, &msg, &buf)) {
291
0
        struct dpif_netlink_dp dp;
292
293
0
        if (!dpif_netlink_dp_from_ofpbuf(&dp, &msg)) {
294
0
            sset_add(all_dps, dp.name);
295
0
        }
296
0
    }
297
0
    ofpbuf_uninit(&buf);
298
0
    return nl_dump_done(&dump);
299
0
}
300
301
static int
302
dpif_netlink_open(const struct dpif_class *class OVS_UNUSED, const char *name,
303
                  bool create, struct dpif **dpifp)
304
0
{
305
0
    struct dpif_netlink_dp dp_request, dp;
306
0
    struct ofpbuf *buf;
307
0
    uint32_t upcall_pid;
308
0
    int error;
309
310
0
    error = dpif_netlink_init();
311
0
    if (error) {
312
0
        return error;
313
0
    }
314
315
    /* Create or look up datapath. */
316
0
    dpif_netlink_dp_init(&dp_request);
317
0
    upcall_pid = 0;
318
0
    dp_request.upcall_pid = &upcall_pid;
319
0
    dp_request.name = name;
320
321
0
    if (create) {
322
0
        dp_request.cmd = OVS_DP_CMD_NEW;
323
0
    } else {
324
0
        dp_request.cmd = OVS_DP_CMD_GET;
325
326
0
        error = dpif_netlink_dp_transact(&dp_request, &dp, &buf);
327
0
        if (error) {
328
0
            return error;
329
0
        }
330
0
        dp_request.user_features = dp.user_features;
331
0
        ofpbuf_delete(buf);
332
333
        /* Use OVS_DP_CMD_SET to report user features */
334
0
        dp_request.cmd = OVS_DP_CMD_SET;
335
0
    }
336
337
    /* Some older kernels will not reject unknown features. This will cause
338
     * 'ovs-vswitchd' to incorrectly assume a feature is supported. In order to
339
     * test for that, we attempt to set a feature that we know is not supported
340
     * by any kernel. If this feature is not rejected, we can assume we are
341
     * running on one of these older kernels.
342
     */
343
0
    dp_request.user_features |= OVS_DP_F_UNALIGNED;
344
0
    dp_request.user_features |= OVS_DP_F_VPORT_PIDS;
345
0
    dp_request.user_features |= OVS_DP_F_UNSUPPORTED;
346
0
    error = dpif_netlink_dp_transact(&dp_request, NULL, NULL);
347
0
    if (error) {
348
        /* The Open vSwitch kernel module has two modes for dispatching
349
         * upcalls: per-vport and per-cpu.
350
         *
351
         * When dispatching upcalls per-vport, the kernel will
352
         * send the upcall via a Netlink socket that has been selected based on
353
         * the vport that received the packet that is causing the upcall.
354
         *
355
         * When dispatching upcall per-cpu, the kernel will send the upcall via
356
         * a Netlink socket that has been selected based on the cpu that
357
         * received the packet that is causing the upcall.
358
         *
359
         * First we test to see if the kernel module supports per-cpu
360
         * dispatching (the preferred method). If it does not support per-cpu
361
         * dispatching, we fall back to the per-vport dispatch mode.
362
         */
363
0
        dp_request.user_features &= ~OVS_DP_F_UNSUPPORTED;
364
0
        dp_request.user_features &= ~OVS_DP_F_VPORT_PIDS;
365
0
        dp_request.user_features |= OVS_DP_F_DISPATCH_UPCALL_PER_CPU;
366
0
        error = dpif_netlink_dp_transact(&dp_request, &dp, &buf);
367
0
        if (error == EOPNOTSUPP) {
368
0
            dp_request.user_features &= ~OVS_DP_F_DISPATCH_UPCALL_PER_CPU;
369
0
            dp_request.user_features |= OVS_DP_F_VPORT_PIDS;
370
0
            error = dpif_netlink_dp_transact(&dp_request, &dp, &buf);
371
0
        }
372
0
        if (error) {
373
0
            return error;
374
0
        }
375
376
0
        error = open_dpif(&dp, dpifp);
377
0
        dpif_netlink_set_features(*dpifp, OVS_DP_F_TC_RECIRC_SHARING);
378
0
    } else {
379
0
        VLOG_INFO("Kernel does not correctly support feature negotiation. "
380
0
                  "Using standard features.");
381
0
        dp_request.cmd = OVS_DP_CMD_SET;
382
0
        dp_request.user_features = 0;
383
0
        dp_request.user_features |= OVS_DP_F_UNALIGNED;
384
0
        dp_request.user_features |= OVS_DP_F_VPORT_PIDS;
385
0
        error = dpif_netlink_dp_transact(&dp_request, &dp, &buf);
386
0
        if (error) {
387
0
            return error;
388
0
        }
389
0
        error = open_dpif(&dp, dpifp);
390
0
    }
391
392
0
    ofpbuf_delete(buf);
393
394
0
    if (create) {
395
0
        VLOG_INFO("Datapath dispatch mode: %s",
396
0
                  dpif_netlink_upcall_per_cpu(dpif_netlink_cast(*dpifp)) ?
397
0
                  "per-cpu" : "per-vport");
398
0
    }
399
400
0
    return error;
401
0
}
402
403
static int
404
open_dpif(const struct dpif_netlink_dp *dp, struct dpif **dpifp)
405
0
{
406
0
    struct dpif_netlink *dpif;
407
408
0
    dpif = xzalloc(sizeof *dpif);
409
0
    dpif->port_notifier = NULL;
410
0
    fat_rwlock_init(&dpif->upcall_lock);
411
412
0
    dpif_init(&dpif->dpif, &dpif_netlink_class, dp->name,
413
0
              dp->dp_ifindex, dp->dp_ifindex);
414
415
0
    dpif->dp_ifindex = dp->dp_ifindex;
416
0
    dpif->user_features = dp->user_features;
417
0
    *dpifp = &dpif->dpif;
418
419
0
    return 0;
420
0
}
421
422
/* Given the port number 'port_idx', extracts the pid of netlink socket
423
 * associated to the port and assigns it to 'upcall_pid'. */
424
static bool
425
vport_get_pid(struct dpif_netlink *dpif, uint32_t port_idx,
426
              uint32_t *upcall_pid)
427
0
{
428
    /* Since the nl_sock can only be assigned in either all
429
     * or none "dpif" channels, the following check
430
     * would suffice. */
431
0
    if (!dpif->channels[port_idx].sock) {
432
0
        return false;
433
0
    }
434
435
0
    *upcall_pid = nl_sock_pid(dpif->channels[port_idx].sock);
436
437
0
    return true;
438
0
}
439
440
static int
441
vport_add_channel(struct dpif_netlink *dpif, odp_port_t port_no,
442
                  struct nl_sock *sock)
443
0
{
444
0
    struct epoll_event event;
445
0
    uint32_t port_idx = odp_to_u32(port_no);
446
0
    size_t i;
447
0
    int error;
448
449
0
    if (dpif->handlers == NULL) {
450
0
        close_nl_sock(sock);
451
0
        return 0;
452
0
    }
453
454
    /* We assume that the datapath densely chooses port numbers, which can
455
     * therefore be used as an index into 'channels' and 'epoll_events' of
456
     * 'dpif'. */
457
0
    if (port_idx >= dpif->uc_array_size) {
458
0
        uint32_t new_size = port_idx + 1;
459
460
0
        if (new_size > MAX_PORTS) {
461
0
            VLOG_WARN_RL(&error_rl, "%s: datapath port %"PRIu32" too big",
462
0
                         dpif_name(&dpif->dpif), port_no);
463
0
            return EFBIG;
464
0
        }
465
466
0
        dpif->channels = xrealloc(dpif->channels,
467
0
                                  new_size * sizeof *dpif->channels);
468
469
0
        for (i = dpif->uc_array_size; i < new_size; i++) {
470
0
            dpif->channels[i].sock = NULL;
471
0
        }
472
473
0
        for (i = 0; i < dpif->n_handlers; i++) {
474
0
            struct dpif_handler *handler = &dpif->handlers[i];
475
476
0
            handler->epoll_events = xrealloc(handler->epoll_events,
477
0
                new_size * sizeof *handler->epoll_events);
478
479
0
        }
480
0
        dpif->uc_array_size = new_size;
481
0
    }
482
483
0
    vport_del_channels(dpif, port_no);
484
485
0
    memset(&event, 0, sizeof event);
486
0
    event.events = EPOLLIN | EPOLLEXCLUSIVE;
487
0
    event.data.u32 = port_idx;
488
489
0
    for (i = 0; i < dpif->n_handlers; i++) {
490
0
        struct dpif_handler *handler = &dpif->handlers[i];
491
492
0
        if (epoll_ctl(handler->epoll_fd, EPOLL_CTL_ADD, nl_sock_fd(sock),
493
0
                      &event) < 0) {
494
0
            error = errno;
495
0
            goto error;
496
0
        }
497
0
    }
498
0
    dpif->channels[port_idx].sock = sock;
499
0
    dpif->channels[port_idx].last_poll = LLONG_MIN;
500
501
0
    return 0;
502
503
0
error:
504
0
    while (i--) {
505
0
        epoll_ctl(dpif->handlers[i].epoll_fd, EPOLL_CTL_DEL,
506
0
                  nl_sock_fd(sock), NULL);
507
0
    }
508
0
    dpif->channels[port_idx].sock = NULL;
509
510
0
    return error;
511
0
}
512
513
static void
514
vport_del_channels(struct dpif_netlink *dpif, odp_port_t port_no)
515
0
{
516
0
    uint32_t port_idx = odp_to_u32(port_no);
517
0
    size_t i;
518
519
0
    if (!dpif->handlers || port_idx >= dpif->uc_array_size
520
0
        || !dpif->channels[port_idx].sock) {
521
0
        return;
522
0
    }
523
524
0
    for (i = 0; i < dpif->n_handlers; i++) {
525
0
        struct dpif_handler *handler = &dpif->handlers[i];
526
0
        epoll_ctl(handler->epoll_fd, EPOLL_CTL_DEL,
527
0
                  nl_sock_fd(dpif->channels[port_idx].sock), NULL);
528
0
        handler->event_offset = handler->n_events = 0;
529
0
    }
530
0
    nl_sock_destroy(dpif->channels[port_idx].sock);
531
0
    dpif->channels[port_idx].sock = NULL;
532
0
}
533
534
static void
535
destroy_all_channels(struct dpif_netlink *dpif)
536
    OVS_REQ_WRLOCK(dpif->upcall_lock)
537
0
{
538
0
    unsigned int i;
539
540
0
    if (!dpif->handlers) {
541
0
        return;
542
0
    }
543
544
0
    for (i = 0; i < dpif->uc_array_size; i++ ) {
545
0
        struct dpif_netlink_vport vport_request;
546
0
        uint32_t upcall_pids = 0;
547
548
0
        if (!dpif->channels[i].sock) {
549
0
            continue;
550
0
        }
551
552
        /* Turn off upcalls. */
553
0
        dpif_netlink_vport_init(&vport_request);
554
0
        vport_request.cmd = OVS_VPORT_CMD_SET;
555
0
        vport_request.dp_ifindex = dpif->dp_ifindex;
556
0
        vport_request.port_no = u32_to_odp(i);
557
0
        vport_request.n_upcall_pids = 1;
558
0
        vport_request.upcall_pids = &upcall_pids;
559
0
        dpif_netlink_vport_transact(&vport_request, NULL, NULL);
560
561
0
        vport_del_channels(dpif, u32_to_odp(i));
562
0
    }
563
564
0
    for (i = 0; i < dpif->n_handlers; i++) {
565
0
        struct dpif_handler *handler = &dpif->handlers[i];
566
567
0
        dpif_netlink_handler_uninit(handler);
568
0
        free(handler->epoll_events);
569
0
    }
570
0
    free(dpif->channels);
571
0
    free(dpif->handlers);
572
0
    dpif->handlers = NULL;
573
0
    dpif->channels = NULL;
574
0
    dpif->n_handlers = 0;
575
0
    dpif->uc_array_size = 0;
576
0
}
577
578
static void
579
destroy_all_handlers(struct dpif_netlink *dpif)
580
    OVS_REQ_WRLOCK(dpif->upcall_lock)
581
0
{
582
0
    int i = 0;
583
584
0
    if (!dpif->handlers) {
585
0
        return;
586
0
    }
587
0
    for (i = 0; i < dpif->n_handlers; i++) {
588
0
        struct dpif_handler *handler = &dpif->handlers[i];
589
0
        close_nl_sock(handler->sock);
590
0
    }
591
0
    free(dpif->handlers);
592
0
    dpif->handlers = NULL;
593
0
    dpif->n_handlers = 0;
594
0
}
595
596
static void
597
dpif_netlink_close(struct dpif *dpif_)
598
0
{
599
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
600
601
0
    nl_sock_destroy(dpif->port_notifier);
602
603
0
    fat_rwlock_wrlock(&dpif->upcall_lock);
604
0
    if (dpif_netlink_upcall_per_cpu(dpif)) {
605
0
        destroy_all_handlers(dpif);
606
0
    } else {
607
0
        destroy_all_channels(dpif);
608
0
    }
609
0
    fat_rwlock_unlock(&dpif->upcall_lock);
610
611
0
    fat_rwlock_destroy(&dpif->upcall_lock);
612
0
    free(dpif);
613
0
}
614
615
static int
616
dpif_netlink_destroy(struct dpif *dpif_)
617
0
{
618
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
619
0
    struct dpif_netlink_dp dp;
620
621
0
    dpif_netlink_dp_init(&dp);
622
0
    dp.cmd = OVS_DP_CMD_DEL;
623
0
    dp.dp_ifindex = dpif->dp_ifindex;
624
0
    return dpif_netlink_dp_transact(&dp, NULL, NULL);
625
0
}
626
627
static bool
628
dpif_netlink_run(struct dpif *dpif_)
629
0
{
630
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
631
632
0
    if (!dpif_netlink_upcall_per_cpu(dpif)) {
633
0
        if (dpif->refresh_channels) {
634
0
            dpif->refresh_channels = false;
635
0
            fat_rwlock_wrlock(&dpif->upcall_lock);
636
0
            dpif_netlink_refresh_handlers_vport_dispatch(dpif,
637
0
                                                         dpif->n_handlers);
638
0
            fat_rwlock_unlock(&dpif->upcall_lock);
639
0
        }
640
0
    }
641
0
    return false;
642
0
}
643
644
static int
645
dpif_netlink_get_stats(const struct dpif *dpif_, struct dpif_dp_stats *stats)
646
0
{
647
0
    struct dpif_netlink_dp dp;
648
0
    struct ofpbuf *buf;
649
0
    int error;
650
651
0
    error = dpif_netlink_dp_get(dpif_, &dp, &buf);
652
0
    if (!error) {
653
0
        memset(stats, 0, sizeof *stats);
654
655
0
        if (dp.stats) {
656
0
            stats->n_hit    = get_32aligned_u64(&dp.stats->n_hit);
657
0
            stats->n_missed = get_32aligned_u64(&dp.stats->n_missed);
658
0
            stats->n_lost   = get_32aligned_u64(&dp.stats->n_lost);
659
0
            stats->n_flows  = get_32aligned_u64(&dp.stats->n_flows);
660
0
        }
661
662
0
        if (dp.megaflow_stats) {
663
0
            stats->n_masks = dp.megaflow_stats->n_masks;
664
0
            stats->n_mask_hit = get_32aligned_u64(
665
0
                &dp.megaflow_stats->n_mask_hit);
666
0
            stats->n_cache_hit = get_32aligned_u64(
667
0
                &dp.megaflow_stats->n_cache_hit);
668
669
0
            if (!stats->n_cache_hit) {
670
                /* Old kernels don't use this field and always
671
                 * report zero instead.  Disable this stat. */
672
0
                stats->n_cache_hit = UINT64_MAX;
673
0
            }
674
0
        } else {
675
0
            stats->n_masks = UINT32_MAX;
676
0
            stats->n_mask_hit = UINT64_MAX;
677
0
            stats->n_cache_hit = UINT64_MAX;
678
0
        }
679
0
        ofpbuf_delete(buf);
680
0
    }
681
0
    return error;
682
0
}
683
684
static int
685
dpif_netlink_set_handler_pids(struct dpif *dpif_, const uint32_t *upcall_pids,
686
                              uint32_t n_upcall_pids)
687
0
{
688
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
689
0
    int largest_cpu_id = ovs_numa_get_largest_core_id();
690
0
    struct dpif_netlink_dp request, reply;
691
0
    struct ofpbuf *bufp;
692
693
0
    uint32_t *corrected;
694
0
    int error, i, n_cores;
695
696
0
    if (largest_cpu_id == OVS_NUMA_UNSPEC) {
697
0
        largest_cpu_id = -1;
698
0
    }
699
700
    /* Some systems have non-continuous cpu core ids.  count_total_cores()
701
     * would return an accurate number, however, this number cannot be used.
702
     * e.g. If the largest core_id of a system is cpu9, but the system only
703
     * has 4 cpus then the OVS kernel module would throw a "CPU mismatch"
704
     * warning.  With the MAX() in place in this example we send an array of
705
     * size 10 and prevent the warning.  This has no bearing on the number of
706
     * threads created.
707
     */
708
0
    n_cores = MAX(count_total_cores(), largest_cpu_id + 1);
709
0
    VLOG_DBG("Dispatch mode(per-cpu): Setting up handler PIDs for %d cores",
710
0
             n_cores);
711
712
0
    dpif_netlink_dp_init(&request);
713
0
    request.cmd = OVS_DP_CMD_SET;
714
0
    request.name = dpif_->base_name;
715
0
    request.dp_ifindex = dpif->dp_ifindex;
716
0
    request.user_features = dpif->user_features |
717
0
                            OVS_DP_F_DISPATCH_UPCALL_PER_CPU;
718
719
0
    corrected = xcalloc(n_cores, sizeof *corrected);
720
721
0
    for (i = 0; i < n_cores; i++) {
722
0
        corrected[i] = upcall_pids[i % n_upcall_pids];
723
0
    }
724
0
    request.upcall_pids = corrected;
725
0
    request.n_upcall_pids = n_cores;
726
727
0
    error = dpif_netlink_dp_transact(&request, &reply, &bufp);
728
0
    if (!error) {
729
0
        dpif->user_features = reply.user_features;
730
0
        ofpbuf_delete(bufp);
731
0
        if (!dpif_netlink_upcall_per_cpu(dpif)) {
732
0
            error = -EOPNOTSUPP;
733
0
        }
734
0
    }
735
0
    free(corrected);
736
0
    return error;
737
0
}
738
739
static int
740
dpif_netlink_set_features(struct dpif *dpif_, uint32_t new_features)
741
0
{
742
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
743
0
    struct dpif_netlink_dp request, reply;
744
0
    struct ofpbuf *bufp;
745
0
    int error;
746
747
0
    dpif_netlink_dp_init(&request);
748
0
    request.cmd = OVS_DP_CMD_SET;
749
0
    request.name = dpif_->base_name;
750
0
    request.dp_ifindex = dpif->dp_ifindex;
751
0
    request.user_features = dpif->user_features | new_features;
752
753
0
    error = dpif_netlink_dp_transact(&request, &reply, &bufp);
754
0
    if (!error) {
755
0
        dpif->user_features = reply.user_features;
756
0
        ofpbuf_delete(bufp);
757
0
        if (!(dpif->user_features & new_features)) {
758
0
            return -EOPNOTSUPP;
759
0
        }
760
0
    }
761
762
0
    return error;
763
0
}
764
765
static uint32_t
766
dpif_netlink_get_features(struct dpif *dpif_)
767
0
{
768
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
769
770
0
    return dpif->user_features;
771
0
}
772
773
static const char *
774
get_vport_type(const struct dpif_netlink_vport *vport)
775
0
{
776
0
    static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
777
778
0
    switch (vport->type) {
779
0
    case OVS_VPORT_TYPE_NETDEV: {
780
0
        const char *type = netdev_get_type_from_name(vport->name);
781
782
0
        return type ? type : "system";
783
0
    }
784
785
0
    case OVS_VPORT_TYPE_INTERNAL:
786
0
        return "internal";
787
788
0
    case OVS_VPORT_TYPE_GENEVE:
789
0
        return "geneve";
790
791
0
    case OVS_VPORT_TYPE_GRE:
792
0
        return "gre";
793
794
0
    case OVS_VPORT_TYPE_VXLAN:
795
0
        return "vxlan";
796
797
0
    case OVS_VPORT_TYPE_ERSPAN:
798
0
        return "erspan";
799
800
0
    case OVS_VPORT_TYPE_IP6ERSPAN:
801
0
        return "ip6erspan";
802
803
0
    case OVS_VPORT_TYPE_IP6GRE:
804
0
        return "ip6gre";
805
806
0
    case OVS_VPORT_TYPE_GTPU:
807
0
        return "gtpu";
808
809
0
    case OVS_VPORT_TYPE_SRV6:
810
0
        return "srv6";
811
812
0
    case OVS_VPORT_TYPE_BAREUDP:
813
0
        return "bareudp";
814
815
0
    case OVS_VPORT_TYPE_UNSPEC:
816
0
    case __OVS_VPORT_TYPE_MAX:
817
0
        break;
818
0
    }
819
820
0
    VLOG_WARN_RL(&rl, "dp%d: port `%s' has unsupported type %u",
821
0
                 vport->dp_ifindex, vport->name, (unsigned int) vport->type);
822
0
    return "unknown";
823
0
}
824
825
enum ovs_vport_type
826
netdev_to_ovs_vport_type(const char *type)
827
0
{
828
0
    if (!strcmp(type, "tap") || !strcmp(type, "system")) {
829
0
        return OVS_VPORT_TYPE_NETDEV;
830
0
    } else if (!strcmp(type, "internal")) {
831
0
        return OVS_VPORT_TYPE_INTERNAL;
832
0
    } else if (!strcmp(type, "geneve")) {
833
0
        return OVS_VPORT_TYPE_GENEVE;
834
0
    } else if (!strcmp(type, "vxlan")) {
835
0
        return OVS_VPORT_TYPE_VXLAN;
836
0
    } else if (!strcmp(type, "erspan")) {
837
0
        return OVS_VPORT_TYPE_ERSPAN;
838
0
    } else if (!strcmp(type, "ip6erspan")) {
839
0
        return OVS_VPORT_TYPE_IP6ERSPAN;
840
0
    } else if (!strcmp(type, "ip6gre")) {
841
0
        return OVS_VPORT_TYPE_IP6GRE;
842
0
    } else if (!strcmp(type, "gre")) {
843
0
        return OVS_VPORT_TYPE_GRE;
844
0
    } else if (!strcmp(type, "gtpu")) {
845
0
        return OVS_VPORT_TYPE_GTPU;
846
0
    } else if (!strcmp(type, "srv6")) {
847
0
        return OVS_VPORT_TYPE_SRV6;
848
0
    } else if (!strcmp(type, "bareudp")) {
849
0
        return OVS_VPORT_TYPE_BAREUDP;
850
0
    } else {
851
0
        return OVS_VPORT_TYPE_UNSPEC;
852
0
    }
853
0
}
854
855
static int
856
dpif_netlink_port_add__(struct dpif_netlink *dpif, const char *name,
857
                        enum ovs_vport_type type, odp_port_t *port_nop)
858
    OVS_REQ_WRLOCK(dpif->upcall_lock)
859
0
{
860
0
    struct dpif_netlink_vport request, reply;
861
0
    struct ofpbuf *buf;
862
0
    struct nl_sock *sock = NULL;
863
0
    uint32_t upcall_pids = 0;
864
0
    int error = 0;
865
866
    /* per-cpu dispatch mode does not require a socket per vport. */
867
0
    if (!dpif_netlink_upcall_per_cpu(dpif)) {
868
0
        if (dpif->handlers) {
869
0
            error = create_nl_sock(dpif, &sock);
870
0
            if (error) {
871
0
                return error;
872
0
            }
873
0
        }
874
0
        if (sock) {
875
0
            upcall_pids = nl_sock_pid(sock);
876
0
        }
877
0
    }
878
879
0
    dpif_netlink_vport_init(&request);
880
0
    request.cmd = OVS_VPORT_CMD_NEW;
881
0
    request.dp_ifindex = dpif->dp_ifindex;
882
0
    request.type = type;
883
0
    request.name = name;
884
885
0
    request.port_no = *port_nop;
886
0
    request.n_upcall_pids = 1;
887
0
    request.upcall_pids = &upcall_pids;
888
889
0
    error = dpif_netlink_vport_transact(&request, &reply, &buf);
890
0
    if (!error) {
891
0
        *port_nop = reply.port_no;
892
0
    } else {
893
0
        if (error == EBUSY && *port_nop != ODPP_NONE) {
894
0
            VLOG_INFO("%s: requested port %"PRIu32" is in use",
895
0
                      dpif_name(&dpif->dpif), *port_nop);
896
0
        }
897
898
0
        close_nl_sock(sock);
899
0
        goto exit;
900
0
    }
901
902
0
    if (!dpif_netlink_upcall_per_cpu(dpif)) {
903
0
        error = vport_add_channel(dpif, *port_nop, sock);
904
0
        if (error) {
905
0
            VLOG_INFO("%s: could not add channel for port %s",
906
0
                        dpif_name(&dpif->dpif), name);
907
908
            /* Delete the port. */
909
0
            dpif_netlink_vport_init(&request);
910
0
            request.cmd = OVS_VPORT_CMD_DEL;
911
0
            request.dp_ifindex = dpif->dp_ifindex;
912
0
            request.port_no = *port_nop;
913
0
            dpif_netlink_vport_transact(&request, NULL, NULL);
914
0
            close_nl_sock(sock);
915
0
            goto exit;
916
0
        }
917
0
    }
918
919
0
exit:
920
0
    ofpbuf_delete(buf);
921
922
0
    return error;
923
0
}
924
925
static int
926
dpif_netlink_port_add(struct dpif *dpif_, struct netdev *netdev,
927
                      odp_port_t *port_nop)
928
0
{
929
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
930
0
    const char *type = netdev_get_type(netdev);
931
0
    char namebuf[NETDEV_VPORT_NAME_BUFSIZE];
932
0
    enum ovs_vport_type ovs_type;
933
0
    const char *name;
934
0
    bool is_tunnel;
935
0
    int error;
936
937
0
    fat_rwlock_wrlock(&dpif->upcall_lock);
938
939
0
    name = netdev_vport_get_dpif_port(netdev, namebuf, sizeof namebuf);
940
0
    is_tunnel = netdev_get_tunnel_config(netdev) != NULL;
941
942
0
    if (is_tunnel) {
943
        /* Tunnel port: create the tunnel device via rtnetlink then add it
944
         * as OVS_VPORT_TYPE_NETDEV. */
945
0
        error = dpif_netlink_rtnl_tunnel_create(netdev);
946
0
        if (error) {
947
0
            if (error != EOPNOTSUPP) {
948
0
                VLOG_WARN_RL(&error_rl,
949
0
                             "Failed to create %s with rtnetlink: %s",
950
0
                             netdev_get_name(netdev), ovs_strerror(error));
951
0
            }
952
0
            goto out;
953
0
        }
954
0
        ovs_type = OVS_VPORT_TYPE_NETDEV;
955
0
    } else {
956
0
        ovs_type = netdev_to_ovs_vport_type(type);
957
0
        if (ovs_type == OVS_VPORT_TYPE_UNSPEC) {
958
0
            VLOG_WARN_RL(&error_rl, "%s: cannot create port '%s' "
959
0
                         "because it has unsupported type '%s'",
960
0
                         dpif_name(&dpif->dpif), name, type);
961
0
            error = EINVAL;
962
0
            goto out;
963
0
        }
964
0
        if (ovs_type == OVS_VPORT_TYPE_NETDEV) {
965
0
            netdev_linux_ethtool_set_flag(netdev, ETH_FLAG_LRO, "LRO", false);
966
0
        }
967
0
    }
968
969
0
    error = dpif_netlink_port_add__(dpif, name, ovs_type, port_nop);
970
0
    if (error && is_tunnel) {
971
0
        dpif_netlink_rtnl_tunnel_destroy(name, type);
972
0
    }
973
974
0
out:
975
0
    fat_rwlock_unlock(&dpif->upcall_lock);
976
0
    return error;
977
0
}
978
979
static int
980
dpif_netlink_port_del(struct dpif *dpif_, odp_port_t port_no)
981
0
{
982
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
983
0
    struct dpif_netlink_vport vport;
984
0
    struct dpif_port dpif_port;
985
0
    int error;
986
987
0
    fat_rwlock_wrlock(&dpif->upcall_lock);
988
0
    error = dpif_netlink_port_query__(dpif, port_no, NULL, &dpif_port);
989
0
    if (error) {
990
0
        goto out;
991
0
    }
992
993
0
    dpif_netlink_vport_init(&vport);
994
0
    vport.cmd = OVS_VPORT_CMD_DEL;
995
0
    vport.dp_ifindex = dpif->dp_ifindex;
996
0
    vport.port_no = port_no;
997
998
0
    error = dpif_netlink_vport_transact(&vport, NULL, NULL);
999
1000
0
    vport_del_channels(dpif, port_no);
1001
1002
0
    if (!error) {
1003
0
        error = dpif_netlink_rtnl_tunnel_destroy(dpif_port.name,
1004
0
                                                 dpif_port.type);
1005
0
        if (error == EOPNOTSUPP) {
1006
0
            error = 0;
1007
0
        }
1008
0
    }
1009
1010
0
    dpif_port_destroy(&dpif_port);
1011
1012
0
out:
1013
0
    fat_rwlock_unlock(&dpif->upcall_lock);
1014
0
    return error;
1015
0
}
1016
1017
static int
1018
dpif_netlink_port_query__(const struct dpif_netlink *dpif, odp_port_t port_no,
1019
                          const char *port_name, struct dpif_port *dpif_port)
1020
0
{
1021
0
    struct dpif_netlink_vport request;
1022
0
    struct dpif_netlink_vport reply;
1023
0
    struct ofpbuf *buf;
1024
0
    int error;
1025
1026
0
    dpif_netlink_vport_init(&request);
1027
0
    request.cmd = OVS_VPORT_CMD_GET;
1028
0
    request.dp_ifindex = dpif->dp_ifindex;
1029
0
    request.port_no = port_no;
1030
0
    request.name = port_name;
1031
1032
0
    error = dpif_netlink_vport_transact(&request, &reply, &buf);
1033
0
    if (!error) {
1034
0
        if (reply.dp_ifindex != request.dp_ifindex) {
1035
            /* A query by name reported that 'port_name' is in some datapath
1036
             * other than 'dpif', but the caller wants to know about 'dpif'. */
1037
0
            error = ENODEV;
1038
0
        } else if (dpif_port) {
1039
0
            dpif_port->name = xstrdup(reply.name);
1040
0
            dpif_port->type = xstrdup(get_vport_type(&reply));
1041
0
            dpif_port->port_no = reply.port_no;
1042
0
        }
1043
0
        ofpbuf_delete(buf);
1044
0
    }
1045
0
    return error;
1046
0
}
1047
1048
static int
1049
dpif_netlink_port_query_by_number(const struct dpif *dpif_, odp_port_t port_no,
1050
                                  struct dpif_port *dpif_port)
1051
0
{
1052
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
1053
1054
0
    return dpif_netlink_port_query__(dpif, port_no, NULL, dpif_port);
1055
0
}
1056
1057
static int
1058
dpif_netlink_port_query_by_name(const struct dpif *dpif_, const char *devname,
1059
                              struct dpif_port *dpif_port)
1060
0
{
1061
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
1062
1063
0
    return dpif_netlink_port_query__(dpif, 0, devname, dpif_port);
1064
0
}
1065
1066
static uint32_t
1067
dpif_netlink_port_get_pid__(const struct dpif_netlink *dpif,
1068
                            odp_port_t port_no)
1069
    OVS_REQ_RDLOCK(dpif->upcall_lock)
1070
0
{
1071
0
    uint32_t port_idx = odp_to_u32(port_no);
1072
0
    uint32_t pid = 0;
1073
1074
0
    if (dpif->handlers && dpif->uc_array_size > 0) {
1075
        /* The ODPP_NONE "reserved" port number uses the "ovs-system"'s
1076
         * channel, since it is not heavily loaded. */
1077
0
        uint32_t idx = port_idx >= dpif->uc_array_size ? 0 : port_idx;
1078
1079
        /* Needs to check in case the socket pointer is changed in between
1080
         * the holding of upcall_lock.  A known case happens when the main
1081
         * thread deletes the vport while the handler thread is handling
1082
         * the upcall from that port. */
1083
0
        if (dpif->channels[idx].sock) {
1084
0
            pid = nl_sock_pid(dpif->channels[idx].sock);
1085
0
        }
1086
0
    }
1087
1088
0
    return pid;
1089
0
}
1090
1091
static uint32_t
1092
dpif_netlink_port_get_pid(const struct dpif *dpif_, odp_port_t port_no)
1093
0
{
1094
0
    const struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
1095
0
    uint32_t ret;
1096
1097
    /* In per-cpu dispatch mode, vports do not have an associated PID */
1098
0
    if (dpif_netlink_upcall_per_cpu(dpif)) {
1099
        /* In per-cpu dispatch mode, this will be ignored as kernel space will
1100
         * select the PID before sending to user space. We set to
1101
         * DPIF_NETLINK_PER_CPU_PID as 0 is rejected by kernel space as an
1102
         * invalid PID.
1103
         */
1104
0
        return DPIF_NETLINK_PER_CPU_PID;
1105
0
    }
1106
1107
0
    fat_rwlock_rdlock(&dpif->upcall_lock);
1108
0
    ret = dpif_netlink_port_get_pid__(dpif, port_no);
1109
0
    fat_rwlock_unlock(&dpif->upcall_lock);
1110
1111
0
    return ret;
1112
0
}
1113
1114
static int
1115
dpif_netlink_flow_flush(struct dpif *dpif_)
1116
0
{
1117
0
    const struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
1118
0
    struct dpif_netlink_flow flow;
1119
1120
0
    dpif_netlink_flow_init(&flow);
1121
0
    flow.cmd = OVS_FLOW_CMD_DEL;
1122
0
    flow.dp_ifindex = dpif->dp_ifindex;
1123
1124
0
    return dpif_netlink_flow_transact(&flow, NULL, NULL);
1125
0
}
1126
1127
struct dpif_netlink_port_state {
1128
    struct nl_dump dump;
1129
    struct ofpbuf buf;
1130
};
1131
1132
static void
1133
dpif_netlink_port_dump_start__(const struct dpif_netlink *dpif,
1134
                               struct nl_dump *dump)
1135
0
{
1136
0
    struct dpif_netlink_vport request;
1137
0
    struct ofpbuf *buf;
1138
1139
0
    dpif_netlink_vport_init(&request);
1140
0
    request.cmd = OVS_VPORT_CMD_GET;
1141
0
    request.dp_ifindex = dpif->dp_ifindex;
1142
1143
0
    buf = ofpbuf_new(1024);
1144
0
    dpif_netlink_vport_to_ofpbuf(&request, buf);
1145
0
    nl_dump_start(dump, NETLINK_GENERIC, buf);
1146
0
    ofpbuf_delete(buf);
1147
0
}
1148
1149
static int
1150
dpif_netlink_port_dump_start(const struct dpif *dpif_, void **statep)
1151
0
{
1152
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
1153
0
    struct dpif_netlink_port_state *state;
1154
1155
0
    *statep = state = xmalloc(sizeof *state);
1156
0
    dpif_netlink_port_dump_start__(dpif, &state->dump);
1157
1158
0
    ofpbuf_init(&state->buf, NL_DUMP_BUFSIZE);
1159
0
    return 0;
1160
0
}
1161
1162
static int
1163
dpif_netlink_port_dump_next__(const struct dpif_netlink *dpif,
1164
                              struct nl_dump *dump,
1165
                              struct dpif_netlink_vport *vport,
1166
                              struct ofpbuf *buffer)
1167
0
{
1168
0
    struct ofpbuf buf;
1169
0
    int error;
1170
1171
0
    if (!nl_dump_next(dump, &buf, buffer)) {
1172
0
        return EOF;
1173
0
    }
1174
1175
0
    error = dpif_netlink_vport_from_ofpbuf(vport, &buf);
1176
0
    if (error) {
1177
0
        VLOG_WARN_RL(&error_rl, "%s: failed to parse vport record (%s)",
1178
0
                     dpif_name(&dpif->dpif), ovs_strerror(error));
1179
0
    }
1180
0
    return error;
1181
0
}
1182
1183
static int
1184
dpif_netlink_port_dump_next(const struct dpif *dpif_, void *state_,
1185
                            struct dpif_port *dpif_port)
1186
0
{
1187
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
1188
0
    struct dpif_netlink_port_state *state = state_;
1189
0
    struct dpif_netlink_vport vport;
1190
0
    int error;
1191
1192
0
    error = dpif_netlink_port_dump_next__(dpif, &state->dump, &vport,
1193
0
                                          &state->buf);
1194
0
    if (error) {
1195
0
        return error;
1196
0
    }
1197
0
    dpif_port->name = CONST_CAST(char *, vport.name);
1198
0
    dpif_port->type = CONST_CAST(char *, get_vport_type(&vport));
1199
0
    dpif_port->port_no = vport.port_no;
1200
0
    return 0;
1201
0
}
1202
1203
static int
1204
dpif_netlink_port_dump_done(const struct dpif *dpif_ OVS_UNUSED, void *state_)
1205
0
{
1206
0
    struct dpif_netlink_port_state *state = state_;
1207
0
    int error = nl_dump_done(&state->dump);
1208
1209
0
    ofpbuf_uninit(&state->buf);
1210
0
    free(state);
1211
0
    return error;
1212
0
}
1213
1214
static int
1215
dpif_netlink_port_poll(const struct dpif *dpif_, char **devnamep)
1216
0
{
1217
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
1218
1219
    /* Lazily create the Netlink socket to listen for notifications. */
1220
0
    if (!dpif->port_notifier) {
1221
0
        struct nl_sock *sock;
1222
0
        int error;
1223
1224
0
        error = nl_sock_create(NETLINK_GENERIC, &sock);
1225
0
        if (error) {
1226
0
            return error;
1227
0
        }
1228
1229
0
        error = nl_sock_join_mcgroup(sock, ovs_vport_mcgroup);
1230
0
        if (error) {
1231
0
            nl_sock_destroy(sock);
1232
0
            return error;
1233
0
        }
1234
0
        dpif->port_notifier = sock;
1235
1236
        /* We have no idea of the current state so report that everything
1237
         * changed. */
1238
0
        return ENOBUFS;
1239
0
    }
1240
1241
0
    for (;;) {
1242
0
        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
1243
0
        uint64_t buf_stub[4096 / 8];
1244
0
        struct ofpbuf buf;
1245
0
        int error;
1246
1247
0
        ofpbuf_use_stub(&buf, buf_stub, sizeof buf_stub);
1248
0
        error = nl_sock_recv(dpif->port_notifier, &buf, NULL, false);
1249
0
        if (!error) {
1250
0
            struct dpif_netlink_vport vport;
1251
1252
0
            error = dpif_netlink_vport_from_ofpbuf(&vport, &buf);
1253
0
            if (!error) {
1254
0
                if (vport.dp_ifindex == dpif->dp_ifindex
1255
0
                    && (vport.cmd == OVS_VPORT_CMD_NEW
1256
0
                        || vport.cmd == OVS_VPORT_CMD_DEL
1257
0
                        || vport.cmd == OVS_VPORT_CMD_SET)) {
1258
0
                    VLOG_DBG("port_changed: dpif:%s vport:%s cmd:%"PRIu8,
1259
0
                             dpif->dpif.full_name, vport.name, vport.cmd);
1260
0
                    if (vport.cmd == OVS_VPORT_CMD_DEL && dpif->handlers) {
1261
0
                        dpif->refresh_channels = true;
1262
0
                    }
1263
0
                    *devnamep = xstrdup(vport.name);
1264
0
                    ofpbuf_uninit(&buf);
1265
0
                    return 0;
1266
0
                }
1267
0
            }
1268
0
        } else if (error != EAGAIN) {
1269
0
            VLOG_WARN_RL(&rl, "error reading or parsing netlink (%s)",
1270
0
                         ovs_strerror(error));
1271
0
            nl_sock_drain(dpif->port_notifier);
1272
0
            error = ENOBUFS;
1273
0
        }
1274
1275
0
        ofpbuf_uninit(&buf);
1276
0
        if (error) {
1277
0
            return error;
1278
0
        }
1279
0
    }
1280
0
}
1281
1282
static void
1283
dpif_netlink_port_poll_wait(const struct dpif *dpif_)
1284
0
{
1285
0
    const struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
1286
1287
0
    if (dpif->port_notifier) {
1288
0
        nl_sock_wait(dpif->port_notifier, POLLIN);
1289
0
    } else {
1290
0
        poll_immediate_wake();
1291
0
    }
1292
0
}
1293
1294
static void
1295
dpif_netlink_flow_init_ufid(struct dpif_netlink_flow *request,
1296
                            const ovs_u128 *ufid, bool terse)
1297
0
{
1298
0
    if (ufid) {
1299
0
        request->ufid = *ufid;
1300
0
        request->ufid_present = true;
1301
0
    } else {
1302
0
        request->ufid_present = false;
1303
0
    }
1304
0
    request->ufid_terse = terse;
1305
0
}
1306
1307
static void
1308
dpif_netlink_init_flow_get__(const struct dpif_netlink *dpif,
1309
                             const struct nlattr *key, size_t key_len,
1310
                             const ovs_u128 *ufid, bool terse,
1311
                             struct dpif_netlink_flow *request)
1312
0
{
1313
0
    dpif_netlink_flow_init(request);
1314
0
    request->cmd = OVS_FLOW_CMD_GET;
1315
0
    request->dp_ifindex = dpif->dp_ifindex;
1316
0
    request->key = key;
1317
0
    request->key_len = key_len;
1318
0
    dpif_netlink_flow_init_ufid(request, ufid, terse);
1319
0
}
1320
1321
static void
1322
dpif_netlink_init_flow_get(const struct dpif_netlink *dpif,
1323
                           const struct dpif_flow_get *get,
1324
                           struct dpif_netlink_flow *request)
1325
0
{
1326
0
    dpif_netlink_init_flow_get__(dpif, get->key, get->key_len, get->ufid,
1327
0
                                 false, request);
1328
0
}
1329
1330
static int
1331
dpif_netlink_flow_get__(const struct dpif_netlink *dpif,
1332
                        const struct nlattr *key, size_t key_len,
1333
                        const ovs_u128 *ufid, bool terse,
1334
                        struct dpif_netlink_flow *reply, struct ofpbuf **bufp)
1335
0
{
1336
0
    struct dpif_netlink_flow request;
1337
1338
0
    dpif_netlink_init_flow_get__(dpif, key, key_len, ufid, terse, &request);
1339
0
    return dpif_netlink_flow_transact(&request, reply, bufp);
1340
0
}
1341
1342
static int
1343
dpif_netlink_flow_get(const struct dpif_netlink *dpif,
1344
                      const struct dpif_netlink_flow *flow,
1345
                      struct dpif_netlink_flow *reply, struct ofpbuf **bufp)
1346
0
{
1347
0
    return dpif_netlink_flow_get__(dpif, flow->key, flow->key_len,
1348
0
                                   flow->ufid_present ? &flow->ufid : NULL,
1349
0
                                   false, reply, bufp);
1350
0
}
1351
1352
static void
1353
dpif_netlink_init_flow_put(struct dpif_netlink *dpif,
1354
                           const struct dpif_flow_put *put,
1355
                           struct dpif_netlink_flow *request)
1356
0
{
1357
0
    static const struct nlattr dummy_action;
1358
1359
0
    dpif_netlink_flow_init(request);
1360
0
    request->cmd = (put->flags & DPIF_FP_CREATE
1361
0
                    ? OVS_FLOW_CMD_NEW : OVS_FLOW_CMD_SET);
1362
0
    request->dp_ifindex = dpif->dp_ifindex;
1363
0
    request->key = put->key;
1364
0
    request->key_len = put->key_len;
1365
0
    request->mask = put->mask;
1366
0
    request->mask_len = put->mask_len;
1367
0
    dpif_netlink_flow_init_ufid(request, put->ufid, false);
1368
1369
    /* Ensure that OVS_FLOW_ATTR_ACTIONS will always be included. */
1370
0
    request->actions = (put->actions
1371
0
                        ? put->actions
1372
0
                        : CONST_CAST(struct nlattr *, &dummy_action));
1373
0
    request->actions_len = put->actions_len;
1374
0
    if (put->flags & DPIF_FP_ZERO_STATS) {
1375
0
        request->clear = true;
1376
0
    }
1377
0
    if (put->flags & DPIF_FP_PROBE) {
1378
0
        request->probe = true;
1379
0
    }
1380
0
    request->nlmsg_flags = put->flags & DPIF_FP_MODIFY ? 0 : NLM_F_CREATE;
1381
0
}
1382
1383
static void
1384
dpif_netlink_init_flow_del__(struct dpif_netlink *dpif,
1385
                             const struct nlattr *key, size_t key_len,
1386
                             const ovs_u128 *ufid, bool terse,
1387
                             struct dpif_netlink_flow *request)
1388
0
{
1389
0
    dpif_netlink_flow_init(request);
1390
0
    request->cmd = OVS_FLOW_CMD_DEL;
1391
0
    request->dp_ifindex = dpif->dp_ifindex;
1392
0
    request->key = key;
1393
0
    request->key_len = key_len;
1394
0
    dpif_netlink_flow_init_ufid(request, ufid, terse);
1395
0
}
1396
1397
static void
1398
dpif_netlink_init_flow_del(struct dpif_netlink *dpif,
1399
                           const struct dpif_flow_del *del,
1400
                           struct dpif_netlink_flow *request)
1401
0
{
1402
0
    dpif_netlink_init_flow_del__(dpif, del->key, del->key_len,
1403
0
                                 del->ufid, del->terse, request);
1404
0
}
1405
1406
struct dpif_netlink_flow_dump {
1407
    struct dpif_flow_dump up;
1408
    struct nl_dump nl_dump;
1409
    atomic_int status;
1410
};
1411
1412
static struct dpif_netlink_flow_dump *
1413
dpif_netlink_flow_dump_cast(struct dpif_flow_dump *dump)
1414
0
{
1415
0
    return CONTAINER_OF(dump, struct dpif_netlink_flow_dump, up);
1416
0
}
1417
1418
static struct dpif_flow_dump *
1419
dpif_netlink_flow_dump_create(const struct dpif *dpif_, bool terse,
1420
                              struct dpif_flow_dump_types *types)
1421
0
{
1422
0
    const struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
1423
0
    struct dpif_netlink_flow_dump *dump;
1424
0
    struct dpif_netlink_flow request;
1425
0
    struct ofpbuf *buf;
1426
1427
0
    dump = xmalloc(sizeof *dump);
1428
0
    dpif_flow_dump_init(&dump->up, dpif_, terse, types);
1429
1430
0
    dpif_netlink_flow_init(&request);
1431
0
    request.cmd = OVS_FLOW_CMD_GET;
1432
0
    request.dp_ifindex = dpif->dp_ifindex;
1433
0
    request.ufid_present = false;
1434
0
    request.ufid_terse = terse;
1435
1436
0
    buf = ofpbuf_new(1024);
1437
0
    dpif_netlink_flow_to_ofpbuf(&request, buf);
1438
0
    nl_dump_start(&dump->nl_dump, NETLINK_GENERIC, buf);
1439
0
    ofpbuf_delete(buf);
1440
0
    atomic_init(&dump->status, 0);
1441
1442
0
    return &dump->up;
1443
0
}
1444
1445
static int
1446
dpif_netlink_flow_dump_destroy(struct dpif_flow_dump *dump_)
1447
0
{
1448
0
    struct dpif_netlink_flow_dump *dump = dpif_netlink_flow_dump_cast(dump_);
1449
0
    unsigned int nl_status = nl_dump_done(&dump->nl_dump);
1450
0
    int dump_status;
1451
1452
    /* No other thread has access to 'dump' at this point. */
1453
0
    atomic_read_relaxed(&dump->status, &dump_status);
1454
0
    free(dump);
1455
0
    return dump_status ? dump_status : nl_status;
1456
0
}
1457
1458
struct dpif_netlink_flow_dump_thread {
1459
    struct dpif_flow_dump_thread up;
1460
    struct dpif_netlink_flow_dump *dump;
1461
    struct dpif_netlink_flow flow;
1462
    struct dpif_flow_stats stats;
1463
    struct ofpbuf nl_flows;     /* Always used to store flows. */
1464
    struct ofpbuf *nl_actions;  /* Used if kernel does not supply actions. */
1465
};
1466
1467
static struct dpif_netlink_flow_dump_thread *
1468
dpif_netlink_flow_dump_thread_cast(struct dpif_flow_dump_thread *thread)
1469
0
{
1470
0
    return CONTAINER_OF(thread, struct dpif_netlink_flow_dump_thread, up);
1471
0
}
1472
1473
static struct dpif_flow_dump_thread *
1474
dpif_netlink_flow_dump_thread_create(struct dpif_flow_dump *dump_)
1475
0
{
1476
0
    struct dpif_netlink_flow_dump *dump = dpif_netlink_flow_dump_cast(dump_);
1477
0
    struct dpif_netlink_flow_dump_thread *thread;
1478
1479
0
    thread = xmalloc(sizeof *thread);
1480
0
    dpif_flow_dump_thread_init(&thread->up, &dump->up);
1481
0
    thread->dump = dump;
1482
0
    ofpbuf_init(&thread->nl_flows, NL_DUMP_BUFSIZE);
1483
0
    thread->nl_actions = NULL;
1484
1485
0
    return &thread->up;
1486
0
}
1487
1488
static void
1489
dpif_netlink_flow_dump_thread_destroy(struct dpif_flow_dump_thread *thread_)
1490
0
{
1491
0
    struct dpif_netlink_flow_dump_thread *thread
1492
0
        = dpif_netlink_flow_dump_thread_cast(thread_);
1493
1494
0
    ofpbuf_uninit(&thread->nl_flows);
1495
0
    ofpbuf_delete(thread->nl_actions);
1496
0
    free(thread);
1497
0
}
1498
1499
static void
1500
dpif_netlink_flow_to_dpif_flow(struct dpif_flow *dpif_flow,
1501
                               const struct dpif_netlink_flow *datapath_flow)
1502
0
{
1503
0
    dpif_flow->key = datapath_flow->key;
1504
0
    dpif_flow->key_len = datapath_flow->key_len;
1505
0
    dpif_flow->mask = datapath_flow->mask;
1506
0
    dpif_flow->mask_len = datapath_flow->mask_len;
1507
0
    dpif_flow->actions = datapath_flow->actions;
1508
0
    dpif_flow->actions_len = datapath_flow->actions_len;
1509
0
    dpif_flow->ufid_present = datapath_flow->ufid_present;
1510
0
    dpif_flow->pmd_id = PMD_ID_NULL;
1511
0
    if (datapath_flow->ufid_present) {
1512
0
        dpif_flow->ufid = datapath_flow->ufid;
1513
0
    } else {
1514
0
        ovs_assert(datapath_flow->key && datapath_flow->key_len);
1515
0
        odp_flow_key_hash(datapath_flow->key, datapath_flow->key_len,
1516
0
                          &dpif_flow->ufid);
1517
0
    }
1518
0
    dpif_netlink_flow_get_stats(datapath_flow, &dpif_flow->stats);
1519
0
    dpif_flow->attrs.offloaded = false;
1520
0
    dpif_flow->attrs.dp_layer = "ovs";
1521
0
    dpif_flow->attrs.dp_extra_info = NULL;
1522
0
}
1523
1524
static int
1525
dpif_netlink_flow_dump_next(struct dpif_flow_dump_thread *thread_,
1526
                            struct dpif_flow *flows, int max_flows)
1527
0
{
1528
0
    struct dpif_netlink_flow_dump_thread *thread
1529
0
        = dpif_netlink_flow_dump_thread_cast(thread_);
1530
0
    struct dpif_netlink_flow_dump *dump = thread->dump;
1531
0
    struct dpif_netlink *dpif = dpif_netlink_cast(thread->up.dump->dpif);
1532
0
    int n_flows = 0;
1533
1534
0
    ofpbuf_delete(thread->nl_actions);
1535
0
    thread->nl_actions = NULL;
1536
1537
0
    while (!n_flows
1538
0
           || (n_flows < max_flows && thread->nl_flows.size)) {
1539
0
        struct dpif_netlink_flow datapath_flow;
1540
0
        struct ofpbuf nl_flow;
1541
0
        int error;
1542
1543
        /* Try to grab another flow. */
1544
0
        if (!nl_dump_next(&dump->nl_dump, &nl_flow, &thread->nl_flows)) {
1545
0
            break;
1546
0
        }
1547
1548
        /* Convert the flow to our output format. */
1549
0
        error = dpif_netlink_flow_from_ofpbuf(&datapath_flow, &nl_flow);
1550
0
        if (error) {
1551
0
            atomic_store_relaxed(&dump->status, error);
1552
0
            break;
1553
0
        }
1554
1555
0
        if (dump->up.terse || datapath_flow.actions) {
1556
            /* Common case: we don't want actions, or the flow includes
1557
             * actions. */
1558
0
            dpif_netlink_flow_to_dpif_flow(&flows[n_flows++], &datapath_flow);
1559
0
        } else {
1560
            /* Rare case: the flow does not include actions.  Retrieve this
1561
             * individual flow again to get the actions. */
1562
0
            error = dpif_netlink_flow_get(dpif, &datapath_flow,
1563
0
                                          &datapath_flow, &thread->nl_actions);
1564
0
            if (error == ENOENT) {
1565
0
                VLOG_DBG("dumped flow disappeared on get");
1566
0
                continue;
1567
0
            } else if (error) {
1568
0
                VLOG_WARN("error fetching dumped flow: %s",
1569
0
                          ovs_strerror(error));
1570
0
                atomic_store_relaxed(&dump->status, error);
1571
0
                break;
1572
0
            }
1573
1574
            /* Save this flow.  Then exit, because we only have one buffer to
1575
             * handle this case. */
1576
0
            dpif_netlink_flow_to_dpif_flow(&flows[n_flows++], &datapath_flow);
1577
0
            break;
1578
0
        }
1579
0
    }
1580
0
    return n_flows;
1581
0
}
1582
1583
static void
1584
dpif_netlink_encode_execute(int dp_ifindex, const struct dpif_execute *d_exec,
1585
                            struct ofpbuf *buf)
1586
0
{
1587
0
    struct ovs_header *k_exec;
1588
0
    size_t key_ofs;
1589
1590
0
    ofpbuf_prealloc_tailroom(buf, (64
1591
0
                                   + dp_packet_size(d_exec->packet)
1592
0
                                   + ODP_KEY_METADATA_SIZE
1593
0
                                   + d_exec->actions_len));
1594
1595
0
    nl_msg_put_genlmsghdr(buf, 0, ovs_packet_family, NLM_F_REQUEST,
1596
0
                          OVS_PACKET_CMD_EXECUTE, OVS_PACKET_VERSION);
1597
1598
0
    k_exec = ofpbuf_put_uninit(buf, sizeof *k_exec);
1599
0
    k_exec->dp_ifindex = dp_ifindex;
1600
1601
0
    nl_msg_put_unspec(buf, OVS_PACKET_ATTR_PACKET,
1602
0
                      dp_packet_data(d_exec->packet),
1603
0
                      dp_packet_size(d_exec->packet));
1604
1605
0
    key_ofs = nl_msg_start_nested(buf, OVS_PACKET_ATTR_KEY);
1606
0
    odp_key_from_dp_packet(buf, d_exec->packet);
1607
0
    nl_msg_end_nested(buf, key_ofs);
1608
1609
0
    nl_msg_put_unspec(buf, OVS_PACKET_ATTR_ACTIONS,
1610
0
                      d_exec->actions, d_exec->actions_len);
1611
0
    if (d_exec->probe) {
1612
0
        nl_msg_put_flag(buf, OVS_PACKET_ATTR_PROBE);
1613
0
    }
1614
0
    if (d_exec->mtu) {
1615
0
        nl_msg_put_u16(buf, OVS_PACKET_ATTR_MRU, d_exec->mtu);
1616
0
    }
1617
1618
0
    if (d_exec->hash) {
1619
0
        nl_msg_put_u64(buf, OVS_PACKET_ATTR_HASH, d_exec->hash);
1620
0
    }
1621
1622
0
    if (d_exec->upcall_pid) {
1623
0
        nl_msg_put_u32(buf, OVS_PACKET_ATTR_UPCALL_PID, d_exec->upcall_pid);
1624
0
    }
1625
0
}
1626
1627
/* Executes, against 'dpif', up to the first 'n_ops' operations in 'ops'.
1628
 * Returns the number actually executed (at least 1, if 'n_ops' is
1629
 * positive). */
1630
static size_t
1631
dpif_netlink_operate__(struct dpif_netlink *dpif,
1632
                       struct dpif_op **ops, size_t n_ops)
1633
0
{
1634
0
    struct op_auxdata {
1635
0
        struct nl_transaction txn;
1636
1637
0
        struct ofpbuf request;
1638
0
        uint64_t request_stub[1024 / 8];
1639
1640
0
        struct ofpbuf reply;
1641
0
        uint64_t reply_stub[1024 / 8];
1642
0
    } auxes[OPERATE_MAX_OPS];
1643
1644
0
    struct nl_transaction *txnsp[OPERATE_MAX_OPS];
1645
0
    size_t i;
1646
1647
0
    n_ops = MIN(n_ops, OPERATE_MAX_OPS);
1648
0
    for (i = 0; i < n_ops; i++) {
1649
0
        struct op_auxdata *aux = &auxes[i];
1650
0
        struct dpif_op *op = ops[i];
1651
0
        struct dpif_flow_put *put;
1652
0
        struct dpif_flow_del *del;
1653
0
        struct dpif_flow_get *get;
1654
0
        struct dpif_netlink_flow flow;
1655
1656
0
        ofpbuf_use_stub(&aux->request,
1657
0
                        aux->request_stub, sizeof aux->request_stub);
1658
0
        aux->txn.request = &aux->request;
1659
1660
0
        ofpbuf_use_stub(&aux->reply, aux->reply_stub, sizeof aux->reply_stub);
1661
0
        aux->txn.reply = NULL;
1662
1663
0
        switch (op->type) {
1664
0
        case DPIF_OP_FLOW_PUT:
1665
0
            put = &op->flow_put;
1666
0
            dpif_netlink_init_flow_put(dpif, put, &flow);
1667
0
            if (put->stats) {
1668
0
                flow.nlmsg_flags |= NLM_F_ECHO;
1669
0
                aux->txn.reply = &aux->reply;
1670
0
            }
1671
0
            dpif_netlink_flow_to_ofpbuf(&flow, &aux->request);
1672
1673
0
            OVS_USDT_PROBE(dpif_netlink_operate__, op_flow_put,
1674
0
                           dpif, put, &flow, &aux->request);
1675
0
            break;
1676
1677
0
        case DPIF_OP_FLOW_DEL:
1678
0
            del = &op->flow_del;
1679
0
            dpif_netlink_init_flow_del(dpif, del, &flow);
1680
0
            if (del->stats) {
1681
0
                flow.nlmsg_flags |= NLM_F_ECHO;
1682
0
                aux->txn.reply = &aux->reply;
1683
0
            }
1684
0
            dpif_netlink_flow_to_ofpbuf(&flow, &aux->request);
1685
1686
0
            OVS_USDT_PROBE(dpif_netlink_operate__, op_flow_del,
1687
0
                           dpif, del, &flow, &aux->request);
1688
0
            break;
1689
1690
0
        case DPIF_OP_EXECUTE:
1691
            /* Can't execute a packet that won't fit in a Netlink attribute. */
1692
0
            if (OVS_UNLIKELY(nl_attr_oversized(
1693
0
                                 dp_packet_size(op->execute.packet)))) {
1694
                /* Report an error immediately if this is the first operation.
1695
                 * Otherwise the easiest thing to do is to postpone to the next
1696
                 * call (when this will be the first operation). */
1697
0
                if (i == 0) {
1698
0
                    VLOG_ERR_RL(&error_rl,
1699
0
                                "dropping oversized %"PRIu32"-byte packet",
1700
0
                                dp_packet_size(op->execute.packet));
1701
0
                    op->error = ENOBUFS;
1702
0
                    return 1;
1703
0
                }
1704
0
                n_ops = i;
1705
0
            } else {
1706
0
                dpif_netlink_encode_execute(dpif->dp_ifindex, &op->execute,
1707
0
                                            &aux->request);
1708
1709
0
                OVS_USDT_PROBE(dpif_netlink_operate__, op_flow_execute,
1710
0
                               dpif, &op->execute,
1711
0
                               dp_packet_data(op->execute.packet),
1712
0
                               dp_packet_size(op->execute.packet),
1713
0
                               &aux->request);
1714
0
            }
1715
0
            break;
1716
1717
0
        case DPIF_OP_FLOW_GET:
1718
0
            get = &op->flow_get;
1719
0
            dpif_netlink_init_flow_get(dpif, get, &flow);
1720
0
            aux->txn.reply = get->buffer;
1721
0
            dpif_netlink_flow_to_ofpbuf(&flow, &aux->request);
1722
1723
0
            OVS_USDT_PROBE(dpif_netlink_operate__, op_flow_get,
1724
0
                           dpif, get, &flow, &aux->request);
1725
0
            break;
1726
1727
0
        default:
1728
0
            OVS_NOT_REACHED();
1729
0
        }
1730
0
    }
1731
1732
0
    for (i = 0; i < n_ops; i++) {
1733
0
        txnsp[i] = &auxes[i].txn;
1734
0
    }
1735
0
    nl_transact_multiple(NETLINK_GENERIC, txnsp, n_ops);
1736
1737
0
    for (i = 0; i < n_ops; i++) {
1738
0
        struct op_auxdata *aux = &auxes[i];
1739
0
        struct nl_transaction *txn = &auxes[i].txn;
1740
0
        struct dpif_op *op = ops[i];
1741
0
        struct dpif_flow_put *put;
1742
0
        struct dpif_flow_del *del;
1743
0
        struct dpif_flow_get *get;
1744
1745
0
        op->error = txn->error;
1746
1747
0
        switch (op->type) {
1748
0
        case DPIF_OP_FLOW_PUT:
1749
0
            put = &op->flow_put;
1750
0
            if (put->stats) {
1751
0
                if (!op->error) {
1752
0
                    struct dpif_netlink_flow reply;
1753
1754
0
                    op->error = dpif_netlink_flow_from_ofpbuf(&reply,
1755
0
                                                              txn->reply);
1756
0
                    if (!op->error) {
1757
0
                        dpif_netlink_flow_get_stats(&reply, put->stats);
1758
0
                    }
1759
0
                }
1760
0
            }
1761
0
            break;
1762
1763
0
        case DPIF_OP_FLOW_DEL:
1764
0
            del = &op->flow_del;
1765
0
            if (del->stats) {
1766
0
                if (!op->error) {
1767
0
                    struct dpif_netlink_flow reply;
1768
1769
0
                    op->error = dpif_netlink_flow_from_ofpbuf(&reply,
1770
0
                                                              txn->reply);
1771
0
                    if (!op->error) {
1772
0
                        dpif_netlink_flow_get_stats(&reply, del->stats);
1773
0
                    }
1774
0
                }
1775
0
            }
1776
0
            break;
1777
1778
0
        case DPIF_OP_EXECUTE:
1779
0
            break;
1780
1781
0
        case DPIF_OP_FLOW_GET:
1782
0
            get = &op->flow_get;
1783
0
            if (!op->error) {
1784
0
                struct dpif_netlink_flow reply;
1785
1786
0
                op->error = dpif_netlink_flow_from_ofpbuf(&reply, txn->reply);
1787
0
                if (!op->error) {
1788
0
                    dpif_netlink_flow_to_dpif_flow(get->flow, &reply);
1789
0
                }
1790
0
            }
1791
0
            break;
1792
1793
0
        default:
1794
0
            OVS_NOT_REACHED();
1795
0
        }
1796
1797
0
        ofpbuf_uninit(&aux->request);
1798
0
        ofpbuf_uninit(&aux->reply);
1799
0
    }
1800
1801
0
    return n_ops;
1802
0
}
1803
1804
static void
1805
dpif_netlink_operate(struct dpif *dpif_, struct dpif_op **ops, size_t n_ops)
1806
0
{
1807
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
1808
1809
0
    while (n_ops > 0) {
1810
0
        size_t chunk = dpif_netlink_operate__(dpif, ops, n_ops);
1811
1812
0
        ops += chunk;
1813
0
        n_ops -= chunk;
1814
0
    }
1815
0
}
1816
1817
static int
1818
dpif_netlink_handler_init(struct dpif_handler *handler)
1819
0
{
1820
0
    handler->epoll_fd = epoll_create(10);
1821
0
    return handler->epoll_fd < 0 ? errno : 0;
1822
0
}
1823
1824
static void
1825
dpif_netlink_handler_uninit(struct dpif_handler *handler)
1826
0
{
1827
0
    close(handler->epoll_fd);
1828
0
}
1829
1830
/* Returns true if num is a prime number,
1831
 * otherwise, return false.
1832
 */
1833
static bool
1834
is_prime(uint32_t num)
1835
0
{
1836
0
    if (num == 2) {
1837
0
        return true;
1838
0
    }
1839
1840
0
    if (num < 2) {
1841
0
        return false;
1842
0
    }
1843
1844
0
    if (num % 2 == 0) {
1845
0
        return false;
1846
0
    }
1847
1848
0
    for (uint64_t i = 3; i * i <= num; i += 2) {
1849
0
        if (num % i == 0) {
1850
0
            return false;
1851
0
        }
1852
0
    }
1853
1854
0
    return true;
1855
0
}
1856
1857
/* Returns start if start is a prime number.  Otherwise returns the next
1858
 * prime greater than start.  Search is limited by UINT32_MAX.
1859
 *
1860
 * Returns 0 if no prime has been found between start and UINT32_MAX.
1861
 */
1862
static uint32_t
1863
next_prime(uint32_t start)
1864
0
{
1865
0
    if (start <= 2) {
1866
0
        return 2;
1867
0
    }
1868
1869
0
    for (uint32_t i = start; i < UINT32_MAX; i++) {
1870
0
        if (is_prime(i)) {
1871
0
            return i;
1872
0
        }
1873
0
    }
1874
1875
0
    return 0;
1876
0
}
1877
1878
/* Calculates and returns the number of handler threads needed based
1879
 * the following formula:
1880
 *
1881
 * handlers_n = min(next_prime(active_cores + 1), total_cores)
1882
 */
1883
static uint32_t
1884
dpif_netlink_calculate_n_handlers(void)
1885
0
{
1886
0
    uint32_t total_cores = count_total_cores();
1887
0
    uint32_t n_handlers = count_cpu_cores();
1888
0
    uint32_t next_prime_num;
1889
1890
    /* If not all cores are available to OVS, create additional handler
1891
     * threads to ensure more fair distribution of load between them.
1892
     */
1893
0
    if (n_handlers < total_cores && total_cores > 2) {
1894
0
        next_prime_num = next_prime(n_handlers + 1);
1895
0
        n_handlers = MIN(next_prime_num, total_cores);
1896
0
    }
1897
1898
0
    return MAX(n_handlers, 1);
1899
0
}
1900
1901
static int
1902
dpif_netlink_refresh_handlers_cpu_dispatch(struct dpif_netlink *dpif)
1903
    OVS_REQ_WRLOCK(dpif->upcall_lock)
1904
0
{
1905
0
    int handler_id;
1906
0
    int error = 0;
1907
0
    uint32_t n_handlers;
1908
0
    uint32_t *upcall_pids;
1909
1910
0
    n_handlers = dpif_netlink_calculate_n_handlers();
1911
0
    if (dpif->n_handlers != n_handlers) {
1912
0
        VLOG_DBG("Dispatch mode(per-cpu): initializing %d handlers",
1913
0
                   n_handlers);
1914
0
        destroy_all_handlers(dpif);
1915
0
        upcall_pids = xzalloc(n_handlers * sizeof *upcall_pids);
1916
0
        dpif->handlers = xzalloc(n_handlers * sizeof *dpif->handlers);
1917
0
        for (handler_id = 0; handler_id < n_handlers; handler_id++) {
1918
0
            struct dpif_handler *handler = &dpif->handlers[handler_id];
1919
0
            error = create_nl_sock(dpif, &handler->sock);
1920
0
            if (error) {
1921
0
                VLOG_ERR("Dispatch mode(per-cpu): Cannot create socket for"
1922
0
                         "handler %d", handler_id);
1923
0
                continue;
1924
0
            }
1925
0
            upcall_pids[handler_id] = nl_sock_pid(handler->sock);
1926
0
            VLOG_DBG("Dispatch mode(per-cpu): "
1927
0
                      "handler %d has Netlink PID of %u",
1928
0
                      handler_id, upcall_pids[handler_id]);
1929
0
        }
1930
1931
0
        dpif->n_handlers = n_handlers;
1932
0
        error = dpif_netlink_set_handler_pids(&dpif->dpif, upcall_pids,
1933
0
                                              n_handlers);
1934
0
        free(upcall_pids);
1935
0
    }
1936
0
    return error;
1937
0
}
1938
1939
/* Synchronizes 'channels' in 'dpif->handlers'  with the set of vports
1940
 * currently in 'dpif' in the kernel, by adding a new set of channels for
1941
 * any kernel vport that lacks one and deleting any channels that have no
1942
 * backing kernel vports. */
1943
static int
1944
dpif_netlink_refresh_handlers_vport_dispatch(struct dpif_netlink *dpif,
1945
                                             uint32_t n_handlers)
1946
    OVS_REQ_WRLOCK(dpif->upcall_lock)
1947
0
{
1948
0
    unsigned long int *keep_channels;
1949
0
    struct dpif_netlink_vport vport;
1950
0
    size_t keep_channels_nbits;
1951
0
    struct nl_dump dump;
1952
0
    uint64_t reply_stub[NL_DUMP_BUFSIZE / 8];
1953
0
    struct ofpbuf buf;
1954
0
    int retval = 0;
1955
0
    size_t i;
1956
1957
0
    if (dpif->n_handlers != n_handlers) {
1958
0
        destroy_all_channels(dpif);
1959
0
        dpif->handlers = xzalloc(n_handlers * sizeof *dpif->handlers);
1960
0
        for (i = 0; i < n_handlers; i++) {
1961
0
            int error;
1962
0
            struct dpif_handler *handler = &dpif->handlers[i];
1963
1964
0
            error = dpif_netlink_handler_init(handler);
1965
0
            if (error) {
1966
0
                size_t j;
1967
1968
0
                for (j = 0; j < i; j++) {
1969
0
                    struct dpif_handler *tmp = &dpif->handlers[j];
1970
0
                    dpif_netlink_handler_uninit(tmp);
1971
0
                }
1972
0
                free(dpif->handlers);
1973
0
                dpif->handlers = NULL;
1974
1975
0
                return error;
1976
0
            }
1977
0
        }
1978
0
        dpif->n_handlers = n_handlers;
1979
0
    }
1980
1981
0
    for (i = 0; i < n_handlers; i++) {
1982
0
        struct dpif_handler *handler = &dpif->handlers[i];
1983
1984
0
        handler->event_offset = handler->n_events = 0;
1985
0
    }
1986
1987
0
    keep_channels_nbits = dpif->uc_array_size;
1988
0
    keep_channels = bitmap_allocate(keep_channels_nbits);
1989
1990
0
    ofpbuf_use_stub(&buf, reply_stub, sizeof reply_stub);
1991
0
    dpif_netlink_port_dump_start__(dpif, &dump);
1992
0
    while (!dpif_netlink_port_dump_next__(dpif, &dump, &vport, &buf)) {
1993
0
        uint32_t port_no = odp_to_u32(vport.port_no);
1994
0
        uint32_t upcall_pid;
1995
0
        int error;
1996
1997
0
        if (port_no >= dpif->uc_array_size
1998
0
            || !vport_get_pid(dpif, port_no, &upcall_pid)) {
1999
0
            struct nl_sock *sock;
2000
0
            error = create_nl_sock(dpif, &sock);
2001
2002
0
            if (error) {
2003
0
                goto error;
2004
0
            }
2005
2006
0
            error = vport_add_channel(dpif, vport.port_no, sock);
2007
0
            if (error) {
2008
0
                VLOG_INFO("%s: could not add channels for port %s",
2009
0
                          dpif_name(&dpif->dpif), vport.name);
2010
0
                nl_sock_destroy(sock);
2011
0
                retval = error;
2012
0
                goto error;
2013
0
            }
2014
0
            upcall_pid = nl_sock_pid(sock);
2015
0
        }
2016
2017
        /* Configure the vport to deliver misses to 'sock'. */
2018
0
        if (vport.upcall_pids[0] == 0
2019
0
            || vport.n_upcall_pids != 1
2020
0
            || upcall_pid != vport.upcall_pids[0]) {
2021
0
            struct dpif_netlink_vport vport_request;
2022
2023
0
            dpif_netlink_vport_init(&vport_request);
2024
0
            vport_request.cmd = OVS_VPORT_CMD_SET;
2025
0
            vport_request.dp_ifindex = dpif->dp_ifindex;
2026
0
            vport_request.port_no = vport.port_no;
2027
0
            vport_request.n_upcall_pids = 1;
2028
0
            vport_request.upcall_pids = &upcall_pid;
2029
0
            error = dpif_netlink_vport_transact(&vport_request, NULL, NULL);
2030
0
            if (error) {
2031
0
                VLOG_WARN_RL(&error_rl,
2032
0
                             "%s: failed to set upcall pid on port: %s",
2033
0
                             dpif_name(&dpif->dpif), ovs_strerror(error));
2034
2035
0
                if (error != ENODEV && error != ENOENT) {
2036
0
                    retval = error;
2037
0
                } else {
2038
                    /* The vport isn't really there, even though the dump says
2039
                     * it is.  Probably we just hit a race after a port
2040
                     * disappeared. */
2041
0
                }
2042
0
                goto error;
2043
0
            }
2044
0
        }
2045
2046
0
        if (port_no < keep_channels_nbits) {
2047
0
            bitmap_set1(keep_channels, port_no);
2048
0
        }
2049
0
        continue;
2050
2051
0
    error:
2052
0
        vport_del_channels(dpif, vport.port_no);
2053
0
    }
2054
0
    nl_dump_done(&dump);
2055
0
    ofpbuf_uninit(&buf);
2056
2057
    /* Discard any saved channels that we didn't reuse. */
2058
0
    for (i = 0; i < keep_channels_nbits; i++) {
2059
0
        if (!bitmap_is_set(keep_channels, i)) {
2060
0
            vport_del_channels(dpif, u32_to_odp(i));
2061
0
        }
2062
0
    }
2063
0
    free(keep_channels);
2064
2065
0
    return retval;
2066
0
}
2067
2068
static int
2069
dpif_netlink_recv_set_vport_dispatch(struct dpif_netlink *dpif, bool enable)
2070
    OVS_REQ_WRLOCK(dpif->upcall_lock)
2071
0
{
2072
0
    if ((dpif->handlers != NULL) == enable) {
2073
0
        return 0;
2074
0
    } else if (!enable) {
2075
0
        destroy_all_channels(dpif);
2076
0
        return 0;
2077
0
    } else {
2078
0
        return dpif_netlink_refresh_handlers_vport_dispatch(dpif, 1);
2079
0
    }
2080
0
}
2081
2082
static int
2083
dpif_netlink_recv_set_cpu_dispatch(struct dpif_netlink *dpif, bool enable)
2084
    OVS_REQ_WRLOCK(dpif->upcall_lock)
2085
0
{
2086
0
    if ((dpif->handlers != NULL) == enable) {
2087
0
        return 0;
2088
0
    } else if (!enable) {
2089
0
        destroy_all_handlers(dpif);
2090
0
        return 0;
2091
0
    } else {
2092
0
        return dpif_netlink_refresh_handlers_cpu_dispatch(dpif);
2093
0
    }
2094
0
}
2095
2096
static int
2097
dpif_netlink_recv_set(struct dpif *dpif_, bool enable)
2098
0
{
2099
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
2100
0
    int error;
2101
2102
0
    fat_rwlock_wrlock(&dpif->upcall_lock);
2103
0
    if (dpif_netlink_upcall_per_cpu(dpif)) {
2104
0
        error = dpif_netlink_recv_set_cpu_dispatch(dpif, enable);
2105
0
    } else {
2106
0
        error = dpif_netlink_recv_set_vport_dispatch(dpif, enable);
2107
0
    }
2108
0
    fat_rwlock_unlock(&dpif->upcall_lock);
2109
2110
0
    return error;
2111
0
}
2112
2113
static int
2114
dpif_netlink_handlers_set(struct dpif *dpif_, uint32_t n_handlers)
2115
0
{
2116
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
2117
0
    int error = 0;
2118
2119
0
    fat_rwlock_wrlock(&dpif->upcall_lock);
2120
0
    if (dpif->handlers) {
2121
0
        if (dpif_netlink_upcall_per_cpu(dpif)) {
2122
0
            error = dpif_netlink_refresh_handlers_cpu_dispatch(dpif);
2123
0
        } else {
2124
0
            error = dpif_netlink_refresh_handlers_vport_dispatch(dpif,
2125
0
                                                                 n_handlers);
2126
0
        }
2127
0
    }
2128
0
    fat_rwlock_unlock(&dpif->upcall_lock);
2129
2130
0
    return error;
2131
0
}
2132
2133
static bool
2134
dpif_netlink_number_handlers_required(struct dpif *dpif_, uint32_t *n_handlers)
2135
0
{
2136
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
2137
2138
0
    if (dpif_netlink_upcall_per_cpu(dpif)) {
2139
0
        *n_handlers = dpif_netlink_calculate_n_handlers();
2140
0
        return true;
2141
0
    }
2142
2143
0
    return false;
2144
0
}
2145
2146
static int
2147
dpif_netlink_queue_to_priority(const struct dpif *dpif OVS_UNUSED,
2148
                             uint32_t queue_id, uint32_t *priority)
2149
0
{
2150
0
    if (queue_id < 0xf000) {
2151
0
        *priority = TC_H_MAKE(1 << 16, queue_id + 1);
2152
0
        return 0;
2153
0
    } else {
2154
0
        return EINVAL;
2155
0
    }
2156
0
}
2157
2158
static int
2159
parse_odp_packet(struct ofpbuf *buf, struct dpif_upcall *upcall,
2160
                 int *dp_ifindex)
2161
0
{
2162
0
    static const struct nl_policy ovs_packet_policy[] = {
2163
        /* Always present. */
2164
0
        [OVS_PACKET_ATTR_PACKET] = { .type = NL_A_UNSPEC,
2165
0
                                     .min_len = ETH_HEADER_LEN },
2166
0
        [OVS_PACKET_ATTR_KEY] = { .type = NL_A_NESTED },
2167
2168
        /* OVS_PACKET_CMD_ACTION only. */
2169
0
        [OVS_PACKET_ATTR_USERDATA] = { .type = NL_A_UNSPEC, .optional = true },
2170
0
        [OVS_PACKET_ATTR_EGRESS_TUN_KEY] = { .type = NL_A_NESTED, .optional = true },
2171
0
        [OVS_PACKET_ATTR_ACTIONS] = { .type = NL_A_NESTED, .optional = true },
2172
0
        [OVS_PACKET_ATTR_MRU] = { .type = NL_A_U16, .optional = true },
2173
0
        [OVS_PACKET_ATTR_HASH] = { .type = NL_A_U64, .optional = true }
2174
0
    };
2175
2176
0
    struct ofpbuf b = ofpbuf_const_initializer(buf->data, buf->size);
2177
0
    struct nlmsghdr *nlmsg = ofpbuf_try_pull(&b, sizeof *nlmsg);
2178
0
    struct genlmsghdr *genl = ofpbuf_try_pull(&b, sizeof *genl);
2179
0
    struct ovs_header *ovs_header = ofpbuf_try_pull(&b, sizeof *ovs_header);
2180
2181
0
    struct nlattr *a[ARRAY_SIZE(ovs_packet_policy)];
2182
0
    if (!nlmsg || !genl || !ovs_header
2183
0
        || nlmsg->nlmsg_type != ovs_packet_family
2184
0
        || !nl_policy_parse(&b, 0, ovs_packet_policy, a,
2185
0
                            ARRAY_SIZE(ovs_packet_policy))) {
2186
0
        return EINVAL;
2187
0
    }
2188
2189
0
    int type = (genl->cmd == OVS_PACKET_CMD_MISS ? DPIF_UC_MISS
2190
0
                : genl->cmd == OVS_PACKET_CMD_ACTION ? DPIF_UC_ACTION
2191
0
                : -1);
2192
0
    if (type < 0) {
2193
0
        return EINVAL;
2194
0
    }
2195
2196
    /* (Re)set ALL fields of '*upcall' on successful return. */
2197
0
    upcall->type = type;
2198
0
    upcall->key = CONST_CAST(struct nlattr *,
2199
0
                             nl_attr_get(a[OVS_PACKET_ATTR_KEY]));
2200
0
    upcall->key_len = nl_attr_get_size(a[OVS_PACKET_ATTR_KEY]);
2201
0
    odp_flow_key_hash(upcall->key, upcall->key_len, &upcall->ufid);
2202
0
    upcall->userdata = a[OVS_PACKET_ATTR_USERDATA];
2203
0
    upcall->out_tun_key = a[OVS_PACKET_ATTR_EGRESS_TUN_KEY];
2204
0
    upcall->actions = a[OVS_PACKET_ATTR_ACTIONS];
2205
0
    upcall->mru = a[OVS_PACKET_ATTR_MRU];
2206
0
    upcall->hash = a[OVS_PACKET_ATTR_HASH];
2207
2208
    /* Allow overwriting the netlink attribute header without reallocating. */
2209
0
    dp_packet_use_stub(&upcall->packet,
2210
0
                    CONST_CAST(struct nlattr *,
2211
0
                               nl_attr_get(a[OVS_PACKET_ATTR_PACKET])) - 1,
2212
0
                    nl_attr_get_size(a[OVS_PACKET_ATTR_PACKET]) +
2213
0
                    sizeof(struct nlattr));
2214
0
    dp_packet_set_data(&upcall->packet,
2215
0
                    (char *)dp_packet_data(&upcall->packet) + sizeof(struct nlattr));
2216
0
    dp_packet_set_size(&upcall->packet, nl_attr_get_size(a[OVS_PACKET_ATTR_PACKET]));
2217
2218
0
    if (nl_attr_find__(upcall->key, upcall->key_len, OVS_KEY_ATTR_ETHERNET)) {
2219
        /* Ethernet frame */
2220
0
        upcall->packet.packet_type = htonl(PT_ETH);
2221
0
    } else {
2222
        /* Non-Ethernet packet. Get the Ethertype from the NL attributes */
2223
0
        ovs_be16 ethertype = 0;
2224
0
        const struct nlattr *et_nla = nl_attr_find__(upcall->key,
2225
0
                                                     upcall->key_len,
2226
0
                                                     OVS_KEY_ATTR_ETHERTYPE);
2227
0
        if (et_nla) {
2228
0
            ethertype = nl_attr_get_be16(et_nla);
2229
0
        }
2230
0
        upcall->packet.packet_type = PACKET_TYPE_BE(OFPHTN_ETHERTYPE,
2231
0
                                                    ntohs(ethertype));
2232
0
        dp_packet_set_l3(&upcall->packet, dp_packet_data(&upcall->packet));
2233
0
    }
2234
2235
0
    *dp_ifindex = ovs_header->dp_ifindex;
2236
2237
0
    return 0;
2238
0
}
2239
2240
static int
2241
dpif_netlink_recv_cpu_dispatch(struct dpif_netlink *dpif, uint32_t handler_id,
2242
                               struct dpif_upcall *upcall, struct ofpbuf *buf)
2243
    OVS_REQ_RDLOCK(dpif->upcall_lock)
2244
0
{
2245
0
    struct dpif_handler *handler;
2246
0
    int read_tries = 0;
2247
2248
0
    if (!dpif->handlers || handler_id >= dpif->n_handlers) {
2249
0
        return EAGAIN;
2250
0
    }
2251
2252
0
    handler = &dpif->handlers[handler_id];
2253
2254
0
    for (;;) {
2255
0
        int dp_ifindex;
2256
0
        int error;
2257
2258
0
        if (++read_tries > 50) {
2259
0
            return EAGAIN;
2260
0
        }
2261
0
        error = nl_sock_recv(handler->sock, buf, NULL, false);
2262
0
        if (error == ENOBUFS) {
2263
            /* ENOBUFS typically means that we've received so many
2264
             * packets that the buffer overflowed.  Try again
2265
             * immediately because there's almost certainly a packet
2266
             * waiting for us. */
2267
0
            report_loss(dpif, NULL, 0, handler_id);
2268
0
            continue;
2269
0
        }
2270
2271
0
        if (error) {
2272
0
            if (error == EAGAIN) {
2273
0
                break;
2274
0
            }
2275
0
            return error;
2276
0
        }
2277
2278
0
        error = parse_odp_packet(buf, upcall, &dp_ifindex);
2279
0
        if (!error && dp_ifindex == dpif->dp_ifindex) {
2280
0
            upcall->pid = nl_sock_pid(handler->sock);
2281
0
            return 0;
2282
0
        } else if (error) {
2283
0
            return error;
2284
0
        }
2285
0
    }
2286
2287
0
    return EAGAIN;
2288
0
}
2289
2290
static int
2291
dpif_netlink_recv_vport_dispatch(struct dpif_netlink *dpif,
2292
                                 uint32_t handler_id,
2293
                                 struct dpif_upcall *upcall,
2294
                                 struct ofpbuf *buf)
2295
    OVS_REQ_RDLOCK(dpif->upcall_lock)
2296
0
{
2297
0
    struct dpif_handler *handler;
2298
0
    int read_tries = 0;
2299
2300
0
    if (!dpif->handlers || handler_id >= dpif->n_handlers) {
2301
0
        return EAGAIN;
2302
0
    }
2303
2304
0
    handler = &dpif->handlers[handler_id];
2305
0
    if (handler->event_offset >= handler->n_events) {
2306
0
        int retval;
2307
2308
0
        handler->event_offset = handler->n_events = 0;
2309
2310
0
        do {
2311
0
            retval = epoll_wait(handler->epoll_fd, handler->epoll_events,
2312
0
                                dpif->uc_array_size, 0);
2313
0
        } while (retval < 0 && errno == EINTR);
2314
2315
0
        if (retval < 0) {
2316
0
            static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
2317
0
            VLOG_WARN_RL(&rl, "epoll_wait failed (%s)", ovs_strerror(errno));
2318
0
        } else if (retval > 0) {
2319
0
            handler->n_events = retval;
2320
0
        }
2321
0
    }
2322
2323
0
    while (handler->event_offset < handler->n_events) {
2324
0
        int idx = handler->epoll_events[handler->event_offset].data.u32;
2325
0
        struct dpif_channel *ch = &dpif->channels[idx];
2326
2327
0
        handler->event_offset++;
2328
2329
0
        for (;;) {
2330
0
            int dp_ifindex;
2331
0
            int error;
2332
2333
0
            if (++read_tries > 50) {
2334
0
                return EAGAIN;
2335
0
            }
2336
2337
0
            error = nl_sock_recv(ch->sock, buf, NULL, false);
2338
0
            if (error == ENOBUFS) {
2339
                /* ENOBUFS typically means that we've received so many
2340
                 * packets that the buffer overflowed.  Try again
2341
                 * immediately because there's almost certainly a packet
2342
                 * waiting for us. */
2343
0
                report_loss(dpif, ch, idx, handler_id);
2344
0
                continue;
2345
0
            }
2346
2347
0
            ch->last_poll = time_msec();
2348
0
            if (error) {
2349
0
                if (error == EAGAIN) {
2350
0
                    break;
2351
0
                }
2352
0
                return error;
2353
0
            }
2354
2355
0
            error = parse_odp_packet(buf, upcall, &dp_ifindex);
2356
0
            if (!error && dp_ifindex == dpif->dp_ifindex) {
2357
0
                upcall->pid = nl_sock_pid(ch->sock);
2358
0
                return 0;
2359
0
            } else if (error) {
2360
0
                return error;
2361
0
            }
2362
0
        }
2363
0
    }
2364
2365
0
    return EAGAIN;
2366
0
}
2367
2368
static int
2369
dpif_netlink_recv(struct dpif *dpif_, uint32_t handler_id,
2370
                  struct dpif_upcall *upcall, struct ofpbuf *buf)
2371
0
{
2372
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
2373
0
    int error;
2374
2375
0
    fat_rwlock_rdlock(&dpif->upcall_lock);
2376
0
    if (dpif_netlink_upcall_per_cpu(dpif)) {
2377
0
        error = dpif_netlink_recv_cpu_dispatch(dpif, handler_id, upcall, buf);
2378
0
    } else {
2379
0
        error = dpif_netlink_recv_vport_dispatch(dpif,
2380
0
                                                 handler_id, upcall, buf);
2381
0
    }
2382
0
    fat_rwlock_unlock(&dpif->upcall_lock);
2383
2384
0
    return error;
2385
0
}
2386
2387
static void
2388
dpif_netlink_recv_wait_vport_dispatch(struct dpif_netlink *dpif,
2389
                                      uint32_t handler_id)
2390
    OVS_REQ_RDLOCK(dpif->upcall_lock)
2391
0
{
2392
0
    if (dpif->handlers && handler_id < dpif->n_handlers) {
2393
0
        struct dpif_handler *handler = &dpif->handlers[handler_id];
2394
2395
0
        poll_fd_wait(handler->epoll_fd, POLLIN);
2396
0
    }
2397
0
}
2398
2399
static void
2400
dpif_netlink_recv_wait_cpu_dispatch(struct dpif_netlink *dpif,
2401
                                    uint32_t handler_id)
2402
    OVS_REQ_RDLOCK(dpif->upcall_lock)
2403
0
{
2404
0
    if (dpif->handlers && handler_id < dpif->n_handlers) {
2405
0
        struct dpif_handler *handler = &dpif->handlers[handler_id];
2406
2407
0
        poll_fd_wait(nl_sock_fd(handler->sock), POLLIN);
2408
0
    }
2409
0
}
2410
2411
static void
2412
dpif_netlink_recv_wait(struct dpif *dpif_, uint32_t handler_id)
2413
0
{
2414
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
2415
2416
0
    fat_rwlock_rdlock(&dpif->upcall_lock);
2417
0
    if (dpif_netlink_upcall_per_cpu(dpif)) {
2418
0
        dpif_netlink_recv_wait_cpu_dispatch(dpif, handler_id);
2419
0
    } else {
2420
0
        dpif_netlink_recv_wait_vport_dispatch(dpif, handler_id);
2421
0
    }
2422
0
    fat_rwlock_unlock(&dpif->upcall_lock);
2423
0
}
2424
2425
static void
2426
dpif_netlink_recv_purge_vport_dispatch(struct dpif_netlink *dpif)
2427
    OVS_REQ_WRLOCK(dpif->upcall_lock)
2428
0
{
2429
0
    if (dpif->handlers) {
2430
0
        size_t i;
2431
2432
0
        if (!dpif->channels[0].sock) {
2433
0
            return;
2434
0
        }
2435
0
        for (i = 0; i < dpif->uc_array_size; i++ ) {
2436
2437
0
            nl_sock_drain(dpif->channels[i].sock);
2438
0
        }
2439
0
    }
2440
0
}
2441
2442
static void
2443
dpif_netlink_recv_purge_cpu_dispatch(struct dpif_netlink *dpif)
2444
    OVS_REQ_WRLOCK(dpif->upcall_lock)
2445
0
{
2446
0
    int handler_id;
2447
2448
0
    if (dpif->handlers) {
2449
0
        for (handler_id = 0; handler_id < dpif->n_handlers; handler_id++) {
2450
0
            struct dpif_handler *handler = &dpif->handlers[handler_id];
2451
0
            nl_sock_drain(handler->sock);
2452
0
        }
2453
0
    }
2454
0
}
2455
2456
static void
2457
dpif_netlink_recv_purge(struct dpif *dpif_)
2458
0
{
2459
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
2460
2461
0
    fat_rwlock_wrlock(&dpif->upcall_lock);
2462
0
    if (dpif_netlink_upcall_per_cpu(dpif)) {
2463
0
        dpif_netlink_recv_purge_cpu_dispatch(dpif);
2464
0
    } else {
2465
0
        dpif_netlink_recv_purge_vport_dispatch(dpif);
2466
0
    }
2467
0
    fat_rwlock_unlock(&dpif->upcall_lock);
2468
0
}
2469
2470
static char *
2471
dpif_netlink_get_datapath_version(void)
2472
0
{
2473
0
    char *version_str = NULL;
2474
2475
0
#ifdef __linux__
2476
2477
0
#define MAX_VERSION_STR_SIZE 80
2478
0
#define LINUX_DATAPATH_VERSION_FILE  "/sys/module/openvswitch/version"
2479
0
    FILE *f;
2480
2481
0
    f = fopen(LINUX_DATAPATH_VERSION_FILE, "r");
2482
0
    if (f) {
2483
0
        char *newline;
2484
0
        char version[MAX_VERSION_STR_SIZE];
2485
2486
0
        if (fgets(version, MAX_VERSION_STR_SIZE, f)) {
2487
0
            newline = strchr(version, '\n');
2488
0
            if (newline) {
2489
0
                *newline = '\0';
2490
0
            }
2491
0
            version_str = xstrdup(version);
2492
0
        }
2493
0
        fclose(f);
2494
0
    }
2495
0
#endif
2496
2497
0
    return version_str;
2498
0
}
2499
2500
struct dpif_netlink_ct_dump_state {
2501
    struct ct_dpif_dump_state up;
2502
    struct nl_ct_dump_state *nl_ct_dump;
2503
};
2504
2505
static int
2506
dpif_netlink_ct_dump_start(struct dpif *dpif OVS_UNUSED,
2507
                           struct ct_dpif_dump_state **dump_,
2508
                           const uint16_t *zone, int *ptot_bkts)
2509
0
{
2510
0
    struct dpif_netlink_ct_dump_state *dump;
2511
0
    int err;
2512
2513
0
    dump = xzalloc(sizeof *dump);
2514
0
    err = nl_ct_dump_start(&dump->nl_ct_dump, zone, ptot_bkts);
2515
0
    if (err) {
2516
0
        free(dump);
2517
0
        return err;
2518
0
    }
2519
2520
0
    *dump_ = &dump->up;
2521
2522
0
    return 0;
2523
0
}
2524
2525
static int
2526
dpif_netlink_ct_dump_next(struct dpif *dpif OVS_UNUSED,
2527
                          struct ct_dpif_dump_state *dump_,
2528
                          struct ct_dpif_entry *entry)
2529
0
{
2530
0
    struct dpif_netlink_ct_dump_state *dump;
2531
2532
0
    INIT_CONTAINER(dump, dump_, up);
2533
2534
0
    return nl_ct_dump_next(dump->nl_ct_dump, entry);
2535
0
}
2536
2537
static int
2538
dpif_netlink_ct_dump_done(struct dpif *dpif OVS_UNUSED,
2539
                          struct ct_dpif_dump_state *dump_)
2540
0
{
2541
0
    struct dpif_netlink_ct_dump_state *dump;
2542
2543
0
    INIT_CONTAINER(dump, dump_, up);
2544
2545
0
    int err = nl_ct_dump_done(dump->nl_ct_dump);
2546
0
    free(dump);
2547
0
    return err;
2548
0
}
2549
2550
static int
2551
dpif_netlink_ct_flush(struct dpif *dpif OVS_UNUSED, const uint16_t *zone,
2552
                      const struct ct_dpif_tuple *tuple)
2553
0
{
2554
0
    if (tuple) {
2555
0
        return nl_ct_flush_tuple(tuple, zone ? *zone : 0);
2556
0
    } else if (zone) {
2557
0
        return nl_ct_flush_zone(*zone);
2558
0
    } else {
2559
0
        return nl_ct_flush();
2560
0
    }
2561
0
}
2562
2563
static int
2564
dpif_netlink_ct_set_limits(struct dpif *dpif OVS_UNUSED,
2565
                           const struct ovs_list *zone_limits)
2566
0
{
2567
0
    if (ovs_ct_limit_family < 0) {
2568
0
        return EOPNOTSUPP;
2569
0
    }
2570
2571
0
    struct ofpbuf *request = ofpbuf_new(NL_DUMP_BUFSIZE);
2572
0
    nl_msg_put_genlmsghdr(request, 0, ovs_ct_limit_family,
2573
0
                          NLM_F_REQUEST | NLM_F_ECHO, OVS_CT_LIMIT_CMD_SET,
2574
0
                          OVS_CT_LIMIT_VERSION);
2575
2576
0
    struct ovs_header *ovs_header;
2577
0
    ovs_header = ofpbuf_put_uninit(request, sizeof *ovs_header);
2578
0
    ovs_header->dp_ifindex = 0;
2579
2580
0
    size_t opt_offset;
2581
0
    opt_offset = nl_msg_start_nested(request, OVS_CT_LIMIT_ATTR_ZONE_LIMIT);
2582
2583
0
    if (!ovs_list_is_empty(zone_limits)) {
2584
0
        struct ct_dpif_zone_limit *zone_limit;
2585
2586
0
        LIST_FOR_EACH (zone_limit, node, zone_limits) {
2587
0
            struct ovs_zone_limit req_zone_limit = {
2588
0
                .zone_id = zone_limit->zone,
2589
0
                .limit   = zone_limit->limit,
2590
0
            };
2591
0
            nl_msg_put(request, &req_zone_limit, sizeof req_zone_limit);
2592
0
        }
2593
0
    }
2594
0
    nl_msg_end_nested(request, opt_offset);
2595
2596
0
    int err = nl_transact(NETLINK_GENERIC, request, NULL);
2597
0
    ofpbuf_delete(request);
2598
0
    return err;
2599
0
}
2600
2601
static int
2602
dpif_netlink_zone_limits_from_ofpbuf(const struct ofpbuf *buf,
2603
                                     struct ovs_list *zone_limits)
2604
0
{
2605
0
    static const struct nl_policy ovs_ct_limit_policy[] = {
2606
0
        [OVS_CT_LIMIT_ATTR_ZONE_LIMIT] = { .type = NL_A_NESTED,
2607
0
                                           .optional = true },
2608
0
    };
2609
2610
0
    struct ofpbuf b = ofpbuf_const_initializer(buf->data, buf->size);
2611
0
    struct nlmsghdr *nlmsg = ofpbuf_try_pull(&b, sizeof *nlmsg);
2612
0
    struct genlmsghdr *genl = ofpbuf_try_pull(&b, sizeof *genl);
2613
0
    struct ovs_header *ovs_header = ofpbuf_try_pull(&b, sizeof *ovs_header);
2614
2615
0
    struct nlattr *attr[ARRAY_SIZE(ovs_ct_limit_policy)];
2616
2617
0
    if (!nlmsg || !genl || !ovs_header
2618
0
        || nlmsg->nlmsg_type != ovs_ct_limit_family
2619
0
        || !nl_policy_parse(&b, 0, ovs_ct_limit_policy, attr,
2620
0
                            ARRAY_SIZE(ovs_ct_limit_policy))) {
2621
0
        return EINVAL;
2622
0
    }
2623
2624
2625
0
    if (!attr[OVS_CT_LIMIT_ATTR_ZONE_LIMIT]) {
2626
0
        return EINVAL;
2627
0
    }
2628
2629
0
    int rem = NLA_ALIGN(
2630
0
                nl_attr_get_size(attr[OVS_CT_LIMIT_ATTR_ZONE_LIMIT]));
2631
0
    const struct ovs_zone_limit *zone_limit =
2632
0
                nl_attr_get(attr[OVS_CT_LIMIT_ATTR_ZONE_LIMIT]);
2633
2634
0
    while (rem >= sizeof *zone_limit) {
2635
0
        if (zone_limit->zone_id >= OVS_ZONE_LIMIT_DEFAULT_ZONE &&
2636
0
            zone_limit->zone_id <= UINT16_MAX) {
2637
0
            ct_dpif_push_zone_limit(zone_limits, zone_limit->zone_id,
2638
0
                                    zone_limit->limit, zone_limit->count);
2639
0
        }
2640
0
        rem -= NLA_ALIGN(sizeof *zone_limit);
2641
0
        zone_limit = ALIGNED_CAST(struct ovs_zone_limit *,
2642
0
            (unsigned char *) zone_limit  + NLA_ALIGN(sizeof *zone_limit));
2643
0
    }
2644
0
    return 0;
2645
0
}
2646
2647
static int
2648
dpif_netlink_ct_get_limits(struct dpif *dpif OVS_UNUSED,
2649
                           const struct ovs_list *zone_limits_request,
2650
                           struct ovs_list *zone_limits_reply)
2651
0
{
2652
0
    if (ovs_ct_limit_family < 0) {
2653
0
        return EOPNOTSUPP;
2654
0
    }
2655
2656
0
    struct ofpbuf *request = ofpbuf_new(NL_DUMP_BUFSIZE);
2657
0
    nl_msg_put_genlmsghdr(request, 0, ovs_ct_limit_family,
2658
0
            NLM_F_REQUEST | NLM_F_ECHO, OVS_CT_LIMIT_CMD_GET,
2659
0
            OVS_CT_LIMIT_VERSION);
2660
2661
0
    struct ovs_header *ovs_header;
2662
0
    ovs_header = ofpbuf_put_uninit(request, sizeof *ovs_header);
2663
0
    ovs_header->dp_ifindex = 0;
2664
2665
0
    if (!ovs_list_is_empty(zone_limits_request)) {
2666
0
        size_t opt_offset = nl_msg_start_nested(request,
2667
0
                                                OVS_CT_LIMIT_ATTR_ZONE_LIMIT);
2668
2669
0
        struct ct_dpif_zone_limit *zone_limit;
2670
0
        LIST_FOR_EACH (zone_limit, node, zone_limits_request) {
2671
0
            struct ovs_zone_limit req_zone_limit = {
2672
0
                .zone_id = zone_limit->zone,
2673
0
            };
2674
0
            nl_msg_put(request, &req_zone_limit, sizeof req_zone_limit);
2675
0
        }
2676
2677
0
        nl_msg_end_nested(request, opt_offset);
2678
0
    }
2679
2680
0
    struct ofpbuf *reply;
2681
0
    int err = nl_transact(NETLINK_GENERIC, request, &reply);
2682
0
    if (err) {
2683
0
        goto out;
2684
0
    }
2685
2686
0
    err = dpif_netlink_zone_limits_from_ofpbuf(reply, zone_limits_reply);
2687
2688
0
out:
2689
0
    ofpbuf_delete(request);
2690
0
    ofpbuf_delete(reply);
2691
0
    return err;
2692
0
}
2693
2694
static int
2695
dpif_netlink_ct_del_limits(struct dpif *dpif OVS_UNUSED,
2696
                           const struct ovs_list *zone_limits)
2697
0
{
2698
0
    if (ovs_ct_limit_family < 0) {
2699
0
        return EOPNOTSUPP;
2700
0
    }
2701
2702
0
    struct ofpbuf *request = ofpbuf_new(NL_DUMP_BUFSIZE);
2703
0
    nl_msg_put_genlmsghdr(request, 0, ovs_ct_limit_family,
2704
0
            NLM_F_REQUEST | NLM_F_ECHO, OVS_CT_LIMIT_CMD_DEL,
2705
0
            OVS_CT_LIMIT_VERSION);
2706
2707
0
    struct ovs_header *ovs_header;
2708
0
    ovs_header = ofpbuf_put_uninit(request, sizeof *ovs_header);
2709
0
    ovs_header->dp_ifindex = 0;
2710
2711
0
    if (!ovs_list_is_empty(zone_limits)) {
2712
0
        size_t opt_offset =
2713
0
            nl_msg_start_nested(request, OVS_CT_LIMIT_ATTR_ZONE_LIMIT);
2714
2715
0
        struct ct_dpif_zone_limit *zone_limit;
2716
0
        LIST_FOR_EACH (zone_limit, node, zone_limits) {
2717
0
            struct ovs_zone_limit req_zone_limit = {
2718
0
                .zone_id = zone_limit->zone,
2719
0
            };
2720
0
            nl_msg_put(request, &req_zone_limit, sizeof req_zone_limit);
2721
0
        }
2722
0
        nl_msg_end_nested(request, opt_offset);
2723
0
    }
2724
2725
0
    int err = nl_transact(NETLINK_GENERIC, request, NULL);
2726
2727
0
    ofpbuf_delete(request);
2728
0
    return err;
2729
0
}
2730
2731
0
#define NL_TP_NAME_PREFIX "ovs_tp_"
2732
2733
struct dpif_netlink_timeout_policy_protocol {
2734
    uint16_t    l3num;
2735
    uint8_t     l4num;
2736
};
2737
2738
enum OVS_PACKED_ENUM dpif_netlink_support_timeout_policy_protocol {
2739
    DPIF_NL_TP_AF_INET_TCP,
2740
    DPIF_NL_TP_AF_INET_UDP,
2741
    DPIF_NL_TP_AF_INET_ICMP,
2742
    DPIF_NL_TP_AF_INET6_TCP,
2743
    DPIF_NL_TP_AF_INET6_UDP,
2744
    DPIF_NL_TP_AF_INET6_ICMPV6,
2745
    DPIF_NL_TP_MAX
2746
};
2747
2748
0
#define DPIF_NL_ALL_TP ((1UL << DPIF_NL_TP_MAX) - 1)
2749
2750
2751
static struct dpif_netlink_timeout_policy_protocol tp_protos[] = {
2752
    [DPIF_NL_TP_AF_INET_TCP] = { .l3num = AF_INET, .l4num = IPPROTO_TCP },
2753
    [DPIF_NL_TP_AF_INET_UDP] = { .l3num = AF_INET, .l4num = IPPROTO_UDP },
2754
    [DPIF_NL_TP_AF_INET_ICMP] = { .l3num = AF_INET, .l4num = IPPROTO_ICMP },
2755
    [DPIF_NL_TP_AF_INET6_TCP] = { .l3num = AF_INET6, .l4num = IPPROTO_TCP },
2756
    [DPIF_NL_TP_AF_INET6_UDP] = { .l3num = AF_INET6, .l4num = IPPROTO_UDP },
2757
    [DPIF_NL_TP_AF_INET6_ICMPV6] = { .l3num = AF_INET6,
2758
                                     .l4num = IPPROTO_ICMPV6 },
2759
};
2760
2761
static void
2762
dpif_netlink_format_tp_name(uint32_t id, uint16_t l3num, uint8_t l4num,
2763
                            char **tp_name)
2764
0
{
2765
0
    struct ds ds = DS_EMPTY_INITIALIZER;
2766
0
    ds_put_format(&ds, "%s%"PRIu32"_", NL_TP_NAME_PREFIX, id);
2767
0
    ct_dpif_format_ipproto(&ds, l4num);
2768
2769
0
    if (l3num == AF_INET) {
2770
0
        ds_put_cstr(&ds, "4");
2771
0
    } else if (l3num == AF_INET6 && l4num != IPPROTO_ICMPV6) {
2772
0
        ds_put_cstr(&ds, "6");
2773
0
    }
2774
2775
0
    ovs_assert(ds.length < CTNL_TIMEOUT_NAME_MAX);
2776
2777
0
    *tp_name = ds_steal_cstr(&ds);
2778
0
}
2779
2780
static int
2781
dpif_netlink_ct_get_timeout_policy_name(struct dpif *dpif OVS_UNUSED,
2782
                                        uint32_t tp_id, uint16_t dl_type,
2783
                                        uint8_t nw_proto, char **tp_name,
2784
                                        bool *is_generic)
2785
0
{
2786
0
    dpif_netlink_format_tp_name(tp_id,
2787
0
                                dl_type == ETH_TYPE_IP ? AF_INET : AF_INET6,
2788
0
                                nw_proto, tp_name);
2789
0
    *is_generic = false;
2790
0
    return 0;
2791
0
}
2792
2793
static int
2794
dpif_netlink_ct_get_features(struct dpif *dpif OVS_UNUSED,
2795
                             enum ct_features *features)
2796
0
{
2797
0
    if (features != NULL) {
2798
0
        *features = CONNTRACK_F_ZERO_SNAT;
2799
0
    }
2800
0
    return 0;
2801
0
}
2802
2803
#define CT_DPIF_NL_TP_TCP_MAPPINGS                              \
2804
0
    CT_DPIF_NL_TP_MAPPING(TCP, TCP, SYN_SENT, SYN_SENT)         \
2805
0
    CT_DPIF_NL_TP_MAPPING(TCP, TCP, SYN_RECV, SYN_RECV)         \
2806
0
    CT_DPIF_NL_TP_MAPPING(TCP, TCP, ESTABLISHED, ESTABLISHED)   \
2807
0
    CT_DPIF_NL_TP_MAPPING(TCP, TCP, FIN_WAIT, FIN_WAIT)         \
2808
0
    CT_DPIF_NL_TP_MAPPING(TCP, TCP, CLOSE_WAIT, CLOSE_WAIT)     \
2809
0
    CT_DPIF_NL_TP_MAPPING(TCP, TCP, LAST_ACK, LAST_ACK)         \
2810
0
    CT_DPIF_NL_TP_MAPPING(TCP, TCP, TIME_WAIT, TIME_WAIT)       \
2811
0
    CT_DPIF_NL_TP_MAPPING(TCP, TCP, CLOSE, CLOSE)               \
2812
0
    CT_DPIF_NL_TP_MAPPING(TCP, TCP, SYN_SENT2, SYN_SENT2)       \
2813
0
    CT_DPIF_NL_TP_MAPPING(TCP, TCP, RETRANSMIT, RETRANS)        \
2814
0
    CT_DPIF_NL_TP_MAPPING(TCP, TCP, UNACK, UNACK)
2815
2816
#define CT_DPIF_NL_TP_UDP_MAPPINGS                              \
2817
0
    CT_DPIF_NL_TP_MAPPING(UDP, UDP, SINGLE, UNREPLIED)          \
2818
0
    CT_DPIF_NL_TP_MAPPING(UDP, UDP, MULTIPLE, REPLIED)
2819
2820
#define CT_DPIF_NL_TP_ICMP_MAPPINGS                             \
2821
0
    CT_DPIF_NL_TP_MAPPING(ICMP, ICMP, FIRST, TIMEOUT)
2822
2823
#define CT_DPIF_NL_TP_ICMPV6_MAPPINGS                           \
2824
0
    CT_DPIF_NL_TP_MAPPING(ICMP, ICMPV6, FIRST, TIMEOUT)
2825
2826
2827
0
#define CT_DPIF_NL_TP_MAPPING(PROTO1, PROTO2, ATTR1, ATTR2)     \
2828
0
if (tp->present & (1 << CT_DPIF_TP_ATTR_##PROTO1##_##ATTR1)) {  \
2829
0
    nl_tp->present |= 1 << CTA_TIMEOUT_##PROTO2##_##ATTR2;      \
2830
0
    nl_tp->attrs[CTA_TIMEOUT_##PROTO2##_##ATTR2] =              \
2831
0
        tp->attrs[CT_DPIF_TP_ATTR_##PROTO1##_##ATTR1];          \
2832
0
}
2833
2834
static void
2835
dpif_netlink_get_nl_tp_tcp_attrs(const struct ct_dpif_timeout_policy *tp,
2836
                                 struct nl_ct_timeout_policy *nl_tp)
2837
0
{
2838
0
    CT_DPIF_NL_TP_TCP_MAPPINGS
2839
0
}
2840
2841
static void
2842
dpif_netlink_get_nl_tp_udp_attrs(const struct ct_dpif_timeout_policy *tp,
2843
                                 struct nl_ct_timeout_policy *nl_tp)
2844
0
{
2845
0
    CT_DPIF_NL_TP_UDP_MAPPINGS
2846
0
}
2847
2848
static void
2849
dpif_netlink_get_nl_tp_icmp_attrs(const struct ct_dpif_timeout_policy *tp,
2850
                                  struct nl_ct_timeout_policy *nl_tp)
2851
0
{
2852
0
    CT_DPIF_NL_TP_ICMP_MAPPINGS
2853
0
}
2854
2855
static void
2856
dpif_netlink_get_nl_tp_icmpv6_attrs(const struct ct_dpif_timeout_policy *tp,
2857
                                    struct nl_ct_timeout_policy *nl_tp)
2858
0
{
2859
0
    CT_DPIF_NL_TP_ICMPV6_MAPPINGS
2860
0
}
2861
2862
#undef CT_DPIF_NL_TP_MAPPING
2863
2864
static void
2865
dpif_netlink_get_nl_tp_attrs(const struct ct_dpif_timeout_policy *tp,
2866
                             uint8_t l4num, struct nl_ct_timeout_policy *nl_tp)
2867
0
{
2868
0
    nl_tp->present = 0;
2869
2870
0
    if (l4num == IPPROTO_TCP) {
2871
0
        dpif_netlink_get_nl_tp_tcp_attrs(tp, nl_tp);
2872
0
    } else if (l4num == IPPROTO_UDP) {
2873
0
        dpif_netlink_get_nl_tp_udp_attrs(tp, nl_tp);
2874
0
    } else if (l4num == IPPROTO_ICMP) {
2875
0
        dpif_netlink_get_nl_tp_icmp_attrs(tp, nl_tp);
2876
0
    } else if (l4num == IPPROTO_ICMPV6) {
2877
0
        dpif_netlink_get_nl_tp_icmpv6_attrs(tp, nl_tp);
2878
0
    }
2879
0
}
2880
2881
0
#define CT_DPIF_NL_TP_MAPPING(PROTO1, PROTO2, ATTR1, ATTR2)                 \
2882
0
if (nl_tp->present & (1 << CTA_TIMEOUT_##PROTO2##_##ATTR2)) {               \
2883
0
    if (tp->present & (1 << CT_DPIF_TP_ATTR_##PROTO1##_##ATTR1)) {          \
2884
0
        if (tp->attrs[CT_DPIF_TP_ATTR_##PROTO1##_##ATTR1] !=                \
2885
0
            nl_tp->attrs[CTA_TIMEOUT_##PROTO2##_##ATTR2]) {                 \
2886
0
            VLOG_WARN_RL(&error_rl, "Inconsistent timeout policy %s "       \
2887
0
                         "attribute %s=%"PRIu32" while %s=%"PRIu32,         \
2888
0
                         nl_tp->name, "CTA_TIMEOUT_"#PROTO2"_"#ATTR2,       \
2889
0
                         nl_tp->attrs[CTA_TIMEOUT_##PROTO2##_##ATTR2],      \
2890
0
                         "CT_DPIF_TP_ATTR_"#PROTO1"_"#ATTR1,                \
2891
0
                         tp->attrs[CT_DPIF_TP_ATTR_##PROTO1##_##ATTR1]);    \
2892
0
        }                                                                   \
2893
0
    } else {                                                                \
2894
0
        tp->present |= 1 << CT_DPIF_TP_ATTR_##PROTO1##_##ATTR1;             \
2895
0
        tp->attrs[CT_DPIF_TP_ATTR_##PROTO1##_##ATTR1] =                     \
2896
0
            nl_tp->attrs[CTA_TIMEOUT_##PROTO2##_##ATTR2];                   \
2897
0
    }                                                                       \
2898
0
}
2899
2900
static void
2901
dpif_netlink_set_ct_dpif_tp_tcp_attrs(const struct nl_ct_timeout_policy *nl_tp,
2902
                                      struct ct_dpif_timeout_policy *tp)
2903
0
{
2904
0
    CT_DPIF_NL_TP_TCP_MAPPINGS
2905
0
}
2906
2907
static void
2908
dpif_netlink_set_ct_dpif_tp_udp_attrs(const struct nl_ct_timeout_policy *nl_tp,
2909
                                      struct ct_dpif_timeout_policy *tp)
2910
0
{
2911
0
    CT_DPIF_NL_TP_UDP_MAPPINGS
2912
0
}
2913
2914
static void
2915
dpif_netlink_set_ct_dpif_tp_icmp_attrs(
2916
    const struct nl_ct_timeout_policy *nl_tp,
2917
    struct ct_dpif_timeout_policy *tp)
2918
0
{
2919
0
    CT_DPIF_NL_TP_ICMP_MAPPINGS
2920
0
}
2921
2922
static void
2923
dpif_netlink_set_ct_dpif_tp_icmpv6_attrs(
2924
    const struct nl_ct_timeout_policy *nl_tp,
2925
    struct ct_dpif_timeout_policy *tp)
2926
0
{
2927
0
    CT_DPIF_NL_TP_ICMPV6_MAPPINGS
2928
0
}
2929
2930
#undef CT_DPIF_NL_TP_MAPPING
2931
2932
static void
2933
dpif_netlink_set_ct_dpif_tp_attrs(const struct nl_ct_timeout_policy *nl_tp,
2934
                                  struct ct_dpif_timeout_policy *tp)
2935
0
{
2936
0
    if (nl_tp->l4num == IPPROTO_TCP) {
2937
0
        dpif_netlink_set_ct_dpif_tp_tcp_attrs(nl_tp, tp);
2938
0
    } else if (nl_tp->l4num == IPPROTO_UDP) {
2939
0
        dpif_netlink_set_ct_dpif_tp_udp_attrs(nl_tp, tp);
2940
0
    } else if (nl_tp->l4num == IPPROTO_ICMP) {
2941
0
        dpif_netlink_set_ct_dpif_tp_icmp_attrs(nl_tp, tp);
2942
0
    } else if (nl_tp->l4num == IPPROTO_ICMPV6) {
2943
0
        dpif_netlink_set_ct_dpif_tp_icmpv6_attrs(nl_tp, tp);
2944
0
    }
2945
0
}
2946
2947
static int
2948
dpif_netlink_ct_set_timeout_policy(struct dpif *dpif OVS_UNUSED,
2949
                                   const struct ct_dpif_timeout_policy *tp)
2950
0
{
2951
0
    int err = 0;
2952
2953
0
    for (int i = 0; i < ARRAY_SIZE(tp_protos); ++i) {
2954
0
        struct nl_ct_timeout_policy nl_tp;
2955
0
        char *nl_tp_name;
2956
2957
0
        dpif_netlink_format_tp_name(tp->id, tp_protos[i].l3num,
2958
0
                                    tp_protos[i].l4num, &nl_tp_name);
2959
0
        ovs_strlcpy(nl_tp.name, nl_tp_name, sizeof nl_tp.name);
2960
0
        free(nl_tp_name);
2961
2962
0
        nl_tp.l3num = tp_protos[i].l3num;
2963
0
        nl_tp.l4num = tp_protos[i].l4num;
2964
0
        dpif_netlink_get_nl_tp_attrs(tp, tp_protos[i].l4num, &nl_tp);
2965
0
        err = nl_ct_set_timeout_policy(&nl_tp);
2966
0
        if (err) {
2967
0
            VLOG_WARN_RL(&error_rl, "failed to add timeout policy %s (%s)",
2968
0
                         nl_tp.name, ovs_strerror(err));
2969
0
            goto out;
2970
0
        }
2971
0
    }
2972
2973
0
out:
2974
0
    return err;
2975
0
}
2976
2977
static int
2978
dpif_netlink_ct_get_timeout_policy(struct dpif *dpif OVS_UNUSED,
2979
                                   uint32_t tp_id,
2980
                                   struct ct_dpif_timeout_policy *tp)
2981
0
{
2982
0
    int err = 0;
2983
2984
0
    tp->id = tp_id;
2985
0
    tp->present = 0;
2986
0
    for (int i = 0; i < ARRAY_SIZE(tp_protos); ++i) {
2987
0
        struct nl_ct_timeout_policy nl_tp;
2988
0
        char *nl_tp_name;
2989
2990
0
        dpif_netlink_format_tp_name(tp_id, tp_protos[i].l3num,
2991
0
                                    tp_protos[i].l4num, &nl_tp_name);
2992
0
        err = nl_ct_get_timeout_policy(nl_tp_name, &nl_tp);
2993
2994
0
        if (err) {
2995
0
            VLOG_WARN_RL(&error_rl, "failed to get timeout policy %s (%s)",
2996
0
                         nl_tp_name, ovs_strerror(err));
2997
0
            free(nl_tp_name);
2998
0
            goto out;
2999
0
        }
3000
0
        free(nl_tp_name);
3001
0
        dpif_netlink_set_ct_dpif_tp_attrs(&nl_tp, tp);
3002
0
    }
3003
3004
0
out:
3005
0
    return err;
3006
0
}
3007
3008
/* Returns 0 if all the sub timeout policies are deleted or not exist in the
3009
 * kernel.  Returns 1 if any sub timeout policy deletion failed. */
3010
static int
3011
dpif_netlink_ct_del_timeout_policy(struct dpif *dpif OVS_UNUSED,
3012
                                   uint32_t tp_id)
3013
0
{
3014
0
    int ret = 0;
3015
3016
0
    for (int i = 0; i < ARRAY_SIZE(tp_protos); ++i) {
3017
0
        char *nl_tp_name;
3018
0
        dpif_netlink_format_tp_name(tp_id, tp_protos[i].l3num,
3019
0
                                    tp_protos[i].l4num, &nl_tp_name);
3020
0
        int err = nl_ct_del_timeout_policy(nl_tp_name);
3021
0
        if (err == ENOENT) {
3022
0
            err = 0;
3023
0
        }
3024
0
        if (err) {
3025
0
            static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(6, 6);
3026
0
            VLOG_INFO_RL(&rl, "failed to delete timeout policy %s (%s)",
3027
0
                         nl_tp_name, ovs_strerror(err));
3028
0
            ret = 1;
3029
0
        }
3030
0
        free(nl_tp_name);
3031
0
    }
3032
3033
0
    return ret;
3034
0
}
3035
3036
struct dpif_netlink_ct_timeout_policy_dump_state {
3037
    struct nl_ct_timeout_policy_dump_state *nl_dump_state;
3038
    struct hmap tp_dump_map;
3039
};
3040
3041
struct dpif_netlink_tp_dump_node {
3042
    struct      hmap_node hmap_node;      /* node in tp_dump_map. */
3043
    struct      ct_dpif_timeout_policy *tp;
3044
    uint32_t    l3_l4_present;
3045
};
3046
3047
static struct dpif_netlink_tp_dump_node *
3048
get_dpif_netlink_tp_dump_node_by_tp_id(uint32_t tp_id,
3049
                                       struct hmap *tp_dump_map)
3050
0
{
3051
0
    struct dpif_netlink_tp_dump_node *tp_dump_node;
3052
3053
0
    HMAP_FOR_EACH_WITH_HASH (tp_dump_node, hmap_node, hash_int(tp_id, 0),
3054
0
                             tp_dump_map) {
3055
0
        if (tp_dump_node->tp->id == tp_id) {
3056
0
            return tp_dump_node;
3057
0
        }
3058
0
    }
3059
0
    return NULL;
3060
0
}
3061
3062
static void
3063
update_dpif_netlink_tp_dump_node(
3064
    const struct nl_ct_timeout_policy *nl_tp,
3065
    struct dpif_netlink_tp_dump_node *tp_dump_node)
3066
0
{
3067
0
    dpif_netlink_set_ct_dpif_tp_attrs(nl_tp, tp_dump_node->tp);
3068
0
    for (int i = 0; i < DPIF_NL_TP_MAX; ++i) {
3069
0
        if (nl_tp->l3num == tp_protos[i].l3num &&
3070
0
            nl_tp->l4num == tp_protos[i].l4num) {
3071
0
            tp_dump_node->l3_l4_present |= 1 << i;
3072
0
            break;
3073
0
        }
3074
0
    }
3075
0
}
3076
3077
static int
3078
dpif_netlink_ct_timeout_policy_dump_start(struct dpif *dpif OVS_UNUSED,
3079
                                          void **statep)
3080
0
{
3081
0
    struct dpif_netlink_ct_timeout_policy_dump_state *dump_state;
3082
3083
0
    *statep = dump_state = xzalloc(sizeof *dump_state);
3084
0
    int err = nl_ct_timeout_policy_dump_start(&dump_state->nl_dump_state);
3085
0
    if (err) {
3086
0
        free(dump_state);
3087
0
        return err;
3088
0
    }
3089
0
    hmap_init(&dump_state->tp_dump_map);
3090
0
    return 0;
3091
0
}
3092
3093
static void
3094
get_and_cleanup_tp_dump_node(struct hmap *hmap,
3095
                             struct dpif_netlink_tp_dump_node *tp_dump_node,
3096
                             struct ct_dpif_timeout_policy *tp)
3097
0
{
3098
0
    hmap_remove(hmap, &tp_dump_node->hmap_node);
3099
0
    *tp = *tp_dump_node->tp;
3100
0
    free(tp_dump_node->tp);
3101
0
    free(tp_dump_node);
3102
0
}
3103
3104
static int
3105
dpif_netlink_ct_timeout_policy_dump_next(struct dpif *dpif OVS_UNUSED,
3106
                                         void *state,
3107
                                         struct ct_dpif_timeout_policy *tp)
3108
0
{
3109
0
    struct dpif_netlink_ct_timeout_policy_dump_state *dump_state = state;
3110
0
    struct dpif_netlink_tp_dump_node *tp_dump_node;
3111
0
    int err;
3112
3113
    /* Dumps all the timeout policies in the kernel. */
3114
0
    do {
3115
0
        struct nl_ct_timeout_policy nl_tp;
3116
0
        uint32_t tp_id;
3117
3118
0
        err =  nl_ct_timeout_policy_dump_next(dump_state->nl_dump_state,
3119
0
                                              &nl_tp);
3120
0
        if (err) {
3121
0
            break;
3122
0
        }
3123
3124
        /* We only interest in OVS installed timeout policies. */
3125
0
        if (!ovs_scan(nl_tp.name, NL_TP_NAME_PREFIX"%"PRIu32, &tp_id)) {
3126
0
            continue;
3127
0
        }
3128
3129
0
        tp_dump_node = get_dpif_netlink_tp_dump_node_by_tp_id(
3130
0
                            tp_id, &dump_state->tp_dump_map);
3131
0
        if (!tp_dump_node) {
3132
0
            tp_dump_node = xzalloc(sizeof *tp_dump_node);
3133
0
            tp_dump_node->tp = xzalloc(sizeof *tp_dump_node->tp);
3134
0
            tp_dump_node->tp->id = tp_id;
3135
0
            hmap_insert(&dump_state->tp_dump_map, &tp_dump_node->hmap_node,
3136
0
                        hash_int(tp_id, 0));
3137
0
        }
3138
3139
0
        update_dpif_netlink_tp_dump_node(&nl_tp, tp_dump_node);
3140
3141
        /* Returns one ct_dpif_timeout_policy if we gather all the L3/L4
3142
         * sub-pieces. */
3143
0
        if (tp_dump_node->l3_l4_present == DPIF_NL_ALL_TP) {
3144
0
            get_and_cleanup_tp_dump_node(&dump_state->tp_dump_map,
3145
0
                                         tp_dump_node, tp);
3146
0
            break;
3147
0
        }
3148
0
    } while (true);
3149
3150
    /* Dump the incomplete timeout policies. */
3151
0
    if (err == EOF) {
3152
0
        if (!hmap_is_empty(&dump_state->tp_dump_map)) {
3153
0
            struct hmap_node *hmap_node = hmap_first(&dump_state->tp_dump_map);
3154
0
            tp_dump_node = CONTAINER_OF(hmap_node,
3155
0
                                        struct dpif_netlink_tp_dump_node,
3156
0
                                        hmap_node);
3157
0
            get_and_cleanup_tp_dump_node(&dump_state->tp_dump_map,
3158
0
                                         tp_dump_node, tp);
3159
0
            return 0;
3160
0
        }
3161
0
    }
3162
3163
0
    return err;
3164
0
}
3165
3166
static int
3167
dpif_netlink_ct_timeout_policy_dump_done(struct dpif *dpif OVS_UNUSED,
3168
                                         void *state)
3169
0
{
3170
0
    struct dpif_netlink_ct_timeout_policy_dump_state *dump_state = state;
3171
0
    struct dpif_netlink_tp_dump_node *tp_dump_node;
3172
3173
0
    int err = nl_ct_timeout_policy_dump_done(dump_state->nl_dump_state);
3174
0
    HMAP_FOR_EACH_POP (tp_dump_node, hmap_node, &dump_state->tp_dump_map) {
3175
0
        free(tp_dump_node->tp);
3176
0
        free(tp_dump_node);
3177
0
    }
3178
0
    hmap_destroy(&dump_state->tp_dump_map);
3179
0
    free(dump_state);
3180
0
    return err;
3181
0
}
3182
3183

3184
/* Meters */
3185
3186
/* Set of supported meter flags */
3187
#define DP_SUPPORTED_METER_FLAGS_MASK \
3188
0
    (OFPMF13_STATS | OFPMF13_PKTPS | OFPMF13_KBPS | OFPMF13_BURST)
3189
3190
/* Meter support was introduced in Linux 4.15.  In some versions of
3191
 * Linux 4.15, 4.16, and 4.17, there was a bug that never set the id
3192
 * when the meter was created, so all meters essentially had an id of
3193
 * zero.  Check for that condition and disable meters on those kernels. */
3194
static bool probe_broken_meters(struct dpif *);
3195
3196
static void
3197
dpif_netlink_meter_init(struct dpif_netlink *dpif, struct ofpbuf *buf,
3198
                        void *stub, size_t size, uint32_t command)
3199
0
{
3200
0
    ofpbuf_use_stub(buf, stub, size);
3201
3202
0
    nl_msg_put_genlmsghdr(buf, 0, ovs_meter_family, NLM_F_REQUEST | NLM_F_ECHO,
3203
0
                          command, OVS_METER_VERSION);
3204
3205
0
    struct ovs_header *ovs_header;
3206
0
    ovs_header = ofpbuf_put_uninit(buf, sizeof *ovs_header);
3207
0
    ovs_header->dp_ifindex = dpif->dp_ifindex;
3208
0
}
3209
3210
/* Execute meter 'request' in the kernel datapath.  If the command
3211
 * fails, returns a positive errno value.  Otherwise, stores the reply
3212
 * in '*replyp', parses the policy according to 'reply_policy' into the
3213
 * array of Netlink attribute in 'a', and returns 0.  On success, the
3214
 * caller is responsible for calling ofpbuf_delete() on '*replyp'
3215
 * ('replyp' will contain pointers into 'a'). */
3216
static int
3217
dpif_netlink_meter_transact(struct ofpbuf *request, struct ofpbuf **replyp,
3218
                            const struct nl_policy *reply_policy,
3219
                            struct nlattr **a, size_t size_a)
3220
0
{
3221
0
    int error = nl_transact(NETLINK_GENERIC, request, replyp);
3222
0
    ofpbuf_uninit(request);
3223
3224
0
    if (error) {
3225
0
        return error;
3226
0
    }
3227
3228
0
    struct nlmsghdr *nlmsg = ofpbuf_try_pull(*replyp, sizeof *nlmsg);
3229
0
    struct genlmsghdr *genl = ofpbuf_try_pull(*replyp, sizeof *genl);
3230
0
    struct ovs_header *ovs_header = ofpbuf_try_pull(*replyp,
3231
0
                                                    sizeof *ovs_header);
3232
0
    if (!nlmsg || !genl || !ovs_header
3233
0
        || nlmsg->nlmsg_type != ovs_meter_family
3234
0
        || !nl_policy_parse(*replyp, 0, reply_policy, a, size_a)) {
3235
0
        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
3236
0
        VLOG_DBG_RL(&rl,
3237
0
                    "Kernel module response to meter tranaction is invalid");
3238
0
        ofpbuf_delete(*replyp);
3239
0
        return EINVAL;
3240
0
    }
3241
0
    return 0;
3242
0
}
3243
3244
static void
3245
dpif_netlink_meter_get_features(const struct dpif *dpif_,
3246
                                struct ofputil_meter_features *features)
3247
0
{
3248
0
    if (probe_broken_meters(CONST_CAST(struct dpif *, dpif_))) {
3249
0
        return;
3250
0
    }
3251
3252
0
    struct ofpbuf buf, *msg;
3253
0
    uint64_t stub[1024 / 8];
3254
3255
0
    static const struct nl_policy ovs_meter_features_policy[] = {
3256
0
        [OVS_METER_ATTR_MAX_METERS] = { .type = NL_A_U32 },
3257
0
        [OVS_METER_ATTR_MAX_BANDS] = { .type = NL_A_U32 },
3258
0
        [OVS_METER_ATTR_BANDS] = { .type = NL_A_NESTED, .optional = true },
3259
0
    };
3260
0
    struct nlattr *a[ARRAY_SIZE(ovs_meter_features_policy)];
3261
3262
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
3263
0
    dpif_netlink_meter_init(dpif, &buf, stub, sizeof stub,
3264
0
                            OVS_METER_CMD_FEATURES);
3265
0
    if (dpif_netlink_meter_transact(&buf, &msg, ovs_meter_features_policy, a,
3266
0
                                    ARRAY_SIZE(ovs_meter_features_policy))) {
3267
0
        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
3268
0
        VLOG_INFO_RL(&rl,
3269
0
                  "dpif_netlink_meter_transact OVS_METER_CMD_FEATURES failed");
3270
0
        return;
3271
0
    }
3272
3273
0
    features->max_meters = nl_attr_get_u32(a[OVS_METER_ATTR_MAX_METERS]);
3274
0
    features->max_bands = nl_attr_get_u32(a[OVS_METER_ATTR_MAX_BANDS]);
3275
3276
    /* Bands is a nested attribute of zero or more nested
3277
     * band attributes.  */
3278
0
    if (a[OVS_METER_ATTR_BANDS]) {
3279
0
        const struct nlattr *nla;
3280
0
        size_t left;
3281
3282
0
        NL_NESTED_FOR_EACH (nla, left, a[OVS_METER_ATTR_BANDS]) {
3283
0
            const struct nlattr *band_nla;
3284
0
            size_t band_left;
3285
3286
0
            NL_NESTED_FOR_EACH (band_nla, band_left, nla) {
3287
0
                if (nl_attr_type(band_nla) == OVS_BAND_ATTR_TYPE) {
3288
0
                    if (nl_attr_get_size(band_nla) == sizeof(uint32_t)) {
3289
0
                        switch (nl_attr_get_u32(band_nla)) {
3290
0
                        case OVS_METER_BAND_TYPE_DROP:
3291
0
                            features->band_types |= 1 << OFPMBT13_DROP;
3292
0
                            break;
3293
0
                        }
3294
0
                    }
3295
0
                }
3296
0
            }
3297
0
        }
3298
0
    }
3299
0
    features->capabilities = DP_SUPPORTED_METER_FLAGS_MASK;
3300
3301
0
    ofpbuf_delete(msg);
3302
0
}
3303
3304
static int
3305
dpif_netlink_meter_set__(struct dpif *dpif_, ofproto_meter_id meter_id,
3306
                         struct ofputil_meter_config *config)
3307
0
{
3308
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
3309
0
    struct ofpbuf buf, *msg;
3310
0
    uint64_t stub[1024 / 8];
3311
3312
0
    static const struct nl_policy ovs_meter_set_response_policy[] = {
3313
0
        [OVS_METER_ATTR_ID] = { .type = NL_A_U32 },
3314
0
    };
3315
0
    struct nlattr *a[ARRAY_SIZE(ovs_meter_set_response_policy)];
3316
3317
0
    if (config->flags & ~DP_SUPPORTED_METER_FLAGS_MASK) {
3318
0
        return EBADF; /* Unsupported flags set */
3319
0
    }
3320
3321
0
    for (size_t i = 0; i < config->n_bands; i++) {
3322
0
        switch (config->bands[i].type) {
3323
0
        case OFPMBT13_DROP:
3324
0
            break;
3325
0
        default:
3326
0
            return ENODEV; /* Unsupported band type */
3327
0
        }
3328
0
    }
3329
3330
0
    dpif_netlink_meter_init(dpif, &buf, stub, sizeof stub, OVS_METER_CMD_SET);
3331
3332
0
    nl_msg_put_u32(&buf, OVS_METER_ATTR_ID, meter_id.uint32);
3333
3334
0
    if (config->flags & OFPMF13_KBPS) {
3335
0
        nl_msg_put_flag(&buf, OVS_METER_ATTR_KBPS);
3336
0
    }
3337
3338
0
    size_t bands_offset = nl_msg_start_nested(&buf, OVS_METER_ATTR_BANDS);
3339
    /* Bands */
3340
0
    for (size_t i = 0; i < config->n_bands; ++i) {
3341
0
        struct ofputil_meter_band * band = &config->bands[i];
3342
0
        uint32_t band_type;
3343
3344
0
        size_t band_offset = nl_msg_start_nested(&buf, OVS_BAND_ATTR_UNSPEC);
3345
3346
0
        switch (band->type) {
3347
0
        case OFPMBT13_DROP:
3348
0
            band_type = OVS_METER_BAND_TYPE_DROP;
3349
0
            break;
3350
0
        default:
3351
0
            band_type = OVS_METER_BAND_TYPE_UNSPEC;
3352
0
        }
3353
0
        nl_msg_put_u32(&buf, OVS_BAND_ATTR_TYPE, band_type);
3354
0
        nl_msg_put_u32(&buf, OVS_BAND_ATTR_RATE, band->rate);
3355
0
        nl_msg_put_u32(&buf, OVS_BAND_ATTR_BURST,
3356
0
                       config->flags & OFPMF13_BURST ?
3357
0
                       band->burst_size : band->rate);
3358
0
        nl_msg_end_nested(&buf, band_offset);
3359
0
    }
3360
0
    nl_msg_end_nested(&buf, bands_offset);
3361
3362
0
    int error = dpif_netlink_meter_transact(&buf, &msg,
3363
0
                                    ovs_meter_set_response_policy, a,
3364
0
                                    ARRAY_SIZE(ovs_meter_set_response_policy));
3365
0
    if (error) {
3366
0
        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
3367
0
        VLOG_INFO_RL(&rl,
3368
0
                     "dpif_netlink_meter_transact OVS_METER_CMD_SET failed");
3369
0
        return error;
3370
0
    }
3371
3372
0
    if (nl_attr_get_u32(a[OVS_METER_ATTR_ID]) != meter_id.uint32) {
3373
0
        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
3374
0
        VLOG_INFO_RL(&rl,
3375
0
                     "Kernel returned a different meter id than requested");
3376
0
    }
3377
0
    ofpbuf_delete(msg);
3378
0
    return 0;
3379
0
}
3380
3381
static int
3382
dpif_netlink_meter_set(struct dpif *dpif_, ofproto_meter_id meter_id,
3383
                       struct ofputil_meter_config *config)
3384
0
{
3385
0
    if (probe_broken_meters(dpif_)) {
3386
0
        return ENOMEM;
3387
0
    }
3388
3389
0
    return dpif_netlink_meter_set__(dpif_, meter_id, config);
3390
0
}
3391
3392
/* Retrieve statistics and/or delete meter 'meter_id'.  Statistics are
3393
 * stored in 'stats', if it is not null.  If 'command' is
3394
 * OVS_METER_CMD_DEL, the meter is deleted and statistics are optionally
3395
 * retrieved.  If 'command' is OVS_METER_CMD_GET, then statistics are
3396
 * simply retrieved. */
3397
static int
3398
dpif_netlink_meter_get_stats(const struct dpif *dpif_,
3399
                             ofproto_meter_id meter_id,
3400
                             struct ofputil_meter_stats *stats,
3401
                             uint16_t max_bands,
3402
                             enum ovs_meter_cmd command)
3403
0
{
3404
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
3405
0
    struct ofpbuf buf, *msg;
3406
0
    uint64_t stub[1024 / 8];
3407
3408
0
    static const struct nl_policy ovs_meter_stats_policy[] = {
3409
0
        [OVS_METER_ATTR_ID] = { .type = NL_A_U32, .optional = true},
3410
0
        [OVS_METER_ATTR_STATS] = { NL_POLICY_FOR(struct ovs_flow_stats),
3411
0
                                   .optional = true},
3412
0
        [OVS_METER_ATTR_BANDS] = { .type = NL_A_NESTED, .optional = true },
3413
0
    };
3414
0
    struct nlattr *a[ARRAY_SIZE(ovs_meter_stats_policy)];
3415
3416
0
    dpif_netlink_meter_init(dpif, &buf, stub, sizeof stub, command);
3417
3418
0
    nl_msg_put_u32(&buf, OVS_METER_ATTR_ID, meter_id.uint32);
3419
3420
0
    int error = dpif_netlink_meter_transact(&buf, &msg,
3421
0
                                            ovs_meter_stats_policy, a,
3422
0
                                            ARRAY_SIZE(ovs_meter_stats_policy));
3423
0
    if (error) {
3424
0
        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
3425
0
        VLOG_RL(&rl, error == ENOENT ? VLL_DBG : VLL_WARN,
3426
0
                "dpif_netlink_meter_transact %s failed: %s",
3427
0
                command == OVS_METER_CMD_GET ? "get" : "del",
3428
0
                ovs_strerror(error));
3429
0
        return error;
3430
0
    }
3431
3432
0
    if (a[OVS_METER_ATTR_ID]
3433
0
        && nl_attr_get_u32(a[OVS_METER_ATTR_ID]) != meter_id.uint32) {
3434
0
        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
3435
0
        VLOG_INFO_RL(&rl,
3436
0
                     "Kernel returned a different meter id than requested");
3437
0
        ofpbuf_delete(msg);
3438
0
        return EINVAL;
3439
0
    }
3440
3441
0
    if (stats && a[OVS_METER_ATTR_STATS]) {
3442
        /* return stats */
3443
0
        const struct ovs_flow_stats *stat;
3444
0
        const struct nlattr *nla;
3445
0
        size_t left;
3446
3447
0
        stat = nl_attr_get(a[OVS_METER_ATTR_STATS]);
3448
0
        stats->packet_in_count = get_32aligned_u64(&stat->n_packets);
3449
0
        stats->byte_in_count = get_32aligned_u64(&stat->n_bytes);
3450
3451
0
        if (a[OVS_METER_ATTR_BANDS]) {
3452
0
            size_t n_bands = 0;
3453
0
            NL_NESTED_FOR_EACH (nla, left, a[OVS_METER_ATTR_BANDS]) {
3454
0
                const struct nlattr *band_nla;
3455
0
                band_nla = nl_attr_find_nested(nla, OVS_BAND_ATTR_STATS);
3456
0
                if (band_nla && nl_attr_get_size(band_nla) \
3457
0
                                == sizeof(struct ovs_flow_stats)) {
3458
0
                    stat = nl_attr_get(band_nla);
3459
3460
0
                    if (n_bands < max_bands) {
3461
0
                        stats->bands[n_bands].packet_count
3462
0
                            = get_32aligned_u64(&stat->n_packets);
3463
0
                        stats->bands[n_bands].byte_count
3464
0
                            = get_32aligned_u64(&stat->n_bytes);
3465
0
                        ++n_bands;
3466
0
                    }
3467
0
                } else {
3468
0
                    stats->bands[n_bands].packet_count = 0;
3469
0
                    stats->bands[n_bands].byte_count = 0;
3470
0
                    ++n_bands;
3471
0
                }
3472
0
            }
3473
0
            stats->n_bands = n_bands;
3474
0
        } else {
3475
            /* For a non-existent meter, return 0 stats. */
3476
0
            stats->n_bands = 0;
3477
0
        }
3478
0
    }
3479
3480
0
    ofpbuf_delete(msg);
3481
0
    return error;
3482
0
}
3483
3484
static int
3485
dpif_netlink_meter_get(const struct dpif *dpif, ofproto_meter_id meter_id,
3486
                       struct ofputil_meter_stats *stats, uint16_t max_bands)
3487
0
{
3488
0
    return dpif_netlink_meter_get_stats(dpif, meter_id, stats, max_bands,
3489
0
                                        OVS_METER_CMD_GET);
3490
0
}
3491
3492
static int
3493
dpif_netlink_meter_del(struct dpif *dpif, ofproto_meter_id meter_id,
3494
                       struct ofputil_meter_stats *stats, uint16_t max_bands)
3495
0
{
3496
0
    return dpif_netlink_meter_get_stats(dpif, meter_id, stats,
3497
0
                                        max_bands, OVS_METER_CMD_DEL);
3498
0
}
3499
3500
static bool
3501
probe_broken_meters__(struct dpif *dpif)
3502
0
{
3503
    /* This test is destructive if a probe occurs while ovs-vswitchd is
3504
     * running (e.g., an ovs-dpctl meter command is called), so choose a
3505
     * high meter id to make this less likely to occur.
3506
     *
3507
     * In Linux kernel v5.10+ meters are stored in a table that is not
3508
     * a real hash table.  It's just an array with 'meter_id % size' used
3509
     * as an index.  The numbers are chosen to fit into the minimal table
3510
     * size (1024) without wrapping, so these IDs are guaranteed to be
3511
     * found under normal conditions in the meter table, if such meters
3512
     * exist.  It's possible to break this check by creating some meters
3513
     * in the kernel manually with different IDs that map onto the same
3514
     * indexes, but that should not be a big problem since ovs-vswitchd
3515
     * always allocates densely packed meter IDs with an id-pool.
3516
     *
3517
     * These IDs will also work in cases where the table in the kernel is
3518
     * a proper hash table. */
3519
0
    ofproto_meter_id id1 = { 1021 };
3520
0
    ofproto_meter_id id2 = { 1022 };
3521
0
    struct ofputil_meter_band band = {OFPMBT13_DROP, 0, 1, 0};
3522
0
    struct ofputil_meter_config config1 = { 1, OFPMF13_KBPS, 1, &band};
3523
0
    struct ofputil_meter_config config2 = { 2, OFPMF13_KBPS, 1, &band};
3524
3525
    /* First check if these meters are already in the kernel.  If we get
3526
     * a proper response from the kernel with all the good meter IDs, then
3527
     * meters are likley supported correctly. */
3528
0
    if (!dpif_netlink_meter_get(dpif, id1, NULL, 0)
3529
0
        || !dpif_netlink_meter_get(dpif, id2, NULL, 0)) {
3530
0
        return false;
3531
0
    }
3532
3533
    /* Try adding two meters and make sure that they both come back with
3534
     * the proper meter id.  Use the "__" version so that we don't cause
3535
     * a recurve deadlock. */
3536
0
    dpif_netlink_meter_set__(dpif, id1, &config1);
3537
0
    dpif_netlink_meter_set__(dpif, id2, &config2);
3538
3539
0
    if (dpif_netlink_meter_get(dpif, id1, NULL, 0)
3540
0
        || dpif_netlink_meter_get(dpif, id2, NULL, 0)) {
3541
0
        VLOG_INFO("The kernel module has a broken meter implementation.");
3542
0
        return true;
3543
0
    }
3544
3545
0
    dpif_netlink_meter_del(dpif, id1, NULL, 0);
3546
0
    dpif_netlink_meter_del(dpif, id2, NULL, 0);
3547
3548
0
    return false;
3549
0
}
3550
3551
static bool
3552
probe_broken_meters(struct dpif *dpif)
3553
0
{
3554
    /* This is a once-only test because currently OVS only has at most a single
3555
     * Netlink capable datapath on any given platform. */
3556
0
    static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
3557
3558
0
    static bool broken_meters = false;
3559
0
    if (ovsthread_once_start(&once)) {
3560
0
        broken_meters = probe_broken_meters__(dpif);
3561
0
        ovsthread_once_done(&once);
3562
0
    }
3563
0
    return broken_meters;
3564
0
}
3565
3566
3567
static int
3568
dpif_netlink_cache_get_supported_levels(struct dpif *dpif_, uint32_t *levels)
3569
0
{
3570
0
    struct dpif_netlink_dp dp;
3571
0
    struct ofpbuf *buf;
3572
0
    int error;
3573
3574
    /* If available, in the kernel we support one level of cache.
3575
     * Unfortunately, there is no way to detect if the older kernel module has
3576
     * the cache feature.  For now, we only report the cache information if the
3577
     * kernel module reports the OVS_DP_ATTR_MASKS_CACHE_SIZE attribute. */
3578
3579
0
    *levels = 0;
3580
0
    error = dpif_netlink_dp_get(dpif_, &dp, &buf);
3581
0
    if (!error) {
3582
3583
0
        if (dp.cache_size != UINT32_MAX) {
3584
0
            *levels = 1;
3585
0
        }
3586
0
        ofpbuf_delete(buf);
3587
0
    }
3588
3589
0
    return error;
3590
0
}
3591
3592
static int
3593
dpif_netlink_cache_get_name(struct dpif *dpif_ OVS_UNUSED, uint32_t level,
3594
                            const char **name)
3595
0
{
3596
0
    if (level != 0) {
3597
0
        return EINVAL;
3598
0
    }
3599
3600
0
    *name = "masks-cache";
3601
0
    return 0;
3602
0
}
3603
3604
static int
3605
dpif_netlink_cache_get_size(struct dpif *dpif_, uint32_t level, uint32_t *size)
3606
0
{
3607
0
    struct dpif_netlink_dp dp;
3608
0
    struct ofpbuf *buf;
3609
0
    int error;
3610
3611
0
    if (level != 0) {
3612
0
        return EINVAL;
3613
0
    }
3614
3615
0
    error = dpif_netlink_dp_get(dpif_, &dp, &buf);
3616
0
    if (!error) {
3617
3618
0
        ofpbuf_delete(buf);
3619
3620
0
        if (dp.cache_size == UINT32_MAX) {
3621
0
            return EOPNOTSUPP;
3622
0
        }
3623
0
        *size = dp.cache_size;
3624
0
    }
3625
0
    return error;
3626
0
}
3627
3628
static int
3629
dpif_netlink_cache_set_size(struct dpif *dpif_, uint32_t level, uint32_t size)
3630
0
{
3631
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
3632
0
    struct dpif_netlink_dp request, reply;
3633
0
    struct ofpbuf *bufp;
3634
0
    int error;
3635
3636
0
    size = ROUND_UP_POW2(size);
3637
3638
0
    if (level != 0) {
3639
0
        return EINVAL;
3640
0
    }
3641
3642
0
    dpif_netlink_dp_init(&request);
3643
0
    request.cmd = OVS_DP_CMD_SET;
3644
0
    request.name = dpif_->base_name;
3645
0
    request.dp_ifindex = dpif->dp_ifindex;
3646
0
    request.cache_size = size;
3647
    /* We need to set the dpif user_features, as the kernel module assumes the
3648
     * OVS_DP_ATTR_USER_FEATURES attribute is always present. If not, it will
3649
     * reset all the features. */
3650
0
    request.user_features = dpif->user_features;
3651
3652
0
    error = dpif_netlink_dp_transact(&request, &reply, &bufp);
3653
0
    if (!error) {
3654
0
        ofpbuf_delete(bufp);
3655
0
        if (reply.cache_size != size) {
3656
0
            return EINVAL;
3657
0
        }
3658
0
    }
3659
3660
0
    return error;
3661
0
}
3662
3663

3664
const struct dpif_class dpif_netlink_class = {
3665
    "system",
3666
    false,                      /* cleanup_required */
3667
    NULL,                       /* init */
3668
    dpif_netlink_enumerate,
3669
    NULL,
3670
    dpif_netlink_open,
3671
    dpif_netlink_close,
3672
    dpif_netlink_destroy,
3673
    dpif_netlink_run,
3674
    NULL,                       /* wait */
3675
    dpif_netlink_get_stats,
3676
    dpif_netlink_set_features,
3677
    dpif_netlink_get_features,
3678
    dpif_netlink_port_add,
3679
    dpif_netlink_port_del,
3680
    NULL,                       /* port_set_config */
3681
    dpif_netlink_port_query_by_number,
3682
    dpif_netlink_port_query_by_name,
3683
    dpif_netlink_port_get_pid,
3684
    dpif_netlink_port_dump_start,
3685
    dpif_netlink_port_dump_next,
3686
    dpif_netlink_port_dump_done,
3687
    dpif_netlink_port_poll,
3688
    dpif_netlink_port_poll_wait,
3689
    dpif_netlink_flow_flush,
3690
    dpif_netlink_flow_dump_create,
3691
    dpif_netlink_flow_dump_destroy,
3692
    dpif_netlink_flow_dump_thread_create,
3693
    dpif_netlink_flow_dump_thread_destroy,
3694
    dpif_netlink_flow_dump_next,
3695
    dpif_netlink_operate,
3696
    dpif_netlink_recv_set,
3697
    dpif_netlink_handlers_set,
3698
    dpif_netlink_number_handlers_required,
3699
    NULL,                       /* set_config */
3700
    dpif_netlink_queue_to_priority,
3701
    dpif_netlink_recv,
3702
    dpif_netlink_recv_wait,
3703
    dpif_netlink_recv_purge,
3704
    NULL,                       /* register_dp_purge_cb */
3705
    NULL,                       /* register_upcall_cb */
3706
    NULL,                       /* enable_upcall */
3707
    NULL,                       /* disable_upcall */
3708
    dpif_netlink_get_datapath_version, /* get_datapath_version */
3709
    dpif_netlink_ct_dump_start,
3710
    dpif_netlink_ct_dump_next,
3711
    dpif_netlink_ct_dump_done,
3712
    NULL,                       /* ct_exp_dump_start */
3713
    NULL,                       /* ct_exp_dump_next */
3714
    NULL,                       /* ct_exp_dump_done */
3715
    dpif_netlink_ct_flush,
3716
    NULL,                       /* ct_set_maxconns */
3717
    NULL,                       /* ct_get_maxconns */
3718
    NULL,                       /* ct_get_nconns */
3719
    NULL,                       /* ct_set_tcp_seq_chk */
3720
    NULL,                       /* ct_get_tcp_seq_chk */
3721
    NULL,                       /* ct_set_sweep_interval */
3722
    NULL,                       /* ct_get_sweep_interval */
3723
    dpif_netlink_ct_set_limits,
3724
    dpif_netlink_ct_get_limits,
3725
    dpif_netlink_ct_del_limits,
3726
    dpif_netlink_ct_set_timeout_policy,
3727
    dpif_netlink_ct_get_timeout_policy,
3728
    dpif_netlink_ct_del_timeout_policy,
3729
    dpif_netlink_ct_timeout_policy_dump_start,
3730
    dpif_netlink_ct_timeout_policy_dump_next,
3731
    dpif_netlink_ct_timeout_policy_dump_done,
3732
    dpif_netlink_ct_get_timeout_policy_name,
3733
    dpif_netlink_ct_get_features,
3734
    NULL,                       /* ipf_set_enabled */
3735
    NULL,                       /* ipf_set_min_frag */
3736
    NULL,                       /* ipf_set_max_nfrags */
3737
    NULL,                       /* ipf_get_status */
3738
    NULL,                       /* ipf_dump_start */
3739
    NULL,                       /* ipf_dump_next */
3740
    NULL,                       /* ipf_dump_done */
3741
    dpif_netlink_meter_get_features,
3742
    dpif_netlink_meter_set,
3743
    dpif_netlink_meter_get,
3744
    dpif_netlink_meter_del,
3745
    NULL,                       /* bond_add */
3746
    NULL,                       /* bond_del */
3747
    NULL,                       /* bond_stats_get */
3748
    dpif_netlink_cache_get_supported_levels,
3749
    dpif_netlink_cache_get_name,
3750
    dpif_netlink_cache_get_size,
3751
    dpif_netlink_cache_set_size,
3752
};
3753
3754
static int
3755
dpif_netlink_init(void)
3756
0
{
3757
0
    static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
3758
0
    static int error;
3759
3760
0
    if (ovsthread_once_start(&once)) {
3761
0
        error = nl_lookup_genl_family(OVS_DATAPATH_FAMILY,
3762
0
                                      &ovs_datapath_family);
3763
0
        if (error) {
3764
0
            VLOG_INFO("Generic Netlink family '%s' does not exist. "
3765
0
                      "The Open vSwitch kernel module is probably not loaded.",
3766
0
                      OVS_DATAPATH_FAMILY);
3767
0
        }
3768
0
        if (!error) {
3769
0
            error = nl_lookup_genl_family(OVS_VPORT_FAMILY, &ovs_vport_family);
3770
0
        }
3771
0
        if (!error) {
3772
0
            error = nl_lookup_genl_family(OVS_FLOW_FAMILY, &ovs_flow_family);
3773
0
        }
3774
0
        if (!error) {
3775
0
            error = nl_lookup_genl_family(OVS_PACKET_FAMILY,
3776
0
                                          &ovs_packet_family);
3777
0
        }
3778
0
        if (!error) {
3779
0
            error = nl_lookup_genl_mcgroup(OVS_VPORT_FAMILY, OVS_VPORT_MCGROUP,
3780
0
                                           &ovs_vport_mcgroup);
3781
0
        }
3782
0
        if (!error) {
3783
0
            if (nl_lookup_genl_family(OVS_METER_FAMILY, &ovs_meter_family)) {
3784
0
                VLOG_INFO("The kernel module does not support meters.");
3785
0
            }
3786
0
        }
3787
0
        if (nl_lookup_genl_family(OVS_CT_LIMIT_FAMILY,
3788
0
                                  &ovs_ct_limit_family) < 0) {
3789
0
            VLOG_INFO("Generic Netlink family '%s' does not exist. "
3790
0
                      "Please update the Open vSwitch kernel module to enable "
3791
0
                      "the conntrack limit feature.", OVS_CT_LIMIT_FAMILY);
3792
0
        }
3793
3794
0
        unixctl_command_register("dpif-netlink/dispatch-mode", "", 0, 0,
3795
0
                                 dpif_netlink_unixctl_dispatch_mode, NULL);
3796
3797
0
        ovsthread_once_done(&once);
3798
0
    }
3799
3800
0
    return error;
3801
0
}
3802
3803
bool
3804
dpif_netlink_is_internal_device(const char *name)
3805
0
{
3806
0
    struct dpif_netlink_vport reply;
3807
0
    struct ofpbuf *buf;
3808
0
    int error;
3809
3810
0
    error = dpif_netlink_vport_get(name, &reply, &buf);
3811
0
    if (!error) {
3812
0
        ofpbuf_delete(buf);
3813
0
    } else if (error != ENODEV && error != ENOENT) {
3814
0
        VLOG_WARN_RL(&error_rl, "%s: vport query failed (%s)",
3815
0
                     name, ovs_strerror(error));
3816
0
    }
3817
3818
0
    return reply.type == OVS_VPORT_TYPE_INTERNAL;
3819
0
}
3820
3821
/* Parses the contents of 'buf', which contains a "struct ovs_header" followed
3822
 * by Netlink attributes, into 'vport'.  Returns 0 if successful, otherwise a
3823
 * positive errno value.
3824
 *
3825
 * 'vport' will contain pointers into 'buf', so the caller should not free
3826
 * 'buf' while 'vport' is still in use. */
3827
static int
3828
dpif_netlink_vport_from_ofpbuf(struct dpif_netlink_vport *vport,
3829
                             const struct ofpbuf *buf)
3830
0
{
3831
0
    static const struct nl_policy ovs_vport_policy[] = {
3832
0
        [OVS_VPORT_ATTR_PORT_NO] = { .type = NL_A_U32 },
3833
0
        [OVS_VPORT_ATTR_TYPE] = { .type = NL_A_U32 },
3834
0
        [OVS_VPORT_ATTR_NAME] = { .type = NL_A_STRING, .max_len = IFNAMSIZ },
3835
0
        [OVS_VPORT_ATTR_UPCALL_PID] = { .type = NL_A_UNSPEC },
3836
0
        [OVS_VPORT_ATTR_STATS] = { NL_POLICY_FOR(struct ovs_vport_stats),
3837
0
                                   .optional = true },
3838
0
        [OVS_VPORT_ATTR_NETNSID] = { .type = NL_A_U32, .optional = true },
3839
0
        [OVS_VPORT_ATTR_UPCALL_STATS] = { .type = NL_A_NESTED,
3840
0
                                          .optional = true },
3841
0
    };
3842
3843
0
    dpif_netlink_vport_init(vport);
3844
3845
0
    struct ofpbuf b = ofpbuf_const_initializer(buf->data, buf->size);
3846
0
    struct nlmsghdr *nlmsg = ofpbuf_try_pull(&b, sizeof *nlmsg);
3847
0
    struct genlmsghdr *genl = ofpbuf_try_pull(&b, sizeof *genl);
3848
0
    struct ovs_header *ovs_header = ofpbuf_try_pull(&b, sizeof *ovs_header);
3849
3850
0
    struct nlattr *a[ARRAY_SIZE(ovs_vport_policy)];
3851
0
    if (!nlmsg || !genl || !ovs_header
3852
0
        || nlmsg->nlmsg_type != ovs_vport_family
3853
0
        || !nl_policy_parse(&b, 0, ovs_vport_policy, a,
3854
0
                            ARRAY_SIZE(ovs_vport_policy))) {
3855
0
        return EINVAL;
3856
0
    }
3857
3858
0
    vport->cmd = genl->cmd;
3859
0
    vport->dp_ifindex = ovs_header->dp_ifindex;
3860
0
    vport->port_no = nl_attr_get_odp_port(a[OVS_VPORT_ATTR_PORT_NO]);
3861
0
    vport->type = nl_attr_get_u32(a[OVS_VPORT_ATTR_TYPE]);
3862
0
    vport->name = nl_attr_get_string(a[OVS_VPORT_ATTR_NAME]);
3863
0
    if (a[OVS_VPORT_ATTR_UPCALL_PID]) {
3864
0
        vport->n_upcall_pids = nl_attr_get_size(a[OVS_VPORT_ATTR_UPCALL_PID])
3865
0
                               / (sizeof *vport->upcall_pids);
3866
0
        vport->upcall_pids = nl_attr_get(a[OVS_VPORT_ATTR_UPCALL_PID]);
3867
3868
0
    }
3869
0
    if (a[OVS_VPORT_ATTR_STATS]) {
3870
0
        vport->stats = nl_attr_get(a[OVS_VPORT_ATTR_STATS]);
3871
0
    }
3872
0
    if (a[OVS_VPORT_ATTR_UPCALL_STATS]) {
3873
0
        const struct nlattr *nla;
3874
0
        size_t left;
3875
3876
0
        NL_NESTED_FOR_EACH (nla, left, a[OVS_VPORT_ATTR_UPCALL_STATS]) {
3877
0
            if (nl_attr_type(nla) == OVS_VPORT_UPCALL_ATTR_SUCCESS) {
3878
0
                vport->upcall_success = nl_attr_get_u64(nla);
3879
0
            } else if (nl_attr_type(nla) == OVS_VPORT_UPCALL_ATTR_FAIL) {
3880
0
                vport->upcall_fail = nl_attr_get_u64(nla);
3881
0
            }
3882
0
        }
3883
0
    } else {
3884
0
        vport->upcall_success = UINT64_MAX;
3885
0
        vport->upcall_fail = UINT64_MAX;
3886
0
    }
3887
0
    if (a[OVS_VPORT_ATTR_NETNSID]) {
3888
0
        netnsid_set(&vport->netnsid,
3889
0
                    nl_attr_get_u32(a[OVS_VPORT_ATTR_NETNSID]));
3890
0
    } else {
3891
0
        netnsid_set_local(&vport->netnsid);
3892
0
    }
3893
0
    return 0;
3894
0
}
3895
3896
/* Appends to 'buf' (which must initially be empty) a "struct ovs_header"
3897
 * followed by Netlink attributes corresponding to 'vport'. */
3898
static void
3899
dpif_netlink_vport_to_ofpbuf(const struct dpif_netlink_vport *vport,
3900
                             struct ofpbuf *buf)
3901
0
{
3902
0
    struct ovs_header *ovs_header;
3903
3904
0
    nl_msg_put_genlmsghdr(buf, 0, ovs_vport_family, NLM_F_REQUEST | NLM_F_ECHO,
3905
0
                          vport->cmd, OVS_VPORT_VERSION);
3906
3907
0
    ovs_header = ofpbuf_put_uninit(buf, sizeof *ovs_header);
3908
0
    ovs_header->dp_ifindex = vport->dp_ifindex;
3909
3910
0
    if (vport->port_no != ODPP_NONE) {
3911
0
        nl_msg_put_odp_port(buf, OVS_VPORT_ATTR_PORT_NO, vport->port_no);
3912
0
    }
3913
3914
0
    if (vport->type != OVS_VPORT_TYPE_UNSPEC) {
3915
0
        nl_msg_put_u32(buf, OVS_VPORT_ATTR_TYPE, vport->type);
3916
0
    }
3917
3918
0
    if (vport->name) {
3919
0
        nl_msg_put_string(buf, OVS_VPORT_ATTR_NAME, vport->name);
3920
0
    }
3921
3922
0
    if (vport->upcall_pids) {
3923
0
        nl_msg_put_unspec(buf, OVS_VPORT_ATTR_UPCALL_PID,
3924
0
                          vport->upcall_pids,
3925
0
                          vport->n_upcall_pids * sizeof *vport->upcall_pids);
3926
0
    }
3927
3928
0
    if (vport->stats) {
3929
0
        nl_msg_put_unspec(buf, OVS_VPORT_ATTR_STATS,
3930
0
                          vport->stats, sizeof *vport->stats);
3931
0
    }
3932
0
}
3933
3934
/* Clears 'vport' to "empty" values. */
3935
void
3936
dpif_netlink_vport_init(struct dpif_netlink_vport *vport)
3937
0
{
3938
0
    memset(vport, 0, sizeof *vport);
3939
0
    vport->port_no = ODPP_NONE;
3940
0
}
3941
3942
/* Executes 'request' in the kernel datapath.  If the command fails, returns a
3943
 * positive errno value.  Otherwise, if 'reply' and 'bufp' are null, returns 0
3944
 * without doing anything else.  If 'reply' and 'bufp' are nonnull, then the
3945
 * result of the command is expected to be an ovs_vport also, which is decoded
3946
 * and stored in '*reply' and '*bufp'.  The caller must free '*bufp' when the
3947
 * reply is no longer needed ('reply' will contain pointers into '*bufp'). */
3948
int
3949
dpif_netlink_vport_transact(const struct dpif_netlink_vport *request,
3950
                            struct dpif_netlink_vport *reply,
3951
                            struct ofpbuf **bufp)
3952
0
{
3953
0
    struct ofpbuf *request_buf;
3954
0
    int error;
3955
3956
0
    ovs_assert((reply != NULL) == (bufp != NULL));
3957
3958
0
    error = dpif_netlink_init();
3959
0
    if (error) {
3960
0
        if (reply) {
3961
0
            *bufp = NULL;
3962
0
            dpif_netlink_vport_init(reply);
3963
0
        }
3964
0
        return error;
3965
0
    }
3966
3967
0
    request_buf = ofpbuf_new(1024);
3968
0
    dpif_netlink_vport_to_ofpbuf(request, request_buf);
3969
0
    error = nl_transact(NETLINK_GENERIC, request_buf, bufp);
3970
0
    ofpbuf_delete(request_buf);
3971
3972
0
    if (reply) {
3973
0
        if (!error) {
3974
0
            error = dpif_netlink_vport_from_ofpbuf(reply, *bufp);
3975
0
        }
3976
0
        if (error) {
3977
0
            dpif_netlink_vport_init(reply);
3978
0
            ofpbuf_delete(*bufp);
3979
0
            *bufp = NULL;
3980
0
        }
3981
0
    }
3982
0
    return error;
3983
0
}
3984
3985
/* Obtains information about the kernel vport named 'name' and stores it into
3986
 * '*reply' and '*bufp'.  The caller must free '*bufp' when the reply is no
3987
 * longer needed ('reply' will contain pointers into '*bufp').  */
3988
int
3989
dpif_netlink_vport_get(const char *name, struct dpif_netlink_vport *reply,
3990
                       struct ofpbuf **bufp)
3991
0
{
3992
0
    struct dpif_netlink_vport request;
3993
3994
0
    dpif_netlink_vport_init(&request);
3995
0
    request.cmd = OVS_VPORT_CMD_GET;
3996
0
    request.name = name;
3997
3998
0
    return dpif_netlink_vport_transact(&request, reply, bufp);
3999
0
}
4000
4001
/* Parses the contents of 'buf', which contains a "struct ovs_header" followed
4002
 * by Netlink attributes, into 'dp'.  Returns 0 if successful, otherwise a
4003
 * positive errno value.
4004
 *
4005
 * 'dp' will contain pointers into 'buf', so the caller should not free 'buf'
4006
 * while 'dp' is still in use. */
4007
static int
4008
dpif_netlink_dp_from_ofpbuf(struct dpif_netlink_dp *dp, const struct ofpbuf *buf)
4009
0
{
4010
0
    static const struct nl_policy ovs_datapath_policy[] = {
4011
0
        [OVS_DP_ATTR_NAME] = { .type = NL_A_STRING, .max_len = IFNAMSIZ },
4012
0
        [OVS_DP_ATTR_STATS] = { NL_POLICY_FOR(struct ovs_dp_stats),
4013
0
                                .optional = true },
4014
0
        [OVS_DP_ATTR_MEGAFLOW_STATS] = {
4015
0
                        NL_POLICY_FOR(struct ovs_dp_megaflow_stats),
4016
0
                        .optional = true },
4017
0
        [OVS_DP_ATTR_USER_FEATURES] = {
4018
0
                        .type = NL_A_U32,
4019
0
                        .optional = true },
4020
0
        [OVS_DP_ATTR_MASKS_CACHE_SIZE] = {
4021
0
                        .type = NL_A_U32,
4022
0
                        .optional = true },
4023
0
    };
4024
4025
0
    dpif_netlink_dp_init(dp);
4026
4027
0
    struct ofpbuf b = ofpbuf_const_initializer(buf->data, buf->size);
4028
0
    struct nlmsghdr *nlmsg = ofpbuf_try_pull(&b, sizeof *nlmsg);
4029
0
    struct genlmsghdr *genl = ofpbuf_try_pull(&b, sizeof *genl);
4030
0
    struct ovs_header *ovs_header = ofpbuf_try_pull(&b, sizeof *ovs_header);
4031
4032
0
    struct nlattr *a[ARRAY_SIZE(ovs_datapath_policy)];
4033
0
    if (!nlmsg || !genl || !ovs_header
4034
0
        || nlmsg->nlmsg_type != ovs_datapath_family
4035
0
        || !nl_policy_parse(&b, 0, ovs_datapath_policy, a,
4036
0
                            ARRAY_SIZE(ovs_datapath_policy))) {
4037
0
        return EINVAL;
4038
0
    }
4039
4040
0
    dp->cmd = genl->cmd;
4041
0
    dp->dp_ifindex = ovs_header->dp_ifindex;
4042
0
    dp->name = nl_attr_get_string(a[OVS_DP_ATTR_NAME]);
4043
0
    if (a[OVS_DP_ATTR_STATS]) {
4044
0
        dp->stats = nl_attr_get(a[OVS_DP_ATTR_STATS]);
4045
0
    }
4046
4047
0
    if (a[OVS_DP_ATTR_MEGAFLOW_STATS]) {
4048
0
        dp->megaflow_stats = nl_attr_get(a[OVS_DP_ATTR_MEGAFLOW_STATS]);
4049
0
    }
4050
4051
0
    if (a[OVS_DP_ATTR_USER_FEATURES]) {
4052
0
        dp->user_features = nl_attr_get_u32(a[OVS_DP_ATTR_USER_FEATURES]);
4053
0
    }
4054
4055
0
    if (a[OVS_DP_ATTR_MASKS_CACHE_SIZE]) {
4056
0
        dp->cache_size = nl_attr_get_u32(a[OVS_DP_ATTR_MASKS_CACHE_SIZE]);
4057
0
    } else {
4058
0
        dp->cache_size = UINT32_MAX;
4059
0
    }
4060
4061
0
    return 0;
4062
0
}
4063
4064
/* Appends to 'buf' the Generic Netlink message described by 'dp'. */
4065
static void
4066
dpif_netlink_dp_to_ofpbuf(const struct dpif_netlink_dp *dp, struct ofpbuf *buf)
4067
0
{
4068
0
    struct ovs_header *ovs_header;
4069
4070
0
    nl_msg_put_genlmsghdr(buf, 0, ovs_datapath_family,
4071
0
                          NLM_F_REQUEST | NLM_F_ECHO, dp->cmd,
4072
0
                          OVS_DATAPATH_VERSION);
4073
4074
0
    ovs_header = ofpbuf_put_uninit(buf, sizeof *ovs_header);
4075
0
    ovs_header->dp_ifindex = dp->dp_ifindex;
4076
4077
0
    if (dp->name) {
4078
0
        nl_msg_put_string(buf, OVS_DP_ATTR_NAME, dp->name);
4079
0
    }
4080
4081
0
    if (dp->upcall_pid) {
4082
0
        nl_msg_put_u32(buf, OVS_DP_ATTR_UPCALL_PID, *dp->upcall_pid);
4083
0
    }
4084
4085
0
    if (dp->user_features) {
4086
0
        nl_msg_put_u32(buf, OVS_DP_ATTR_USER_FEATURES, dp->user_features);
4087
0
    }
4088
4089
0
    if (dp->upcall_pids) {
4090
0
        nl_msg_put_unspec(buf, OVS_DP_ATTR_PER_CPU_PIDS, dp->upcall_pids,
4091
0
                          sizeof *dp->upcall_pids * dp->n_upcall_pids);
4092
0
    }
4093
4094
0
    if (dp->cache_size != UINT32_MAX) {
4095
0
        nl_msg_put_u32(buf, OVS_DP_ATTR_MASKS_CACHE_SIZE, dp->cache_size);
4096
0
    }
4097
4098
    /* Skip OVS_DP_ATTR_STATS since we never have a reason to serialize it. */
4099
0
}
4100
4101
/* Clears 'dp' to "empty" values. */
4102
static void
4103
dpif_netlink_dp_init(struct dpif_netlink_dp *dp)
4104
0
{
4105
0
    memset(dp, 0, sizeof *dp);
4106
0
    dp->cache_size = UINT32_MAX;
4107
0
}
4108
4109
static void
4110
dpif_netlink_dp_dump_start(struct nl_dump *dump)
4111
0
{
4112
0
    struct dpif_netlink_dp request;
4113
0
    struct ofpbuf *buf;
4114
4115
0
    dpif_netlink_dp_init(&request);
4116
0
    request.cmd = OVS_DP_CMD_GET;
4117
4118
0
    buf = ofpbuf_new(1024);
4119
0
    dpif_netlink_dp_to_ofpbuf(&request, buf);
4120
0
    nl_dump_start(dump, NETLINK_GENERIC, buf);
4121
0
    ofpbuf_delete(buf);
4122
0
}
4123
4124
/* Executes 'request' in the kernel datapath.  If the command fails, returns a
4125
 * positive errno value.  Otherwise, if 'reply' and 'bufp' are null, returns 0
4126
 * without doing anything else.  If 'reply' and 'bufp' are nonnull, then the
4127
 * result of the command is expected to be of the same form, which is decoded
4128
 * and stored in '*reply' and '*bufp'.  The caller must free '*bufp' when the
4129
 * reply is no longer needed ('reply' will contain pointers into '*bufp'). */
4130
static int
4131
dpif_netlink_dp_transact(const struct dpif_netlink_dp *request,
4132
                         struct dpif_netlink_dp *reply, struct ofpbuf **bufp)
4133
0
{
4134
0
    struct ofpbuf *request_buf;
4135
0
    int error;
4136
4137
0
    ovs_assert((reply != NULL) == (bufp != NULL));
4138
4139
0
    request_buf = ofpbuf_new(1024);
4140
0
    dpif_netlink_dp_to_ofpbuf(request, request_buf);
4141
0
    error = nl_transact(NETLINK_GENERIC, request_buf, bufp);
4142
0
    ofpbuf_delete(request_buf);
4143
4144
0
    if (reply) {
4145
0
        dpif_netlink_dp_init(reply);
4146
0
        if (!error) {
4147
0
            error = dpif_netlink_dp_from_ofpbuf(reply, *bufp);
4148
0
        }
4149
0
        if (error) {
4150
0
            ofpbuf_delete(*bufp);
4151
0
            *bufp = NULL;
4152
0
        }
4153
0
    }
4154
0
    return error;
4155
0
}
4156
4157
/* Obtains information about 'dpif_' and stores it into '*reply' and '*bufp'.
4158
 * The caller must free '*bufp' when the reply is no longer needed ('reply'
4159
 * will contain pointers into '*bufp').  */
4160
static int
4161
dpif_netlink_dp_get(const struct dpif *dpif_, struct dpif_netlink_dp *reply,
4162
                    struct ofpbuf **bufp)
4163
0
{
4164
0
    struct dpif_netlink *dpif = dpif_netlink_cast(dpif_);
4165
0
    struct dpif_netlink_dp request;
4166
4167
0
    dpif_netlink_dp_init(&request);
4168
0
    request.cmd = OVS_DP_CMD_GET;
4169
0
    request.dp_ifindex = dpif->dp_ifindex;
4170
4171
0
    return dpif_netlink_dp_transact(&request, reply, bufp);
4172
0
}
4173
4174
/* Parses the contents of 'buf', which contains a "struct ovs_header" followed
4175
 * by Netlink attributes, into 'flow'.  Returns 0 if successful, otherwise a
4176
 * positive errno value.
4177
 *
4178
 * 'flow' will contain pointers into 'buf', so the caller should not free 'buf'
4179
 * while 'flow' is still in use. */
4180
static int
4181
dpif_netlink_flow_from_ofpbuf(struct dpif_netlink_flow *flow,
4182
                              const struct ofpbuf *buf)
4183
0
{
4184
0
    static const struct nl_policy ovs_flow_policy[__OVS_FLOW_ATTR_MAX] = {
4185
0
        [OVS_FLOW_ATTR_KEY] = { .type = NL_A_NESTED, .optional = true },
4186
0
        [OVS_FLOW_ATTR_MASK] = { .type = NL_A_NESTED, .optional = true },
4187
0
        [OVS_FLOW_ATTR_ACTIONS] = { .type = NL_A_NESTED, .optional = true },
4188
0
        [OVS_FLOW_ATTR_STATS] = { NL_POLICY_FOR(struct ovs_flow_stats),
4189
0
                                  .optional = true },
4190
0
        [OVS_FLOW_ATTR_TCP_FLAGS] = { .type = NL_A_U8, .optional = true },
4191
0
        [OVS_FLOW_ATTR_USED] = { .type = NL_A_U64, .optional = true },
4192
0
        [OVS_FLOW_ATTR_UFID] = { .type = NL_A_U128, .optional = true },
4193
        /* The kernel never uses OVS_FLOW_ATTR_CLEAR. */
4194
        /* The kernel never uses OVS_FLOW_ATTR_PROBE. */
4195
        /* The kernel never uses OVS_FLOW_ATTR_UFID_FLAGS. */
4196
0
    };
4197
4198
0
    dpif_netlink_flow_init(flow);
4199
4200
0
    struct ofpbuf b = ofpbuf_const_initializer(buf->data, buf->size);
4201
0
    struct nlmsghdr *nlmsg = ofpbuf_try_pull(&b, sizeof *nlmsg);
4202
0
    struct genlmsghdr *genl = ofpbuf_try_pull(&b, sizeof *genl);
4203
0
    struct ovs_header *ovs_header = ofpbuf_try_pull(&b, sizeof *ovs_header);
4204
4205
0
    struct nlattr *a[ARRAY_SIZE(ovs_flow_policy)];
4206
0
    if (!nlmsg || !genl || !ovs_header
4207
0
        || nlmsg->nlmsg_type != ovs_flow_family
4208
0
        || !nl_policy_parse(&b, 0, ovs_flow_policy, a,
4209
0
                            ARRAY_SIZE(ovs_flow_policy))) {
4210
0
        return EINVAL;
4211
0
    }
4212
0
    if (!a[OVS_FLOW_ATTR_KEY] && !a[OVS_FLOW_ATTR_UFID]) {
4213
0
        return EINVAL;
4214
0
    }
4215
4216
0
    flow->nlmsg_flags = nlmsg->nlmsg_flags;
4217
0
    flow->dp_ifindex = ovs_header->dp_ifindex;
4218
0
    if (a[OVS_FLOW_ATTR_KEY]) {
4219
0
        flow->key = nl_attr_get(a[OVS_FLOW_ATTR_KEY]);
4220
0
        flow->key_len = nl_attr_get_size(a[OVS_FLOW_ATTR_KEY]);
4221
0
    }
4222
4223
0
    if (a[OVS_FLOW_ATTR_UFID]) {
4224
0
        flow->ufid = nl_attr_get_u128(a[OVS_FLOW_ATTR_UFID]);
4225
0
        flow->ufid_present = true;
4226
0
    }
4227
0
    if (a[OVS_FLOW_ATTR_MASK]) {
4228
0
        flow->mask = nl_attr_get(a[OVS_FLOW_ATTR_MASK]);
4229
0
        flow->mask_len = nl_attr_get_size(a[OVS_FLOW_ATTR_MASK]);
4230
0
    }
4231
0
    if (a[OVS_FLOW_ATTR_ACTIONS]) {
4232
0
        flow->actions = nl_attr_get(a[OVS_FLOW_ATTR_ACTIONS]);
4233
0
        flow->actions_len = nl_attr_get_size(a[OVS_FLOW_ATTR_ACTIONS]);
4234
0
    }
4235
0
    if (a[OVS_FLOW_ATTR_STATS]) {
4236
0
        flow->stats = nl_attr_get(a[OVS_FLOW_ATTR_STATS]);
4237
0
    }
4238
0
    if (a[OVS_FLOW_ATTR_TCP_FLAGS]) {
4239
0
        flow->tcp_flags = nl_attr_get(a[OVS_FLOW_ATTR_TCP_FLAGS]);
4240
0
    }
4241
0
    if (a[OVS_FLOW_ATTR_USED]) {
4242
0
        flow->used = nl_attr_get(a[OVS_FLOW_ATTR_USED]);
4243
0
    }
4244
0
    return 0;
4245
0
}
4246
4247
4248
/*
4249
 * If PACKET_TYPE attribute is present in 'data', it filters PACKET_TYPE out.
4250
 * If the flow is not Ethernet, the OVS_KEY_ATTR_PACKET_TYPE is converted to
4251
 * OVS_KEY_ATTR_ETHERTYPE. Puts 'data' to 'buf'.
4252
 */
4253
static void
4254
put_exclude_packet_type(struct ofpbuf *buf, uint16_t type,
4255
                        const struct nlattr *data, uint16_t data_len)
4256
0
{
4257
0
    const struct nlattr *packet_type;
4258
4259
0
    packet_type = nl_attr_find__(data, data_len, OVS_KEY_ATTR_PACKET_TYPE);
4260
4261
0
    if (packet_type) {
4262
        /* exclude PACKET_TYPE Netlink attribute. */
4263
0
        ovs_assert(NLA_ALIGN(packet_type->nla_len) == NL_A_U32_SIZE);
4264
0
        size_t packet_type_len = NL_A_U32_SIZE;
4265
0
        size_t first_chunk_size = (uint8_t *)packet_type - (uint8_t *)data;
4266
0
        size_t second_chunk_size = data_len - first_chunk_size
4267
0
                                   - packet_type_len;
4268
0
        struct nlattr *next_attr = nl_attr_next(packet_type);
4269
0
        size_t ofs;
4270
4271
0
        ofs = nl_msg_start_nested(buf, type);
4272
0
        nl_msg_put(buf, data, first_chunk_size);
4273
0
        nl_msg_put(buf, next_attr, second_chunk_size);
4274
0
        if (!nl_attr_find__(data, data_len, OVS_KEY_ATTR_ETHERNET)) {
4275
0
            ovs_be16 pt = pt_ns_type_be(nl_attr_get_be32(packet_type));
4276
0
            const struct nlattr *nla;
4277
4278
0
            nla = nl_attr_find(buf, ofs + NLA_HDRLEN, OVS_KEY_ATTR_ETHERTYPE);
4279
0
            if (nla) {
4280
0
                ovs_be16 *ethertype;
4281
4282
0
                ethertype = CONST_CAST(ovs_be16 *, nl_attr_get(nla));
4283
0
                *ethertype = pt;
4284
0
            } else {
4285
0
                nl_msg_put_be16(buf, OVS_KEY_ATTR_ETHERTYPE, pt);
4286
0
            }
4287
0
        }
4288
0
        nl_msg_end_nested(buf, ofs);
4289
0
    } else {
4290
0
        nl_msg_put_unspec(buf, type, data, data_len);
4291
0
    }
4292
0
}
4293
4294
/* Appends to 'buf' (which must initially be empty) a "struct ovs_header"
4295
 * followed by Netlink attributes corresponding to 'flow'. */
4296
static void
4297
dpif_netlink_flow_to_ofpbuf(const struct dpif_netlink_flow *flow,
4298
                            struct ofpbuf *buf)
4299
0
{
4300
0
    struct ovs_header *ovs_header;
4301
4302
0
    nl_msg_put_genlmsghdr(buf, 0, ovs_flow_family,
4303
0
                          NLM_F_REQUEST | flow->nlmsg_flags,
4304
0
                          flow->cmd, OVS_FLOW_VERSION);
4305
4306
0
    ovs_header = ofpbuf_put_uninit(buf, sizeof *ovs_header);
4307
0
    ovs_header->dp_ifindex = flow->dp_ifindex;
4308
4309
0
    if (flow->ufid_present) {
4310
0
        nl_msg_put_u128(buf, OVS_FLOW_ATTR_UFID, flow->ufid);
4311
0
    }
4312
0
    if (flow->ufid_terse) {
4313
0
        nl_msg_put_u32(buf, OVS_FLOW_ATTR_UFID_FLAGS,
4314
0
                       OVS_UFID_F_OMIT_KEY | OVS_UFID_F_OMIT_MASK
4315
0
                       | OVS_UFID_F_OMIT_ACTIONS);
4316
0
    }
4317
0
    if (!flow->ufid_terse || !flow->ufid_present) {
4318
0
        if (flow->key_len) {
4319
0
            put_exclude_packet_type(buf, OVS_FLOW_ATTR_KEY, flow->key,
4320
0
                                           flow->key_len);
4321
0
        }
4322
0
        if (flow->mask_len) {
4323
0
            put_exclude_packet_type(buf, OVS_FLOW_ATTR_MASK, flow->mask,
4324
0
                                           flow->mask_len);
4325
0
        }
4326
0
        if (flow->actions) {
4327
0
            nl_msg_put_unspec(buf, OVS_FLOW_ATTR_ACTIONS,
4328
0
                              flow->actions, flow->actions_len);
4329
0
        }
4330
0
    }
4331
4332
    /* We never need to send these to the kernel. */
4333
0
    ovs_assert(!flow->stats);
4334
0
    ovs_assert(!flow->tcp_flags);
4335
0
    ovs_assert(!flow->used);
4336
4337
0
    if (flow->clear) {
4338
0
        nl_msg_put_flag(buf, OVS_FLOW_ATTR_CLEAR);
4339
0
    }
4340
0
    if (flow->probe) {
4341
0
        nl_msg_put_flag(buf, OVS_FLOW_ATTR_PROBE);
4342
0
    }
4343
0
}
4344
4345
/* Clears 'flow' to "empty" values. */
4346
static void
4347
dpif_netlink_flow_init(struct dpif_netlink_flow *flow)
4348
0
{
4349
0
    memset(flow, 0, sizeof *flow);
4350
0
}
4351
4352
/* Executes 'request' in the kernel datapath.  If the command fails, returns a
4353
 * positive errno value.  Otherwise, if 'reply' and 'bufp' are null, returns 0
4354
 * without doing anything else.  If 'reply' and 'bufp' are nonnull, then the
4355
 * result of the command is expected to be a flow also, which is decoded and
4356
 * stored in '*reply' and '*bufp'.  The caller must free '*bufp' when the reply
4357
 * is no longer needed ('reply' will contain pointers into '*bufp'). */
4358
static int
4359
dpif_netlink_flow_transact(struct dpif_netlink_flow *request,
4360
                           struct dpif_netlink_flow *reply,
4361
                           struct ofpbuf **bufp)
4362
0
{
4363
0
    struct ofpbuf *request_buf;
4364
0
    int error;
4365
4366
0
    ovs_assert((reply != NULL) == (bufp != NULL));
4367
4368
0
    if (reply) {
4369
0
        request->nlmsg_flags |= NLM_F_ECHO;
4370
0
    }
4371
4372
0
    request_buf = ofpbuf_new(1024);
4373
0
    dpif_netlink_flow_to_ofpbuf(request, request_buf);
4374
0
    error = nl_transact(NETLINK_GENERIC, request_buf, bufp);
4375
0
    ofpbuf_delete(request_buf);
4376
4377
0
    if (reply) {
4378
0
        if (!error) {
4379
0
            error = dpif_netlink_flow_from_ofpbuf(reply, *bufp);
4380
0
        }
4381
0
        if (error) {
4382
0
            dpif_netlink_flow_init(reply);
4383
0
            ofpbuf_delete(*bufp);
4384
0
            *bufp = NULL;
4385
0
        }
4386
0
    }
4387
0
    return error;
4388
0
}
4389
4390
static void
4391
dpif_netlink_flow_get_stats(const struct dpif_netlink_flow *flow,
4392
                            struct dpif_flow_stats *stats)
4393
0
{
4394
0
    if (flow->stats) {
4395
0
        stats->n_packets = get_32aligned_u64(&flow->stats->n_packets);
4396
0
        stats->n_bytes = get_32aligned_u64(&flow->stats->n_bytes);
4397
0
    } else {
4398
0
        stats->n_packets = 0;
4399
0
        stats->n_bytes = 0;
4400
0
    }
4401
0
    stats->used = flow->used ? get_32aligned_u64(flow->used) : 0;
4402
0
    stats->tcp_flags = flow->tcp_flags ? *flow->tcp_flags : 0;
4403
0
}
4404
4405
/* Logs information about a packet that was recently lost in 'ch' (in
4406
 * 'dpif_'). */
4407
static void
4408
report_loss(struct dpif_netlink *dpif, struct dpif_channel *ch, uint32_t ch_idx,
4409
            uint32_t handler_id)
4410
0
{
4411
0
    static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 5);
4412
0
    struct ds s;
4413
4414
0
    if (VLOG_DROP_WARN(&rl)) {
4415
0
        return;
4416
0
    }
4417
4418
0
    if (dpif_netlink_upcall_per_cpu(dpif)) {
4419
0
        VLOG_WARN("%s: lost packet on handler %u",
4420
0
                  dpif_name(&dpif->dpif), handler_id);
4421
0
    } else {
4422
0
        ds_init(&s);
4423
0
        if (ch->last_poll != LLONG_MIN) {
4424
0
            ds_put_format(&s, " (last polled %lld ms ago)",
4425
0
                        time_msec() - ch->last_poll);
4426
0
        }
4427
4428
0
        VLOG_WARN("%s: lost packet on port channel %u of handler %u%s",
4429
0
                  dpif_name(&dpif->dpif), ch_idx, handler_id, ds_cstr(&s));
4430
0
        ds_destroy(&s);
4431
0
    }
4432
0
}
4433
4434
static void
4435
dpif_netlink_unixctl_dispatch_mode(struct unixctl_conn *conn,
4436
                                   int argc OVS_UNUSED,
4437
                                   const char *argv[] OVS_UNUSED,
4438
                                   void *aux OVS_UNUSED)
4439
0
{
4440
0
    struct ds reply = DS_EMPTY_INITIALIZER;
4441
0
    struct nl_dump dump;
4442
0
    uint64_t reply_stub[NL_DUMP_BUFSIZE / 8];
4443
0
    struct ofpbuf msg, buf;
4444
0
    int error;
4445
4446
0
    error = dpif_netlink_init();
4447
0
    if (error) {
4448
0
        return;
4449
0
    }
4450
4451
0
    ofpbuf_use_stub(&buf, reply_stub, sizeof reply_stub);
4452
0
    dpif_netlink_dp_dump_start(&dump);
4453
0
    while (nl_dump_next(&dump, &msg, &buf)) {
4454
0
        struct dpif_netlink_dp dp;
4455
0
        if (!dpif_netlink_dp_from_ofpbuf(&dp, &msg)) {
4456
0
            ds_put_format(&reply, "%s: ", dp.name);
4457
0
            if (dp.user_features & OVS_DP_F_DISPATCH_UPCALL_PER_CPU) {
4458
0
                ds_put_format(&reply, "per-cpu dispatch mode");
4459
0
            } else {
4460
0
                ds_put_format(&reply, "per-vport dispatch mode");
4461
0
            }
4462
0
            ds_put_format(&reply, "\n");
4463
0
        }
4464
0
    }
4465
0
    ofpbuf_uninit(&buf);
4466
0
    error = nl_dump_done(&dump);
4467
0
    if (!error) {
4468
0
        unixctl_command_reply(conn, ds_cstr(&reply));
4469
0
    }
4470
4471
0
    ds_destroy(&reply);
4472
0
}