~ubuntu-branches/ubuntu/precise/openvswitch/precise-proposed

« back to all changes in this revision

Viewing changes to .pc/0011-netdev-linux-Get-carrier-from-ioctl-instead-of-sysfs.patch/lib/netdev-linux.c

  • Committer: Package Import Robot
  • Author(s): Chris J Arges
  • Date: 2014-02-14 12:38:07 UTC
  • Revision ID: package-import@ubuntu.com-20140214123807-rjw0c8a60t9ax7ld
Tags: 1.4.6-0ubuntu1.12.04.3
d/p/0011-netdev-linux-Get-carrier-from-ioctl-instead-of-sysfs.patch:
d/p/0012-netdev-linux-Cache-flags-using-netlink.patch:
Fix latency issues between VMs using OVS. (LP: #1280370)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2009, 2010, 2011 Nicira Networks.
 
3
 *
 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
 
5
 * you may not use this file except in compliance with the License.
 
6
 * You may obtain a copy of the License at:
 
7
 *
 
8
 *     http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
10
 * Unless required by applicable law or agreed to in writing, software
 
11
 * distributed under the License is distributed on an "AS IS" BASIS,
 
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
 * See the License for the specific language governing permissions and
 
14
 * limitations under the License.
 
15
 */
 
16
 
 
17
#include <config.h>
 
18
 
 
19
#include "netdev-linux.h"
 
20
 
 
21
#include <assert.h>
 
22
#include <errno.h>
 
23
#include <fcntl.h>
 
24
#include <arpa/inet.h>
 
25
#include <inttypes.h>
 
26
#include <linux/gen_stats.h>
 
27
#include <linux/if_ether.h>
 
28
#include <linux/if_tun.h>
 
29
#include <linux/ip.h>
 
30
#include <linux/types.h>
 
31
#include <linux/ethtool.h>
 
32
#include <linux/mii.h>
 
33
#include <linux/pkt_sched.h>
 
34
#include <linux/rtnetlink.h>
 
35
#include <linux/sockios.h>
 
36
#include <linux/version.h>
 
37
#include <sys/types.h>
 
38
#include <sys/ioctl.h>
 
39
#include <sys/socket.h>
 
40
#include <netpacket/packet.h>
 
41
#include <net/if.h>
 
42
#include <net/if_arp.h>
 
43
#include <net/if_packet.h>
 
44
#include <net/route.h>
 
45
#include <netinet/in.h>
 
46
#include <poll.h>
 
47
#include <stdlib.h>
 
48
#include <string.h>
 
49
#include <unistd.h>
 
50
 
 
51
#include "coverage.h"
 
52
#include "dpif-linux.h"
 
53
#include "dynamic-string.h"
 
54
#include "fatal-signal.h"
 
55
#include "hash.h"
 
56
#include "hmap.h"
 
57
#include "netdev-provider.h"
 
58
#include "netdev-vport.h"
 
59
#include "netlink.h"
 
60
#include "netlink-notifier.h"
 
61
#include "netlink-socket.h"
 
62
#include "ofpbuf.h"
 
63
#include "openflow/openflow.h"
 
64
#include "packets.h"
 
65
#include "poll-loop.h"
 
66
#include "rtnetlink-link.h"
 
67
#include "socket-util.h"
 
68
#include "shash.h"
 
69
#include "sset.h"
 
70
#include "timer.h"
 
71
#include "vlog.h"
 
72
 
 
73
VLOG_DEFINE_THIS_MODULE(netdev_linux);
 
74
 
 
75
COVERAGE_DEFINE(netdev_set_policing);
 
76
COVERAGE_DEFINE(netdev_arp_lookup);
 
77
COVERAGE_DEFINE(netdev_get_ifindex);
 
78
COVERAGE_DEFINE(netdev_get_hwaddr);
 
79
COVERAGE_DEFINE(netdev_set_hwaddr);
 
80
COVERAGE_DEFINE(netdev_ethtool);
 
81
 
 
82
/* These were introduced in Linux 2.6.14, so they might be missing if we have
 
83
 * old headers. */
 
84
#ifndef ADVERTISED_Pause
 
85
#define ADVERTISED_Pause                (1 << 13)
 
86
#endif
 
87
#ifndef ADVERTISED_Asym_Pause
 
88
#define ADVERTISED_Asym_Pause           (1 << 14)
 
89
#endif
 
90
 
 
91
/* These were introduced in Linux 2.6.24, so they might be missing if we
 
92
 * have old headers. */
 
93
#ifndef ETHTOOL_GFLAGS
 
94
#define ETHTOOL_GFLAGS       0x00000025 /* Get flags bitmap(ethtool_value) */
 
95
#endif
 
96
#ifndef ETHTOOL_SFLAGS
 
97
#define ETHTOOL_SFLAGS       0x00000026 /* Set flags bitmap(ethtool_value) */
 
98
#endif
 
99
 
 
100
/* This was introduced in Linux 2.6.25, so it might be missing if we have old
 
101
 * headers. */
 
102
#ifndef TC_RTAB_SIZE
 
103
#define TC_RTAB_SIZE 1024
 
104
#endif
 
105
 
 
106
static struct nln_notifier *netdev_linux_cache_notifier = NULL;
 
107
static int cache_notifier_refcount;
 
108
 
 
109
enum {
 
110
    VALID_IFINDEX           = 1 << 0,
 
111
    VALID_ETHERADDR         = 1 << 1,
 
112
    VALID_IN4               = 1 << 2,
 
113
    VALID_IN6               = 1 << 3,
 
114
    VALID_MTU               = 1 << 4,
 
115
    VALID_POLICING          = 1 << 5,
 
116
    VALID_HAVE_VPORT_STATS  = 1 << 6
 
117
};
 
118
 
 
119
struct tap_state {
 
120
    int fd;
 
121
    bool opened;
 
122
};
 
123
 
 
124
/* Traffic control. */
 
125
 
 
126
/* An instance of a traffic control class.  Always associated with a particular
 
127
 * network device.
 
128
 *
 
129
 * Each TC implementation subclasses this with whatever additional data it
 
130
 * needs. */
 
131
struct tc {
 
132
    const struct tc_ops *ops;
 
133
    struct hmap queues;         /* Contains "struct tc_queue"s.
 
134
                                 * Read by generic TC layer.
 
135
                                 * Written only by TC implementation. */
 
136
};
 
137
 
 
138
/* One traffic control queue.
 
139
 *
 
140
 * Each TC implementation subclasses this with whatever additional data it
 
141
 * needs. */
 
142
struct tc_queue {
 
143
    struct hmap_node hmap_node; /* In struct tc's "queues" hmap. */
 
144
    unsigned int queue_id;      /* OpenFlow queue ID. */
 
145
};
 
146
 
 
147
/* A particular kind of traffic control.  Each implementation generally maps to
 
148
 * one particular Linux qdisc class.
 
149
 *
 
150
 * The functions below return 0 if successful or a positive errno value on
 
151
 * failure, except where otherwise noted.  All of them must be provided, except
 
152
 * where otherwise noted. */
 
153
struct tc_ops {
 
154
    /* Name used by kernel in the TCA_KIND attribute of tcmsg, e.g. "htb".
 
155
     * This is null for tc_ops_default and tc_ops_other, for which there are no
 
156
     * appropriate values. */
 
157
    const char *linux_name;
 
158
 
 
159
    /* Name used in OVS database, e.g. "linux-htb".  Must be nonnull. */
 
160
    const char *ovs_name;
 
161
 
 
162
    /* Number of supported OpenFlow queues, 0 for qdiscs that have no
 
163
     * queues.  The queues are numbered 0 through n_queues - 1. */
 
164
    unsigned int n_queues;
 
165
 
 
166
    /* Called to install this TC class on 'netdev'.  The implementation should
 
167
     * make the Netlink calls required to set up 'netdev' with the right qdisc
 
168
     * and configure it according to 'details'.  The implementation may assume
 
169
     * that the current qdisc is the default; that is, there is no need for it
 
170
     * to delete the current qdisc before installing itself.
 
171
     *
 
172
     * The contents of 'details' should be documented as valid for 'ovs_name'
 
173
     * in the "other_config" column in the "QoS" table in vswitchd/vswitch.xml
 
174
     * (which is built as ovs-vswitchd.conf.db(8)).
 
175
     *
 
176
     * This function must return 0 if and only if it sets 'netdev->tc' to an
 
177
     * initialized 'struct tc'.
 
178
     *
 
179
     * (This function is null for tc_ops_other, which cannot be installed.  For
 
180
     * other TC classes it should always be nonnull.) */
 
181
    int (*tc_install)(struct netdev *netdev, const struct shash *details);
 
182
 
 
183
    /* Called when the netdev code determines (through a Netlink query) that
 
184
     * this TC class's qdisc is installed on 'netdev', but we didn't install
 
185
     * it ourselves and so don't know any of the details.
 
186
     *
 
187
     * 'nlmsg' is the kernel reply to a RTM_GETQDISC Netlink message for
 
188
     * 'netdev'.  The TCA_KIND attribute of 'nlmsg' is 'linux_name'.  The
 
189
     * implementation should parse the other attributes of 'nlmsg' as
 
190
     * necessary to determine its configuration.  If necessary it should also
 
191
     * use Netlink queries to determine the configuration of queues on
 
192
     * 'netdev'.
 
193
     *
 
194
     * This function must return 0 if and only if it sets 'netdev->tc' to an
 
195
     * initialized 'struct tc'. */
 
196
    int (*tc_load)(struct netdev *netdev, struct ofpbuf *nlmsg);
 
197
 
 
198
    /* Destroys the data structures allocated by the implementation as part of
 
199
     * 'tc'.  (This includes destroying 'tc->queues' by calling
 
200
     * tc_destroy(tc).
 
201
     *
 
202
     * The implementation should not need to perform any Netlink calls.  If
 
203
     * desirable, the caller is responsible for deconfiguring the kernel qdisc.
 
204
     * (But it may not be desirable.)
 
205
     *
 
206
     * This function may be null if 'tc' is trivial. */
 
207
    void (*tc_destroy)(struct tc *tc);
 
208
 
 
209
    /* Retrieves details of 'netdev->tc' configuration into 'details'.
 
210
     *
 
211
     * The implementation should not need to perform any Netlink calls, because
 
212
     * the 'tc_install' or 'tc_load' that instantiated 'netdev->tc' should have
 
213
     * cached the configuration.
 
214
     *
 
215
     * The contents of 'details' should be documented as valid for 'ovs_name'
 
216
     * in the "other_config" column in the "QoS" table in vswitchd/vswitch.xml
 
217
     * (which is built as ovs-vswitchd.conf.db(8)).
 
218
     *
 
219
     * This function may be null if 'tc' is not configurable.
 
220
     */
 
221
    int (*qdisc_get)(const struct netdev *netdev, struct shash *details);
 
222
 
 
223
    /* Reconfigures 'netdev->tc' according to 'details', performing any
 
224
     * required Netlink calls to complete the reconfiguration.
 
225
     *
 
226
     * The contents of 'details' should be documented as valid for 'ovs_name'
 
227
     * in the "other_config" column in the "QoS" table in vswitchd/vswitch.xml
 
228
     * (which is built as ovs-vswitchd.conf.db(8)).
 
229
     *
 
230
     * This function may be null if 'tc' is not configurable.
 
231
     */
 
232
    int (*qdisc_set)(struct netdev *, const struct shash *details);
 
233
 
 
234
    /* Retrieves details of 'queue' on 'netdev->tc' into 'details'.  'queue' is
 
235
     * one of the 'struct tc_queue's within 'netdev->tc->queues'.
 
236
     *
 
237
     * The contents of 'details' should be documented as valid for 'ovs_name'
 
238
     * in the "other_config" column in the "Queue" table in
 
239
     * vswitchd/vswitch.xml (which is built as ovs-vswitchd.conf.db(8)).
 
240
     *
 
241
     * The implementation should not need to perform any Netlink calls, because
 
242
     * the 'tc_install' or 'tc_load' that instantiated 'netdev->tc' should have
 
243
     * cached the queue configuration.
 
244
     *
 
245
     * This function may be null if 'tc' does not have queues ('n_queues' is
 
246
     * 0). */
 
247
    int (*class_get)(const struct netdev *netdev, const struct tc_queue *queue,
 
248
                     struct shash *details);
 
249
 
 
250
    /* Configures or reconfigures 'queue_id' on 'netdev->tc' according to
 
251
     * 'details', perfoming any required Netlink calls to complete the
 
252
     * reconfiguration.  The caller ensures that 'queue_id' is less than
 
253
     * 'n_queues'.
 
254
     *
 
255
     * The contents of 'details' should be documented as valid for 'ovs_name'
 
256
     * in the "other_config" column in the "Queue" table in
 
257
     * vswitchd/vswitch.xml (which is built as ovs-vswitchd.conf.db(8)).
 
258
     *
 
259
     * This function may be null if 'tc' does not have queues or its queues are
 
260
     * not configurable. */
 
261
    int (*class_set)(struct netdev *, unsigned int queue_id,
 
262
                     const struct shash *details);
 
263
 
 
264
    /* Deletes 'queue' from 'netdev->tc'.  'queue' is one of the 'struct
 
265
     * tc_queue's within 'netdev->tc->queues'.
 
266
     *
 
267
     * This function may be null if 'tc' does not have queues or its queues
 
268
     * cannot be deleted. */
 
269
    int (*class_delete)(struct netdev *, struct tc_queue *queue);
 
270
 
 
271
    /* Obtains stats for 'queue' from 'netdev->tc'.  'queue' is one of the
 
272
     * 'struct tc_queue's within 'netdev->tc->queues'.
 
273
     *
 
274
     * On success, initializes '*stats'.
 
275
     *
 
276
     * This function may be null if 'tc' does not have queues or if it cannot
 
277
     * report queue statistics. */
 
278
    int (*class_get_stats)(const struct netdev *netdev,
 
279
                           const struct tc_queue *queue,
 
280
                           struct netdev_queue_stats *stats);
 
281
 
 
282
    /* Extracts queue stats from 'nlmsg', which is a response to a
 
283
     * RTM_GETTCLASS message, and passes them to 'cb' along with 'aux'.
 
284
     *
 
285
     * This function may be null if 'tc' does not have queues or if it cannot
 
286
     * report queue statistics. */
 
287
    int (*class_dump_stats)(const struct netdev *netdev,
 
288
                            const struct ofpbuf *nlmsg,
 
289
                            netdev_dump_queue_stats_cb *cb, void *aux);
 
290
};
 
291
 
 
292
static void
 
293
tc_init(struct tc *tc, const struct tc_ops *ops)
 
294
{
 
295
    tc->ops = ops;
 
296
    hmap_init(&tc->queues);
 
297
}
 
298
 
 
299
static void
 
300
tc_destroy(struct tc *tc)
 
301
{
 
302
    hmap_destroy(&tc->queues);
 
303
}
 
304
 
 
305
static const struct tc_ops tc_ops_htb;
 
306
static const struct tc_ops tc_ops_hfsc;
 
307
static const struct tc_ops tc_ops_default;
 
308
static const struct tc_ops tc_ops_other;
 
309
 
 
310
static const struct tc_ops *tcs[] = {
 
311
    &tc_ops_htb,                /* Hierarchy token bucket (see tc-htb(8)). */
 
312
    &tc_ops_hfsc,               /* Hierarchical fair service curve. */
 
313
    &tc_ops_default,            /* Default qdisc (see tc-pfifo_fast(8)). */
 
314
    &tc_ops_other,              /* Some other qdisc. */
 
315
    NULL
 
316
};
 
317
 
 
318
static unsigned int tc_make_handle(unsigned int major, unsigned int minor);
 
319
static unsigned int tc_get_major(unsigned int handle);
 
320
static unsigned int tc_get_minor(unsigned int handle);
 
321
 
 
322
static unsigned int tc_ticks_to_bytes(unsigned int rate, unsigned int ticks);
 
323
static unsigned int tc_bytes_to_ticks(unsigned int rate, unsigned int size);
 
324
static unsigned int tc_buffer_per_jiffy(unsigned int rate);
 
325
 
 
326
static struct tcmsg *tc_make_request(const struct netdev *, int type,
 
327
                                     unsigned int flags, struct ofpbuf *);
 
328
static int tc_transact(struct ofpbuf *request, struct ofpbuf **replyp);
 
329
 
 
330
static int tc_parse_qdisc(const struct ofpbuf *, const char **kind,
 
331
                          struct nlattr **options);
 
332
static int tc_parse_class(const struct ofpbuf *, unsigned int *queue_id,
 
333
                          struct nlattr **options,
 
334
                          struct netdev_queue_stats *);
 
335
static int tc_query_class(const struct netdev *,
 
336
                          unsigned int handle, unsigned int parent,
 
337
                          struct ofpbuf **replyp);
 
338
static int tc_delete_class(const struct netdev *, unsigned int handle);
 
339
 
 
340
static int tc_del_qdisc(struct netdev *netdev);
 
341
static int tc_query_qdisc(const struct netdev *netdev);
 
342
 
 
343
static int tc_calc_cell_log(unsigned int mtu);
 
344
static void tc_fill_rate(struct tc_ratespec *rate, uint64_t bps, int mtu);
 
345
static void tc_put_rtab(struct ofpbuf *, uint16_t type,
 
346
                        const struct tc_ratespec *rate);
 
347
static int tc_calc_buffer(unsigned int Bps, int mtu, uint64_t burst_bytes);
 
348
 
 
349
struct netdev_dev_linux {
 
350
    struct netdev_dev netdev_dev;
 
351
 
 
352
    struct shash_node *shash_node;
 
353
    unsigned int cache_valid;
 
354
    unsigned int change_seq;
 
355
 
 
356
    bool miimon;                    /* Link status of last poll. */
 
357
    long long int miimon_interval;  /* Miimon Poll rate. Disabled if <= 0. */
 
358
    struct timer miimon_timer;
 
359
 
 
360
    /* The following are figured out "on demand" only.  They are only valid
 
361
     * when the corresponding VALID_* bit in 'cache_valid' is set. */
 
362
    int ifindex;
 
363
    uint8_t etheraddr[ETH_ADDR_LEN];
 
364
    struct in_addr address, netmask;
 
365
    struct in6_addr in6;
 
366
    int mtu;
 
367
    bool carrier;
 
368
    long long int carrier_resets;
 
369
    uint32_t kbits_rate;        /* Policing data. */
 
370
    uint32_t kbits_burst;
 
371
    bool have_vport_stats;
 
372
    struct tc *tc;
 
373
 
 
374
    union {
 
375
        struct tap_state tap;
 
376
    } state;
 
377
};
 
378
 
 
379
struct netdev_linux {
 
380
    struct netdev netdev;
 
381
    int fd;
 
382
};
 
383
 
 
384
/* Sockets used for ioctl operations. */
 
385
static int af_inet_sock = -1;   /* AF_INET, SOCK_DGRAM. */
 
386
 
 
387
/* A Netlink routing socket that is not subscribed to any multicast groups. */
 
388
static struct nl_sock *rtnl_sock;
 
389
 
 
390
/* This is set pretty low because we probably won't learn anything from the
 
391
 * additional log messages. */
 
392
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
 
393
 
 
394
static int netdev_linux_init(void);
 
395
 
 
396
static int netdev_linux_do_ethtool(const char *name, struct ethtool_cmd *,
 
397
                                   int cmd, const char *cmd_name);
 
398
static int netdev_linux_do_ioctl(const char *name, struct ifreq *, int cmd,
 
399
                                 const char *cmd_name);
 
400
static int netdev_linux_get_ipv4(const struct netdev *, struct in_addr *,
 
401
                                 int cmd, const char *cmd_name);
 
402
static int get_flags(const struct netdev *, int *flagsp);
 
403
static int set_flags(struct netdev *, int flags);
 
404
static int do_get_ifindex(const char *netdev_name);
 
405
static int get_ifindex(const struct netdev *, int *ifindexp);
 
406
static int do_set_addr(struct netdev *netdev,
 
407
                       int ioctl_nr, const char *ioctl_name,
 
408
                       struct in_addr addr);
 
409
static int get_etheraddr(const char *netdev_name, uint8_t ea[ETH_ADDR_LEN]);
 
410
static int set_etheraddr(const char *netdev_name, int hwaddr_family,
 
411
                         const uint8_t[ETH_ADDR_LEN]);
 
412
static int get_stats_via_netlink(int ifindex, struct netdev_stats *stats);
 
413
static int get_stats_via_proc(const char *netdev_name, struct netdev_stats *stats);
 
414
static int get_carrier_via_sysfs(const char *name, bool *carrier);
 
415
static int af_packet_sock(void);
 
416
static void netdev_linux_miimon_run(void);
 
417
static void netdev_linux_miimon_wait(void);
 
418
 
 
419
static bool
 
420
is_netdev_linux_class(const struct netdev_class *netdev_class)
 
421
{
 
422
    return netdev_class->init == netdev_linux_init;
 
423
}
 
424
 
 
425
static struct netdev_dev_linux *
 
426
netdev_dev_linux_cast(const struct netdev_dev *netdev_dev)
 
427
{
 
428
    const struct netdev_class *netdev_class = netdev_dev_get_class(netdev_dev);
 
429
    assert(is_netdev_linux_class(netdev_class));
 
430
 
 
431
    return CONTAINER_OF(netdev_dev, struct netdev_dev_linux, netdev_dev);
 
432
}
 
433
 
 
434
static struct netdev_linux *
 
435
netdev_linux_cast(const struct netdev *netdev)
 
436
{
 
437
    struct netdev_dev *netdev_dev = netdev_get_dev(netdev);
 
438
    const struct netdev_class *netdev_class = netdev_dev_get_class(netdev_dev);
 
439
    assert(is_netdev_linux_class(netdev_class));
 
440
 
 
441
    return CONTAINER_OF(netdev, struct netdev_linux, netdev);
 
442
}
 
443
 
 
444
static int
 
445
netdev_linux_init(void)
 
446
{
 
447
    static int status = -1;
 
448
    if (status < 0) {
 
449
        /* Create AF_INET socket. */
 
450
        af_inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
 
451
        status = af_inet_sock >= 0 ? 0 : errno;
 
452
        if (status) {
 
453
            VLOG_ERR("failed to create inet socket: %s", strerror(status));
 
454
        }
 
455
 
 
456
        /* Create rtnetlink socket. */
 
457
        if (!status) {
 
458
            status = nl_sock_create(NETLINK_ROUTE, &rtnl_sock);
 
459
            if (status) {
 
460
                VLOG_ERR_RL(&rl, "failed to create rtnetlink socket: %s",
 
461
                            strerror(status));
 
462
            }
 
463
        }
 
464
    }
 
465
    return status;
 
466
}
 
467
 
 
468
static void
 
469
netdev_linux_run(void)
 
470
{
 
471
    rtnetlink_link_run();
 
472
    netdev_linux_miimon_run();
 
473
}
 
474
 
 
475
static void
 
476
netdev_linux_wait(void)
 
477
{
 
478
    rtnetlink_link_wait();
 
479
    netdev_linux_miimon_wait();
 
480
}
 
481
 
 
482
static void
 
483
netdev_dev_linux_changed(struct netdev_dev_linux *dev)
 
484
{
 
485
    dev->change_seq++;
 
486
    if (!dev->change_seq) {
 
487
        dev->change_seq++;
 
488
    }
 
489
    dev->cache_valid = 0;
 
490
}
 
491
 
 
492
static void
 
493
netdev_linux_cache_cb(const struct rtnetlink_link_change *change,
 
494
                      void *aux OVS_UNUSED)
 
495
{
 
496
    struct netdev_dev_linux *dev;
 
497
    if (change) {
 
498
        struct netdev_dev *base_dev = netdev_dev_from_name(change->ifname);
 
499
        if (base_dev) {
 
500
            const struct netdev_class *netdev_class =
 
501
                                                netdev_dev_get_class(base_dev);
 
502
 
 
503
            if (is_netdev_linux_class(netdev_class)) {
 
504
                dev = netdev_dev_linux_cast(base_dev);
 
505
 
 
506
                if (dev->carrier != change->running) {
 
507
                    dev->carrier = change->running;
 
508
                    dev->carrier_resets++;
 
509
                }
 
510
 
 
511
                netdev_dev_linux_changed(dev);
 
512
            }
 
513
        }
 
514
    } else {
 
515
        struct shash device_shash;
 
516
        struct shash_node *node;
 
517
 
 
518
        shash_init(&device_shash);
 
519
        netdev_dev_get_devices(&netdev_linux_class, &device_shash);
 
520
        SHASH_FOR_EACH (node, &device_shash) {
 
521
            bool carrier;
 
522
 
 
523
            dev = node->data;
 
524
 
 
525
            get_carrier_via_sysfs(node->name, &carrier);
 
526
            if (dev->carrier != carrier) {
 
527
                dev->carrier = carrier;
 
528
                dev->carrier_resets++;
 
529
            }
 
530
 
 
531
            netdev_dev_linux_changed(dev);
 
532
        }
 
533
        shash_destroy(&device_shash);
 
534
    }
 
535
}
 
536
 
 
537
/* Creates system and internal devices. */
 
538
static int
 
539
netdev_linux_create(const struct netdev_class *class, const char *name,
 
540
                    struct netdev_dev **netdev_devp)
 
541
{
 
542
    struct netdev_dev_linux *netdev_dev;
 
543
 
 
544
    if (!cache_notifier_refcount) {
 
545
        assert(!netdev_linux_cache_notifier);
 
546
 
 
547
        netdev_linux_cache_notifier =
 
548
            rtnetlink_link_notifier_create(netdev_linux_cache_cb, NULL);
 
549
 
 
550
        if (!netdev_linux_cache_notifier) {
 
551
            return EINVAL;
 
552
        }
 
553
    }
 
554
    cache_notifier_refcount++;
 
555
 
 
556
    netdev_dev = xzalloc(sizeof *netdev_dev);
 
557
    netdev_dev->change_seq = 1;
 
558
    netdev_dev_init(&netdev_dev->netdev_dev, name, class);
 
559
    get_carrier_via_sysfs(name, &netdev_dev->carrier);
 
560
 
 
561
    *netdev_devp = &netdev_dev->netdev_dev;
 
562
    return 0;
 
563
}
 
564
 
 
565
/* For most types of netdevs we open the device for each call of
 
566
 * netdev_open().  However, this is not the case with tap devices,
 
567
 * since it is only possible to open the device once.  In this
 
568
 * situation we share a single file descriptor, and consequently
 
569
 * buffers, across all readers.  Therefore once data is read it will
 
570
 * be unavailable to other reads for tap devices. */
 
571
static int
 
572
netdev_linux_create_tap(const struct netdev_class *class OVS_UNUSED,
 
573
                        const char *name, struct netdev_dev **netdev_devp)
 
574
{
 
575
    struct netdev_dev_linux *netdev_dev;
 
576
    struct tap_state *state;
 
577
    static const char tap_dev[] = "/dev/net/tun";
 
578
    struct ifreq ifr;
 
579
    int error;
 
580
 
 
581
    netdev_dev = xzalloc(sizeof *netdev_dev);
 
582
    state = &netdev_dev->state.tap;
 
583
 
 
584
    /* Open tap device. */
 
585
    state->fd = open(tap_dev, O_RDWR);
 
586
    if (state->fd < 0) {
 
587
        error = errno;
 
588
        VLOG_WARN("opening \"%s\" failed: %s", tap_dev, strerror(error));
 
589
        goto error;
 
590
    }
 
591
 
 
592
    /* Create tap device. */
 
593
    ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
 
594
    ovs_strzcpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
 
595
    if (ioctl(state->fd, TUNSETIFF, &ifr) == -1) {
 
596
        VLOG_WARN("%s: creating tap device failed: %s", name,
 
597
                  strerror(errno));
 
598
        error = errno;
 
599
        goto error;
 
600
    }
 
601
 
 
602
    /* Make non-blocking. */
 
603
    error = set_nonblocking(state->fd);
 
604
    if (error) {
 
605
        goto error;
 
606
    }
 
607
 
 
608
    netdev_dev_init(&netdev_dev->netdev_dev, name, &netdev_tap_class);
 
609
    *netdev_devp = &netdev_dev->netdev_dev;
 
610
    return 0;
 
611
 
 
612
error:
 
613
    free(netdev_dev);
 
614
    return error;
 
615
}
 
616
 
 
617
static void
 
618
destroy_tap(struct netdev_dev_linux *netdev_dev)
 
619
{
 
620
    struct tap_state *state = &netdev_dev->state.tap;
 
621
 
 
622
    if (state->fd >= 0) {
 
623
        close(state->fd);
 
624
    }
 
625
}
 
626
 
 
627
/* Destroys the netdev device 'netdev_dev_'. */
 
628
static void
 
629
netdev_linux_destroy(struct netdev_dev *netdev_dev_)
 
630
{
 
631
    struct netdev_dev_linux *netdev_dev = netdev_dev_linux_cast(netdev_dev_);
 
632
    const struct netdev_class *class = netdev_dev_get_class(netdev_dev_);
 
633
 
 
634
    if (netdev_dev->tc && netdev_dev->tc->ops->tc_destroy) {
 
635
        netdev_dev->tc->ops->tc_destroy(netdev_dev->tc);
 
636
    }
 
637
 
 
638
    if (class == &netdev_linux_class || class == &netdev_internal_class) {
 
639
        cache_notifier_refcount--;
 
640
 
 
641
        if (!cache_notifier_refcount) {
 
642
            assert(netdev_linux_cache_notifier);
 
643
            rtnetlink_link_notifier_destroy(netdev_linux_cache_notifier);
 
644
            netdev_linux_cache_notifier = NULL;
 
645
        }
 
646
    } else if (class == &netdev_tap_class) {
 
647
        destroy_tap(netdev_dev);
 
648
    } else {
 
649
        NOT_REACHED();
 
650
    }
 
651
 
 
652
    free(netdev_dev);
 
653
}
 
654
 
 
655
static int
 
656
netdev_linux_open(struct netdev_dev *netdev_dev_, struct netdev **netdevp)
 
657
{
 
658
    struct netdev_dev_linux *netdev_dev = netdev_dev_linux_cast(netdev_dev_);
 
659
    struct netdev_linux *netdev;
 
660
    enum netdev_flags flags;
 
661
    int error;
 
662
 
 
663
    /* Allocate network device. */
 
664
    netdev = xzalloc(sizeof *netdev);
 
665
    netdev->fd = -1;
 
666
    netdev_init(&netdev->netdev, netdev_dev_);
 
667
 
 
668
    /* Verify that the device really exists, by attempting to read its flags.
 
669
     * (The flags might be cached, in which case this won't actually do an
 
670
     * ioctl.)
 
671
     *
 
672
     * Don't do this for "internal" netdevs, though, because those have to be
 
673
     * created as netdev objects before they exist in the kernel, because
 
674
     * creating them in the kernel happens by passing a netdev object to
 
675
     * dpif_port_add(). */
 
676
    if (netdev_dev_get_class(netdev_dev_) != &netdev_internal_class) {
 
677
        error = netdev_get_flags(&netdev->netdev, &flags);
 
678
        if (error == ENODEV) {
 
679
            goto error;
 
680
        }
 
681
    }
 
682
 
 
683
    if (!strcmp(netdev_dev_get_type(netdev_dev_), "tap") &&
 
684
        !netdev_dev->state.tap.opened) {
 
685
 
 
686
        /* We assume that the first user of the tap device is the primary user
 
687
         * and give them the tap FD.  Subsequent users probably just expect
 
688
         * this to be a system device so open it normally to avoid send/receive
 
689
         * directions appearing to be reversed. */
 
690
        netdev->fd = netdev_dev->state.tap.fd;
 
691
        netdev_dev->state.tap.opened = true;
 
692
    }
 
693
 
 
694
    *netdevp = &netdev->netdev;
 
695
    return 0;
 
696
 
 
697
error:
 
698
    netdev_uninit(&netdev->netdev, true);
 
699
    return error;
 
700
}
 
701
 
 
702
/* Closes and destroys 'netdev'. */
 
703
static void
 
704
netdev_linux_close(struct netdev *netdev_)
 
705
{
 
706
    struct netdev_linux *netdev = netdev_linux_cast(netdev_);
 
707
 
 
708
    if (netdev->fd > 0 && strcmp(netdev_get_type(netdev_), "tap")) {
 
709
        close(netdev->fd);
 
710
    }
 
711
    free(netdev);
 
712
}
 
713
 
 
714
static int
 
715
netdev_linux_listen(struct netdev *netdev_)
 
716
{
 
717
    struct netdev_linux *netdev = netdev_linux_cast(netdev_);
 
718
    struct sockaddr_ll sll;
 
719
    int ifindex;
 
720
    int error;
 
721
    int fd;
 
722
 
 
723
    if (netdev->fd >= 0) {
 
724
        return 0;
 
725
    }
 
726
 
 
727
    /* Create file descriptor. */
 
728
    fd = socket(PF_PACKET, SOCK_RAW, 0);
 
729
    if (fd < 0) {
 
730
        error = errno;
 
731
        VLOG_ERR("failed to create raw socket (%s)", strerror(error));
 
732
        goto error;
 
733
    }
 
734
 
 
735
    /* Set non-blocking mode. */
 
736
    error = set_nonblocking(fd);
 
737
    if (error) {
 
738
        goto error;
 
739
    }
 
740
 
 
741
    /* Get ethernet device index. */
 
742
    error = get_ifindex(&netdev->netdev, &ifindex);
 
743
    if (error) {
 
744
        goto error;
 
745
    }
 
746
 
 
747
    /* Bind to specific ethernet device. */
 
748
    memset(&sll, 0, sizeof sll);
 
749
    sll.sll_family = AF_PACKET;
 
750
    sll.sll_ifindex = ifindex;
 
751
    sll.sll_protocol = (OVS_FORCE unsigned short int) htons(ETH_P_ALL);
 
752
    if (bind(fd, (struct sockaddr *) &sll, sizeof sll) < 0) {
 
753
        error = errno;
 
754
        VLOG_ERR("%s: failed to bind raw socket (%s)",
 
755
                 netdev_get_name(netdev_), strerror(error));
 
756
        goto error;
 
757
    }
 
758
 
 
759
    netdev->fd = fd;
 
760
    return 0;
 
761
 
 
762
error:
 
763
    if (fd >= 0) {
 
764
        close(fd);
 
765
    }
 
766
    return error;
 
767
}
 
768
 
 
769
static int
 
770
netdev_linux_recv(struct netdev *netdev_, void *data, size_t size)
 
771
{
 
772
    struct netdev_linux *netdev = netdev_linux_cast(netdev_);
 
773
 
 
774
    if (netdev->fd < 0) {
 
775
        /* Device is not listening. */
 
776
        return -EAGAIN;
 
777
    }
 
778
 
 
779
    for (;;) {
 
780
        ssize_t retval = read(netdev->fd, data, size);
 
781
        if (retval >= 0) {
 
782
            return retval;
 
783
        } else if (errno != EINTR) {
 
784
            if (errno != EAGAIN) {
 
785
                VLOG_WARN_RL(&rl, "error receiving Ethernet packet on %s: %s",
 
786
                             strerror(errno), netdev_get_name(netdev_));
 
787
            }
 
788
            return -errno;
 
789
        }
 
790
    }
 
791
}
 
792
 
 
793
/* Registers with the poll loop to wake up from the next call to poll_block()
 
794
 * when a packet is ready to be received with netdev_recv() on 'netdev'. */
 
795
static void
 
796
netdev_linux_recv_wait(struct netdev *netdev_)
 
797
{
 
798
    struct netdev_linux *netdev = netdev_linux_cast(netdev_);
 
799
    if (netdev->fd >= 0) {
 
800
        poll_fd_wait(netdev->fd, POLLIN);
 
801
    }
 
802
}
 
803
 
 
804
/* Discards all packets waiting to be received from 'netdev'. */
 
805
static int
 
806
netdev_linux_drain(struct netdev *netdev_)
 
807
{
 
808
    struct netdev_linux *netdev = netdev_linux_cast(netdev_);
 
809
    if (netdev->fd < 0) {
 
810
        return 0;
 
811
    } else if (!strcmp(netdev_get_type(netdev_), "tap")) {
 
812
        struct ifreq ifr;
 
813
        int error = netdev_linux_do_ioctl(netdev_get_name(netdev_), &ifr,
 
814
                                          SIOCGIFTXQLEN, "SIOCGIFTXQLEN");
 
815
        if (error) {
 
816
            return error;
 
817
        }
 
818
        drain_fd(netdev->fd, ifr.ifr_qlen);
 
819
        return 0;
 
820
    } else {
 
821
        return drain_rcvbuf(netdev->fd);
 
822
    }
 
823
}
 
824
 
 
825
/* Sends 'buffer' on 'netdev'.  Returns 0 if successful, otherwise a positive
 
826
 * errno value.  Returns EAGAIN without blocking if the packet cannot be queued
 
827
 * immediately.  Returns EMSGSIZE if a partial packet was transmitted or if
 
828
 * the packet is too big or too small to transmit on the device.
 
829
 *
 
830
 * The caller retains ownership of 'buffer' in all cases.
 
831
 *
 
832
 * The kernel maintains a packet transmission queue, so the caller is not
 
833
 * expected to do additional queuing of packets. */
 
834
static int
 
835
netdev_linux_send(struct netdev *netdev_, const void *data, size_t size)
 
836
{
 
837
    struct netdev_linux *netdev = netdev_linux_cast(netdev_);
 
838
    for (;;) {
 
839
        ssize_t retval;
 
840
 
 
841
        if (netdev->fd < 0) {
 
842
            /* Use our AF_PACKET socket to send to this device. */
 
843
            struct sockaddr_ll sll;
 
844
            struct msghdr msg;
 
845
            struct iovec iov;
 
846
            int ifindex;
 
847
            int error;
 
848
            int sock;
 
849
 
 
850
            sock = af_packet_sock();
 
851
            if (sock < 0) {
 
852
                return sock;
 
853
            }
 
854
 
 
855
            error = get_ifindex(netdev_, &ifindex);
 
856
            if (error) {
 
857
                return error;
 
858
            }
 
859
 
 
860
            /* We don't bother setting most fields in sockaddr_ll because the
 
861
             * kernel ignores them for SOCK_RAW. */
 
862
            memset(&sll, 0, sizeof sll);
 
863
            sll.sll_family = AF_PACKET;
 
864
            sll.sll_ifindex = ifindex;
 
865
 
 
866
            iov.iov_base = (void *) data;
 
867
            iov.iov_len = size;
 
868
 
 
869
            msg.msg_name = &sll;
 
870
            msg.msg_namelen = sizeof sll;
 
871
            msg.msg_iov = &iov;
 
872
            msg.msg_iovlen = 1;
 
873
            msg.msg_control = NULL;
 
874
            msg.msg_controllen = 0;
 
875
            msg.msg_flags = 0;
 
876
 
 
877
            retval = sendmsg(sock, &msg, 0);
 
878
        } else {
 
879
            /* Use the netdev's own fd to send to this device.  This is
 
880
             * essential for tap devices, because packets sent to a tap device
 
881
             * with an AF_PACKET socket will loop back to be *received* again
 
882
             * on the tap device. */
 
883
            retval = write(netdev->fd, data, size);
 
884
        }
 
885
 
 
886
        if (retval < 0) {
 
887
            /* The Linux AF_PACKET implementation never blocks waiting for room
 
888
             * for packets, instead returning ENOBUFS.  Translate this into
 
889
             * EAGAIN for the caller. */
 
890
            if (errno == ENOBUFS) {
 
891
                return EAGAIN;
 
892
            } else if (errno == EINTR) {
 
893
                continue;
 
894
            } else if (errno != EAGAIN) {
 
895
                VLOG_WARN_RL(&rl, "error sending Ethernet packet on %s: %s",
 
896
                             netdev_get_name(netdev_), strerror(errno));
 
897
            }
 
898
            return errno;
 
899
        } else if (retval != size) {
 
900
            VLOG_WARN_RL(&rl, "sent partial Ethernet packet (%zd bytes of "
 
901
                         "%zu) on %s", retval, size, netdev_get_name(netdev_));
 
902
            return EMSGSIZE;
 
903
        } else {
 
904
            return 0;
 
905
        }
 
906
    }
 
907
}
 
908
 
 
909
/* Registers with the poll loop to wake up from the next call to poll_block()
 
910
 * when the packet transmission queue has sufficient room to transmit a packet
 
911
 * with netdev_send().
 
912
 *
 
913
 * The kernel maintains a packet transmission queue, so the client is not
 
914
 * expected to do additional queuing of packets.  Thus, this function is
 
915
 * unlikely to ever be used.  It is included for completeness. */
 
916
static void
 
917
netdev_linux_send_wait(struct netdev *netdev_)
 
918
{
 
919
    struct netdev_linux *netdev = netdev_linux_cast(netdev_);
 
920
    if (netdev->fd < 0) {
 
921
        /* Nothing to do. */
 
922
    } else if (strcmp(netdev_get_type(netdev_), "tap")) {
 
923
        poll_fd_wait(netdev->fd, POLLOUT);
 
924
    } else {
 
925
        /* TAP device always accepts packets.*/
 
926
        poll_immediate_wake();
 
927
    }
 
928
}
 
929
 
 
930
/* Attempts to set 'netdev''s MAC address to 'mac'.  Returns 0 if successful,
 
931
 * otherwise a positive errno value. */
 
932
static int
 
933
netdev_linux_set_etheraddr(struct netdev *netdev_,
 
934
                           const uint8_t mac[ETH_ADDR_LEN])
 
935
{
 
936
    struct netdev_dev_linux *netdev_dev =
 
937
                                netdev_dev_linux_cast(netdev_get_dev(netdev_));
 
938
    int error;
 
939
 
 
940
    if (!(netdev_dev->cache_valid & VALID_ETHERADDR)
 
941
        || !eth_addr_equals(netdev_dev->etheraddr, mac)) {
 
942
        error = set_etheraddr(netdev_get_name(netdev_), ARPHRD_ETHER, mac);
 
943
        if (!error) {
 
944
            netdev_dev->cache_valid |= VALID_ETHERADDR;
 
945
            memcpy(netdev_dev->etheraddr, mac, ETH_ADDR_LEN);
 
946
        }
 
947
    } else {
 
948
        error = 0;
 
949
    }
 
950
    return error;
 
951
}
 
952
 
 
953
/* Returns a pointer to 'netdev''s MAC address.  The caller must not modify or
 
954
 * free the returned buffer. */
 
955
static int
 
956
netdev_linux_get_etheraddr(const struct netdev *netdev_,
 
957
                           uint8_t mac[ETH_ADDR_LEN])
 
958
{
 
959
    struct netdev_dev_linux *netdev_dev =
 
960
                                netdev_dev_linux_cast(netdev_get_dev(netdev_));
 
961
    if (!(netdev_dev->cache_valid & VALID_ETHERADDR)) {
 
962
        int error = get_etheraddr(netdev_get_name(netdev_),
 
963
                                  netdev_dev->etheraddr);
 
964
        if (error) {
 
965
            return error;
 
966
        }
 
967
        netdev_dev->cache_valid |= VALID_ETHERADDR;
 
968
    }
 
969
    memcpy(mac, netdev_dev->etheraddr, ETH_ADDR_LEN);
 
970
    return 0;
 
971
}
 
972
 
 
973
/* Returns the maximum size of transmitted (and received) packets on 'netdev',
 
974
 * in bytes, not including the hardware header; thus, this is typically 1500
 
975
 * bytes for Ethernet devices. */
 
976
static int
 
977
netdev_linux_get_mtu(const struct netdev *netdev_, int *mtup)
 
978
{
 
979
    struct netdev_dev_linux *netdev_dev =
 
980
                                netdev_dev_linux_cast(netdev_get_dev(netdev_));
 
981
    if (!(netdev_dev->cache_valid & VALID_MTU)) {
 
982
        struct ifreq ifr;
 
983
        int error;
 
984
 
 
985
        error = netdev_linux_do_ioctl(netdev_get_name(netdev_), &ifr,
 
986
                                      SIOCGIFMTU, "SIOCGIFMTU");
 
987
        if (error) {
 
988
            return error;
 
989
        }
 
990
        netdev_dev->mtu = ifr.ifr_mtu;
 
991
        netdev_dev->cache_valid |= VALID_MTU;
 
992
    }
 
993
    *mtup = netdev_dev->mtu;
 
994
    return 0;
 
995
}
 
996
 
 
997
/* Sets the maximum size of transmitted (MTU) for given device using linux
 
998
 * networking ioctl interface.
 
999
 */
 
1000
static int
 
1001
netdev_linux_set_mtu(const struct netdev *netdev_, int mtu)
 
1002
{
 
1003
    struct netdev_dev_linux *netdev_dev =
 
1004
                                netdev_dev_linux_cast(netdev_get_dev(netdev_));
 
1005
    struct ifreq ifr;
 
1006
    int error;
 
1007
 
 
1008
    ifr.ifr_mtu = mtu;
 
1009
    error = netdev_linux_do_ioctl(netdev_get_name(netdev_), &ifr,
 
1010
                                  SIOCSIFMTU, "SIOCSIFMTU");
 
1011
    if (error) {
 
1012
        return error;
 
1013
    }
 
1014
 
 
1015
    netdev_dev->mtu = ifr.ifr_mtu;
 
1016
    netdev_dev->cache_valid |= VALID_MTU;
 
1017
    return 0;
 
1018
}
 
1019
 
 
1020
/* Returns the ifindex of 'netdev', if successful, as a positive number.
 
1021
 * On failure, returns a negative errno value. */
 
1022
static int
 
1023
netdev_linux_get_ifindex(const struct netdev *netdev)
 
1024
{
 
1025
    int ifindex, error;
 
1026
 
 
1027
    error = get_ifindex(netdev, &ifindex);
 
1028
    return error ? -error : ifindex;
 
1029
}
 
1030
 
 
1031
static int
 
1032
netdev_linux_get_carrier(const struct netdev *netdev_, bool *carrier)
 
1033
{
 
1034
    struct netdev_dev_linux *netdev_dev =
 
1035
                                netdev_dev_linux_cast(netdev_get_dev(netdev_));
 
1036
 
 
1037
    if (netdev_dev->miimon_interval > 0) {
 
1038
        *carrier = netdev_dev->miimon;
 
1039
    } else {
 
1040
        *carrier = netdev_dev->carrier;
 
1041
    }
 
1042
 
 
1043
    return 0;
 
1044
}
 
1045
 
 
1046
static long long int
 
1047
netdev_linux_get_carrier_resets(const struct netdev *netdev)
 
1048
{
 
1049
    return netdev_dev_linux_cast(netdev_get_dev(netdev))->carrier_resets;
 
1050
}
 
1051
 
 
1052
static int
 
1053
netdev_linux_do_miimon(const char *name, int cmd, const char *cmd_name,
 
1054
                       struct mii_ioctl_data *data)
 
1055
{
 
1056
    struct ifreq ifr;
 
1057
    int error;
 
1058
 
 
1059
    memset(&ifr, 0, sizeof ifr);
 
1060
    memcpy(&ifr.ifr_data, data, sizeof *data);
 
1061
    error = netdev_linux_do_ioctl(name, &ifr, cmd, cmd_name);
 
1062
    memcpy(data, &ifr.ifr_data, sizeof *data);
 
1063
 
 
1064
    return error;
 
1065
}
 
1066
 
 
1067
static int
 
1068
netdev_linux_get_miimon(const char *name, bool *miimon)
 
1069
{
 
1070
    struct mii_ioctl_data data;
 
1071
    int error;
 
1072
 
 
1073
    *miimon = false;
 
1074
 
 
1075
    memset(&data, 0, sizeof data);
 
1076
    error = netdev_linux_do_miimon(name, SIOCGMIIPHY, "SIOCGMIIPHY", &data);
 
1077
    if (!error) {
 
1078
        /* data.phy_id is filled out by previous SIOCGMIIPHY miimon call. */
 
1079
        data.reg_num = MII_BMSR;
 
1080
        error = netdev_linux_do_miimon(name, SIOCGMIIREG, "SIOCGMIIREG",
 
1081
                                       &data);
 
1082
 
 
1083
        if (!error) {
 
1084
            *miimon = !!(data.val_out & BMSR_LSTATUS);
 
1085
        } else {
 
1086
            VLOG_WARN_RL(&rl, "%s: failed to query MII", name);
 
1087
        }
 
1088
    } else {
 
1089
        struct ethtool_cmd ecmd;
 
1090
 
 
1091
        VLOG_DBG_RL(&rl, "%s: failed to query MII, falling back to ethtool",
 
1092
                    name);
 
1093
 
 
1094
        memset(&ecmd, 0, sizeof ecmd);
 
1095
        error = netdev_linux_do_ethtool(name, &ecmd, ETHTOOL_GLINK,
 
1096
                                        "ETHTOOL_GLINK");
 
1097
        if (!error) {
 
1098
            struct ethtool_value eval;
 
1099
 
 
1100
            memcpy(&eval, &ecmd, sizeof eval);
 
1101
            *miimon = !!eval.data;
 
1102
        } else {
 
1103
            VLOG_WARN_RL(&rl, "%s: ethtool link status failed", name);
 
1104
        }
 
1105
    }
 
1106
 
 
1107
    return error;
 
1108
}
 
1109
 
 
1110
static int
 
1111
netdev_linux_set_miimon_interval(struct netdev *netdev_,
 
1112
                                 long long int interval)
 
1113
{
 
1114
    struct netdev_dev_linux *netdev_dev;
 
1115
 
 
1116
    netdev_dev = netdev_dev_linux_cast(netdev_get_dev(netdev_));
 
1117
 
 
1118
    interval = interval > 0 ? MAX(interval, 100) : 0;
 
1119
    if (netdev_dev->miimon_interval != interval) {
 
1120
        netdev_dev->miimon_interval = interval;
 
1121
        timer_set_expired(&netdev_dev->miimon_timer);
 
1122
    }
 
1123
 
 
1124
    return 0;
 
1125
}
 
1126
 
 
1127
static void
 
1128
netdev_linux_miimon_run(void)
 
1129
{
 
1130
    struct shash device_shash;
 
1131
    struct shash_node *node;
 
1132
 
 
1133
    shash_init(&device_shash);
 
1134
    netdev_dev_get_devices(&netdev_linux_class, &device_shash);
 
1135
    SHASH_FOR_EACH (node, &device_shash) {
 
1136
        struct netdev_dev_linux *dev = node->data;
 
1137
        bool miimon;
 
1138
 
 
1139
        if (dev->miimon_interval <= 0 || !timer_expired(&dev->miimon_timer)) {
 
1140
            continue;
 
1141
        }
 
1142
 
 
1143
        netdev_linux_get_miimon(dev->netdev_dev.name, &miimon);
 
1144
        if (miimon != dev->miimon) {
 
1145
            dev->miimon = miimon;
 
1146
            netdev_dev_linux_changed(dev);
 
1147
        }
 
1148
 
 
1149
        timer_set_duration(&dev->miimon_timer, dev->miimon_interval);
 
1150
    }
 
1151
 
 
1152
    shash_destroy(&device_shash);
 
1153
}
 
1154
 
 
1155
static void
 
1156
netdev_linux_miimon_wait(void)
 
1157
{
 
1158
    struct shash device_shash;
 
1159
    struct shash_node *node;
 
1160
 
 
1161
    shash_init(&device_shash);
 
1162
    netdev_dev_get_devices(&netdev_linux_class, &device_shash);
 
1163
    SHASH_FOR_EACH (node, &device_shash) {
 
1164
        struct netdev_dev_linux *dev = node->data;
 
1165
 
 
1166
        if (dev->miimon_interval > 0) {
 
1167
            timer_wait(&dev->miimon_timer);
 
1168
        }
 
1169
    }
 
1170
    shash_destroy(&device_shash);
 
1171
}
 
1172
 
 
1173
/* Check whether we can we use RTM_GETLINK to get network device statistics.
 
1174
 * In pre-2.6.19 kernels, this was only available if wireless extensions were
 
1175
 * enabled. */
 
1176
static bool
 
1177
check_for_working_netlink_stats(void)
 
1178
{
 
1179
    /* Decide on the netdev_get_stats() implementation to use.  Netlink is
 
1180
     * preferable, so if that works, we'll use it. */
 
1181
    int ifindex = do_get_ifindex("lo");
 
1182
    if (ifindex < 0) {
 
1183
        VLOG_WARN("failed to get ifindex for lo, "
 
1184
                  "obtaining netdev stats from proc");
 
1185
        return false;
 
1186
    } else {
 
1187
        struct netdev_stats stats;
 
1188
        int error = get_stats_via_netlink(ifindex, &stats);
 
1189
        if (!error) {
 
1190
            VLOG_DBG("obtaining netdev stats via rtnetlink");
 
1191
            return true;
 
1192
        } else {
 
1193
            VLOG_INFO("RTM_GETLINK failed (%s), obtaining netdev stats "
 
1194
                      "via proc (you are probably running a pre-2.6.19 "
 
1195
                      "kernel)", strerror(error));
 
1196
            return false;
 
1197
        }
 
1198
    }
 
1199
}
 
1200
 
 
1201
static void
 
1202
swap_uint64(uint64_t *a, uint64_t *b)
 
1203
{
 
1204
    uint64_t tmp = *a;
 
1205
    *a = *b;
 
1206
    *b = tmp;
 
1207
}
 
1208
 
 
1209
static void
 
1210
get_stats_via_vport(const struct netdev *netdev_,
 
1211
                    struct netdev_stats *stats)
 
1212
{
 
1213
    struct netdev_dev_linux *netdev_dev =
 
1214
                                netdev_dev_linux_cast(netdev_get_dev(netdev_));
 
1215
 
 
1216
    if (netdev_dev->have_vport_stats ||
 
1217
        !(netdev_dev->cache_valid & VALID_HAVE_VPORT_STATS)) {
 
1218
        int error;
 
1219
 
 
1220
        error = netdev_vport_get_stats(netdev_, stats);
 
1221
        if (error) {
 
1222
            VLOG_WARN_RL(&rl, "%s: obtaining netdev stats via vport failed %d",
 
1223
                         netdev_get_name(netdev_), error);
 
1224
        }
 
1225
        netdev_dev->have_vport_stats = !error;
 
1226
        netdev_dev->cache_valid |= VALID_HAVE_VPORT_STATS;
 
1227
    }
 
1228
}
 
1229
 
 
1230
static int
 
1231
netdev_linux_sys_get_stats(const struct netdev *netdev_,
 
1232
                         struct netdev_stats *stats)
 
1233
{
 
1234
    static int use_netlink_stats = -1;
 
1235
    int error;
 
1236
 
 
1237
    if (use_netlink_stats < 0) {
 
1238
        use_netlink_stats = check_for_working_netlink_stats();
 
1239
    }
 
1240
 
 
1241
    if (use_netlink_stats) {
 
1242
        int ifindex;
 
1243
 
 
1244
        error = get_ifindex(netdev_, &ifindex);
 
1245
        if (!error) {
 
1246
            error = get_stats_via_netlink(ifindex, stats);
 
1247
        }
 
1248
    } else {
 
1249
        error = get_stats_via_proc(netdev_get_name(netdev_), stats);
 
1250
    }
 
1251
 
 
1252
    if (error) {
 
1253
        VLOG_WARN_RL(&rl, "%s: linux-sys get stats failed %d",
 
1254
                      netdev_get_name(netdev_), error);
 
1255
    }
 
1256
    return error;
 
1257
 
 
1258
}
 
1259
 
 
1260
/* Retrieves current device stats for 'netdev-linux'. */
 
1261
static int
 
1262
netdev_linux_get_stats(const struct netdev *netdev_,
 
1263
                       struct netdev_stats *stats)
 
1264
{
 
1265
    struct netdev_dev_linux *netdev_dev =
 
1266
                                netdev_dev_linux_cast(netdev_get_dev(netdev_));
 
1267
    struct netdev_stats dev_stats;
 
1268
    int error;
 
1269
 
 
1270
    get_stats_via_vport(netdev_, stats);
 
1271
 
 
1272
    error = netdev_linux_sys_get_stats(netdev_, &dev_stats);
 
1273
 
 
1274
    if (error) {
 
1275
        if (!netdev_dev->have_vport_stats) {
 
1276
            return error;
 
1277
        } else {
 
1278
            return 0;
 
1279
        }
 
1280
    }
 
1281
 
 
1282
    if (!netdev_dev->have_vport_stats) {
 
1283
        /* stats not available from OVS then use ioctl stats. */
 
1284
        *stats = dev_stats;
 
1285
    } else {
 
1286
        stats->rx_errors           += dev_stats.rx_errors;
 
1287
        stats->tx_errors           += dev_stats.tx_errors;
 
1288
        stats->rx_dropped          += dev_stats.rx_dropped;
 
1289
        stats->tx_dropped          += dev_stats.tx_dropped;
 
1290
        stats->multicast           += dev_stats.multicast;
 
1291
        stats->collisions          += dev_stats.collisions;
 
1292
        stats->rx_length_errors    += dev_stats.rx_length_errors;
 
1293
        stats->rx_over_errors      += dev_stats.rx_over_errors;
 
1294
        stats->rx_crc_errors       += dev_stats.rx_crc_errors;
 
1295
        stats->rx_frame_errors     += dev_stats.rx_frame_errors;
 
1296
        stats->rx_fifo_errors      += dev_stats.rx_fifo_errors;
 
1297
        stats->rx_missed_errors    += dev_stats.rx_missed_errors;
 
1298
        stats->tx_aborted_errors   += dev_stats.tx_aborted_errors;
 
1299
        stats->tx_carrier_errors   += dev_stats.tx_carrier_errors;
 
1300
        stats->tx_fifo_errors      += dev_stats.tx_fifo_errors;
 
1301
        stats->tx_heartbeat_errors += dev_stats.tx_heartbeat_errors;
 
1302
        stats->tx_window_errors    += dev_stats.tx_window_errors;
 
1303
    }
 
1304
    return 0;
 
1305
}
 
1306
 
 
1307
/* Retrieves current device stats for 'netdev-tap' netdev or
 
1308
 * netdev-internal. */
 
1309
static int
 
1310
netdev_pseudo_get_stats(const struct netdev *netdev_,
 
1311
                        struct netdev_stats *stats)
 
1312
{
 
1313
    struct netdev_dev_linux *netdev_dev =
 
1314
                                netdev_dev_linux_cast(netdev_get_dev(netdev_));
 
1315
    struct netdev_stats dev_stats;
 
1316
    int error;
 
1317
 
 
1318
    get_stats_via_vport(netdev_, stats);
 
1319
 
 
1320
    error = netdev_linux_sys_get_stats(netdev_, &dev_stats);
 
1321
    if (error) {
 
1322
        if (!netdev_dev->have_vport_stats) {
 
1323
            return error;
 
1324
        } else {
 
1325
            return 0;
 
1326
        }
 
1327
    }
 
1328
 
 
1329
    /* If this port is an internal port then the transmit and receive stats
 
1330
     * will appear to be swapped relative to the other ports since we are the
 
1331
     * one sending the data, not a remote computer.  For consistency, we swap
 
1332
     * them back here. This does not apply if we are getting stats from the
 
1333
     * vport layer because it always tracks stats from the perspective of the
 
1334
     * switch. */
 
1335
    if (!netdev_dev->have_vport_stats) {
 
1336
        *stats = dev_stats;
 
1337
        swap_uint64(&stats->rx_packets, &stats->tx_packets);
 
1338
        swap_uint64(&stats->rx_bytes, &stats->tx_bytes);
 
1339
        swap_uint64(&stats->rx_errors, &stats->tx_errors);
 
1340
        swap_uint64(&stats->rx_dropped, &stats->tx_dropped);
 
1341
        stats->rx_length_errors = 0;
 
1342
        stats->rx_over_errors = 0;
 
1343
        stats->rx_crc_errors = 0;
 
1344
        stats->rx_frame_errors = 0;
 
1345
        stats->rx_fifo_errors = 0;
 
1346
        stats->rx_missed_errors = 0;
 
1347
        stats->tx_aborted_errors = 0;
 
1348
        stats->tx_carrier_errors = 0;
 
1349
        stats->tx_fifo_errors = 0;
 
1350
        stats->tx_heartbeat_errors = 0;
 
1351
        stats->tx_window_errors = 0;
 
1352
    } else {
 
1353
        stats->rx_dropped          += dev_stats.tx_dropped;
 
1354
        stats->tx_dropped          += dev_stats.rx_dropped;
 
1355
 
 
1356
        stats->rx_errors           += dev_stats.tx_errors;
 
1357
        stats->tx_errors           += dev_stats.rx_errors;
 
1358
 
 
1359
        stats->multicast           += dev_stats.multicast;
 
1360
        stats->collisions          += dev_stats.collisions;
 
1361
    }
 
1362
    return 0;
 
1363
}
 
1364
 
 
1365
/* Stores the features supported by 'netdev' into each of '*current',
 
1366
 * '*advertised', '*supported', and '*peer' that are non-null.  Each value is a
 
1367
 * bitmap of "enum ofp_port_features" bits, in host byte order.  Returns 0 if
 
1368
 * successful, otherwise a positive errno value. */
 
1369
static int
 
1370
netdev_linux_get_features(const struct netdev *netdev,
 
1371
                          uint32_t *current, uint32_t *advertised,
 
1372
                          uint32_t *supported, uint32_t *peer)
 
1373
{
 
1374
    struct ethtool_cmd ecmd;
 
1375
    int error;
 
1376
 
 
1377
    memset(&ecmd, 0, sizeof ecmd);
 
1378
    error = netdev_linux_do_ethtool(netdev_get_name(netdev), &ecmd,
 
1379
                                    ETHTOOL_GSET, "ETHTOOL_GSET");
 
1380
    if (error) {
 
1381
        return error;
 
1382
    }
 
1383
 
 
1384
    /* Supported features. */
 
1385
    *supported = 0;
 
1386
    if (ecmd.supported & SUPPORTED_10baseT_Half) {
 
1387
        *supported |= OFPPF_10MB_HD;
 
1388
    }
 
1389
    if (ecmd.supported & SUPPORTED_10baseT_Full) {
 
1390
        *supported |= OFPPF_10MB_FD;
 
1391
    }
 
1392
    if (ecmd.supported & SUPPORTED_100baseT_Half)  {
 
1393
        *supported |= OFPPF_100MB_HD;
 
1394
    }
 
1395
    if (ecmd.supported & SUPPORTED_100baseT_Full) {
 
1396
        *supported |= OFPPF_100MB_FD;
 
1397
    }
 
1398
    if (ecmd.supported & SUPPORTED_1000baseT_Half) {
 
1399
        *supported |= OFPPF_1GB_HD;
 
1400
    }
 
1401
    if (ecmd.supported & SUPPORTED_1000baseT_Full) {
 
1402
        *supported |= OFPPF_1GB_FD;
 
1403
    }
 
1404
    if (ecmd.supported & SUPPORTED_10000baseT_Full) {
 
1405
        *supported |= OFPPF_10GB_FD;
 
1406
    }
 
1407
    if (ecmd.supported & SUPPORTED_TP) {
 
1408
        *supported |= OFPPF_COPPER;
 
1409
    }
 
1410
    if (ecmd.supported & SUPPORTED_FIBRE) {
 
1411
        *supported |= OFPPF_FIBER;
 
1412
    }
 
1413
    if (ecmd.supported & SUPPORTED_Autoneg) {
 
1414
        *supported |= OFPPF_AUTONEG;
 
1415
    }
 
1416
    if (ecmd.supported & SUPPORTED_Pause) {
 
1417
        *supported |= OFPPF_PAUSE;
 
1418
    }
 
1419
    if (ecmd.supported & SUPPORTED_Asym_Pause) {
 
1420
        *supported |= OFPPF_PAUSE_ASYM;
 
1421
    }
 
1422
 
 
1423
    /* Advertised features. */
 
1424
    *advertised = 0;
 
1425
    if (ecmd.advertising & ADVERTISED_10baseT_Half) {
 
1426
        *advertised |= OFPPF_10MB_HD;
 
1427
    }
 
1428
    if (ecmd.advertising & ADVERTISED_10baseT_Full) {
 
1429
        *advertised |= OFPPF_10MB_FD;
 
1430
    }
 
1431
    if (ecmd.advertising & ADVERTISED_100baseT_Half) {
 
1432
        *advertised |= OFPPF_100MB_HD;
 
1433
    }
 
1434
    if (ecmd.advertising & ADVERTISED_100baseT_Full) {
 
1435
        *advertised |= OFPPF_100MB_FD;
 
1436
    }
 
1437
    if (ecmd.advertising & ADVERTISED_1000baseT_Half) {
 
1438
        *advertised |= OFPPF_1GB_HD;
 
1439
    }
 
1440
    if (ecmd.advertising & ADVERTISED_1000baseT_Full) {
 
1441
        *advertised |= OFPPF_1GB_FD;
 
1442
    }
 
1443
    if (ecmd.advertising & ADVERTISED_10000baseT_Full) {
 
1444
        *advertised |= OFPPF_10GB_FD;
 
1445
    }
 
1446
    if (ecmd.advertising & ADVERTISED_TP) {
 
1447
        *advertised |= OFPPF_COPPER;
 
1448
    }
 
1449
    if (ecmd.advertising & ADVERTISED_FIBRE) {
 
1450
        *advertised |= OFPPF_FIBER;
 
1451
    }
 
1452
    if (ecmd.advertising & ADVERTISED_Autoneg) {
 
1453
        *advertised |= OFPPF_AUTONEG;
 
1454
    }
 
1455
    if (ecmd.advertising & ADVERTISED_Pause) {
 
1456
        *advertised |= OFPPF_PAUSE;
 
1457
    }
 
1458
    if (ecmd.advertising & ADVERTISED_Asym_Pause) {
 
1459
        *advertised |= OFPPF_PAUSE_ASYM;
 
1460
    }
 
1461
 
 
1462
    /* Current settings. */
 
1463
    if (ecmd.speed == SPEED_10) {
 
1464
        *current = ecmd.duplex ? OFPPF_10MB_FD : OFPPF_10MB_HD;
 
1465
    } else if (ecmd.speed == SPEED_100) {
 
1466
        *current = ecmd.duplex ? OFPPF_100MB_FD : OFPPF_100MB_HD;
 
1467
    } else if (ecmd.speed == SPEED_1000) {
 
1468
        *current = ecmd.duplex ? OFPPF_1GB_FD : OFPPF_1GB_HD;
 
1469
    } else if (ecmd.speed == SPEED_10000) {
 
1470
        *current = OFPPF_10GB_FD;
 
1471
    } else {
 
1472
        *current = 0;
 
1473
    }
 
1474
 
 
1475
    if (ecmd.port == PORT_TP) {
 
1476
        *current |= OFPPF_COPPER;
 
1477
    } else if (ecmd.port == PORT_FIBRE) {
 
1478
        *current |= OFPPF_FIBER;
 
1479
    }
 
1480
 
 
1481
    if (ecmd.autoneg) {
 
1482
        *current |= OFPPF_AUTONEG;
 
1483
    }
 
1484
 
 
1485
    /* Peer advertisements. */
 
1486
    *peer = 0;                  /* XXX */
 
1487
 
 
1488
    return 0;
 
1489
}
 
1490
 
 
1491
/* Set the features advertised by 'netdev' to 'advertise'. */
 
1492
static int
 
1493
netdev_linux_set_advertisements(struct netdev *netdev, uint32_t advertise)
 
1494
{
 
1495
    struct ethtool_cmd ecmd;
 
1496
    int error;
 
1497
 
 
1498
    memset(&ecmd, 0, sizeof ecmd);
 
1499
    error = netdev_linux_do_ethtool(netdev_get_name(netdev), &ecmd,
 
1500
                                    ETHTOOL_GSET, "ETHTOOL_GSET");
 
1501
    if (error) {
 
1502
        return error;
 
1503
    }
 
1504
 
 
1505
    ecmd.advertising = 0;
 
1506
    if (advertise & OFPPF_10MB_HD) {
 
1507
        ecmd.advertising |= ADVERTISED_10baseT_Half;
 
1508
    }
 
1509
    if (advertise & OFPPF_10MB_FD) {
 
1510
        ecmd.advertising |= ADVERTISED_10baseT_Full;
 
1511
    }
 
1512
    if (advertise & OFPPF_100MB_HD) {
 
1513
        ecmd.advertising |= ADVERTISED_100baseT_Half;
 
1514
    }
 
1515
    if (advertise & OFPPF_100MB_FD) {
 
1516
        ecmd.advertising |= ADVERTISED_100baseT_Full;
 
1517
    }
 
1518
    if (advertise & OFPPF_1GB_HD) {
 
1519
        ecmd.advertising |= ADVERTISED_1000baseT_Half;
 
1520
    }
 
1521
    if (advertise & OFPPF_1GB_FD) {
 
1522
        ecmd.advertising |= ADVERTISED_1000baseT_Full;
 
1523
    }
 
1524
    if (advertise & OFPPF_10GB_FD) {
 
1525
        ecmd.advertising |= ADVERTISED_10000baseT_Full;
 
1526
    }
 
1527
    if (advertise & OFPPF_COPPER) {
 
1528
        ecmd.advertising |= ADVERTISED_TP;
 
1529
    }
 
1530
    if (advertise & OFPPF_FIBER) {
 
1531
        ecmd.advertising |= ADVERTISED_FIBRE;
 
1532
    }
 
1533
    if (advertise & OFPPF_AUTONEG) {
 
1534
        ecmd.advertising |= ADVERTISED_Autoneg;
 
1535
    }
 
1536
    if (advertise & OFPPF_PAUSE) {
 
1537
        ecmd.advertising |= ADVERTISED_Pause;
 
1538
    }
 
1539
    if (advertise & OFPPF_PAUSE_ASYM) {
 
1540
        ecmd.advertising |= ADVERTISED_Asym_Pause;
 
1541
    }
 
1542
    return netdev_linux_do_ethtool(netdev_get_name(netdev), &ecmd,
 
1543
                                   ETHTOOL_SSET, "ETHTOOL_SSET");
 
1544
}
 
1545
 
 
1546
#define POLICE_ADD_CMD "/sbin/tc qdisc add dev %s handle ffff: ingress"
 
1547
#define POLICE_CONFIG_CMD "/sbin/tc filter add dev %s parent ffff: protocol ip prio 50 u32 match ip src 0.0.0.0/0 police rate %dkbit burst %dk mtu 65535 drop flowid :1"
 
1548
 
 
1549
/* Remove ingress policing from 'netdev'.  Returns 0 if successful, otherwise a
 
1550
 * positive errno value.
 
1551
 *
 
1552
 * This function is equivalent to running
 
1553
 *     /sbin/tc qdisc del dev %s handle ffff: ingress
 
1554
 * but it is much, much faster.
 
1555
 */
 
1556
static int
 
1557
netdev_linux_remove_policing(struct netdev *netdev)
 
1558
{
 
1559
    struct netdev_dev_linux *netdev_dev =
 
1560
        netdev_dev_linux_cast(netdev_get_dev(netdev));
 
1561
    const char *netdev_name = netdev_get_name(netdev);
 
1562
 
 
1563
    struct ofpbuf request;
 
1564
    struct tcmsg *tcmsg;
 
1565
    int error;
 
1566
 
 
1567
    tcmsg = tc_make_request(netdev, RTM_DELQDISC, 0, &request);
 
1568
    if (!tcmsg) {
 
1569
        return ENODEV;
 
1570
    }
 
1571
    tcmsg->tcm_handle = tc_make_handle(0xffff, 0);
 
1572
    tcmsg->tcm_parent = TC_H_INGRESS;
 
1573
    nl_msg_put_string(&request, TCA_KIND, "ingress");
 
1574
    nl_msg_put_unspec(&request, TCA_OPTIONS, NULL, 0);
 
1575
 
 
1576
    error = tc_transact(&request, NULL);
 
1577
    if (error && error != ENOENT && error != EINVAL) {
 
1578
        VLOG_WARN_RL(&rl, "%s: removing policing failed: %s",
 
1579
                     netdev_name, strerror(error));
 
1580
        return error;
 
1581
    }
 
1582
 
 
1583
    netdev_dev->kbits_rate = 0;
 
1584
    netdev_dev->kbits_burst = 0;
 
1585
    netdev_dev->cache_valid |= VALID_POLICING;
 
1586
    return 0;
 
1587
}
 
1588
 
 
1589
/* Attempts to set input rate limiting (policing) policy. */
 
1590
static int
 
1591
netdev_linux_set_policing(struct netdev *netdev,
 
1592
                          uint32_t kbits_rate, uint32_t kbits_burst)
 
1593
{
 
1594
    struct netdev_dev_linux *netdev_dev =
 
1595
        netdev_dev_linux_cast(netdev_get_dev(netdev));
 
1596
    const char *netdev_name = netdev_get_name(netdev);
 
1597
    char command[1024];
 
1598
 
 
1599
    COVERAGE_INC(netdev_set_policing);
 
1600
 
 
1601
    kbits_burst = (!kbits_rate ? 0       /* Force to 0 if no rate specified. */
 
1602
                   : !kbits_burst ? 1000 /* Default to 1000 kbits if 0. */
 
1603
                   : kbits_burst);       /* Stick with user-specified value. */
 
1604
 
 
1605
    if (netdev_dev->cache_valid & VALID_POLICING
 
1606
        && netdev_dev->kbits_rate == kbits_rate
 
1607
        && netdev_dev->kbits_burst == kbits_burst) {
 
1608
        /* Assume that settings haven't changed since we last set them. */
 
1609
        return 0;
 
1610
    }
 
1611
 
 
1612
    netdev_linux_remove_policing(netdev);
 
1613
    if (kbits_rate) {
 
1614
        snprintf(command, sizeof(command), POLICE_ADD_CMD, netdev_name);
 
1615
        if (system(command) != 0) {
 
1616
            VLOG_WARN_RL(&rl, "%s: problem adding policing", netdev_name);
 
1617
            return -1;
 
1618
        }
 
1619
 
 
1620
        snprintf(command, sizeof(command), POLICE_CONFIG_CMD, netdev_name,
 
1621
                kbits_rate, kbits_burst);
 
1622
        if (system(command) != 0) {
 
1623
            VLOG_WARN_RL(&rl, "%s: problem configuring policing",
 
1624
                    netdev_name);
 
1625
            return -1;
 
1626
        }
 
1627
 
 
1628
        netdev_dev->kbits_rate = kbits_rate;
 
1629
        netdev_dev->kbits_burst = kbits_burst;
 
1630
        netdev_dev->cache_valid |= VALID_POLICING;
 
1631
    }
 
1632
 
 
1633
    return 0;
 
1634
}
 
1635
 
 
1636
static int
 
1637
netdev_linux_get_qos_types(const struct netdev *netdev OVS_UNUSED,
 
1638
                           struct sset *types)
 
1639
{
 
1640
    const struct tc_ops **opsp;
 
1641
 
 
1642
    for (opsp = tcs; *opsp != NULL; opsp++) {
 
1643
        const struct tc_ops *ops = *opsp;
 
1644
        if (ops->tc_install && ops->ovs_name[0] != '\0') {
 
1645
            sset_add(types, ops->ovs_name);
 
1646
        }
 
1647
    }
 
1648
    return 0;
 
1649
}
 
1650
 
 
1651
static const struct tc_ops *
 
1652
tc_lookup_ovs_name(const char *name)
 
1653
{
 
1654
    const struct tc_ops **opsp;
 
1655
 
 
1656
    for (opsp = tcs; *opsp != NULL; opsp++) {
 
1657
        const struct tc_ops *ops = *opsp;
 
1658
        if (!strcmp(name, ops->ovs_name)) {
 
1659
            return ops;
 
1660
        }
 
1661
    }
 
1662
    return NULL;
 
1663
}
 
1664
 
 
1665
static const struct tc_ops *
 
1666
tc_lookup_linux_name(const char *name)
 
1667
{
 
1668
    const struct tc_ops **opsp;
 
1669
 
 
1670
    for (opsp = tcs; *opsp != NULL; opsp++) {
 
1671
        const struct tc_ops *ops = *opsp;
 
1672
        if (ops->linux_name && !strcmp(name, ops->linux_name)) {
 
1673
            return ops;
 
1674
        }
 
1675
    }
 
1676
    return NULL;
 
1677
}
 
1678
 
 
1679
static struct tc_queue *
 
1680
tc_find_queue__(const struct netdev *netdev, unsigned int queue_id,
 
1681
                size_t hash)
 
1682
{
 
1683
    struct netdev_dev_linux *netdev_dev =
 
1684
                                netdev_dev_linux_cast(netdev_get_dev(netdev));
 
1685
    struct tc_queue *queue;
 
1686
 
 
1687
    HMAP_FOR_EACH_IN_BUCKET (queue, hmap_node, hash, &netdev_dev->tc->queues) {
 
1688
        if (queue->queue_id == queue_id) {
 
1689
            return queue;
 
1690
        }
 
1691
    }
 
1692
    return NULL;
 
1693
}
 
1694
 
 
1695
static struct tc_queue *
 
1696
tc_find_queue(const struct netdev *netdev, unsigned int queue_id)
 
1697
{
 
1698
    return tc_find_queue__(netdev, queue_id, hash_int(queue_id, 0));
 
1699
}
 
1700
 
 
1701
static int
 
1702
netdev_linux_get_qos_capabilities(const struct netdev *netdev OVS_UNUSED,
 
1703
                                  const char *type,
 
1704
                                  struct netdev_qos_capabilities *caps)
 
1705
{
 
1706
    const struct tc_ops *ops = tc_lookup_ovs_name(type);
 
1707
    if (!ops) {
 
1708
        return EOPNOTSUPP;
 
1709
    }
 
1710
    caps->n_queues = ops->n_queues;
 
1711
    return 0;
 
1712
}
 
1713
 
 
1714
static int
 
1715
netdev_linux_get_qos(const struct netdev *netdev,
 
1716
                     const char **typep, struct shash *details)
 
1717
{
 
1718
    struct netdev_dev_linux *netdev_dev =
 
1719
                                netdev_dev_linux_cast(netdev_get_dev(netdev));
 
1720
    int error;
 
1721
 
 
1722
    error = tc_query_qdisc(netdev);
 
1723
    if (error) {
 
1724
        return error;
 
1725
    }
 
1726
 
 
1727
    *typep = netdev_dev->tc->ops->ovs_name;
 
1728
    return (netdev_dev->tc->ops->qdisc_get
 
1729
            ? netdev_dev->tc->ops->qdisc_get(netdev, details)
 
1730
            : 0);
 
1731
}
 
1732
 
 
1733
static int
 
1734
netdev_linux_set_qos(struct netdev *netdev,
 
1735
                     const char *type, const struct shash *details)
 
1736
{
 
1737
    struct netdev_dev_linux *netdev_dev =
 
1738
                                netdev_dev_linux_cast(netdev_get_dev(netdev));
 
1739
    const struct tc_ops *new_ops;
 
1740
    int error;
 
1741
 
 
1742
    new_ops = tc_lookup_ovs_name(type);
 
1743
    if (!new_ops || !new_ops->tc_install) {
 
1744
        return EOPNOTSUPP;
 
1745
    }
 
1746
 
 
1747
    error = tc_query_qdisc(netdev);
 
1748
    if (error) {
 
1749
        return error;
 
1750
    }
 
1751
 
 
1752
    if (new_ops == netdev_dev->tc->ops) {
 
1753
        return new_ops->qdisc_set ? new_ops->qdisc_set(netdev, details) : 0;
 
1754
    } else {
 
1755
        /* Delete existing qdisc. */
 
1756
        error = tc_del_qdisc(netdev);
 
1757
        if (error) {
 
1758
            return error;
 
1759
        }
 
1760
        assert(netdev_dev->tc == NULL);
 
1761
 
 
1762
        /* Install new qdisc. */
 
1763
        error = new_ops->tc_install(netdev, details);
 
1764
        assert((error == 0) == (netdev_dev->tc != NULL));
 
1765
 
 
1766
        return error;
 
1767
    }
 
1768
}
 
1769
 
 
1770
static int
 
1771
netdev_linux_get_queue(const struct netdev *netdev,
 
1772
                       unsigned int queue_id, struct shash *details)
 
1773
{
 
1774
    struct netdev_dev_linux *netdev_dev =
 
1775
                                netdev_dev_linux_cast(netdev_get_dev(netdev));
 
1776
    int error;
 
1777
 
 
1778
    error = tc_query_qdisc(netdev);
 
1779
    if (error) {
 
1780
        return error;
 
1781
    } else {
 
1782
        struct tc_queue *queue = tc_find_queue(netdev, queue_id);
 
1783
        return (queue
 
1784
                ? netdev_dev->tc->ops->class_get(netdev, queue, details)
 
1785
                : ENOENT);
 
1786
    }
 
1787
}
 
1788
 
 
1789
static int
 
1790
netdev_linux_set_queue(struct netdev *netdev,
 
1791
                       unsigned int queue_id, const struct shash *details)
 
1792
{
 
1793
    struct netdev_dev_linux *netdev_dev =
 
1794
                                netdev_dev_linux_cast(netdev_get_dev(netdev));
 
1795
    int error;
 
1796
 
 
1797
    error = tc_query_qdisc(netdev);
 
1798
    if (error) {
 
1799
        return error;
 
1800
    } else if (queue_id >= netdev_dev->tc->ops->n_queues
 
1801
               || !netdev_dev->tc->ops->class_set) {
 
1802
        return EINVAL;
 
1803
    }
 
1804
 
 
1805
    return netdev_dev->tc->ops->class_set(netdev, queue_id, details);
 
1806
}
 
1807
 
 
1808
static int
 
1809
netdev_linux_delete_queue(struct netdev *netdev, unsigned int queue_id)
 
1810
{
 
1811
    struct netdev_dev_linux *netdev_dev =
 
1812
                                netdev_dev_linux_cast(netdev_get_dev(netdev));
 
1813
    int error;
 
1814
 
 
1815
    error = tc_query_qdisc(netdev);
 
1816
    if (error) {
 
1817
        return error;
 
1818
    } else if (!netdev_dev->tc->ops->class_delete) {
 
1819
        return EINVAL;
 
1820
    } else {
 
1821
        struct tc_queue *queue = tc_find_queue(netdev, queue_id);
 
1822
        return (queue
 
1823
                ? netdev_dev->tc->ops->class_delete(netdev, queue)
 
1824
                : ENOENT);
 
1825
    }
 
1826
}
 
1827
 
 
1828
static int
 
1829
netdev_linux_get_queue_stats(const struct netdev *netdev,
 
1830
                             unsigned int queue_id,
 
1831
                             struct netdev_queue_stats *stats)
 
1832
{
 
1833
    struct netdev_dev_linux *netdev_dev =
 
1834
                                netdev_dev_linux_cast(netdev_get_dev(netdev));
 
1835
    int error;
 
1836
 
 
1837
    error = tc_query_qdisc(netdev);
 
1838
    if (error) {
 
1839
        return error;
 
1840
    } else if (!netdev_dev->tc->ops->class_get_stats) {
 
1841
        return EOPNOTSUPP;
 
1842
    } else {
 
1843
        const struct tc_queue *queue = tc_find_queue(netdev, queue_id);
 
1844
        return (queue
 
1845
                ? netdev_dev->tc->ops->class_get_stats(netdev, queue, stats)
 
1846
                : ENOENT);
 
1847
    }
 
1848
}
 
1849
 
 
1850
static bool
 
1851
start_queue_dump(const struct netdev *netdev, struct nl_dump *dump)
 
1852
{
 
1853
    struct ofpbuf request;
 
1854
    struct tcmsg *tcmsg;
 
1855
 
 
1856
    tcmsg = tc_make_request(netdev, RTM_GETTCLASS, 0, &request);
 
1857
    if (!tcmsg) {
 
1858
        return false;
 
1859
    }
 
1860
    tcmsg->tcm_parent = 0;
 
1861
    nl_dump_start(dump, rtnl_sock, &request);
 
1862
    ofpbuf_uninit(&request);
 
1863
    return true;
 
1864
}
 
1865
 
 
1866
static int
 
1867
netdev_linux_dump_queues(const struct netdev *netdev,
 
1868
                         netdev_dump_queues_cb *cb, void *aux)
 
1869
{
 
1870
    struct netdev_dev_linux *netdev_dev =
 
1871
                                netdev_dev_linux_cast(netdev_get_dev(netdev));
 
1872
    struct tc_queue *queue, *next_queue;
 
1873
    struct shash details;
 
1874
    int last_error;
 
1875
    int error;
 
1876
 
 
1877
    error = tc_query_qdisc(netdev);
 
1878
    if (error) {
 
1879
        return error;
 
1880
    } else if (!netdev_dev->tc->ops->class_get) {
 
1881
        return EOPNOTSUPP;
 
1882
    }
 
1883
 
 
1884
    last_error = 0;
 
1885
    shash_init(&details);
 
1886
    HMAP_FOR_EACH_SAFE (queue, next_queue, hmap_node,
 
1887
                        &netdev_dev->tc->queues) {
 
1888
        shash_clear(&details);
 
1889
 
 
1890
        error = netdev_dev->tc->ops->class_get(netdev, queue, &details);
 
1891
        if (!error) {
 
1892
            (*cb)(queue->queue_id, &details, aux);
 
1893
        } else {
 
1894
            last_error = error;
 
1895
        }
 
1896
    }
 
1897
    shash_destroy(&details);
 
1898
 
 
1899
    return last_error;
 
1900
}
 
1901
 
 
1902
static int
 
1903
netdev_linux_dump_queue_stats(const struct netdev *netdev,
 
1904
                              netdev_dump_queue_stats_cb *cb, void *aux)
 
1905
{
 
1906
    struct netdev_dev_linux *netdev_dev =
 
1907
                                netdev_dev_linux_cast(netdev_get_dev(netdev));
 
1908
    struct nl_dump dump;
 
1909
    struct ofpbuf msg;
 
1910
    int last_error;
 
1911
    int error;
 
1912
 
 
1913
    error = tc_query_qdisc(netdev);
 
1914
    if (error) {
 
1915
        return error;
 
1916
    } else if (!netdev_dev->tc->ops->class_dump_stats) {
 
1917
        return EOPNOTSUPP;
 
1918
    }
 
1919
 
 
1920
    last_error = 0;
 
1921
    if (!start_queue_dump(netdev, &dump)) {
 
1922
        return ENODEV;
 
1923
    }
 
1924
    while (nl_dump_next(&dump, &msg)) {
 
1925
        error = netdev_dev->tc->ops->class_dump_stats(netdev, &msg, cb, aux);
 
1926
        if (error) {
 
1927
            last_error = error;
 
1928
        }
 
1929
    }
 
1930
 
 
1931
    error = nl_dump_done(&dump);
 
1932
    return error ? error : last_error;
 
1933
}
 
1934
 
 
1935
static int
 
1936
netdev_linux_get_in4(const struct netdev *netdev_,
 
1937
                     struct in_addr *address, struct in_addr *netmask)
 
1938
{
 
1939
    struct netdev_dev_linux *netdev_dev =
 
1940
                                netdev_dev_linux_cast(netdev_get_dev(netdev_));
 
1941
 
 
1942
    if (!(netdev_dev->cache_valid & VALID_IN4)) {
 
1943
        int error;
 
1944
 
 
1945
        error = netdev_linux_get_ipv4(netdev_, &netdev_dev->address,
 
1946
                                      SIOCGIFADDR, "SIOCGIFADDR");
 
1947
        if (error) {
 
1948
            return error;
 
1949
        }
 
1950
 
 
1951
        error = netdev_linux_get_ipv4(netdev_, &netdev_dev->netmask,
 
1952
                                      SIOCGIFNETMASK, "SIOCGIFNETMASK");
 
1953
        if (error) {
 
1954
            return error;
 
1955
        }
 
1956
 
 
1957
        netdev_dev->cache_valid |= VALID_IN4;
 
1958
    }
 
1959
    *address = netdev_dev->address;
 
1960
    *netmask = netdev_dev->netmask;
 
1961
    return address->s_addr == INADDR_ANY ? EADDRNOTAVAIL : 0;
 
1962
}
 
1963
 
 
1964
static int
 
1965
netdev_linux_set_in4(struct netdev *netdev_, struct in_addr address,
 
1966
                     struct in_addr netmask)
 
1967
{
 
1968
    struct netdev_dev_linux *netdev_dev =
 
1969
                                netdev_dev_linux_cast(netdev_get_dev(netdev_));
 
1970
    int error;
 
1971
 
 
1972
    error = do_set_addr(netdev_, SIOCSIFADDR, "SIOCSIFADDR", address);
 
1973
    if (!error) {
 
1974
        netdev_dev->cache_valid |= VALID_IN4;
 
1975
        netdev_dev->address = address;
 
1976
        netdev_dev->netmask = netmask;
 
1977
        if (address.s_addr != INADDR_ANY) {
 
1978
            error = do_set_addr(netdev_, SIOCSIFNETMASK,
 
1979
                                "SIOCSIFNETMASK", netmask);
 
1980
        }
 
1981
    }
 
1982
    return error;
 
1983
}
 
1984
 
 
1985
static bool
 
1986
parse_if_inet6_line(const char *line,
 
1987
                    struct in6_addr *in6, char ifname[16 + 1])
 
1988
{
 
1989
    uint8_t *s6 = in6->s6_addr;
 
1990
#define X8 "%2"SCNx8
 
1991
    return sscanf(line,
 
1992
                  " "X8 X8 X8 X8 X8 X8 X8 X8 X8 X8 X8 X8 X8 X8 X8 X8
 
1993
                  "%*x %*x %*x %*x %16s\n",
 
1994
                  &s6[0], &s6[1], &s6[2], &s6[3],
 
1995
                  &s6[4], &s6[5], &s6[6], &s6[7],
 
1996
                  &s6[8], &s6[9], &s6[10], &s6[11],
 
1997
                  &s6[12], &s6[13], &s6[14], &s6[15],
 
1998
                  ifname) == 17;
 
1999
}
 
2000
 
 
2001
/* If 'netdev' has an assigned IPv6 address, sets '*in6' to that address (if
 
2002
 * 'in6' is non-null) and returns true.  Otherwise, returns false. */
 
2003
static int
 
2004
netdev_linux_get_in6(const struct netdev *netdev_, struct in6_addr *in6)
 
2005
{
 
2006
    struct netdev_dev_linux *netdev_dev =
 
2007
                                netdev_dev_linux_cast(netdev_get_dev(netdev_));
 
2008
    if (!(netdev_dev->cache_valid & VALID_IN6)) {
 
2009
        FILE *file;
 
2010
        char line[128];
 
2011
 
 
2012
        netdev_dev->in6 = in6addr_any;
 
2013
 
 
2014
        file = fopen("/proc/net/if_inet6", "r");
 
2015
        if (file != NULL) {
 
2016
            const char *name = netdev_get_name(netdev_);
 
2017
            while (fgets(line, sizeof line, file)) {
 
2018
                struct in6_addr in6_tmp;
 
2019
                char ifname[16 + 1];
 
2020
                if (parse_if_inet6_line(line, &in6_tmp, ifname)
 
2021
                    && !strcmp(name, ifname))
 
2022
                {
 
2023
                    netdev_dev->in6 = in6_tmp;
 
2024
                    break;
 
2025
                }
 
2026
            }
 
2027
            fclose(file);
 
2028
        }
 
2029
        netdev_dev->cache_valid |= VALID_IN6;
 
2030
    }
 
2031
    *in6 = netdev_dev->in6;
 
2032
    return 0;
 
2033
}
 
2034
 
 
2035
static void
 
2036
make_in4_sockaddr(struct sockaddr *sa, struct in_addr addr)
 
2037
{
 
2038
    struct sockaddr_in sin;
 
2039
    memset(&sin, 0, sizeof sin);
 
2040
    sin.sin_family = AF_INET;
 
2041
    sin.sin_addr = addr;
 
2042
    sin.sin_port = 0;
 
2043
 
 
2044
    memset(sa, 0, sizeof *sa);
 
2045
    memcpy(sa, &sin, sizeof sin);
 
2046
}
 
2047
 
 
2048
static int
 
2049
do_set_addr(struct netdev *netdev,
 
2050
            int ioctl_nr, const char *ioctl_name, struct in_addr addr)
 
2051
{
 
2052
    struct ifreq ifr;
 
2053
    ovs_strzcpy(ifr.ifr_name, netdev_get_name(netdev), sizeof ifr.ifr_name);
 
2054
    make_in4_sockaddr(&ifr.ifr_addr, addr);
 
2055
 
 
2056
    return netdev_linux_do_ioctl(netdev_get_name(netdev), &ifr, ioctl_nr,
 
2057
                                 ioctl_name);
 
2058
}
 
2059
 
 
2060
/* Adds 'router' as a default IP gateway. */
 
2061
static int
 
2062
netdev_linux_add_router(struct netdev *netdev OVS_UNUSED, struct in_addr router)
 
2063
{
 
2064
    struct in_addr any = { INADDR_ANY };
 
2065
    struct rtentry rt;
 
2066
    int error;
 
2067
 
 
2068
    memset(&rt, 0, sizeof rt);
 
2069
    make_in4_sockaddr(&rt.rt_dst, any);
 
2070
    make_in4_sockaddr(&rt.rt_gateway, router);
 
2071
    make_in4_sockaddr(&rt.rt_genmask, any);
 
2072
    rt.rt_flags = RTF_UP | RTF_GATEWAY;
 
2073
    error = ioctl(af_inet_sock, SIOCADDRT, &rt) < 0 ? errno : 0;
 
2074
    if (error) {
 
2075
        VLOG_WARN("ioctl(SIOCADDRT): %s", strerror(error));
 
2076
    }
 
2077
    return error;
 
2078
}
 
2079
 
 
2080
static int
 
2081
netdev_linux_get_next_hop(const struct in_addr *host, struct in_addr *next_hop,
 
2082
                          char **netdev_name)
 
2083
{
 
2084
    static const char fn[] = "/proc/net/route";
 
2085
    FILE *stream;
 
2086
    char line[256];
 
2087
    int ln;
 
2088
 
 
2089
    *netdev_name = NULL;
 
2090
    stream = fopen(fn, "r");
 
2091
    if (stream == NULL) {
 
2092
        VLOG_WARN_RL(&rl, "%s: open failed: %s", fn, strerror(errno));
 
2093
        return errno;
 
2094
    }
 
2095
 
 
2096
    ln = 0;
 
2097
    while (fgets(line, sizeof line, stream)) {
 
2098
        if (++ln >= 2) {
 
2099
            char iface[17];
 
2100
            ovs_be32 dest, gateway, mask;
 
2101
            int refcnt, metric, mtu;
 
2102
            unsigned int flags, use, window, irtt;
 
2103
 
 
2104
            if (sscanf(line,
 
2105
                       "%16s %"SCNx32" %"SCNx32" %04X %d %u %d %"SCNx32
 
2106
                       " %d %u %u\n",
 
2107
                       iface, &dest, &gateway, &flags, &refcnt,
 
2108
                       &use, &metric, &mask, &mtu, &window, &irtt) != 11) {
 
2109
 
 
2110
                VLOG_WARN_RL(&rl, "%s: could not parse line %d: %s",
 
2111
                        fn, ln, line);
 
2112
                continue;
 
2113
            }
 
2114
            if (!(flags & RTF_UP)) {
 
2115
                /* Skip routes that aren't up. */
 
2116
                continue;
 
2117
            }
 
2118
 
 
2119
            /* The output of 'dest', 'mask', and 'gateway' were given in
 
2120
             * network byte order, so we don't need need any endian
 
2121
             * conversions here. */
 
2122
            if ((dest & mask) == (host->s_addr & mask)) {
 
2123
                if (!gateway) {
 
2124
                    /* The host is directly reachable. */
 
2125
                    next_hop->s_addr = 0;
 
2126
                } else {
 
2127
                    /* To reach the host, we must go through a gateway. */
 
2128
                    next_hop->s_addr = gateway;
 
2129
                }
 
2130
                *netdev_name = xstrdup(iface);
 
2131
                fclose(stream);
 
2132
                return 0;
 
2133
            }
 
2134
        }
 
2135
    }
 
2136
 
 
2137
    fclose(stream);
 
2138
    return ENXIO;
 
2139
}
 
2140
 
 
2141
static int
 
2142
netdev_linux_get_status(const struct netdev *netdev, struct shash *sh)
 
2143
{
 
2144
    struct ethtool_drvinfo drvinfo;
 
2145
    int error;
 
2146
 
 
2147
    memset(&drvinfo, 0, sizeof drvinfo);
 
2148
    error = netdev_linux_do_ethtool(netdev_get_name(netdev),
 
2149
                                    (struct ethtool_cmd *)&drvinfo,
 
2150
                                    ETHTOOL_GDRVINFO,
 
2151
                                    "ETHTOOL_GDRVINFO");
 
2152
    if (!error) {
 
2153
        shash_add(sh, "driver_name", xstrdup(drvinfo.driver));
 
2154
        shash_add(sh, "driver_version", xstrdup(drvinfo.version));
 
2155
        shash_add(sh, "firmware_version", xstrdup(drvinfo.fw_version));
 
2156
    }
 
2157
 
 
2158
    return error;
 
2159
}
 
2160
 
 
2161
/* Looks up the ARP table entry for 'ip' on 'netdev'.  If one exists and can be
 
2162
 * successfully retrieved, it stores the corresponding MAC address in 'mac' and
 
2163
 * returns 0.  Otherwise, it returns a positive errno value; in particular,
 
2164
 * ENXIO indicates that there is not ARP table entry for 'ip' on 'netdev'. */
 
2165
static int
 
2166
netdev_linux_arp_lookup(const struct netdev *netdev,
 
2167
                        ovs_be32 ip, uint8_t mac[ETH_ADDR_LEN])
 
2168
{
 
2169
    struct arpreq r;
 
2170
    struct sockaddr_in sin;
 
2171
    int retval;
 
2172
 
 
2173
    memset(&r, 0, sizeof r);
 
2174
    memset(&sin, 0, sizeof sin);
 
2175
    sin.sin_family = AF_INET;
 
2176
    sin.sin_addr.s_addr = ip;
 
2177
    sin.sin_port = 0;
 
2178
    memcpy(&r.arp_pa, &sin, sizeof sin);
 
2179
    r.arp_ha.sa_family = ARPHRD_ETHER;
 
2180
    r.arp_flags = 0;
 
2181
    ovs_strzcpy(r.arp_dev, netdev_get_name(netdev), sizeof r.arp_dev);
 
2182
    COVERAGE_INC(netdev_arp_lookup);
 
2183
    retval = ioctl(af_inet_sock, SIOCGARP, &r) < 0 ? errno : 0;
 
2184
    if (!retval) {
 
2185
        memcpy(mac, r.arp_ha.sa_data, ETH_ADDR_LEN);
 
2186
    } else if (retval != ENXIO) {
 
2187
        VLOG_WARN_RL(&rl, "%s: could not look up ARP entry for "IP_FMT": %s",
 
2188
                     netdev_get_name(netdev), IP_ARGS(&ip), strerror(retval));
 
2189
    }
 
2190
    return retval;
 
2191
}
 
2192
 
 
2193
static int
 
2194
nd_to_iff_flags(enum netdev_flags nd)
 
2195
{
 
2196
    int iff = 0;
 
2197
    if (nd & NETDEV_UP) {
 
2198
        iff |= IFF_UP;
 
2199
    }
 
2200
    if (nd & NETDEV_PROMISC) {
 
2201
        iff |= IFF_PROMISC;
 
2202
    }
 
2203
    return iff;
 
2204
}
 
2205
 
 
2206
static int
 
2207
iff_to_nd_flags(int iff)
 
2208
{
 
2209
    enum netdev_flags nd = 0;
 
2210
    if (iff & IFF_UP) {
 
2211
        nd |= NETDEV_UP;
 
2212
    }
 
2213
    if (iff & IFF_PROMISC) {
 
2214
        nd |= NETDEV_PROMISC;
 
2215
    }
 
2216
    return nd;
 
2217
}
 
2218
 
 
2219
static int
 
2220
netdev_linux_update_flags(struct netdev *netdev, enum netdev_flags off,
 
2221
                          enum netdev_flags on, enum netdev_flags *old_flagsp)
 
2222
{
 
2223
    int old_flags, new_flags;
 
2224
    int error;
 
2225
 
 
2226
    error = get_flags(netdev, &old_flags);
 
2227
    if (!error) {
 
2228
        *old_flagsp = iff_to_nd_flags(old_flags);
 
2229
        new_flags = (old_flags & ~nd_to_iff_flags(off)) | nd_to_iff_flags(on);
 
2230
        if (new_flags != old_flags) {
 
2231
            error = set_flags(netdev, new_flags);
 
2232
        }
 
2233
    }
 
2234
    return error;
 
2235
}
 
2236
 
 
2237
static unsigned int
 
2238
netdev_linux_change_seq(const struct netdev *netdev)
 
2239
{
 
2240
    return netdev_dev_linux_cast(netdev_get_dev(netdev))->change_seq;
 
2241
}
 
2242
 
 
2243
#define NETDEV_LINUX_CLASS(NAME, CREATE, GET_STATS, SET_STATS)  \
 
2244
{                                                               \
 
2245
    NAME,                                                       \
 
2246
                                                                \
 
2247
    netdev_linux_init,                                          \
 
2248
    netdev_linux_run,                                           \
 
2249
    netdev_linux_wait,                                          \
 
2250
                                                                \
 
2251
    CREATE,                                                     \
 
2252
    netdev_linux_destroy,                                       \
 
2253
    NULL,                       /* get_config */                \
 
2254
    NULL,                       /* set_config */                \
 
2255
                                                                \
 
2256
    netdev_linux_open,                                          \
 
2257
    netdev_linux_close,                                         \
 
2258
                                                                \
 
2259
    netdev_linux_listen,                                        \
 
2260
    netdev_linux_recv,                                          \
 
2261
    netdev_linux_recv_wait,                                     \
 
2262
    netdev_linux_drain,                                         \
 
2263
                                                                \
 
2264
    netdev_linux_send,                                          \
 
2265
    netdev_linux_send_wait,                                     \
 
2266
                                                                \
 
2267
    netdev_linux_set_etheraddr,                                 \
 
2268
    netdev_linux_get_etheraddr,                                 \
 
2269
    netdev_linux_get_mtu,                                       \
 
2270
    netdev_linux_set_mtu,                                       \
 
2271
    netdev_linux_get_ifindex,                                   \
 
2272
    netdev_linux_get_carrier,                                   \
 
2273
    netdev_linux_get_carrier_resets,                            \
 
2274
    netdev_linux_set_miimon_interval,                           \
 
2275
    GET_STATS,                                                  \
 
2276
    SET_STATS,                                                  \
 
2277
                                                                \
 
2278
    netdev_linux_get_features,                                  \
 
2279
    netdev_linux_set_advertisements,                            \
 
2280
                                                                \
 
2281
    netdev_linux_set_policing,                                  \
 
2282
    netdev_linux_get_qos_types,                                 \
 
2283
    netdev_linux_get_qos_capabilities,                          \
 
2284
    netdev_linux_get_qos,                                       \
 
2285
    netdev_linux_set_qos,                                       \
 
2286
    netdev_linux_get_queue,                                     \
 
2287
    netdev_linux_set_queue,                                     \
 
2288
    netdev_linux_delete_queue,                                  \
 
2289
    netdev_linux_get_queue_stats,                               \
 
2290
    netdev_linux_dump_queues,                                   \
 
2291
    netdev_linux_dump_queue_stats,                              \
 
2292
                                                                \
 
2293
    netdev_linux_get_in4,                                       \
 
2294
    netdev_linux_set_in4,                                       \
 
2295
    netdev_linux_get_in6,                                       \
 
2296
    netdev_linux_add_router,                                    \
 
2297
    netdev_linux_get_next_hop,                                  \
 
2298
    netdev_linux_get_status,                                    \
 
2299
    netdev_linux_arp_lookup,                                    \
 
2300
                                                                \
 
2301
    netdev_linux_update_flags,                                  \
 
2302
                                                                \
 
2303
    netdev_linux_change_seq                                     \
 
2304
}
 
2305
 
 
2306
const struct netdev_class netdev_linux_class =
 
2307
    NETDEV_LINUX_CLASS(
 
2308
        "system",
 
2309
        netdev_linux_create,
 
2310
        netdev_linux_get_stats,
 
2311
        NULL);                  /* set_stats */
 
2312
 
 
2313
const struct netdev_class netdev_tap_class =
 
2314
    NETDEV_LINUX_CLASS(
 
2315
        "tap",
 
2316
        netdev_linux_create_tap,
 
2317
        netdev_pseudo_get_stats,
 
2318
        NULL);                  /* set_stats */
 
2319
 
 
2320
const struct netdev_class netdev_internal_class =
 
2321
    NETDEV_LINUX_CLASS(
 
2322
        "internal",
 
2323
        netdev_linux_create,
 
2324
        netdev_pseudo_get_stats,
 
2325
        netdev_vport_set_stats);
 
2326
 
 
2327
/* HTB traffic control class. */
 
2328
 
 
2329
#define HTB_N_QUEUES 0xf000
 
2330
 
 
2331
struct htb {
 
2332
    struct tc tc;
 
2333
    unsigned int max_rate;      /* In bytes/s. */
 
2334
};
 
2335
 
 
2336
struct htb_class {
 
2337
    struct tc_queue tc_queue;
 
2338
    unsigned int min_rate;      /* In bytes/s. */
 
2339
    unsigned int max_rate;      /* In bytes/s. */
 
2340
    unsigned int burst;         /* In bytes. */
 
2341
    unsigned int priority;      /* Lower values are higher priorities. */
 
2342
};
 
2343
 
 
2344
static struct htb *
 
2345
htb_get__(const struct netdev *netdev)
 
2346
{
 
2347
    struct netdev_dev_linux *netdev_dev =
 
2348
                                netdev_dev_linux_cast(netdev_get_dev(netdev));
 
2349
    return CONTAINER_OF(netdev_dev->tc, struct htb, tc);
 
2350
}
 
2351
 
 
2352
static void
 
2353
htb_install__(struct netdev *netdev, uint64_t max_rate)
 
2354
{
 
2355
    struct netdev_dev_linux *netdev_dev =
 
2356
                                netdev_dev_linux_cast(netdev_get_dev(netdev));
 
2357
    struct htb *htb;
 
2358
 
 
2359
    htb = xmalloc(sizeof *htb);
 
2360
    tc_init(&htb->tc, &tc_ops_htb);
 
2361
    htb->max_rate = max_rate;
 
2362
 
 
2363
    netdev_dev->tc = &htb->tc;
 
2364
}
 
2365
 
 
2366
/* Create an HTB qdisc.
 
2367
 *
 
2368
 * Equivalent to "tc qdisc add dev <dev> root handle 1: htb default 1". */
 
2369
static int
 
2370
htb_setup_qdisc__(struct netdev *netdev)
 
2371
{
 
2372
    size_t opt_offset;
 
2373
    struct tc_htb_glob opt;
 
2374
    struct ofpbuf request;
 
2375
    struct tcmsg *tcmsg;
 
2376
 
 
2377
    tc_del_qdisc(netdev);
 
2378
 
 
2379
    tcmsg = tc_make_request(netdev, RTM_NEWQDISC,
 
2380
                            NLM_F_EXCL | NLM_F_CREATE, &request);
 
2381
    if (!tcmsg) {
 
2382
        return ENODEV;
 
2383
    }
 
2384
    tcmsg->tcm_handle = tc_make_handle(1, 0);
 
2385
    tcmsg->tcm_parent = TC_H_ROOT;
 
2386
 
 
2387
    nl_msg_put_string(&request, TCA_KIND, "htb");
 
2388
 
 
2389
    memset(&opt, 0, sizeof opt);
 
2390
    opt.rate2quantum = 10;
 
2391
    opt.version = 3;
 
2392
    opt.defcls = 1;
 
2393
 
 
2394
    opt_offset = nl_msg_start_nested(&request, TCA_OPTIONS);
 
2395
    nl_msg_put_unspec(&request, TCA_HTB_INIT, &opt, sizeof opt);
 
2396
    nl_msg_end_nested(&request, opt_offset);
 
2397
 
 
2398
    return tc_transact(&request, NULL);
 
2399
}
 
2400
 
 
2401
/* Equivalent to "tc class replace <dev> classid <handle> parent <parent> htb
 
2402
 * rate <min_rate>bps ceil <max_rate>bps burst <burst>b prio <priority>". */
 
2403
static int
 
2404
htb_setup_class__(struct netdev *netdev, unsigned int handle,
 
2405
                  unsigned int parent, struct htb_class *class)
 
2406
{
 
2407
    size_t opt_offset;
 
2408
    struct tc_htb_opt opt;
 
2409
    struct ofpbuf request;
 
2410
    struct tcmsg *tcmsg;
 
2411
    int error;
 
2412
    int mtu;
 
2413
 
 
2414
    error = netdev_get_mtu(netdev, &mtu);
 
2415
    if (error) {
 
2416
        VLOG_WARN_RL(&rl, "cannot set up HTB on device %s that lacks MTU",
 
2417
                     netdev_get_name(netdev));
 
2418
        return error;
 
2419
    }
 
2420
 
 
2421
    memset(&opt, 0, sizeof opt);
 
2422
    tc_fill_rate(&opt.rate, class->min_rate, mtu);
 
2423
    tc_fill_rate(&opt.ceil, class->max_rate, mtu);
 
2424
    opt.buffer = tc_calc_buffer(opt.rate.rate, mtu, class->burst);
 
2425
    opt.cbuffer = tc_calc_buffer(opt.ceil.rate, mtu, class->burst);
 
2426
    opt.prio = class->priority;
 
2427
 
 
2428
    tcmsg = tc_make_request(netdev, RTM_NEWTCLASS, NLM_F_CREATE, &request);
 
2429
    if (!tcmsg) {
 
2430
        return ENODEV;
 
2431
    }
 
2432
    tcmsg->tcm_handle = handle;
 
2433
    tcmsg->tcm_parent = parent;
 
2434
 
 
2435
    nl_msg_put_string(&request, TCA_KIND, "htb");
 
2436
    opt_offset = nl_msg_start_nested(&request, TCA_OPTIONS);
 
2437
    nl_msg_put_unspec(&request, TCA_HTB_PARMS, &opt, sizeof opt);
 
2438
    tc_put_rtab(&request, TCA_HTB_RTAB, &opt.rate);
 
2439
    tc_put_rtab(&request, TCA_HTB_CTAB, &opt.ceil);
 
2440
    nl_msg_end_nested(&request, opt_offset);
 
2441
 
 
2442
    error = tc_transact(&request, NULL);
 
2443
    if (error) {
 
2444
        VLOG_WARN_RL(&rl, "failed to replace %s class %u:%u, parent %u:%u, "
 
2445
                     "min_rate=%u max_rate=%u burst=%u prio=%u (%s)",
 
2446
                     netdev_get_name(netdev),
 
2447
                     tc_get_major(handle), tc_get_minor(handle),
 
2448
                     tc_get_major(parent), tc_get_minor(parent),
 
2449
                     class->min_rate, class->max_rate,
 
2450
                     class->burst, class->priority, strerror(error));
 
2451
    }
 
2452
    return error;
 
2453
}
 
2454
 
 
2455
/* Parses Netlink attributes in 'options' for HTB parameters and stores a
 
2456
 * description of them into 'details'.  The description complies with the
 
2457
 * specification given in the vswitch database documentation for linux-htb
 
2458
 * queue details. */
 
2459
static int
 
2460
htb_parse_tca_options__(struct nlattr *nl_options, struct htb_class *class)
 
2461
{
 
2462
    static const struct nl_policy tca_htb_policy[] = {
 
2463
        [TCA_HTB_PARMS] = { .type = NL_A_UNSPEC, .optional = false,
 
2464
                            .min_len = sizeof(struct tc_htb_opt) },
 
2465
    };
 
2466
 
 
2467
    struct nlattr *attrs[ARRAY_SIZE(tca_htb_policy)];
 
2468
    const struct tc_htb_opt *htb;
 
2469
 
 
2470
    if (!nl_parse_nested(nl_options, tca_htb_policy,
 
2471
                         attrs, ARRAY_SIZE(tca_htb_policy))) {
 
2472
        VLOG_WARN_RL(&rl, "failed to parse HTB class options");
 
2473
        return EPROTO;
 
2474
    }
 
2475
 
 
2476
    htb = nl_attr_get(attrs[TCA_HTB_PARMS]);
 
2477
    class->min_rate = htb->rate.rate;
 
2478
    class->max_rate = htb->ceil.rate;
 
2479
    class->burst = tc_ticks_to_bytes(htb->rate.rate, htb->buffer);
 
2480
    class->priority = htb->prio;
 
2481
    return 0;
 
2482
}
 
2483
 
 
2484
static int
 
2485
htb_parse_tcmsg__(struct ofpbuf *tcmsg, unsigned int *queue_id,
 
2486
                  struct htb_class *options,
 
2487
                  struct netdev_queue_stats *stats)
 
2488
{
 
2489
    struct nlattr *nl_options;
 
2490
    unsigned int handle;
 
2491
    int error;
 
2492
 
 
2493
    error = tc_parse_class(tcmsg, &handle, &nl_options, stats);
 
2494
    if (!error && queue_id) {
 
2495
        unsigned int major = tc_get_major(handle);
 
2496
        unsigned int minor = tc_get_minor(handle);
 
2497
        if (major == 1 && minor > 0 && minor <= HTB_N_QUEUES) {
 
2498
            *queue_id = minor - 1;
 
2499
        } else {
 
2500
            error = EPROTO;
 
2501
        }
 
2502
    }
 
2503
    if (!error && options) {
 
2504
        error = htb_parse_tca_options__(nl_options, options);
 
2505
    }
 
2506
    return error;
 
2507
}
 
2508
 
 
2509
static void
 
2510
htb_parse_qdisc_details__(struct netdev *netdev,
 
2511
                          const struct shash *details, struct htb_class *hc)
 
2512
{
 
2513
    const char *max_rate_s;
 
2514
 
 
2515
    max_rate_s = shash_find_data(details, "max-rate");
 
2516
    hc->max_rate = max_rate_s ? strtoull(max_rate_s, NULL, 10) / 8 : 0;
 
2517
    if (!hc->max_rate) {
 
2518
        uint32_t current;
 
2519
 
 
2520
        netdev_get_features(netdev, &current, NULL, NULL, NULL);
 
2521
        hc->max_rate = netdev_features_to_bps(current) / 8;
 
2522
    }
 
2523
    hc->min_rate = hc->max_rate;
 
2524
    hc->burst = 0;
 
2525
    hc->priority = 0;
 
2526
}
 
2527
 
 
2528
static int
 
2529
htb_parse_class_details__(struct netdev *netdev,
 
2530
                          const struct shash *details, struct htb_class *hc)
 
2531
{
 
2532
    const struct htb *htb = htb_get__(netdev);
 
2533
    const char *min_rate_s = shash_find_data(details, "min-rate");
 
2534
    const char *max_rate_s = shash_find_data(details, "max-rate");
 
2535
    const char *burst_s = shash_find_data(details, "burst");
 
2536
    const char *priority_s = shash_find_data(details, "priority");
 
2537
    int mtu, error;
 
2538
 
 
2539
    error = netdev_get_mtu(netdev, &mtu);
 
2540
    if (error) {
 
2541
        VLOG_WARN_RL(&rl, "cannot parse HTB class on device %s that lacks MTU",
 
2542
                     netdev_get_name(netdev));
 
2543
        return error;
 
2544
    }
 
2545
 
 
2546
    /* HTB requires at least an mtu sized min-rate to send any traffic even
 
2547
     * on uncongested links. */
 
2548
    hc->min_rate = min_rate_s ? strtoull(min_rate_s, NULL, 10) / 8 : 0;
 
2549
    hc->min_rate = MAX(hc->min_rate, mtu);
 
2550
    hc->min_rate = MIN(hc->min_rate, htb->max_rate);
 
2551
 
 
2552
    /* max-rate */
 
2553
    hc->max_rate = (max_rate_s
 
2554
                    ? strtoull(max_rate_s, NULL, 10) / 8
 
2555
                    : htb->max_rate);
 
2556
    hc->max_rate = MAX(hc->max_rate, hc->min_rate);
 
2557
    hc->max_rate = MIN(hc->max_rate, htb->max_rate);
 
2558
 
 
2559
    /* burst
 
2560
     *
 
2561
     * According to hints in the documentation that I've read, it is important
 
2562
     * that 'burst' be at least as big as the largest frame that might be
 
2563
     * transmitted.  Also, making 'burst' a bit bigger than necessary is OK,
 
2564
     * but having it a bit too small is a problem.  Since netdev_get_mtu()
 
2565
     * doesn't include the Ethernet header, we need to add at least 14 (18?) to
 
2566
     * the MTU.  We actually add 64, instead of 14, as a guard against
 
2567
     * additional headers get tacked on somewhere that we're not aware of. */
 
2568
    hc->burst = burst_s ? strtoull(burst_s, NULL, 10) / 8 : 0;
 
2569
    hc->burst = MAX(hc->burst, mtu + 64);
 
2570
 
 
2571
    /* priority */
 
2572
    hc->priority = priority_s ? strtoul(priority_s, NULL, 10) : 0;
 
2573
 
 
2574
    return 0;
 
2575
}
 
2576
 
 
2577
static int
 
2578
htb_query_class__(const struct netdev *netdev, unsigned int handle,
 
2579
                  unsigned int parent, struct htb_class *options,
 
2580
                  struct netdev_queue_stats *stats)
 
2581
{
 
2582
    struct ofpbuf *reply;
 
2583
    int error;
 
2584
 
 
2585
    error = tc_query_class(netdev, handle, parent, &reply);
 
2586
    if (!error) {
 
2587
        error = htb_parse_tcmsg__(reply, NULL, options, stats);
 
2588
        ofpbuf_delete(reply);
 
2589
    }
 
2590
    return error;
 
2591
}
 
2592
 
 
2593
static int
 
2594
htb_tc_install(struct netdev *netdev, const struct shash *details)
 
2595
{
 
2596
    int error;
 
2597
 
 
2598
    error = htb_setup_qdisc__(netdev);
 
2599
    if (!error) {
 
2600
        struct htb_class hc;
 
2601
 
 
2602
        htb_parse_qdisc_details__(netdev, details, &hc);
 
2603
        error = htb_setup_class__(netdev, tc_make_handle(1, 0xfffe),
 
2604
                                  tc_make_handle(1, 0), &hc);
 
2605
        if (!error) {
 
2606
            htb_install__(netdev, hc.max_rate);
 
2607
        }
 
2608
    }
 
2609
    return error;
 
2610
}
 
2611
 
 
2612
static struct htb_class *
 
2613
htb_class_cast__(const struct tc_queue *queue)
 
2614
{
 
2615
    return CONTAINER_OF(queue, struct htb_class, tc_queue);
 
2616
}
 
2617
 
 
2618
static void
 
2619
htb_update_queue__(struct netdev *netdev, unsigned int queue_id,
 
2620
                   const struct htb_class *hc)
 
2621
{
 
2622
    struct htb *htb = htb_get__(netdev);
 
2623
    size_t hash = hash_int(queue_id, 0);
 
2624
    struct tc_queue *queue;
 
2625
    struct htb_class *hcp;
 
2626
 
 
2627
    queue = tc_find_queue__(netdev, queue_id, hash);
 
2628
    if (queue) {
 
2629
        hcp = htb_class_cast__(queue);
 
2630
    } else {
 
2631
        hcp = xmalloc(sizeof *hcp);
 
2632
        queue = &hcp->tc_queue;
 
2633
        queue->queue_id = queue_id;
 
2634
        hmap_insert(&htb->tc.queues, &queue->hmap_node, hash);
 
2635
    }
 
2636
 
 
2637
    hcp->min_rate = hc->min_rate;
 
2638
    hcp->max_rate = hc->max_rate;
 
2639
    hcp->burst = hc->burst;
 
2640
    hcp->priority = hc->priority;
 
2641
}
 
2642
 
 
2643
static int
 
2644
htb_tc_load(struct netdev *netdev, struct ofpbuf *nlmsg OVS_UNUSED)
 
2645
{
 
2646
    struct ofpbuf msg;
 
2647
    struct nl_dump dump;
 
2648
    struct htb_class hc;
 
2649
 
 
2650
    /* Get qdisc options. */
 
2651
    hc.max_rate = 0;
 
2652
    htb_query_class__(netdev, tc_make_handle(1, 0xfffe), 0, &hc, NULL);
 
2653
    htb_install__(netdev, hc.max_rate);
 
2654
 
 
2655
    /* Get queues. */
 
2656
    if (!start_queue_dump(netdev, &dump)) {
 
2657
        return ENODEV;
 
2658
    }
 
2659
    while (nl_dump_next(&dump, &msg)) {
 
2660
        unsigned int queue_id;
 
2661
 
 
2662
        if (!htb_parse_tcmsg__(&msg, &queue_id, &hc, NULL)) {
 
2663
            htb_update_queue__(netdev, queue_id, &hc);
 
2664
        }
 
2665
    }
 
2666
    nl_dump_done(&dump);
 
2667
 
 
2668
    return 0;
 
2669
}
 
2670
 
 
2671
static void
 
2672
htb_tc_destroy(struct tc *tc)
 
2673
{
 
2674
    struct htb *htb = CONTAINER_OF(tc, struct htb, tc);
 
2675
    struct htb_class *hc, *next;
 
2676
 
 
2677
    HMAP_FOR_EACH_SAFE (hc, next, tc_queue.hmap_node, &htb->tc.queues) {
 
2678
        hmap_remove(&htb->tc.queues, &hc->tc_queue.hmap_node);
 
2679
        free(hc);
 
2680
    }
 
2681
    tc_destroy(tc);
 
2682
    free(htb);
 
2683
}
 
2684
 
 
2685
static int
 
2686
htb_qdisc_get(const struct netdev *netdev, struct shash *details)
 
2687
{
 
2688
    const struct htb *htb = htb_get__(netdev);
 
2689
    shash_add(details, "max-rate", xasprintf("%llu", 8ULL * htb->max_rate));
 
2690
    return 0;
 
2691
}
 
2692
 
 
2693
static int
 
2694
htb_qdisc_set(struct netdev *netdev, const struct shash *details)
 
2695
{
 
2696
    struct htb_class hc;
 
2697
    int error;
 
2698
 
 
2699
    htb_parse_qdisc_details__(netdev, details, &hc);
 
2700
    error = htb_setup_class__(netdev, tc_make_handle(1, 0xfffe),
 
2701
                              tc_make_handle(1, 0), &hc);
 
2702
    if (!error) {
 
2703
        htb_get__(netdev)->max_rate = hc.max_rate;
 
2704
    }
 
2705
    return error;
 
2706
}
 
2707
 
 
2708
static int
 
2709
htb_class_get(const struct netdev *netdev OVS_UNUSED,
 
2710
              const struct tc_queue *queue, struct shash *details)
 
2711
{
 
2712
    const struct htb_class *hc = htb_class_cast__(queue);
 
2713
 
 
2714
    shash_add(details, "min-rate", xasprintf("%llu", 8ULL * hc->min_rate));
 
2715
    if (hc->min_rate != hc->max_rate) {
 
2716
        shash_add(details, "max-rate", xasprintf("%llu", 8ULL * hc->max_rate));
 
2717
    }
 
2718
    shash_add(details, "burst", xasprintf("%llu", 8ULL * hc->burst));
 
2719
    if (hc->priority) {
 
2720
        shash_add(details, "priority", xasprintf("%u", hc->priority));
 
2721
    }
 
2722
    return 0;
 
2723
}
 
2724
 
 
2725
static int
 
2726
htb_class_set(struct netdev *netdev, unsigned int queue_id,
 
2727
              const struct shash *details)
 
2728
{
 
2729
    struct htb_class hc;
 
2730
    int error;
 
2731
 
 
2732
    error = htb_parse_class_details__(netdev, details, &hc);
 
2733
    if (error) {
 
2734
        return error;
 
2735
    }
 
2736
 
 
2737
    error = htb_setup_class__(netdev, tc_make_handle(1, queue_id + 1),
 
2738
                              tc_make_handle(1, 0xfffe), &hc);
 
2739
    if (error) {
 
2740
        return error;
 
2741
    }
 
2742
 
 
2743
    htb_update_queue__(netdev, queue_id, &hc);
 
2744
    return 0;
 
2745
}
 
2746
 
 
2747
static int
 
2748
htb_class_delete(struct netdev *netdev, struct tc_queue *queue)
 
2749
{
 
2750
    struct htb_class *hc = htb_class_cast__(queue);
 
2751
    struct htb *htb = htb_get__(netdev);
 
2752
    int error;
 
2753
 
 
2754
    error = tc_delete_class(netdev, tc_make_handle(1, queue->queue_id + 1));
 
2755
    if (!error) {
 
2756
        hmap_remove(&htb->tc.queues, &hc->tc_queue.hmap_node);
 
2757
        free(hc);
 
2758
    }
 
2759
    return error;
 
2760
}
 
2761
 
 
2762
static int
 
2763
htb_class_get_stats(const struct netdev *netdev, const struct tc_queue *queue,
 
2764
                    struct netdev_queue_stats *stats)
 
2765
{
 
2766
    return htb_query_class__(netdev, tc_make_handle(1, queue->queue_id + 1),
 
2767
                             tc_make_handle(1, 0xfffe), NULL, stats);
 
2768
}
 
2769
 
 
2770
static int
 
2771
htb_class_dump_stats(const struct netdev *netdev OVS_UNUSED,
 
2772
                     const struct ofpbuf *nlmsg,
 
2773
                     netdev_dump_queue_stats_cb *cb, void *aux)
 
2774
{
 
2775
    struct netdev_queue_stats stats;
 
2776
    unsigned int handle, major, minor;
 
2777
    int error;
 
2778
 
 
2779
    error = tc_parse_class(nlmsg, &handle, NULL, &stats);
 
2780
    if (error) {
 
2781
        return error;
 
2782
    }
 
2783
 
 
2784
    major = tc_get_major(handle);
 
2785
    minor = tc_get_minor(handle);
 
2786
    if (major == 1 && minor > 0 && minor <= HTB_N_QUEUES) {
 
2787
        (*cb)(minor - 1, &stats, aux);
 
2788
    }
 
2789
    return 0;
 
2790
}
 
2791
 
 
2792
static const struct tc_ops tc_ops_htb = {
 
2793
    "htb",                      /* linux_name */
 
2794
    "linux-htb",                /* ovs_name */
 
2795
    HTB_N_QUEUES,               /* n_queues */
 
2796
    htb_tc_install,
 
2797
    htb_tc_load,
 
2798
    htb_tc_destroy,
 
2799
    htb_qdisc_get,
 
2800
    htb_qdisc_set,
 
2801
    htb_class_get,
 
2802
    htb_class_set,
 
2803
    htb_class_delete,
 
2804
    htb_class_get_stats,
 
2805
    htb_class_dump_stats
 
2806
};
 
2807
 
 
2808
/* "linux-hfsc" traffic control class. */
 
2809
 
 
2810
#define HFSC_N_QUEUES 0xf000
 
2811
 
 
2812
struct hfsc {
 
2813
    struct tc tc;
 
2814
    uint32_t max_rate;
 
2815
};
 
2816
 
 
2817
struct hfsc_class {
 
2818
    struct tc_queue tc_queue;
 
2819
    uint32_t min_rate;
 
2820
    uint32_t max_rate;
 
2821
};
 
2822
 
 
2823
static struct hfsc *
 
2824
hfsc_get__(const struct netdev *netdev)
 
2825
{
 
2826
    struct netdev_dev_linux *netdev_dev;
 
2827
    netdev_dev = netdev_dev_linux_cast(netdev_get_dev(netdev));
 
2828
    return CONTAINER_OF(netdev_dev->tc, struct hfsc, tc);
 
2829
}
 
2830
 
 
2831
static struct hfsc_class *
 
2832
hfsc_class_cast__(const struct tc_queue *queue)
 
2833
{
 
2834
    return CONTAINER_OF(queue, struct hfsc_class, tc_queue);
 
2835
}
 
2836
 
 
2837
static void
 
2838
hfsc_install__(struct netdev *netdev, uint32_t max_rate)
 
2839
{
 
2840
    struct netdev_dev_linux * netdev_dev;
 
2841
    struct hfsc *hfsc;
 
2842
 
 
2843
    netdev_dev = netdev_dev_linux_cast(netdev_get_dev(netdev));
 
2844
    hfsc = xmalloc(sizeof *hfsc);
 
2845
    tc_init(&hfsc->tc, &tc_ops_hfsc);
 
2846
    hfsc->max_rate = max_rate;
 
2847
    netdev_dev->tc = &hfsc->tc;
 
2848
}
 
2849
 
 
2850
static void
 
2851
hfsc_update_queue__(struct netdev *netdev, unsigned int queue_id,
 
2852
                    const struct hfsc_class *hc)
 
2853
{
 
2854
    size_t hash;
 
2855
    struct hfsc *hfsc;
 
2856
    struct hfsc_class *hcp;
 
2857
    struct tc_queue *queue;
 
2858
 
 
2859
    hfsc = hfsc_get__(netdev);
 
2860
    hash = hash_int(queue_id, 0);
 
2861
 
 
2862
    queue = tc_find_queue__(netdev, queue_id, hash);
 
2863
    if (queue) {
 
2864
        hcp = hfsc_class_cast__(queue);
 
2865
    } else {
 
2866
        hcp             = xmalloc(sizeof *hcp);
 
2867
        queue           = &hcp->tc_queue;
 
2868
        queue->queue_id = queue_id;
 
2869
        hmap_insert(&hfsc->tc.queues, &queue->hmap_node, hash);
 
2870
    }
 
2871
 
 
2872
    hcp->min_rate = hc->min_rate;
 
2873
    hcp->max_rate = hc->max_rate;
 
2874
}
 
2875
 
 
2876
static int
 
2877
hfsc_parse_tca_options__(struct nlattr *nl_options, struct hfsc_class *class)
 
2878
{
 
2879
    const struct tc_service_curve *rsc, *fsc, *usc;
 
2880
    static const struct nl_policy tca_hfsc_policy[] = {
 
2881
        [TCA_HFSC_RSC] = {
 
2882
            .type      = NL_A_UNSPEC,
 
2883
            .optional  = false,
 
2884
            .min_len   = sizeof(struct tc_service_curve),
 
2885
        },
 
2886
        [TCA_HFSC_FSC] = {
 
2887
            .type      = NL_A_UNSPEC,
 
2888
            .optional  = false,
 
2889
            .min_len   = sizeof(struct tc_service_curve),
 
2890
        },
 
2891
        [TCA_HFSC_USC] = {
 
2892
            .type      = NL_A_UNSPEC,
 
2893
            .optional  = false,
 
2894
            .min_len   = sizeof(struct tc_service_curve),
 
2895
        },
 
2896
    };
 
2897
    struct nlattr *attrs[ARRAY_SIZE(tca_hfsc_policy)];
 
2898
 
 
2899
    if (!nl_parse_nested(nl_options, tca_hfsc_policy,
 
2900
                         attrs, ARRAY_SIZE(tca_hfsc_policy))) {
 
2901
        VLOG_WARN_RL(&rl, "failed to parse HFSC class options");
 
2902
        return EPROTO;
 
2903
    }
 
2904
 
 
2905
    rsc = nl_attr_get(attrs[TCA_HFSC_RSC]);
 
2906
    fsc = nl_attr_get(attrs[TCA_HFSC_FSC]);
 
2907
    usc = nl_attr_get(attrs[TCA_HFSC_USC]);
 
2908
 
 
2909
    if (rsc->m1 != 0 || rsc->d != 0 ||
 
2910
        fsc->m1 != 0 || fsc->d != 0 ||
 
2911
        usc->m1 != 0 || usc->d != 0) {
 
2912
        VLOG_WARN_RL(&rl, "failed to parse HFSC class options. "
 
2913
                     "Non-linear service curves are not supported.");
 
2914
        return EPROTO;
 
2915
    }
 
2916
 
 
2917
    if (rsc->m2 != fsc->m2) {
 
2918
        VLOG_WARN_RL(&rl, "failed to parse HFSC class options. "
 
2919
                     "Real-time service curves are not supported ");
 
2920
        return EPROTO;
 
2921
    }
 
2922
 
 
2923
    if (rsc->m2 > usc->m2) {
 
2924
        VLOG_WARN_RL(&rl, "failed to parse HFSC class options. "
 
2925
                     "Min-rate service curve is greater than "
 
2926
                     "the max-rate service curve.");
 
2927
        return EPROTO;
 
2928
    }
 
2929
 
 
2930
    class->min_rate = fsc->m2;
 
2931
    class->max_rate = usc->m2;
 
2932
    return 0;
 
2933
}
 
2934
 
 
2935
static int
 
2936
hfsc_parse_tcmsg__(struct ofpbuf *tcmsg, unsigned int *queue_id,
 
2937
                   struct hfsc_class *options,
 
2938
                   struct netdev_queue_stats *stats)
 
2939
{
 
2940
    int error;
 
2941
    unsigned int handle;
 
2942
    struct nlattr *nl_options;
 
2943
 
 
2944
    error = tc_parse_class(tcmsg, &handle, &nl_options, stats);
 
2945
    if (error) {
 
2946
        return error;
 
2947
    }
 
2948
 
 
2949
    if (queue_id) {
 
2950
        unsigned int major, minor;
 
2951
 
 
2952
        major = tc_get_major(handle);
 
2953
        minor = tc_get_minor(handle);
 
2954
        if (major == 1 && minor > 0 && minor <= HFSC_N_QUEUES) {
 
2955
            *queue_id = minor - 1;
 
2956
        } else {
 
2957
            return EPROTO;
 
2958
        }
 
2959
    }
 
2960
 
 
2961
    if (options) {
 
2962
        error = hfsc_parse_tca_options__(nl_options, options);
 
2963
    }
 
2964
 
 
2965
    return error;
 
2966
}
 
2967
 
 
2968
static int
 
2969
hfsc_query_class__(const struct netdev *netdev, unsigned int handle,
 
2970
                   unsigned int parent, struct hfsc_class *options,
 
2971
                   struct netdev_queue_stats *stats)
 
2972
{
 
2973
    int error;
 
2974
    struct ofpbuf *reply;
 
2975
 
 
2976
    error = tc_query_class(netdev, handle, parent, &reply);
 
2977
    if (error) {
 
2978
        return error;
 
2979
    }
 
2980
 
 
2981
    error = hfsc_parse_tcmsg__(reply, NULL, options, stats);
 
2982
    ofpbuf_delete(reply);
 
2983
    return error;
 
2984
}
 
2985
 
 
2986
static void
 
2987
hfsc_parse_qdisc_details__(struct netdev *netdev, const struct shash *details,
 
2988
                           struct hfsc_class *class)
 
2989
{
 
2990
    uint32_t max_rate;
 
2991
    const char *max_rate_s;
 
2992
 
 
2993
    max_rate_s = shash_find_data(details, "max-rate");
 
2994
    max_rate   = max_rate_s ? strtoull(max_rate_s, NULL, 10) / 8 : 0;
 
2995
 
 
2996
    if (!max_rate) {
 
2997
        uint32_t current;
 
2998
 
 
2999
        netdev_get_features(netdev, &current, NULL, NULL, NULL);
 
3000
        max_rate = netdev_features_to_bps(current) / 8;
 
3001
    }
 
3002
 
 
3003
    class->min_rate = max_rate;
 
3004
    class->max_rate = max_rate;
 
3005
}
 
3006
 
 
3007
static int
 
3008
hfsc_parse_class_details__(struct netdev *netdev,
 
3009
                           const struct shash *details,
 
3010
                           struct hfsc_class * class)
 
3011
{
 
3012
    const struct hfsc *hfsc;
 
3013
    uint32_t min_rate, max_rate;
 
3014
    const char *min_rate_s, *max_rate_s;
 
3015
 
 
3016
    hfsc       = hfsc_get__(netdev);
 
3017
    min_rate_s = shash_find_data(details, "min-rate");
 
3018
    max_rate_s = shash_find_data(details, "max-rate");
 
3019
 
 
3020
    min_rate = min_rate_s ? strtoull(min_rate_s, NULL, 10) / 8 : 0;
 
3021
    min_rate = MAX(min_rate, 1);
 
3022
    min_rate = MIN(min_rate, hfsc->max_rate);
 
3023
 
 
3024
    max_rate = (max_rate_s
 
3025
                ? strtoull(max_rate_s, NULL, 10) / 8
 
3026
                : hfsc->max_rate);
 
3027
    max_rate = MAX(max_rate, min_rate);
 
3028
    max_rate = MIN(max_rate, hfsc->max_rate);
 
3029
 
 
3030
    class->min_rate = min_rate;
 
3031
    class->max_rate = max_rate;
 
3032
 
 
3033
    return 0;
 
3034
}
 
3035
 
 
3036
/* Create an HFSC qdisc.
 
3037
 *
 
3038
 * Equivalent to "tc qdisc add dev <dev> root handle 1: hfsc default 1". */
 
3039
static int
 
3040
hfsc_setup_qdisc__(struct netdev * netdev)
 
3041
{
 
3042
    struct tcmsg *tcmsg;
 
3043
    struct ofpbuf request;
 
3044
    struct tc_hfsc_qopt opt;
 
3045
 
 
3046
    tc_del_qdisc(netdev);
 
3047
 
 
3048
    tcmsg = tc_make_request(netdev, RTM_NEWQDISC,
 
3049
                            NLM_F_EXCL | NLM_F_CREATE, &request);
 
3050
 
 
3051
    if (!tcmsg) {
 
3052
        return ENODEV;
 
3053
    }
 
3054
 
 
3055
    tcmsg->tcm_handle = tc_make_handle(1, 0);
 
3056
    tcmsg->tcm_parent = TC_H_ROOT;
 
3057
 
 
3058
    memset(&opt, 0, sizeof opt);
 
3059
    opt.defcls = 1;
 
3060
 
 
3061
    nl_msg_put_string(&request, TCA_KIND, "hfsc");
 
3062
    nl_msg_put_unspec(&request, TCA_OPTIONS, &opt, sizeof opt);
 
3063
 
 
3064
    return tc_transact(&request, NULL);
 
3065
}
 
3066
 
 
3067
/* Create an HFSC class.
 
3068
 *
 
3069
 * Equivalent to "tc class add <dev> parent <parent> classid <handle> hfsc
 
3070
 * sc rate <min_rate> ul rate <max_rate>" */
 
3071
static int
 
3072
hfsc_setup_class__(struct netdev *netdev, unsigned int handle,
 
3073
                   unsigned int parent, struct hfsc_class *class)
 
3074
{
 
3075
    int error;
 
3076
    size_t opt_offset;
 
3077
    struct tcmsg *tcmsg;
 
3078
    struct ofpbuf request;
 
3079
    struct tc_service_curve min, max;
 
3080
 
 
3081
    tcmsg = tc_make_request(netdev, RTM_NEWTCLASS, NLM_F_CREATE, &request);
 
3082
 
 
3083
    if (!tcmsg) {
 
3084
        return ENODEV;
 
3085
    }
 
3086
 
 
3087
    tcmsg->tcm_handle = handle;
 
3088
    tcmsg->tcm_parent = parent;
 
3089
 
 
3090
    min.m1 = 0;
 
3091
    min.d  = 0;
 
3092
    min.m2 = class->min_rate;
 
3093
 
 
3094
    max.m1 = 0;
 
3095
    max.d  = 0;
 
3096
    max.m2 = class->max_rate;
 
3097
 
 
3098
    nl_msg_put_string(&request, TCA_KIND, "hfsc");
 
3099
    opt_offset = nl_msg_start_nested(&request, TCA_OPTIONS);
 
3100
    nl_msg_put_unspec(&request, TCA_HFSC_RSC, &min, sizeof min);
 
3101
    nl_msg_put_unspec(&request, TCA_HFSC_FSC, &min, sizeof min);
 
3102
    nl_msg_put_unspec(&request, TCA_HFSC_USC, &max, sizeof max);
 
3103
    nl_msg_end_nested(&request, opt_offset);
 
3104
 
 
3105
    error = tc_transact(&request, NULL);
 
3106
    if (error) {
 
3107
        VLOG_WARN_RL(&rl, "failed to replace %s class %u:%u, parent %u:%u, "
 
3108
                     "min-rate %ubps, max-rate %ubps (%s)",
 
3109
                     netdev_get_name(netdev),
 
3110
                     tc_get_major(handle), tc_get_minor(handle),
 
3111
                     tc_get_major(parent), tc_get_minor(parent),
 
3112
                     class->min_rate, class->max_rate, strerror(error));
 
3113
    }
 
3114
 
 
3115
    return error;
 
3116
}
 
3117
 
 
3118
static int
 
3119
hfsc_tc_install(struct netdev *netdev, const struct shash *details)
 
3120
{
 
3121
    int error;
 
3122
    struct hfsc_class class;
 
3123
 
 
3124
    error = hfsc_setup_qdisc__(netdev);
 
3125
 
 
3126
    if (error) {
 
3127
        return error;
 
3128
    }
 
3129
 
 
3130
    hfsc_parse_qdisc_details__(netdev, details, &class);
 
3131
    error = hfsc_setup_class__(netdev, tc_make_handle(1, 0xfffe),
 
3132
                               tc_make_handle(1, 0), &class);
 
3133
 
 
3134
    if (error) {
 
3135
        return error;
 
3136
    }
 
3137
 
 
3138
    hfsc_install__(netdev, class.max_rate);
 
3139
    return 0;
 
3140
}
 
3141
 
 
3142
static int
 
3143
hfsc_tc_load(struct netdev *netdev, struct ofpbuf *nlmsg OVS_UNUSED)
 
3144
{
 
3145
    struct ofpbuf msg;
 
3146
    struct nl_dump dump;
 
3147
    struct hfsc_class hc;
 
3148
 
 
3149
    hc.max_rate = 0;
 
3150
    hfsc_query_class__(netdev, tc_make_handle(1, 0xfffe), 0, &hc, NULL);
 
3151
    hfsc_install__(netdev, hc.max_rate);
 
3152
 
 
3153
    if (!start_queue_dump(netdev, &dump)) {
 
3154
        return ENODEV;
 
3155
    }
 
3156
 
 
3157
    while (nl_dump_next(&dump, &msg)) {
 
3158
        unsigned int queue_id;
 
3159
 
 
3160
        if (!hfsc_parse_tcmsg__(&msg, &queue_id, &hc, NULL)) {
 
3161
            hfsc_update_queue__(netdev, queue_id, &hc);
 
3162
        }
 
3163
    }
 
3164
 
 
3165
    nl_dump_done(&dump);
 
3166
    return 0;
 
3167
}
 
3168
 
 
3169
static void
 
3170
hfsc_tc_destroy(struct tc *tc)
 
3171
{
 
3172
    struct hfsc *hfsc;
 
3173
    struct hfsc_class *hc, *next;
 
3174
 
 
3175
    hfsc = CONTAINER_OF(tc, struct hfsc, tc);
 
3176
 
 
3177
    HMAP_FOR_EACH_SAFE (hc, next, tc_queue.hmap_node, &hfsc->tc.queues) {
 
3178
        hmap_remove(&hfsc->tc.queues, &hc->tc_queue.hmap_node);
 
3179
        free(hc);
 
3180
    }
 
3181
 
 
3182
    tc_destroy(tc);
 
3183
    free(hfsc);
 
3184
}
 
3185
 
 
3186
static int
 
3187
hfsc_qdisc_get(const struct netdev *netdev, struct shash *details)
 
3188
{
 
3189
    const struct hfsc *hfsc;
 
3190
    hfsc = hfsc_get__(netdev);
 
3191
    shash_add(details, "max-rate", xasprintf("%llu", 8ULL * hfsc->max_rate));
 
3192
    return 0;
 
3193
}
 
3194
 
 
3195
static int
 
3196
hfsc_qdisc_set(struct netdev *netdev, const struct shash *details)
 
3197
{
 
3198
    int error;
 
3199
    struct hfsc_class class;
 
3200
 
 
3201
    hfsc_parse_qdisc_details__(netdev, details, &class);
 
3202
    error = hfsc_setup_class__(netdev, tc_make_handle(1, 0xfffe),
 
3203
                               tc_make_handle(1, 0), &class);
 
3204
 
 
3205
    if (!error) {
 
3206
        hfsc_get__(netdev)->max_rate = class.max_rate;
 
3207
    }
 
3208
 
 
3209
    return error;
 
3210
}
 
3211
 
 
3212
static int
 
3213
hfsc_class_get(const struct netdev *netdev OVS_UNUSED,
 
3214
              const struct tc_queue *queue, struct shash *details)
 
3215
{
 
3216
    const struct hfsc_class *hc;
 
3217
 
 
3218
    hc = hfsc_class_cast__(queue);
 
3219
    shash_add(details, "min-rate", xasprintf("%llu", 8ULL * hc->min_rate));
 
3220
    if (hc->min_rate != hc->max_rate) {
 
3221
        shash_add(details, "max-rate", xasprintf("%llu", 8ULL * hc->max_rate));
 
3222
    }
 
3223
    return 0;
 
3224
}
 
3225
 
 
3226
static int
 
3227
hfsc_class_set(struct netdev *netdev, unsigned int queue_id,
 
3228
               const struct shash *details)
 
3229
{
 
3230
    int error;
 
3231
    struct hfsc_class class;
 
3232
 
 
3233
    error = hfsc_parse_class_details__(netdev, details, &class);
 
3234
    if (error) {
 
3235
        return error;
 
3236
    }
 
3237
 
 
3238
    error = hfsc_setup_class__(netdev, tc_make_handle(1, queue_id + 1),
 
3239
                               tc_make_handle(1, 0xfffe), &class);
 
3240
    if (error) {
 
3241
        return error;
 
3242
    }
 
3243
 
 
3244
    hfsc_update_queue__(netdev, queue_id, &class);
 
3245
    return 0;
 
3246
}
 
3247
 
 
3248
static int
 
3249
hfsc_class_delete(struct netdev *netdev, struct tc_queue *queue)
 
3250
{
 
3251
    int error;
 
3252
    struct hfsc *hfsc;
 
3253
    struct hfsc_class *hc;
 
3254
 
 
3255
    hc   = hfsc_class_cast__(queue);
 
3256
    hfsc = hfsc_get__(netdev);
 
3257
 
 
3258
    error = tc_delete_class(netdev, tc_make_handle(1, queue->queue_id + 1));
 
3259
    if (!error) {
 
3260
        hmap_remove(&hfsc->tc.queues, &hc->tc_queue.hmap_node);
 
3261
        free(hc);
 
3262
    }
 
3263
    return error;
 
3264
}
 
3265
 
 
3266
static int
 
3267
hfsc_class_get_stats(const struct netdev *netdev, const struct tc_queue *queue,
 
3268
                     struct netdev_queue_stats *stats)
 
3269
{
 
3270
    return hfsc_query_class__(netdev, tc_make_handle(1, queue->queue_id + 1),
 
3271
                             tc_make_handle(1, 0xfffe), NULL, stats);
 
3272
}
 
3273
 
 
3274
static int
 
3275
hfsc_class_dump_stats(const struct netdev *netdev OVS_UNUSED,
 
3276
                      const struct ofpbuf *nlmsg,
 
3277
                      netdev_dump_queue_stats_cb *cb, void *aux)
 
3278
{
 
3279
    struct netdev_queue_stats stats;
 
3280
    unsigned int handle, major, minor;
 
3281
    int error;
 
3282
 
 
3283
    error = tc_parse_class(nlmsg, &handle, NULL, &stats);
 
3284
    if (error) {
 
3285
        return error;
 
3286
    }
 
3287
 
 
3288
    major = tc_get_major(handle);
 
3289
    minor = tc_get_minor(handle);
 
3290
    if (major == 1 && minor > 0 && minor <= HFSC_N_QUEUES) {
 
3291
        (*cb)(minor - 1, &stats, aux);
 
3292
    }
 
3293
    return 0;
 
3294
}
 
3295
 
 
3296
static const struct tc_ops tc_ops_hfsc = {
 
3297
    "hfsc",                     /* linux_name */
 
3298
    "linux-hfsc",               /* ovs_name */
 
3299
    HFSC_N_QUEUES,              /* n_queues */
 
3300
    hfsc_tc_install,            /* tc_install */
 
3301
    hfsc_tc_load,               /* tc_load */
 
3302
    hfsc_tc_destroy,            /* tc_destroy */
 
3303
    hfsc_qdisc_get,             /* qdisc_get */
 
3304
    hfsc_qdisc_set,             /* qdisc_set */
 
3305
    hfsc_class_get,             /* class_get */
 
3306
    hfsc_class_set,             /* class_set */
 
3307
    hfsc_class_delete,          /* class_delete */
 
3308
    hfsc_class_get_stats,       /* class_get_stats */
 
3309
    hfsc_class_dump_stats       /* class_dump_stats */
 
3310
};
 
3311
 
 
3312
/* "linux-default" traffic control class.
 
3313
 *
 
3314
 * This class represents the default, unnamed Linux qdisc.  It corresponds to
 
3315
 * the "" (empty string) QoS type in the OVS database. */
 
3316
 
 
3317
static void
 
3318
default_install__(struct netdev *netdev)
 
3319
{
 
3320
    struct netdev_dev_linux *netdev_dev =
 
3321
                                netdev_dev_linux_cast(netdev_get_dev(netdev));
 
3322
    static struct tc *tc;
 
3323
 
 
3324
    if (!tc) {
 
3325
        tc = xmalloc(sizeof *tc);
 
3326
        tc_init(tc, &tc_ops_default);
 
3327
    }
 
3328
    netdev_dev->tc = tc;
 
3329
}
 
3330
 
 
3331
static int
 
3332
default_tc_install(struct netdev *netdev,
 
3333
                   const struct shash *details OVS_UNUSED)
 
3334
{
 
3335
    default_install__(netdev);
 
3336
    return 0;
 
3337
}
 
3338
 
 
3339
static int
 
3340
default_tc_load(struct netdev *netdev, struct ofpbuf *nlmsg OVS_UNUSED)
 
3341
{
 
3342
    default_install__(netdev);
 
3343
    return 0;
 
3344
}
 
3345
 
 
3346
static const struct tc_ops tc_ops_default = {
 
3347
    NULL,                       /* linux_name */
 
3348
    "",                         /* ovs_name */
 
3349
    0,                          /* n_queues */
 
3350
    default_tc_install,
 
3351
    default_tc_load,
 
3352
    NULL,                       /* tc_destroy */
 
3353
    NULL,                       /* qdisc_get */
 
3354
    NULL,                       /* qdisc_set */
 
3355
    NULL,                       /* class_get */
 
3356
    NULL,                       /* class_set */
 
3357
    NULL,                       /* class_delete */
 
3358
    NULL,                       /* class_get_stats */
 
3359
    NULL                        /* class_dump_stats */
 
3360
};
 
3361
 
 
3362
/* "linux-other" traffic control class.
 
3363
 *
 
3364
 * */
 
3365
 
 
3366
static int
 
3367
other_tc_load(struct netdev *netdev, struct ofpbuf *nlmsg OVS_UNUSED)
 
3368
{
 
3369
    struct netdev_dev_linux *netdev_dev =
 
3370
                                netdev_dev_linux_cast(netdev_get_dev(netdev));
 
3371
    static struct tc *tc;
 
3372
 
 
3373
    if (!tc) {
 
3374
        tc = xmalloc(sizeof *tc);
 
3375
        tc_init(tc, &tc_ops_other);
 
3376
    }
 
3377
    netdev_dev->tc = tc;
 
3378
    return 0;
 
3379
}
 
3380
 
 
3381
static const struct tc_ops tc_ops_other = {
 
3382
    NULL,                       /* linux_name */
 
3383
    "linux-other",              /* ovs_name */
 
3384
    0,                          /* n_queues */
 
3385
    NULL,                       /* tc_install */
 
3386
    other_tc_load,
 
3387
    NULL,                       /* tc_destroy */
 
3388
    NULL,                       /* qdisc_get */
 
3389
    NULL,                       /* qdisc_set */
 
3390
    NULL,                       /* class_get */
 
3391
    NULL,                       /* class_set */
 
3392
    NULL,                       /* class_delete */
 
3393
    NULL,                       /* class_get_stats */
 
3394
    NULL                        /* class_dump_stats */
 
3395
};
 
3396
 
 
3397
/* Traffic control. */
 
3398
 
 
3399
/* Number of kernel "tc" ticks per second. */
 
3400
static double ticks_per_s;
 
3401
 
 
3402
/* Number of kernel "jiffies" per second.  This is used for the purpose of
 
3403
 * computing buffer sizes.  Generally kernel qdiscs need to be able to buffer
 
3404
 * one jiffy's worth of data.
 
3405
 *
 
3406
 * There are two possibilities here:
 
3407
 *
 
3408
 *    - 'buffer_hz' is the kernel's real timer tick rate, a small number in the
 
3409
 *      approximate range of 100 to 1024.  That means that we really need to
 
3410
 *      make sure that the qdisc can buffer that much data.
 
3411
 *
 
3412
 *    - 'buffer_hz' is an absurdly large number.  That means that the kernel
 
3413
 *      has finely granular timers and there's no need to fudge additional room
 
3414
 *      for buffers.  (There's no extra effort needed to implement that: the
 
3415
 *      large 'buffer_hz' is used as a divisor, so practically any number will
 
3416
 *      come out as 0 in the division.  Small integer results in the case of
 
3417
 *      really high dividends won't have any real effect anyhow.)
 
3418
 */
 
3419
static unsigned int buffer_hz;
 
3420
 
 
3421
/* Returns tc handle 'major':'minor'. */
 
3422
static unsigned int
 
3423
tc_make_handle(unsigned int major, unsigned int minor)
 
3424
{
 
3425
    return TC_H_MAKE(major << 16, minor);
 
3426
}
 
3427
 
 
3428
/* Returns the major number from 'handle'. */
 
3429
static unsigned int
 
3430
tc_get_major(unsigned int handle)
 
3431
{
 
3432
    return TC_H_MAJ(handle) >> 16;
 
3433
}
 
3434
 
 
3435
/* Returns the minor number from 'handle'. */
 
3436
static unsigned int
 
3437
tc_get_minor(unsigned int handle)
 
3438
{
 
3439
    return TC_H_MIN(handle);
 
3440
}
 
3441
 
 
3442
static struct tcmsg *
 
3443
tc_make_request(const struct netdev *netdev, int type, unsigned int flags,
 
3444
                struct ofpbuf *request)
 
3445
{
 
3446
    struct tcmsg *tcmsg;
 
3447
    int ifindex;
 
3448
    int error;
 
3449
 
 
3450
    error = get_ifindex(netdev, &ifindex);
 
3451
    if (error) {
 
3452
        return NULL;
 
3453
    }
 
3454
 
 
3455
    ofpbuf_init(request, 512);
 
3456
    nl_msg_put_nlmsghdr(request, sizeof *tcmsg, type, NLM_F_REQUEST | flags);
 
3457
    tcmsg = ofpbuf_put_zeros(request, sizeof *tcmsg);
 
3458
    tcmsg->tcm_family = AF_UNSPEC;
 
3459
    tcmsg->tcm_ifindex = ifindex;
 
3460
    /* Caller should fill in tcmsg->tcm_handle. */
 
3461
    /* Caller should fill in tcmsg->tcm_parent. */
 
3462
 
 
3463
    return tcmsg;
 
3464
}
 
3465
 
 
3466
static int
 
3467
tc_transact(struct ofpbuf *request, struct ofpbuf **replyp)
 
3468
{
 
3469
    int error = nl_sock_transact(rtnl_sock, request, replyp);
 
3470
    ofpbuf_uninit(request);
 
3471
    return error;
 
3472
}
 
3473
 
 
3474
static void
 
3475
read_psched(void)
 
3476
{
 
3477
    /* The values in psched are not individually very meaningful, but they are
 
3478
     * important.  The tables below show some values seen in the wild.
 
3479
     *
 
3480
     * Some notes:
 
3481
     *
 
3482
     *   - "c" has always been a constant 1000000 since at least Linux 2.4.14.
 
3483
     *     (Before that, there are hints that it was 1000000000.)
 
3484
     *
 
3485
     *   - "d" can be unrealistically large, see the comment on 'buffer_hz'
 
3486
     *     above.
 
3487
     *
 
3488
     *                        /proc/net/psched
 
3489
     *     -----------------------------------
 
3490
     * [1] 000c8000 000f4240 000f4240 00000064
 
3491
     * [2] 000003e8 00000400 000f4240 3b9aca00
 
3492
     * [3] 000003e8 00000400 000f4240 3b9aca00
 
3493
     * [4] 000003e8 00000400 000f4240 00000064
 
3494
     * [5] 000003e8 00000040 000f4240 3b9aca00
 
3495
     * [6] 000003e8 00000040 000f4240 000000f9
 
3496
     *
 
3497
     *           a         b          c             d ticks_per_s     buffer_hz
 
3498
     *     ------- --------- ---------- ------------- ----------- -------------
 
3499
     * [1] 819,200 1,000,000  1,000,000           100     819,200           100
 
3500
     * [2]   1,000     1,024  1,000,000 1,000,000,000     976,562 1,000,000,000
 
3501
     * [3]   1,000     1,024  1,000,000 1,000,000,000     976,562 1,000,000,000
 
3502
     * [4]   1,000     1,024  1,000,000           100     976,562           100
 
3503
     * [5]   1,000        64  1,000,000 1,000,000,000  15,625,000 1,000,000,000
 
3504
     * [6]   1,000        64  1,000,000           249  15,625,000           249
 
3505
     *
 
3506
     * [1] 2.6.18-128.1.6.el5.xs5.5.0.505.1024xen from XenServer 5.5.0-24648p
 
3507
     * [2] 2.6.26-1-686-bigmem from Debian lenny
 
3508
     * [3] 2.6.26-2-sparc64 from Debian lenny
 
3509
     * [4] 2.6.27.42-0.1.1.xs5.6.810.44.111163xen from XenServer 5.6.810-31078p
 
3510
     * [5] 2.6.32.21.22 (approx.) from Ubuntu 10.04 on VMware Fusion
 
3511
     * [6] 2.6.34 from kernel.org on KVM
 
3512
     */
 
3513
    static const char fn[] = "/proc/net/psched";
 
3514
    unsigned int a, b, c, d;
 
3515
    FILE *stream;
 
3516
 
 
3517
    ticks_per_s = 1.0;
 
3518
    buffer_hz = 100;
 
3519
 
 
3520
    stream = fopen(fn, "r");
 
3521
    if (!stream) {
 
3522
        VLOG_WARN("%s: open failed: %s", fn, strerror(errno));
 
3523
        return;
 
3524
    }
 
3525
 
 
3526
    if (fscanf(stream, "%x %x %x %x", &a, &b, &c, &d) != 4) {
 
3527
        VLOG_WARN("%s: read failed", fn);
 
3528
        fclose(stream);
 
3529
        return;
 
3530
    }
 
3531
    VLOG_DBG("%s: psched parameters are: %u %u %u %u", fn, a, b, c, d);
 
3532
    fclose(stream);
 
3533
 
 
3534
    if (!a || !c) {
 
3535
        VLOG_WARN("%s: invalid scheduler parameters", fn);
 
3536
        return;
 
3537
    }
 
3538
 
 
3539
    ticks_per_s = (double) a * c / b;
 
3540
    if (c == 1000000) {
 
3541
        buffer_hz = d;
 
3542
    } else {
 
3543
        VLOG_WARN("%s: unexpected psched parameters: %u %u %u %u",
 
3544
                  fn, a, b, c, d);
 
3545
    }
 
3546
    VLOG_DBG("%s: ticks_per_s=%f buffer_hz=%u", fn, ticks_per_s, buffer_hz);
 
3547
}
 
3548
 
 
3549
/* Returns the number of bytes that can be transmitted in 'ticks' ticks at a
 
3550
 * rate of 'rate' bytes per second. */
 
3551
static unsigned int
 
3552
tc_ticks_to_bytes(unsigned int rate, unsigned int ticks)
 
3553
{
 
3554
    if (!buffer_hz) {
 
3555
        read_psched();
 
3556
    }
 
3557
    return (rate * ticks) / ticks_per_s;
 
3558
}
 
3559
 
 
3560
/* Returns the number of ticks that it would take to transmit 'size' bytes at a
 
3561
 * rate of 'rate' bytes per second. */
 
3562
static unsigned int
 
3563
tc_bytes_to_ticks(unsigned int rate, unsigned int size)
 
3564
{
 
3565
    if (!buffer_hz) {
 
3566
        read_psched();
 
3567
    }
 
3568
    return rate ? ((unsigned long long int) ticks_per_s * size) / rate : 0;
 
3569
}
 
3570
 
 
3571
/* Returns the number of bytes that need to be reserved for qdisc buffering at
 
3572
 * a transmission rate of 'rate' bytes per second. */
 
3573
static unsigned int
 
3574
tc_buffer_per_jiffy(unsigned int rate)
 
3575
{
 
3576
    if (!buffer_hz) {
 
3577
        read_psched();
 
3578
    }
 
3579
    return rate / buffer_hz;
 
3580
}
 
3581
 
 
3582
/* Given Netlink 'msg' that describes a qdisc, extracts the name of the qdisc,
 
3583
 * e.g. "htb", into '*kind' (if it is nonnull).  If 'options' is nonnull,
 
3584
 * extracts 'msg''s TCA_OPTIONS attributes into '*options' if it is present or
 
3585
 * stores NULL into it if it is absent.
 
3586
 *
 
3587
 * '*kind' and '*options' point into 'msg', so they are owned by whoever owns
 
3588
 * 'msg'.
 
3589
 *
 
3590
 * Returns 0 if successful, otherwise a positive errno value. */
 
3591
static int
 
3592
tc_parse_qdisc(const struct ofpbuf *msg, const char **kind,
 
3593
               struct nlattr **options)
 
3594
{
 
3595
    static const struct nl_policy tca_policy[] = {
 
3596
        [TCA_KIND] = { .type = NL_A_STRING, .optional = false },
 
3597
        [TCA_OPTIONS] = { .type = NL_A_NESTED, .optional = true },
 
3598
    };
 
3599
    struct nlattr *ta[ARRAY_SIZE(tca_policy)];
 
3600
 
 
3601
    if (!nl_policy_parse(msg, NLMSG_HDRLEN + sizeof(struct tcmsg),
 
3602
                         tca_policy, ta, ARRAY_SIZE(ta))) {
 
3603
        VLOG_WARN_RL(&rl, "failed to parse qdisc message");
 
3604
        goto error;
 
3605
    }
 
3606
 
 
3607
    if (kind) {
 
3608
        *kind = nl_attr_get_string(ta[TCA_KIND]);
 
3609
    }
 
3610
 
 
3611
    if (options) {
 
3612
        *options = ta[TCA_OPTIONS];
 
3613
    }
 
3614
 
 
3615
    return 0;
 
3616
 
 
3617
error:
 
3618
    if (kind) {
 
3619
        *kind = NULL;
 
3620
    }
 
3621
    if (options) {
 
3622
        *options = NULL;
 
3623
    }
 
3624
    return EPROTO;
 
3625
}
 
3626
 
 
3627
/* Given Netlink 'msg' that describes a class, extracts the queue ID (e.g. the
 
3628
 * minor number of its class ID) into '*queue_id', its TCA_OPTIONS attribute
 
3629
 * into '*options', and its queue statistics into '*stats'.  Any of the output
 
3630
 * arguments may be null.
 
3631
 *
 
3632
 * Returns 0 if successful, otherwise a positive errno value. */
 
3633
static int
 
3634
tc_parse_class(const struct ofpbuf *msg, unsigned int *handlep,
 
3635
               struct nlattr **options, struct netdev_queue_stats *stats)
 
3636
{
 
3637
    static const struct nl_policy tca_policy[] = {
 
3638
        [TCA_OPTIONS] = { .type = NL_A_NESTED, .optional = false },
 
3639
        [TCA_STATS2] = { .type = NL_A_NESTED, .optional = false },
 
3640
    };
 
3641
    struct nlattr *ta[ARRAY_SIZE(tca_policy)];
 
3642
 
 
3643
    if (!nl_policy_parse(msg, NLMSG_HDRLEN + sizeof(struct tcmsg),
 
3644
                         tca_policy, ta, ARRAY_SIZE(ta))) {
 
3645
        VLOG_WARN_RL(&rl, "failed to parse class message");
 
3646
        goto error;
 
3647
    }
 
3648
 
 
3649
    if (handlep) {
 
3650
        struct tcmsg *tc = ofpbuf_at_assert(msg, NLMSG_HDRLEN, sizeof *tc);
 
3651
        *handlep = tc->tcm_handle;
 
3652
    }
 
3653
 
 
3654
    if (options) {
 
3655
        *options = ta[TCA_OPTIONS];
 
3656
    }
 
3657
 
 
3658
    if (stats) {
 
3659
        const struct gnet_stats_queue *gsq;
 
3660
        struct gnet_stats_basic gsb;
 
3661
 
 
3662
        static const struct nl_policy stats_policy[] = {
 
3663
            [TCA_STATS_BASIC] = { .type = NL_A_UNSPEC, .optional = false,
 
3664
                                  .min_len = sizeof gsb },
 
3665
            [TCA_STATS_QUEUE] = { .type = NL_A_UNSPEC, .optional = false,
 
3666
                                  .min_len = sizeof *gsq },
 
3667
        };
 
3668
        struct nlattr *sa[ARRAY_SIZE(stats_policy)];
 
3669
 
 
3670
        if (!nl_parse_nested(ta[TCA_STATS2], stats_policy,
 
3671
                             sa, ARRAY_SIZE(sa))) {
 
3672
            VLOG_WARN_RL(&rl, "failed to parse class stats");
 
3673
            goto error;
 
3674
        }
 
3675
 
 
3676
        /* Alignment issues screw up the length of struct gnet_stats_basic on
 
3677
         * some arch/bitsize combinations.  Newer versions of Linux have a
 
3678
         * struct gnet_stats_basic_packed, but we can't depend on that.  The
 
3679
         * easiest thing to do is just to make a copy. */
 
3680
        memset(&gsb, 0, sizeof gsb);
 
3681
        memcpy(&gsb, nl_attr_get(sa[TCA_STATS_BASIC]),
 
3682
               MIN(nl_attr_get_size(sa[TCA_STATS_BASIC]), sizeof gsb));
 
3683
        stats->tx_bytes = gsb.bytes;
 
3684
        stats->tx_packets = gsb.packets;
 
3685
 
 
3686
        gsq = nl_attr_get(sa[TCA_STATS_QUEUE]);
 
3687
        stats->tx_errors = gsq->drops;
 
3688
    }
 
3689
 
 
3690
    return 0;
 
3691
 
 
3692
error:
 
3693
    if (options) {
 
3694
        *options = NULL;
 
3695
    }
 
3696
    if (stats) {
 
3697
        memset(stats, 0, sizeof *stats);
 
3698
    }
 
3699
    return EPROTO;
 
3700
}
 
3701
 
 
3702
/* Queries the kernel for class with identifier 'handle' and parent 'parent'
 
3703
 * on 'netdev'. */
 
3704
static int
 
3705
tc_query_class(const struct netdev *netdev,
 
3706
               unsigned int handle, unsigned int parent,
 
3707
               struct ofpbuf **replyp)
 
3708
{
 
3709
    struct ofpbuf request;
 
3710
    struct tcmsg *tcmsg;
 
3711
    int error;
 
3712
 
 
3713
    tcmsg = tc_make_request(netdev, RTM_GETTCLASS, NLM_F_ECHO, &request);
 
3714
    if (!tcmsg) {
 
3715
        return ENODEV;
 
3716
    }
 
3717
    tcmsg->tcm_handle = handle;
 
3718
    tcmsg->tcm_parent = parent;
 
3719
 
 
3720
    error = tc_transact(&request, replyp);
 
3721
    if (error) {
 
3722
        VLOG_WARN_RL(&rl, "query %s class %u:%u (parent %u:%u) failed (%s)",
 
3723
                     netdev_get_name(netdev),
 
3724
                     tc_get_major(handle), tc_get_minor(handle),
 
3725
                     tc_get_major(parent), tc_get_minor(parent),
 
3726
                     strerror(error));
 
3727
    }
 
3728
    return error;
 
3729
}
 
3730
 
 
3731
/* Equivalent to "tc class del dev <name> handle <handle>". */
 
3732
static int
 
3733
tc_delete_class(const struct netdev *netdev, unsigned int handle)
 
3734
{
 
3735
    struct ofpbuf request;
 
3736
    struct tcmsg *tcmsg;
 
3737
    int error;
 
3738
 
 
3739
    tcmsg = tc_make_request(netdev, RTM_DELTCLASS, 0, &request);
 
3740
    if (!tcmsg) {
 
3741
        return ENODEV;
 
3742
    }
 
3743
    tcmsg->tcm_handle = handle;
 
3744
    tcmsg->tcm_parent = 0;
 
3745
 
 
3746
    error = tc_transact(&request, NULL);
 
3747
    if (error) {
 
3748
        VLOG_WARN_RL(&rl, "delete %s class %u:%u failed (%s)",
 
3749
                     netdev_get_name(netdev),
 
3750
                     tc_get_major(handle), tc_get_minor(handle),
 
3751
                     strerror(error));
 
3752
    }
 
3753
    return error;
 
3754
}
 
3755
 
 
3756
/* Equivalent to "tc qdisc del dev <name> root". */
 
3757
static int
 
3758
tc_del_qdisc(struct netdev *netdev)
 
3759
{
 
3760
    struct netdev_dev_linux *netdev_dev =
 
3761
                                netdev_dev_linux_cast(netdev_get_dev(netdev));
 
3762
    struct ofpbuf request;
 
3763
    struct tcmsg *tcmsg;
 
3764
    int error;
 
3765
 
 
3766
    tcmsg = tc_make_request(netdev, RTM_DELQDISC, 0, &request);
 
3767
    if (!tcmsg) {
 
3768
        return ENODEV;
 
3769
    }
 
3770
    tcmsg->tcm_handle = tc_make_handle(1, 0);
 
3771
    tcmsg->tcm_parent = TC_H_ROOT;
 
3772
 
 
3773
    error = tc_transact(&request, NULL);
 
3774
    if (error == EINVAL) {
 
3775
        /* EINVAL probably means that the default qdisc was in use, in which
 
3776
         * case we've accomplished our purpose. */
 
3777
        error = 0;
 
3778
    }
 
3779
    if (!error && netdev_dev->tc) {
 
3780
        if (netdev_dev->tc->ops->tc_destroy) {
 
3781
            netdev_dev->tc->ops->tc_destroy(netdev_dev->tc);
 
3782
        }
 
3783
        netdev_dev->tc = NULL;
 
3784
    }
 
3785
    return error;
 
3786
}
 
3787
 
 
3788
/* If 'netdev''s qdisc type and parameters are not yet known, queries the
 
3789
 * kernel to determine what they are.  Returns 0 if successful, otherwise a
 
3790
 * positive errno value. */
 
3791
static int
 
3792
tc_query_qdisc(const struct netdev *netdev)
 
3793
{
 
3794
    struct netdev_dev_linux *netdev_dev =
 
3795
                                netdev_dev_linux_cast(netdev_get_dev(netdev));
 
3796
    struct ofpbuf request, *qdisc;
 
3797
    const struct tc_ops *ops;
 
3798
    struct tcmsg *tcmsg;
 
3799
    int load_error;
 
3800
    int error;
 
3801
 
 
3802
    if (netdev_dev->tc) {
 
3803
        return 0;
 
3804
    }
 
3805
 
 
3806
    /* This RTM_GETQDISC is crafted to avoid OOPSing kernels that do not have
 
3807
     * commit 53b0f08 "net_sched: Fix qdisc_notify()", which is anything before
 
3808
     * 2.6.35 without that fix backported to it.
 
3809
     *
 
3810
     * To avoid the OOPS, we must not make a request that would attempt to dump
 
3811
     * a "built-in" qdisc, that is, the default pfifo_fast qdisc or one of a
 
3812
     * few others.  There are a few ways that I can see to do this, but most of
 
3813
     * them seem to be racy (and if you lose the race the kernel OOPSes).  The
 
3814
     * technique chosen here is to assume that any non-default qdisc that we
 
3815
     * create will have a class with handle 1:0.  The built-in qdiscs only have
 
3816
     * a class with handle 0:0.
 
3817
     *
 
3818
     * We could check for Linux 2.6.35+ and use a more straightforward method
 
3819
     * there. */
 
3820
    tcmsg = tc_make_request(netdev, RTM_GETQDISC, NLM_F_ECHO, &request);
 
3821
    if (!tcmsg) {
 
3822
        return ENODEV;
 
3823
    }
 
3824
    tcmsg->tcm_handle = tc_make_handle(1, 0);
 
3825
    tcmsg->tcm_parent = 0;
 
3826
 
 
3827
    /* Figure out what tc class to instantiate. */
 
3828
    error = tc_transact(&request, &qdisc);
 
3829
    if (!error) {
 
3830
        const char *kind;
 
3831
 
 
3832
        error = tc_parse_qdisc(qdisc, &kind, NULL);
 
3833
        if (error) {
 
3834
            ops = &tc_ops_other;
 
3835
        } else {
 
3836
            ops = tc_lookup_linux_name(kind);
 
3837
            if (!ops) {
 
3838
                static struct vlog_rate_limit rl2 = VLOG_RATE_LIMIT_INIT(1, 1);
 
3839
                VLOG_INFO_RL(&rl2, "unknown qdisc \"%s\"", kind);
 
3840
 
 
3841
                ops = &tc_ops_other;
 
3842
            }
 
3843
        }
 
3844
    } else if (error == ENOENT) {
 
3845
        /* Either it's a built-in qdisc, or it's a qdisc set up by some
 
3846
         * other entity that doesn't have a handle 1:0.  We will assume
 
3847
         * that it's the system default qdisc. */
 
3848
        ops = &tc_ops_default;
 
3849
        error = 0;
 
3850
    } else {
 
3851
        /* Who knows?  Maybe the device got deleted. */
 
3852
        VLOG_WARN_RL(&rl, "query %s qdisc failed (%s)",
 
3853
                     netdev_get_name(netdev), strerror(error));
 
3854
        ops = &tc_ops_other;
 
3855
    }
 
3856
 
 
3857
    /* Instantiate it. */
 
3858
    load_error = ops->tc_load((struct netdev *) netdev, qdisc);
 
3859
    assert((load_error == 0) == (netdev_dev->tc != NULL));
 
3860
    ofpbuf_delete(qdisc);
 
3861
 
 
3862
    return error ? error : load_error;
 
3863
}
 
3864
 
 
3865
/* Linux traffic control uses tables with 256 entries ("rtab" tables) to
 
3866
   approximate the time to transmit packets of various lengths.  For an MTU of
 
3867
   256 or less, each entry is exact; for an MTU of 257 through 512, each entry
 
3868
   represents two possible packet lengths; for a MTU of 513 through 1024, four
 
3869
   possible lengths; and so on.
 
3870
 
 
3871
   Returns, for the specified 'mtu', the number of bits that packet lengths
 
3872
   need to be shifted right to fit within such a 256-entry table. */
 
3873
static int
 
3874
tc_calc_cell_log(unsigned int mtu)
 
3875
{
 
3876
    int cell_log;
 
3877
 
 
3878
    if (!mtu) {
 
3879
        mtu = ETH_PAYLOAD_MAX;
 
3880
    }
 
3881
    mtu += ETH_HEADER_LEN + VLAN_HEADER_LEN;
 
3882
 
 
3883
    for (cell_log = 0; mtu >= 256; cell_log++) {
 
3884
        mtu >>= 1;
 
3885
    }
 
3886
 
 
3887
    return cell_log;
 
3888
}
 
3889
 
 
3890
/* Initializes 'rate' properly for a rate of 'Bps' bytes per second with an MTU
 
3891
 * of 'mtu'. */
 
3892
static void
 
3893
tc_fill_rate(struct tc_ratespec *rate, uint64_t Bps, int mtu)
 
3894
{
 
3895
    memset(rate, 0, sizeof *rate);
 
3896
    rate->cell_log = tc_calc_cell_log(mtu);
 
3897
    /* rate->overhead = 0; */           /* New in 2.6.24, not yet in some */
 
3898
    /* rate->cell_align = 0; */         /* distro headers. */
 
3899
    rate->mpu = ETH_TOTAL_MIN;
 
3900
    rate->rate = Bps;
 
3901
}
 
3902
 
 
3903
/* Appends to 'msg' an "rtab" table for the specified 'rate' as a Netlink
 
3904
 * attribute of the specified "type".
 
3905
 *
 
3906
 * See tc_calc_cell_log() above for a description of "rtab"s. */
 
3907
static void
 
3908
tc_put_rtab(struct ofpbuf *msg, uint16_t type, const struct tc_ratespec *rate)
 
3909
{
 
3910
    uint32_t *rtab;
 
3911
    unsigned int i;
 
3912
 
 
3913
    rtab = nl_msg_put_unspec_uninit(msg, type, TC_RTAB_SIZE);
 
3914
    for (i = 0; i < TC_RTAB_SIZE / sizeof *rtab; i++) {
 
3915
        unsigned packet_size = (i + 1) << rate->cell_log;
 
3916
        if (packet_size < rate->mpu) {
 
3917
            packet_size = rate->mpu;
 
3918
        }
 
3919
        rtab[i] = tc_bytes_to_ticks(rate->rate, packet_size);
 
3920
    }
 
3921
}
 
3922
 
 
3923
/* Calculates the proper value of 'buffer' or 'cbuffer' in HTB options given a
 
3924
 * rate of 'Bps' bytes per second, the specified 'mtu', and a user-requested
 
3925
 * burst size of 'burst_bytes'.  (If no value was requested, a 'burst_bytes' of
 
3926
 * 0 is fine.) */
 
3927
static int
 
3928
tc_calc_buffer(unsigned int Bps, int mtu, uint64_t burst_bytes)
 
3929
{
 
3930
    unsigned int min_burst = tc_buffer_per_jiffy(Bps) + mtu;
 
3931
    return tc_bytes_to_ticks(Bps, MAX(burst_bytes, min_burst));
 
3932
}
 
3933
 
 
3934
/* Linux-only functions declared in netdev-linux.h  */
 
3935
 
 
3936
/* Returns a fd for an AF_INET socket or a negative errno value. */
 
3937
int
 
3938
netdev_linux_get_af_inet_sock(void)
 
3939
{
 
3940
    int error = netdev_linux_init();
 
3941
    return error ? -error : af_inet_sock;
 
3942
}
 
3943
 
 
3944
/* Modifies the 'flag' bit in ethtool's flags field for 'netdev'.  If
 
3945
 * 'enable' is true, the bit is set.  Otherwise, it is cleared. */
 
3946
int
 
3947
netdev_linux_ethtool_set_flag(struct netdev *netdev, uint32_t flag,
 
3948
                              const char *flag_name, bool enable)
 
3949
{
 
3950
    const char *netdev_name = netdev_get_name(netdev);
 
3951
    struct ethtool_value evalue;
 
3952
    uint32_t new_flags;
 
3953
    int error;
 
3954
 
 
3955
    memset(&evalue, 0, sizeof evalue);
 
3956
    error = netdev_linux_do_ethtool(netdev_name,
 
3957
                                    (struct ethtool_cmd *)&evalue,
 
3958
                                    ETHTOOL_GFLAGS, "ETHTOOL_GFLAGS");
 
3959
    if (error) {
 
3960
        return error;
 
3961
    }
 
3962
 
 
3963
    evalue.data = new_flags = (evalue.data & ~flag) | (enable ? flag : 0);
 
3964
    error = netdev_linux_do_ethtool(netdev_name,
 
3965
                                    (struct ethtool_cmd *)&evalue,
 
3966
                                    ETHTOOL_SFLAGS, "ETHTOOL_SFLAGS");
 
3967
    if (error) {
 
3968
        return error;
 
3969
    }
 
3970
 
 
3971
    memset(&evalue, 0, sizeof evalue);
 
3972
    error = netdev_linux_do_ethtool(netdev_name,
 
3973
                                    (struct ethtool_cmd *)&evalue,
 
3974
                                    ETHTOOL_GFLAGS, "ETHTOOL_GFLAGS");
 
3975
    if (error) {
 
3976
        return error;
 
3977
    }
 
3978
 
 
3979
    if (new_flags != evalue.data) {
 
3980
        VLOG_WARN_RL(&rl, "attempt to %s ethtool %s flag on network "
 
3981
                     "device %s failed", enable ? "enable" : "disable",
 
3982
                     flag_name, netdev_name);
 
3983
        return EOPNOTSUPP;
 
3984
    }
 
3985
 
 
3986
    return 0;
 
3987
}
 
3988
 
 
3989
/* Utility functions. */
 
3990
 
 
3991
/* Copies 'src' into 'dst', performing format conversion in the process. */
 
3992
static void
 
3993
netdev_stats_from_rtnl_link_stats(struct netdev_stats *dst,
 
3994
                                  const struct rtnl_link_stats *src)
 
3995
{
 
3996
    dst->rx_packets = src->rx_packets;
 
3997
    dst->tx_packets = src->tx_packets;
 
3998
    dst->rx_bytes = src->rx_bytes;
 
3999
    dst->tx_bytes = src->tx_bytes;
 
4000
    dst->rx_errors = src->rx_errors;
 
4001
    dst->tx_errors = src->tx_errors;
 
4002
    dst->rx_dropped = src->rx_dropped;
 
4003
    dst->tx_dropped = src->tx_dropped;
 
4004
    dst->multicast = src->multicast;
 
4005
    dst->collisions = src->collisions;
 
4006
    dst->rx_length_errors = src->rx_length_errors;
 
4007
    dst->rx_over_errors = src->rx_over_errors;
 
4008
    dst->rx_crc_errors = src->rx_crc_errors;
 
4009
    dst->rx_frame_errors = src->rx_frame_errors;
 
4010
    dst->rx_fifo_errors = src->rx_fifo_errors;
 
4011
    dst->rx_missed_errors = src->rx_missed_errors;
 
4012
    dst->tx_aborted_errors = src->tx_aborted_errors;
 
4013
    dst->tx_carrier_errors = src->tx_carrier_errors;
 
4014
    dst->tx_fifo_errors = src->tx_fifo_errors;
 
4015
    dst->tx_heartbeat_errors = src->tx_heartbeat_errors;
 
4016
    dst->tx_window_errors = src->tx_window_errors;
 
4017
}
 
4018
 
 
4019
static int
 
4020
get_stats_via_netlink(int ifindex, struct netdev_stats *stats)
 
4021
{
 
4022
    /* Policy for RTNLGRP_LINK messages.
 
4023
     *
 
4024
     * There are *many* more fields in these messages, but currently we only
 
4025
     * care about these fields. */
 
4026
    static const struct nl_policy rtnlgrp_link_policy[] = {
 
4027
        [IFLA_IFNAME] = { .type = NL_A_STRING, .optional = false },
 
4028
        [IFLA_STATS] = { .type = NL_A_UNSPEC, .optional = true,
 
4029
                         .min_len = sizeof(struct rtnl_link_stats) },
 
4030
    };
 
4031
 
 
4032
    struct ofpbuf request;
 
4033
    struct ofpbuf *reply;
 
4034
    struct ifinfomsg *ifi;
 
4035
    struct nlattr *attrs[ARRAY_SIZE(rtnlgrp_link_policy)];
 
4036
    int error;
 
4037
 
 
4038
    ofpbuf_init(&request, 0);
 
4039
    nl_msg_put_nlmsghdr(&request, sizeof *ifi, RTM_GETLINK, NLM_F_REQUEST);
 
4040
    ifi = ofpbuf_put_zeros(&request, sizeof *ifi);
 
4041
    ifi->ifi_family = PF_UNSPEC;
 
4042
    ifi->ifi_index = ifindex;
 
4043
    error = nl_sock_transact(rtnl_sock, &request, &reply);
 
4044
    ofpbuf_uninit(&request);
 
4045
    if (error) {
 
4046
        return error;
 
4047
    }
 
4048
 
 
4049
    if (!nl_policy_parse(reply, NLMSG_HDRLEN + sizeof(struct ifinfomsg),
 
4050
                         rtnlgrp_link_policy,
 
4051
                         attrs, ARRAY_SIZE(rtnlgrp_link_policy))) {
 
4052
        ofpbuf_delete(reply);
 
4053
        return EPROTO;
 
4054
    }
 
4055
 
 
4056
    if (!attrs[IFLA_STATS]) {
 
4057
        VLOG_WARN_RL(&rl, "RTM_GETLINK reply lacks stats");
 
4058
        ofpbuf_delete(reply);
 
4059
        return EPROTO;
 
4060
    }
 
4061
 
 
4062
    netdev_stats_from_rtnl_link_stats(stats, nl_attr_get(attrs[IFLA_STATS]));
 
4063
 
 
4064
    ofpbuf_delete(reply);
 
4065
 
 
4066
    return 0;
 
4067
}
 
4068
 
 
4069
static int
 
4070
get_stats_via_proc(const char *netdev_name, struct netdev_stats *stats)
 
4071
{
 
4072
    static const char fn[] = "/proc/net/dev";
 
4073
    char line[1024];
 
4074
    FILE *stream;
 
4075
    int ln;
 
4076
 
 
4077
    stream = fopen(fn, "r");
 
4078
    if (!stream) {
 
4079
        VLOG_WARN_RL(&rl, "%s: open failed: %s", fn, strerror(errno));
 
4080
        return errno;
 
4081
    }
 
4082
 
 
4083
    ln = 0;
 
4084
    while (fgets(line, sizeof line, stream)) {
 
4085
        if (++ln >= 3) {
 
4086
            char devname[16];
 
4087
#define X64 "%"SCNu64
 
4088
            if (sscanf(line,
 
4089
                       " %15[^:]:"
 
4090
                       X64 X64 X64 X64 X64 X64 X64 "%*u"
 
4091
                       X64 X64 X64 X64 X64 X64 X64 "%*u",
 
4092
                       devname,
 
4093
                       &stats->rx_bytes,
 
4094
                       &stats->rx_packets,
 
4095
                       &stats->rx_errors,
 
4096
                       &stats->rx_dropped,
 
4097
                       &stats->rx_fifo_errors,
 
4098
                       &stats->rx_frame_errors,
 
4099
                       &stats->multicast,
 
4100
                       &stats->tx_bytes,
 
4101
                       &stats->tx_packets,
 
4102
                       &stats->tx_errors,
 
4103
                       &stats->tx_dropped,
 
4104
                       &stats->tx_fifo_errors,
 
4105
                       &stats->collisions,
 
4106
                       &stats->tx_carrier_errors) != 15) {
 
4107
                VLOG_WARN_RL(&rl, "%s:%d: parse error", fn, ln);
 
4108
            } else if (!strcmp(devname, netdev_name)) {
 
4109
                stats->rx_length_errors = UINT64_MAX;
 
4110
                stats->rx_over_errors = UINT64_MAX;
 
4111
                stats->rx_crc_errors = UINT64_MAX;
 
4112
                stats->rx_missed_errors = UINT64_MAX;
 
4113
                stats->tx_aborted_errors = UINT64_MAX;
 
4114
                stats->tx_heartbeat_errors = UINT64_MAX;
 
4115
                stats->tx_window_errors = UINT64_MAX;
 
4116
                fclose(stream);
 
4117
                return 0;
 
4118
            }
 
4119
        }
 
4120
    }
 
4121
    VLOG_WARN_RL(&rl, "%s: no stats for %s", fn, netdev_name);
 
4122
    fclose(stream);
 
4123
    return ENODEV;
 
4124
}
 
4125
 
 
4126
static int
 
4127
get_carrier_via_sysfs(const char *name, bool *carrier)
 
4128
{
 
4129
    char line[8];
 
4130
    int retval;
 
4131
 
 
4132
    int error = 0;
 
4133
    char *fn = NULL;
 
4134
    int fd = -1;
 
4135
 
 
4136
    *carrier = false;
 
4137
 
 
4138
    fn = xasprintf("/sys/class/net/%s/carrier", name);
 
4139
    fd = open(fn, O_RDONLY);
 
4140
    if (fd < 0) {
 
4141
        error = errno;
 
4142
        VLOG_WARN_RL(&rl, "%s: open failed: %s", fn, strerror(error));
 
4143
        goto exit;
 
4144
    }
 
4145
 
 
4146
    retval = read(fd, line, sizeof line);
 
4147
    if (retval < 0) {
 
4148
        error = errno;
 
4149
        if (error == EINVAL) {
 
4150
            /* This is the normal return value when we try to check carrier if
 
4151
             * the network device is not up. */
 
4152
        } else {
 
4153
            VLOG_WARN_RL(&rl, "%s: read failed: %s", fn, strerror(error));
 
4154
        }
 
4155
        goto exit;
 
4156
    } else if (retval == 0) {
 
4157
        error = EPROTO;
 
4158
        VLOG_WARN_RL(&rl, "%s: unexpected end of file", fn);
 
4159
        goto exit;
 
4160
    }
 
4161
 
 
4162
    if (line[0] != '0' && line[0] != '1') {
 
4163
        error = EPROTO;
 
4164
        VLOG_WARN_RL(&rl, "%s: value is %c (expected 0 or 1)", fn, line[0]);
 
4165
        goto exit;
 
4166
    }
 
4167
    *carrier = line[0] != '0';
 
4168
    error = 0;
 
4169
 
 
4170
exit:
 
4171
    if (fd >= 0) {
 
4172
        close(fd);
 
4173
    }
 
4174
    free(fn);
 
4175
    return error;
 
4176
}
 
4177
 
 
4178
static int
 
4179
get_flags(const struct netdev *netdev, int *flags)
 
4180
{
 
4181
    struct ifreq ifr;
 
4182
    int error;
 
4183
 
 
4184
    error = netdev_linux_do_ioctl(netdev_get_name(netdev), &ifr, SIOCGIFFLAGS,
 
4185
                                  "SIOCGIFFLAGS");
 
4186
    *flags = ifr.ifr_flags;
 
4187
    return error;
 
4188
}
 
4189
 
 
4190
static int
 
4191
set_flags(struct netdev *netdev, int flags)
 
4192
{
 
4193
    struct ifreq ifr;
 
4194
 
 
4195
    ifr.ifr_flags = flags;
 
4196
    return netdev_linux_do_ioctl(netdev_get_name(netdev), &ifr, SIOCSIFFLAGS,
 
4197
                                 "SIOCSIFFLAGS");
 
4198
}
 
4199
 
 
4200
static int
 
4201
do_get_ifindex(const char *netdev_name)
 
4202
{
 
4203
    struct ifreq ifr;
 
4204
 
 
4205
    ovs_strzcpy(ifr.ifr_name, netdev_name, sizeof ifr.ifr_name);
 
4206
    COVERAGE_INC(netdev_get_ifindex);
 
4207
    if (ioctl(af_inet_sock, SIOCGIFINDEX, &ifr) < 0) {
 
4208
        VLOG_WARN_RL(&rl, "ioctl(SIOCGIFINDEX) on %s device failed: %s",
 
4209
                     netdev_name, strerror(errno));
 
4210
        return -errno;
 
4211
    }
 
4212
    return ifr.ifr_ifindex;
 
4213
}
 
4214
 
 
4215
static int
 
4216
get_ifindex(const struct netdev *netdev_, int *ifindexp)
 
4217
{
 
4218
    struct netdev_dev_linux *netdev_dev =
 
4219
                                netdev_dev_linux_cast(netdev_get_dev(netdev_));
 
4220
    *ifindexp = 0;
 
4221
    if (!(netdev_dev->cache_valid & VALID_IFINDEX)) {
 
4222
        int ifindex = do_get_ifindex(netdev_get_name(netdev_));
 
4223
        if (ifindex < 0) {
 
4224
            return -ifindex;
 
4225
        }
 
4226
        netdev_dev->cache_valid |= VALID_IFINDEX;
 
4227
        netdev_dev->ifindex = ifindex;
 
4228
    }
 
4229
    *ifindexp = netdev_dev->ifindex;
 
4230
    return 0;
 
4231
}
 
4232
 
 
4233
static int
 
4234
get_etheraddr(const char *netdev_name, uint8_t ea[ETH_ADDR_LEN])
 
4235
{
 
4236
    struct ifreq ifr;
 
4237
    int hwaddr_family;
 
4238
 
 
4239
    memset(&ifr, 0, sizeof ifr);
 
4240
    ovs_strzcpy(ifr.ifr_name, netdev_name, sizeof ifr.ifr_name);
 
4241
    COVERAGE_INC(netdev_get_hwaddr);
 
4242
    if (ioctl(af_inet_sock, SIOCGIFHWADDR, &ifr) < 0) {
 
4243
        /* ENODEV probably means that a vif disappeared asynchronously and
 
4244
         * hasn't been removed from the database yet, so reduce the log level
 
4245
         * to INFO for that case. */
 
4246
        VLOG(errno == ENODEV ? VLL_INFO : VLL_ERR,
 
4247
             "ioctl(SIOCGIFHWADDR) on %s device failed: %s",
 
4248
             netdev_name, strerror(errno));
 
4249
        return errno;
 
4250
    }
 
4251
    hwaddr_family = ifr.ifr_hwaddr.sa_family;
 
4252
    if (hwaddr_family != AF_UNSPEC && hwaddr_family != ARPHRD_ETHER) {
 
4253
        VLOG_WARN("%s device has unknown hardware address family %d",
 
4254
                  netdev_name, hwaddr_family);
 
4255
    }
 
4256
    memcpy(ea, ifr.ifr_hwaddr.sa_data, ETH_ADDR_LEN);
 
4257
    return 0;
 
4258
}
 
4259
 
 
4260
static int
 
4261
set_etheraddr(const char *netdev_name, int hwaddr_family,
 
4262
              const uint8_t mac[ETH_ADDR_LEN])
 
4263
{
 
4264
    struct ifreq ifr;
 
4265
 
 
4266
    memset(&ifr, 0, sizeof ifr);
 
4267
    ovs_strzcpy(ifr.ifr_name, netdev_name, sizeof ifr.ifr_name);
 
4268
    ifr.ifr_hwaddr.sa_family = hwaddr_family;
 
4269
    memcpy(ifr.ifr_hwaddr.sa_data, mac, ETH_ADDR_LEN);
 
4270
    COVERAGE_INC(netdev_set_hwaddr);
 
4271
    if (ioctl(af_inet_sock, SIOCSIFHWADDR, &ifr) < 0) {
 
4272
        VLOG_ERR("ioctl(SIOCSIFHWADDR) on %s device failed: %s",
 
4273
                 netdev_name, strerror(errno));
 
4274
        return errno;
 
4275
    }
 
4276
    return 0;
 
4277
}
 
4278
 
 
4279
static int
 
4280
netdev_linux_do_ethtool(const char *name, struct ethtool_cmd *ecmd,
 
4281
                        int cmd, const char *cmd_name)
 
4282
{
 
4283
    struct ifreq ifr;
 
4284
 
 
4285
    memset(&ifr, 0, sizeof ifr);
 
4286
    ovs_strzcpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
 
4287
    ifr.ifr_data = (caddr_t) ecmd;
 
4288
 
 
4289
    ecmd->cmd = cmd;
 
4290
    COVERAGE_INC(netdev_ethtool);
 
4291
    if (ioctl(af_inet_sock, SIOCETHTOOL, &ifr) == 0) {
 
4292
        return 0;
 
4293
    } else {
 
4294
        if (errno != EOPNOTSUPP) {
 
4295
            VLOG_WARN_RL(&rl, "ethtool command %s on network device %s "
 
4296
                         "failed: %s", cmd_name, name, strerror(errno));
 
4297
        } else {
 
4298
            /* The device doesn't support this operation.  That's pretty
 
4299
             * common, so there's no point in logging anything. */
 
4300
        }
 
4301
        return errno;
 
4302
    }
 
4303
}
 
4304
 
 
4305
static int
 
4306
netdev_linux_do_ioctl(const char *name, struct ifreq *ifr, int cmd,
 
4307
                      const char *cmd_name)
 
4308
{
 
4309
    ovs_strzcpy(ifr->ifr_name, name, sizeof ifr->ifr_name);
 
4310
    if (ioctl(af_inet_sock, cmd, ifr) == -1) {
 
4311
        VLOG_DBG_RL(&rl, "%s: ioctl(%s) failed: %s", name, cmd_name,
 
4312
                     strerror(errno));
 
4313
        return errno;
 
4314
    }
 
4315
    return 0;
 
4316
}
 
4317
 
 
4318
static int
 
4319
netdev_linux_get_ipv4(const struct netdev *netdev, struct in_addr *ip,
 
4320
                      int cmd, const char *cmd_name)
 
4321
{
 
4322
    struct ifreq ifr;
 
4323
    int error;
 
4324
 
 
4325
    ifr.ifr_addr.sa_family = AF_INET;
 
4326
    error = netdev_linux_do_ioctl(netdev_get_name(netdev), &ifr, cmd, cmd_name);
 
4327
    if (!error) {
 
4328
        const struct sockaddr_in *sin = (struct sockaddr_in *) &ifr.ifr_addr;
 
4329
        *ip = sin->sin_addr;
 
4330
    }
 
4331
    return error;
 
4332
}
 
4333
 
 
4334
/* Returns an AF_PACKET raw socket or a negative errno value. */
 
4335
static int
 
4336
af_packet_sock(void)
 
4337
{
 
4338
    static int sock = INT_MIN;
 
4339
 
 
4340
    if (sock == INT_MIN) {
 
4341
        sock = socket(AF_PACKET, SOCK_RAW, 0);
 
4342
        if (sock >= 0) {
 
4343
            set_nonblocking(sock);
 
4344
        } else {
 
4345
            sock = -errno;
 
4346
            VLOG_ERR("failed to create packet socket: %s", strerror(errno));
 
4347
        }
 
4348
    }
 
4349
 
 
4350
    return sock;
 
4351
}