~james-page/ubuntu/saucy/openvswitch/1.12-snapshot

« back to all changes in this revision

Viewing changes to lib/netdev-bsd.c

  • Committer: James Page
  • Date: 2013-08-21 10:16:57 UTC
  • mfrom: (1.1.20)
  • Revision ID: james.page@canonical.com-20130821101657-3o0z0qeiv5zkwlzi
New upstream snapshot

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * Copyright (c) 2011 Gaetano Catalli.
 
3
 * Copyright (c) 2013 YAMAMOTO Takashi.
3
4
 *
4
5
 * Licensed under the Apache License, Version 2.0 (the "License");
5
6
 * you may not use this file except in compliance with the License.
16
17
 
17
18
#include <config.h>
18
19
 
 
20
#include "netdev-provider.h"
19
21
#include <stdlib.h>
20
22
#include <errno.h>
21
23
#include <fcntl.h>
31
33
#include <net/if_media.h>
32
34
#include <net/if_tap.h>
33
35
#include <netinet/in.h>
 
36
#ifdef HAVE_NET_IF_MIB_H
34
37
#include <net/if_mib.h>
 
38
#endif
35
39
#include <poll.h>
36
40
#include <string.h>
37
41
#include <unistd.h>
38
42
#include <sys/sysctl.h>
 
43
#if defined(__NetBSD__)
 
44
#include <net/route.h>
 
45
#endif
39
46
 
40
47
#include "rtbsd.h"
41
48
#include "coverage.h"
42
49
#include "dynamic-string.h"
43
50
#include "fatal-signal.h"
44
 
#include "netdev-provider.h"
45
51
#include "ofpbuf.h"
46
52
#include "openflow/openflow.h"
47
53
#include "packets.h"
55
61
VLOG_DEFINE_THIS_MODULE(netdev_bsd);
56
62
 
57
63
 
58
 
/*
59
 
 * This file implements objects to access interfaces.
60
 
 * Externally, interfaces are represented by two structures:
61
 
 *   + struct netdev_dev, representing a network device,
62
 
 *     containing e.g. name and a refcount;
63
 
 *     We can have private variables by embedding the
64
 
 *     struct netdev_dev into our own structure
65
 
 *     (e.g. netdev_dev_bsd)
66
 
 *
67
 
 *   + struct netdev, representing an instance of an open netdev_dev.
68
 
 *     The structure contains a pointer to the 'struct netdev'
69
 
 *     representing the device. Again, private information
70
 
 *     such as file descriptor etc. are stored in our
71
 
 *     own struct netdev_bsd which includes a struct netdev.
72
 
 *
73
 
 * Both 'struct netdev' and 'struct netdev_dev' are referenced
74
 
 * in containers which hold pointers to the data structures.
75
 
 * We can reach our own struct netdev_XXX_bsd by putting a
76
 
 * struct netdev_XXX within our own struct, and using CONTAINER_OF
77
 
 * to access the parent structure.
78
 
 */
 
64
struct netdev_rx_bsd {
 
65
    struct netdev_rx up;
 
66
 
 
67
    /* Packet capture descriptor for a system network device.
 
68
     * For a tap device this is NULL. */
 
69
    pcap_t *pcap_handle;
 
70
 
 
71
    /* Selectable file descriptor for the network device.
 
72
     * This descriptor will be used for polling operations. */
 
73
    int fd;
 
74
};
 
75
 
 
76
static const struct netdev_rx_class netdev_rx_bsd_class;
 
77
 
79
78
struct netdev_bsd {
80
 
    struct netdev netdev;
81
 
 
82
 
    int netdev_fd;   /* Selectable file descriptor for the network device.
83
 
                        This descriptor will be used for polling operations */
84
 
 
85
 
    pcap_t *pcap_handle;  /* Packet capture descriptor for a system network
86
 
                             device */
87
 
};
88
 
 
89
 
struct netdev_dev_bsd {
90
 
    struct netdev_dev netdev_dev;
 
79
    struct netdev up;
91
80
    unsigned int cache_valid;
92
81
    unsigned int change_seq;
93
82
 
98
87
    int mtu;
99
88
    int carrier;
100
89
 
101
 
    bool tap_opened;
102
 
    int tap_fd;         /* TAP character device, if any */
 
90
    int tap_fd;         /* TAP character device, if any, otherwise -1. */
 
91
 
 
92
    /* Used for sending packets on non-tap devices. */
 
93
    pcap_t *pcap;
 
94
    int fd;
 
95
 
 
96
    char *kernel_name;
103
97
};
104
98
 
105
99
 
115
109
/* An AF_INET socket (used for ioctl operations). */
116
110
static int af_inet_sock = -1;
117
111
 
 
112
#if defined(__NetBSD__)
 
113
/* AF_LINK socket used for netdev_bsd_get_stats and set_etheraddr */
 
114
static int af_link_sock = -1;
 
115
#endif /* defined(__NetBSD__) */
 
116
 
118
117
#define PCAP_SNAPLEN 2048
119
118
 
120
119
 
133
132
 
134
133
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
135
134
 
136
 
static int netdev_bsd_do_ioctl(const struct netdev *, struct ifreq *,
137
 
                                 unsigned long cmd, const char *cmd_name);
 
135
static int netdev_bsd_do_ioctl(const char *, struct ifreq *, unsigned long cmd,
 
136
                               const char *cmd_name);
138
137
static void destroy_tap(int fd, const char *name);
139
138
static int get_flags(const struct netdev *, int *flagsp);
140
 
static int set_flags(struct netdev *, int flags);
 
139
static int set_flags(const char *, int flags);
141
140
static int do_set_addr(struct netdev *netdev,
142
141
                       int ioctl_nr, const char *ioctl_name,
143
142
                       struct in_addr addr);
146
145
                         int hwaddr_len, const uint8_t[ETH_ADDR_LEN]);
147
146
static int get_ifindex(const struct netdev *, int *ifindexp);
148
147
 
 
148
static int ifr_get_flags(const struct ifreq *);
 
149
static void ifr_set_flags(struct ifreq *, int flags);
 
150
 
149
151
static int netdev_bsd_init(void);
150
152
 
151
153
static bool
157
159
static struct netdev_bsd *
158
160
netdev_bsd_cast(const struct netdev *netdev)
159
161
{
160
 
    ovs_assert(is_netdev_bsd_class(netdev_dev_get_class(
161
 
                                       netdev_get_dev(netdev))));
162
 
    return CONTAINER_OF(netdev, struct netdev_bsd, netdev);
163
 
}
164
 
 
165
 
static struct netdev_dev_bsd *
166
 
netdev_dev_bsd_cast(const struct netdev_dev *netdev_dev)
167
 
{
168
 
    ovs_assert(is_netdev_bsd_class(netdev_dev_get_class(netdev_dev)));
169
 
    return CONTAINER_OF(netdev_dev, struct netdev_dev_bsd, netdev_dev);
 
162
    ovs_assert(is_netdev_bsd_class(netdev_get_class(netdev)));
 
163
    return CONTAINER_OF(netdev, struct netdev_bsd, up);
 
164
}
 
165
 
 
166
static struct netdev_rx_bsd *
 
167
netdev_rx_bsd_cast(const struct netdev_rx *rx)
 
168
{
 
169
    netdev_rx_assert_class(rx, &netdev_rx_bsd_class);
 
170
    return CONTAINER_OF(rx, struct netdev_rx_bsd, up);
 
171
}
 
172
 
 
173
static const char *
 
174
netdev_get_kernel_name(const struct netdev *netdev)
 
175
{
 
176
    return netdev_bsd_cast(netdev)->kernel_name;
170
177
}
171
178
 
172
179
/* Initialize the AF_INET socket used for ioctl operations */
181
188
 
182
189
    af_inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
183
190
    status = af_inet_sock >= 0 ? 0 : errno;
 
191
    if (status) {
 
192
        VLOG_ERR("failed to create inet socket: %s", ovs_strerror(status));
 
193
        return status;
 
194
    }
184
195
 
 
196
#if defined(__NetBSD__)
 
197
    af_link_sock = socket(AF_LINK, SOCK_DGRAM, 0);
 
198
    status = af_link_sock >= 0 ? 0 : errno;
185
199
    if (status) {
186
 
        VLOG_ERR("failed to create inet socket: %s", strerror(status));
 
200
        VLOG_ERR("failed to create link socket: %s", ovs_strerror(status));
 
201
        close(af_inet_sock);
 
202
        af_inet_sock = -1;
187
203
    }
 
204
#endif /* defined(__NetBSD__) */
188
205
 
189
206
    return status;
190
207
}
210
227
}
211
228
 
212
229
static void
213
 
netdev_dev_bsd_changed(struct netdev_dev_bsd *dev)
 
230
netdev_bsd_changed(struct netdev_bsd *dev)
214
231
{
215
232
    dev->change_seq++;
216
233
    if (!dev->change_seq) {
221
238
/* Invalidate cache in case of interface status change. */
222
239
static void
223
240
netdev_bsd_cache_cb(const struct rtbsd_change *change,
224
 
                      void *aux OVS_UNUSED)
 
241
                    void *aux OVS_UNUSED)
225
242
{
226
 
    struct netdev_dev_bsd *dev;
 
243
    struct netdev_bsd *dev;
227
244
 
228
245
    if (change) {
229
 
        struct netdev_dev *base_dev = netdev_dev_from_name(change->if_name);
 
246
        struct netdev *base_dev = netdev_from_name(change->if_name);
230
247
 
231
248
        if (base_dev) {
232
249
            const struct netdev_class *netdev_class =
233
 
                                                netdev_dev_get_class(base_dev);
 
250
                                                netdev_get_class(base_dev);
234
251
 
235
252
            if (is_netdev_bsd_class(netdev_class)) {
236
 
                dev = netdev_dev_bsd_cast(base_dev);
 
253
                dev = netdev_bsd_cast(base_dev);
237
254
                dev->cache_valid = 0;
238
 
                netdev_dev_bsd_changed(dev);
 
255
                netdev_bsd_changed(dev);
239
256
            }
240
257
        }
241
258
    } else {
247
264
        struct shash_node *node;
248
265
 
249
266
        shash_init(&device_shash);
250
 
        netdev_dev_get_devices(&netdev_bsd_class, &device_shash);
 
267
        netdev_get_devices(&netdev_bsd_class, &device_shash);
251
268
        SHASH_FOR_EACH (node, &device_shash) {
252
269
            dev = node->data;
253
270
            dev->cache_valid = 0;
254
 
            netdev_dev_bsd_changed(dev);
 
271
            netdev_bsd_changed(dev);
255
272
        }
256
273
        shash_destroy(&device_shash);
257
274
    }
283
300
    return 0;
284
301
}
285
302
 
286
 
/* Allocate a netdev_dev_bsd structure */
 
303
/* Allocate a netdev_bsd structure */
287
304
static int
288
305
netdev_bsd_create_system(const struct netdev_class *class, const char *name,
289
 
                  struct netdev_dev **netdev_devp)
 
306
                  struct netdev **netdevp)
290
307
{
291
 
    struct netdev_dev_bsd *netdev_dev;
 
308
    struct netdev_bsd *netdev;
 
309
    enum netdev_flags flags;
292
310
    int error;
293
311
 
294
312
    error = cache_notifier_ref();
296
314
        return error;
297
315
    }
298
316
 
299
 
    netdev_dev = xzalloc(sizeof *netdev_dev);
300
 
    netdev_dev->change_seq = 1;
301
 
    netdev_dev_init(&netdev_dev->netdev_dev, name, class);
302
 
    *netdev_devp = &netdev_dev->netdev_dev;
303
 
 
 
317
    netdev = xzalloc(sizeof *netdev);
 
318
    netdev->change_seq = 1;
 
319
    netdev_init(&netdev->up, name, class);
 
320
    netdev->tap_fd = -1;
 
321
    netdev->kernel_name = xstrdup(name);
 
322
 
 
323
    /* Verify that the netdev really exists by attempting to read its flags */
 
324
    error = netdev_get_flags(&netdev->up, &flags);
 
325
    if (error == ENXIO) {
 
326
        netdev_uninit(&netdev->up, false);
 
327
        free(netdev);
 
328
        cache_notifier_unref();
 
329
        return error;
 
330
    }
 
331
 
 
332
    *netdevp = &netdev->up;
304
333
    return 0;
305
334
}
306
335
 
307
336
/*
308
 
 * Allocate a netdev_dev_bsd structure with 'tap' class.
 
337
 * Allocate a netdev_bsd structure with 'tap' class.
309
338
 */
310
339
static int
311
340
netdev_bsd_create_tap(const struct netdev_class *class, const char *name,
312
 
                  struct netdev_dev **netdev_devp)
 
341
                  struct netdev **netdevp)
313
342
{
314
 
    struct netdev_dev_bsd *netdev_dev = NULL;
 
343
    struct netdev_bsd *netdev = NULL;
315
344
    int error = 0;
316
345
    struct ifreq ifr;
 
346
    char *kernel_name = NULL;
317
347
 
318
348
    error = cache_notifier_ref();
319
349
    if (error) {
321
351
    }
322
352
 
323
353
    /* allocate the device structure and set the internal flag */
324
 
    netdev_dev = xzalloc(sizeof *netdev_dev);
 
354
    netdev = xzalloc(sizeof *netdev);
325
355
 
326
356
    memset(&ifr, 0, sizeof(ifr));
327
357
 
328
358
    /* Create a tap device by opening /dev/tap.  The TAPGIFNAME ioctl is used
329
359
     * to retrieve the name of the tap device. */
330
 
    netdev_dev->tap_fd = open("/dev/tap", O_RDWR);
331
 
    netdev_dev->change_seq = 1;
332
 
    if (netdev_dev->tap_fd < 0) {
 
360
    netdev->tap_fd = open("/dev/tap", O_RDWR);
 
361
    netdev->change_seq = 1;
 
362
    if (netdev->tap_fd < 0) {
333
363
        error = errno;
334
 
        VLOG_WARN("opening \"/dev/tap\" failed: %s", strerror(error));
 
364
        VLOG_WARN("opening \"/dev/tap\" failed: %s", ovs_strerror(error));
335
365
        goto error_undef_notifier;
336
366
    }
337
367
 
338
368
    /* Retrieve tap name (e.g. tap0) */
339
 
    if (ioctl(netdev_dev->tap_fd, TAPGIFNAME, &ifr) == -1) {
 
369
    if (ioctl(netdev->tap_fd, TAPGIFNAME, &ifr) == -1) {
340
370
        /* XXX Need to destroy the device? */
341
371
        error = errno;
342
372
        goto error_undef_notifier;
343
373
    }
344
374
 
345
375
    /* Change the name of the tap device */
 
376
#if defined(SIOCSIFNAME)
346
377
    ifr.ifr_data = (void *)name;
347
378
    if (ioctl(af_inet_sock, SIOCSIFNAME, &ifr) == -1) {
348
379
        error = errno;
349
 
        destroy_tap(netdev_dev->tap_fd, ifr.ifr_name);
 
380
        destroy_tap(netdev->tap_fd, ifr.ifr_name);
350
381
        goto error_undef_notifier;
351
382
    }
 
383
    kernel_name = xstrdup(name);
 
384
#else
 
385
    /*
 
386
     * NetBSD doesn't support inteface renaming.
 
387
     */
 
388
    VLOG_INFO("tap %s is created for bridge %s", ifr.ifr_name, name);
 
389
    kernel_name = xstrdup(ifr.ifr_name);
 
390
#endif
352
391
 
353
392
    /* set non-blocking. */
354
 
    error = set_nonblocking(netdev_dev->tap_fd);
 
393
    error = set_nonblocking(netdev->tap_fd);
355
394
    if (error) {
356
 
        destroy_tap(netdev_dev->tap_fd, name);
 
395
        destroy_tap(netdev->tap_fd, kernel_name);
357
396
        goto error_undef_notifier;
358
397
    }
359
398
 
360
399
    /* Turn device UP */
361
 
    ifr.ifr_flags = (uint16_t)IFF_UP;
362
 
    ifr.ifr_flagshigh = 0;
363
 
    strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
 
400
    ifr_set_flags(&ifr, IFF_UP);
 
401
    strncpy(ifr.ifr_name, kernel_name, sizeof ifr.ifr_name);
364
402
    if (ioctl(af_inet_sock, SIOCSIFFLAGS, &ifr) == -1) {
365
403
        error = errno;
366
 
        destroy_tap(netdev_dev->tap_fd, name);
 
404
        destroy_tap(netdev->tap_fd, kernel_name);
367
405
        goto error_undef_notifier;
368
406
    }
369
407
 
370
408
    /* initialize the device structure and
371
409
     * link the structure to its netdev */
372
 
    netdev_dev_init(&netdev_dev->netdev_dev, name, class);
373
 
    *netdev_devp = &netdev_dev->netdev_dev;
 
410
    netdev_init(&netdev->up, name, class);
 
411
    netdev->kernel_name = kernel_name;
 
412
    *netdevp = &netdev->up;
374
413
 
375
414
    return 0;
376
415
 
377
416
error_undef_notifier:
378
417
    cache_notifier_unref();
379
418
error:
380
 
    free(netdev_dev);
 
419
    free(netdev);
 
420
    free(kernel_name);
381
421
    return error;
382
422
}
383
423
 
384
424
static void
385
 
netdev_bsd_destroy(struct netdev_dev *netdev_dev_)
 
425
netdev_bsd_destroy(struct netdev *netdev_)
386
426
{
387
 
    struct netdev_dev_bsd *netdev_dev = netdev_dev_bsd_cast(netdev_dev_);
 
427
    struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
388
428
 
389
429
    cache_notifier_unref();
390
430
 
391
 
    if (netdev_dev->tap_fd >= 0 &&
392
 
            !strcmp(netdev_dev_get_type(netdev_dev_), "tap")) {
393
 
        destroy_tap(netdev_dev->tap_fd, netdev_dev_get_name(netdev_dev_));
394
 
    }
395
 
    free(netdev_dev);
396
 
}
397
 
 
398
 
 
399
 
static int
400
 
netdev_bsd_open_system(struct netdev_dev *netdev_dev_, struct netdev **netdevp)
401
 
{
402
 
    struct netdev_bsd *netdev;
403
 
    int error;
404
 
    enum netdev_flags flags;
405
 
 
406
 
    /* Allocate network device. */
407
 
    netdev = xcalloc(1, sizeof *netdev);
408
 
    netdev->netdev_fd = -1;
409
 
    netdev_init(&netdev->netdev, netdev_dev_);
410
 
 
411
 
    /* Verify that the netdev really exists by attempting to read its flags */
412
 
    error = netdev_get_flags(&netdev->netdev, &flags);
413
 
    if (error == ENXIO) {
414
 
        goto error;
415
 
    }
416
 
 
417
 
    *netdevp = &netdev->netdev;
418
 
    return 0;
419
 
 
420
 
error:
421
 
    netdev_uninit(&netdev->netdev, true);
422
 
    return error;
423
 
}
424
 
 
425
 
 
426
 
 
427
 
/* Close a 'netdev'. */
428
 
static void
429
 
netdev_bsd_close(struct netdev *netdev_)
430
 
{
431
 
    struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
432
 
 
433
 
    if (netdev->netdev_fd >= 0 && strcmp(netdev_get_type(netdev_), "tap")) {
434
 
        pcap_close(netdev->pcap_handle);
435
 
    }
436
 
 
 
431
    if (netdev->tap_fd >= 0) {
 
432
        destroy_tap(netdev->tap_fd, netdev_get_kernel_name(netdev_));
 
433
    }
 
434
    if (netdev->pcap) {
 
435
        pcap_close(netdev->pcap);
 
436
    }
 
437
    free(netdev->kernel_name);
437
438
    free(netdev);
438
439
}
439
440
 
440
441
static int
441
 
netdev_bsd_listen(struct netdev *netdev_)
 
442
netdev_bsd_open_pcap(const char *name, pcap_t **pcapp, int *fdp)
442
443
{
443
 
    struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
444
 
    struct netdev_dev_bsd *netdev_dev =
445
 
                              netdev_dev_bsd_cast(netdev_get_dev(netdev_));
446
 
 
447
444
    char errbuf[PCAP_ERRBUF_SIZE];
448
 
    int error;
449
 
    int fd = -1;
 
445
    pcap_t *pcap = NULL;
450
446
    int one = 1;
451
 
 
452
 
    if (netdev->netdev_fd >= 0) {
453
 
        return 0;
454
 
    }
455
 
 
456
 
    if (!strcmp(netdev_get_type(netdev_), "tap") &&
457
 
            !netdev_dev->tap_opened) {
458
 
        netdev->netdev_fd = netdev_dev->tap_fd;
459
 
        netdev_dev->tap_opened = true;
460
 
        return 0;
461
 
    }
462
 
 
463
 
    /* open the pcap device. The device is opened in non-promiscuous mode
 
447
    int error;
 
448
    int fd;
 
449
 
 
450
    /* Open the pcap device.  The device is opened in non-promiscuous mode
464
451
     * because the interface flags are manually set by the caller. */
465
452
    errbuf[0] = '\0';
466
 
    netdev->pcap_handle = pcap_open_live(netdev_get_name(netdev_), PCAP_SNAPLEN,
467
 
                                     0, 1000, errbuf);
468
 
    if (netdev->pcap_handle == NULL) {
469
 
        VLOG_ERR("%s: pcap_open_live failed: %s",
470
 
                netdev_get_name(netdev_), errbuf);
 
453
    pcap = pcap_open_live(name, PCAP_SNAPLEN, 0, 1000, errbuf);
 
454
    if (!pcap) {
 
455
        VLOG_ERR_RL(&rl, "%s: pcap_open_live failed: %s", name, errbuf);
471
456
        error = EIO;
472
457
        goto error;
473
 
    } else if (errbuf[0] !=  '\0') {
474
 
        VLOG_WARN("%s: pcap_open_live: %s",
475
 
                netdev_get_name(netdev_), errbuf);
476
 
    }
477
 
 
478
 
    netdev_dev_bsd_changed(netdev_dev_bsd_cast(netdev_get_dev(netdev_)));
479
 
 
480
 
    /* initialize netdev->netdev_fd */
481
 
    fd = pcap_get_selectable_fd(netdev->pcap_handle);
 
458
    }
 
459
    if (errbuf[0] != '\0') {
 
460
        VLOG_WARN_RL(&rl, "%s: pcap_open_live: %s", name, errbuf);
 
461
    }
 
462
 
 
463
    /* Get the underlying fd. */
 
464
    fd = pcap_get_selectable_fd(pcap);
482
465
    if (fd == -1) {
 
466
        VLOG_WARN_RL(&rl, "%s: no selectable file descriptor", name);
483
467
        error = errno;
484
468
        goto error;
485
469
    }
487
471
    /* Set non-blocking mode. Also the BIOCIMMEDIATE ioctl must be called
488
472
     * on the file descriptor returned by pcap_get_selectable_fd to achieve
489
473
     * a real non-blocking behaviour.*/
490
 
    error = pcap_setnonblock(netdev->pcap_handle, 1, errbuf);
491
 
    if (error == -1) {
492
 
        error = errno;
493
 
        goto error;
494
 
    }
495
 
 
496
 
    /* This call assure that reads return immediately upon packet reception.
497
 
     * Otherwise, a read will block until either the kernel buffer becomes
498
 
     * full or a timeout occurs. */
499
 
    if(ioctl(fd, BIOCIMMEDIATE, &one) < 0 ) {
500
 
        VLOG_ERR("ioctl(BIOCIMMEDIATE) on %s device failed: %s",
501
 
                netdev_get_name(netdev_), strerror(errno));
502
 
        error = errno;
503
 
        goto error;
504
 
    }
505
 
 
506
 
    /* Capture only incoming packets */
507
 
    error = pcap_setdirection(netdev->pcap_handle, PCAP_D_IN);
508
 
    if (error == -1) {
509
 
        error = errno;
510
 
        goto error;
511
 
    }
512
 
 
513
 
    netdev->netdev_fd = fd;
 
474
    error = pcap_setnonblock(pcap, 1, errbuf);
 
475
    if (error == -1) {
 
476
        error = errno;
 
477
        goto error;
 
478
    }
 
479
 
 
480
    /* This call assure that reads return immediately upon packet
 
481
     * reception.  Otherwise, a read will block until either the kernel
 
482
     * buffer becomes full or a timeout occurs. */
 
483
    if (ioctl(fd, BIOCIMMEDIATE, &one) < 0 ) {
 
484
        VLOG_ERR_RL(&rl, "ioctl(BIOCIMMEDIATE) on %s device failed: %s",
 
485
                    name, ovs_strerror(errno));
 
486
        error = errno;
 
487
        goto error;
 
488
    }
 
489
 
 
490
    /* Capture only incoming packets. */
 
491
    error = pcap_setdirection(pcap, PCAP_D_IN);
 
492
    if (error == -1) {
 
493
        error = errno;
 
494
        goto error;
 
495
    }
 
496
 
 
497
    *pcapp = pcap;
 
498
    *fdp = fd;
514
499
    return 0;
515
500
 
516
501
error:
517
 
    if (fd >= 0) {
518
 
        close(netdev->netdev_fd);
 
502
    if (pcap) {
 
503
        pcap_close(pcap);
519
504
    }
 
505
    *pcapp = NULL;
 
506
    *fdp = -1;
520
507
    return error;
521
508
}
522
509
 
 
510
static int
 
511
netdev_bsd_rx_open(struct netdev *netdev_, struct netdev_rx **rxp)
 
512
{
 
513
    struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
 
514
 
 
515
    struct netdev_rx_bsd *rx;
 
516
    pcap_t *pcap;
 
517
    int fd;
 
518
 
 
519
    if (!strcmp(netdev_get_type(netdev_), "tap")) {
 
520
        pcap = NULL;
 
521
        fd = netdev->tap_fd;
 
522
    } else {
 
523
        int error = netdev_bsd_open_pcap(netdev_get_kernel_name(netdev_),
 
524
                                         &pcap, &fd);
 
525
        if (error) {
 
526
            return error;
 
527
        }
 
528
 
 
529
        netdev_bsd_changed(netdev);
 
530
    }
 
531
 
 
532
    rx = xmalloc(sizeof *rx);
 
533
    netdev_rx_init(&rx->up, netdev_, &netdev_rx_bsd_class);
 
534
    rx->pcap_handle = pcap;
 
535
    rx->fd = fd;
 
536
 
 
537
    *rxp = &rx->up;
 
538
    return 0;
 
539
}
 
540
 
 
541
static void
 
542
netdev_rx_bsd_destroy(struct netdev_rx *rx_)
 
543
{
 
544
    struct netdev_rx_bsd *rx = netdev_rx_bsd_cast(rx_);
 
545
 
 
546
    if (rx->pcap_handle) {
 
547
        pcap_close(rx->pcap_handle);
 
548
    }
 
549
    free(rx);
 
550
}
523
551
 
524
552
/* The recv callback of the netdev class returns the number of bytes of the
525
553
 * received packet.
566
594
 * This function attempts to receive a packet from the specified network
567
595
 * device. It is assumed that the network device is a system device or a tap
568
596
 * device opened as a system one. In this case the read operation is performed
569
 
 * on the 'netdev' pcap descriptor.
 
597
 * from rx->pcap.
570
598
 */
571
599
static int
572
 
netdev_bsd_recv_system(struct netdev_bsd *netdev, void *data, size_t size)
 
600
netdev_rx_bsd_recv_pcap(struct netdev_rx_bsd *rx, void *data, size_t size)
573
601
{
574
602
    struct pcap_arg arg;
575
603
    int ret;
576
604
 
577
 
    if (netdev->netdev_fd < 0) {
578
 
        return -EAGAIN;
579
 
    }
580
 
 
581
605
    /* prepare the pcap argument to store the packet */
582
606
    arg.size = size;
583
607
    arg.data = data;
584
608
 
585
609
    for (;;) {
586
 
        ret = pcap_dispatch(netdev->pcap_handle, 1, proc_pkt, (u_char *)&arg);
 
610
        ret = pcap_dispatch(rx->pcap_handle, 1, proc_pkt, (u_char *) &arg);
587
611
 
588
612
        if (ret > 0) {
589
613
            return arg.retval;  /* arg.retval < 0 is handled in the caller */
600
624
 
601
625
/*
602
626
 * This function attempts to receive a packet from the specified network
603
 
 * device. It is assumed that the network device is a tap device and the
604
 
 * 'netdev_fd' member of the 'netdev' structure is initialized with the tap
605
 
 * file descriptor.
 
627
 * device. It is assumed that the network device is a tap device and
 
628
 * 'rx->fd' is initialized with the tap file descriptor.
606
629
 */
607
630
static int
608
 
netdev_bsd_recv_tap(struct netdev_bsd *netdev, void *data, size_t size)
 
631
netdev_rx_bsd_recv_tap(struct netdev_rx_bsd *rx, void *data, size_t size)
609
632
{
610
 
    if (netdev->netdev_fd < 0) {
611
 
        return -EAGAIN;
612
 
    }
613
 
 
614
633
    for (;;) {
615
 
        ssize_t retval = read(netdev->netdev_fd, data, size);
 
634
        ssize_t retval = read(rx->fd, data, size);
616
635
        if (retval >= 0) {
617
636
            return retval;
618
637
        } else if (errno != EINTR) {
619
638
            if (errno != EAGAIN) {
620
639
                VLOG_WARN_RL(&rl, "error receiving Ethernet packet on %s: %s",
621
 
                             strerror(errno), netdev->netdev.netdev_dev->name);
 
640
                             ovs_strerror(errno), netdev_rx_get_name(&rx->up));
622
641
            }
623
642
            return -errno;
624
643
        }
626
645
}
627
646
 
628
647
 
629
 
/*
630
 
 * According with the nature of the device a different function must be called.
631
 
 * If the device is the bridge local port the 'netdev_bsd_recv_tap' function
632
 
 * must be called, otherwise the 'netdev_bsd_recv_system' function is called.
633
 
 *
634
 
 * type!="tap"                                        --->  system device.
635
 
 * type=="tap" && netdev_fd == tap_fd                 --->  internal tap device
636
 
 * type=="tap" && netdev_fd != tap_fd                 --->  internal tap device
637
 
 *                                                          opened as a system
638
 
 *                                                          device.
639
 
 */
640
648
static int
641
 
netdev_bsd_recv(struct netdev *netdev_, void* data, size_t size)
 
649
netdev_rx_bsd_recv(struct netdev_rx *rx_, void *data, size_t size)
642
650
{
643
 
    struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
644
 
    struct netdev_dev_bsd * netdev_dev =
645
 
        netdev_dev_bsd_cast(netdev_get_dev(netdev_));
 
651
    struct netdev_rx_bsd *rx = netdev_rx_bsd_cast(rx_);
646
652
 
647
 
    if (!strcmp(netdev_get_type(netdev_), "tap") &&
648
 
            netdev->netdev_fd == netdev_dev->tap_fd) {
649
 
        return netdev_bsd_recv_tap(netdev, data, size);
650
 
    } else {
651
 
        return netdev_bsd_recv_system(netdev, data, size);
652
 
    }
 
653
    return (rx->pcap_handle
 
654
            ? netdev_rx_bsd_recv_pcap(rx, data, size)
 
655
            : netdev_rx_bsd_recv_tap(rx, data, size));
653
656
}
654
657
 
655
 
 
656
658
/*
657
659
 * Registers with the poll loop to wake up from the next call to poll_block()
658
 
 * when a packet is ready to be received with netdev_recv() on 'netdev'.
 
660
 * when a packet is ready to be received with netdev_rx_recv() on 'rx'.
659
661
 */
660
662
static void
661
 
netdev_bsd_recv_wait(struct netdev *netdev_)
 
663
netdev_rx_bsd_wait(struct netdev_rx *rx_)
662
664
{
663
 
    struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
 
665
    struct netdev_rx_bsd *rx = netdev_rx_bsd_cast(rx_);
664
666
 
665
 
    if (netdev->netdev_fd >= 0) {
666
 
        poll_fd_wait(netdev->netdev_fd, POLLIN);
667
 
    }
 
667
    poll_fd_wait(rx->fd, POLLIN);
668
668
}
669
669
 
670
 
/* Discards all packets waiting to be received from 'netdev'. */
 
670
/* Discards all packets waiting to be received from 'rx'. */
671
671
static int
672
 
netdev_bsd_drain(struct netdev *netdev_)
 
672
netdev_rx_bsd_drain(struct netdev_rx *rx_)
673
673
{
674
674
    struct ifreq ifr;
675
 
    struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
 
675
    struct netdev_rx_bsd *rx = netdev_rx_bsd_cast(rx_);
676
676
 
677
 
    strcpy(ifr.ifr_name, netdev_get_name(netdev_));
678
 
    if (ioctl(netdev->netdev_fd, BIOCFLUSH, &ifr) == -1) {
 
677
    strcpy(ifr.ifr_name, netdev_get_kernel_name(netdev_rx_get_netdev(rx_)));
 
678
    if (ioctl(rx->fd, BIOCFLUSH, &ifr) == -1) {
679
679
        VLOG_DBG_RL(&rl, "%s: ioctl(BIOCFLUSH) failed: %s",
680
 
                    netdev_get_name(netdev_), strerror(errno));
 
680
                    netdev_rx_get_name(rx_), ovs_strerror(errno));
681
681
        return errno;
682
682
    }
683
683
    return 0;
690
690
static int
691
691
netdev_bsd_send(struct netdev *netdev_, const void *data, size_t size)
692
692
{
693
 
    struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
694
 
    struct netdev_dev_bsd * netdev_dev =
695
 
        netdev_dev_bsd_cast(netdev_get_dev(netdev_));
 
693
    struct netdev_bsd *dev = netdev_bsd_cast(netdev_);
 
694
    const char *name = netdev_get_name(netdev_);
696
695
 
697
 
    if (netdev->netdev_fd < 0) {
698
 
        return EPIPE;
 
696
    if (dev->tap_fd < 0 && !dev->pcap) {
 
697
        int error = netdev_bsd_open_pcap(name, &dev->pcap, &dev->fd);
 
698
        if (error) {
 
699
            return error;
 
700
        }
699
701
    }
700
702
 
701
703
    for (;;) {
702
704
        ssize_t retval;
703
 
        if (!strcmp(netdev_get_type(netdev_), "tap") &&
704
 
                netdev_dev->tap_fd == netdev->netdev_fd) {
705
 
            retval = write(netdev->netdev_fd, data, size);
 
705
        if (dev->tap_fd >= 0) {
 
706
            retval = write(dev->tap_fd, data, size);
706
707
        } else {
707
 
            retval = pcap_inject(netdev->pcap_handle, data, size);
 
708
            retval = pcap_inject(dev->pcap, data, size);
708
709
        }
709
710
        if (retval < 0) {
710
711
            if (errno == EINTR) {
711
712
                continue;
712
713
            } else if (errno != EAGAIN) {
713
714
                VLOG_WARN_RL(&rl, "error sending Ethernet packet on %s: %s",
714
 
                             netdev_get_name(netdev_), strerror(errno));
 
715
                             name, ovs_strerror(errno));
715
716
            }
716
717
            return errno;
717
718
        } else if (retval != size) {
718
719
            VLOG_WARN_RL(&rl, "sent partial Ethernet packet (%zd bytes of "
719
 
                         "%zu) on %s", retval, size,
720
 
                         netdev_get_name(netdev_));
 
720
                         "%zu) on %s", retval, size, name);
721
721
           return EMSGSIZE;
722
722
        } else {
723
723
            return 0;
733
733
static void
734
734
netdev_bsd_send_wait(struct netdev *netdev_)
735
735
{
736
 
    struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
737
 
 
738
 
    if (netdev->netdev_fd < 0) { /* Nothing to do. */
739
 
        return;
740
 
    }
741
 
 
742
 
    if (strcmp(netdev_get_type(netdev_), "tap")) {
743
 
        poll_fd_wait(netdev->netdev_fd, POLLOUT);
744
 
    } else {
 
736
    struct netdev_bsd *dev = netdev_bsd_cast(netdev_);
 
737
 
 
738
    if (dev->tap_fd >= 0) {
745
739
        /* TAP device always accepts packets. */
746
740
        poll_immediate_wake();
 
741
    } else if (dev->pcap) {
 
742
        poll_fd_wait(dev->fd, POLLOUT);
 
743
    } else {
 
744
        /* We haven't even tried to send a packet yet. */
 
745
        poll_immediate_wake();
747
746
    }
748
747
}
749
748
 
753
752
 */
754
753
static int
755
754
netdev_bsd_set_etheraddr(struct netdev *netdev_,
756
 
                           const uint8_t mac[ETH_ADDR_LEN])
 
755
                         const uint8_t mac[ETH_ADDR_LEN])
757
756
{
758
 
    struct netdev_dev_bsd *netdev_dev =
759
 
                                netdev_dev_bsd_cast(netdev_get_dev(netdev_));
 
757
    struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
760
758
    int error;
761
759
 
762
 
    if (!(netdev_dev->cache_valid & VALID_ETHERADDR)
763
 
        || !eth_addr_equals(netdev_dev->etheraddr, mac)) {
764
 
        error = set_etheraddr(netdev_get_name(netdev_), AF_LINK, ETH_ADDR_LEN,
765
 
                              mac);
 
760
    if (!(netdev->cache_valid & VALID_ETHERADDR)
 
761
        || !eth_addr_equals(netdev->etheraddr, mac)) {
 
762
        error = set_etheraddr(netdev_get_kernel_name(netdev_), AF_LINK,
 
763
                              ETH_ADDR_LEN, mac);
766
764
        if (!error) {
767
 
            netdev_dev->cache_valid |= VALID_ETHERADDR;
768
 
            memcpy(netdev_dev->etheraddr, mac, ETH_ADDR_LEN);
769
 
            netdev_dev_bsd_changed(netdev_dev);
 
765
            netdev->cache_valid |= VALID_ETHERADDR;
 
766
            memcpy(netdev->etheraddr, mac, ETH_ADDR_LEN);
 
767
            netdev_bsd_changed(netdev);
770
768
        }
771
769
    } else {
772
770
        error = 0;
780
778
 */
781
779
static int
782
780
netdev_bsd_get_etheraddr(const struct netdev *netdev_,
783
 
                           uint8_t mac[ETH_ADDR_LEN])
 
781
                         uint8_t mac[ETH_ADDR_LEN])
784
782
{
785
 
    struct netdev_dev_bsd *netdev_dev =
786
 
        netdev_dev_bsd_cast(netdev_get_dev(netdev_));
 
783
    struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
787
784
 
788
 
    if (!(netdev_dev->cache_valid & VALID_ETHERADDR)) {
789
 
        int error = get_etheraddr(netdev_get_name(netdev_),
790
 
                                  netdev_dev->etheraddr);
 
785
    if (!(netdev->cache_valid & VALID_ETHERADDR)) {
 
786
        int error = get_etheraddr(netdev_get_kernel_name(netdev_),
 
787
                                  netdev->etheraddr);
791
788
        if (error) {
792
789
            return error;
793
790
        }
794
 
        netdev_dev->cache_valid |= VALID_ETHERADDR;
 
791
        netdev->cache_valid |= VALID_ETHERADDR;
795
792
    }
796
 
    memcpy(mac, netdev_dev->etheraddr, ETH_ADDR_LEN);
 
793
    memcpy(mac, netdev->etheraddr, ETH_ADDR_LEN);
797
794
 
798
795
    return 0;
799
796
}
806
803
static int
807
804
netdev_bsd_get_mtu(const struct netdev *netdev_, int *mtup)
808
805
{
809
 
    struct netdev_dev_bsd *netdev_dev =
810
 
        netdev_dev_bsd_cast(netdev_get_dev(netdev_));
 
806
    struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
811
807
 
812
 
    if (!(netdev_dev->cache_valid & VALID_MTU)) {
 
808
    if (!(netdev->cache_valid & VALID_MTU)) {
813
809
        struct ifreq ifr;
814
810
        int error;
815
811
 
816
 
        error = netdev_bsd_do_ioctl(netdev_, &ifr, SIOCGIFMTU, "SIOCGIFMTU");
 
812
        error = netdev_bsd_do_ioctl(netdev_get_kernel_name(netdev_), &ifr,
 
813
                                    SIOCGIFMTU, "SIOCGIFMTU");
817
814
        if (error) {
818
815
            return error;
819
816
        }
820
 
        netdev_dev->mtu = ifr.ifr_mtu;
821
 
        netdev_dev->cache_valid |= VALID_MTU;
 
817
        netdev->mtu = ifr.ifr_mtu;
 
818
        netdev->cache_valid |= VALID_MTU;
822
819
    }
823
820
 
824
 
    *mtup = netdev_dev->mtu;
 
821
    *mtup = netdev->mtu;
825
822
    return 0;
826
823
}
827
824
 
837
834
static int
838
835
netdev_bsd_get_carrier(const struct netdev *netdev_, bool *carrier)
839
836
{
840
 
    struct netdev_dev_bsd *netdev_dev =
841
 
        netdev_dev_bsd_cast(netdev_get_dev(netdev_));
 
837
    struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
842
838
 
843
 
    if (!(netdev_dev->cache_valid & VALID_CARRIER)) {
 
839
    if (!(netdev->cache_valid & VALID_CARRIER)) {
844
840
        struct ifmediareq ifmr;
845
841
 
846
842
        memset(&ifmr, 0, sizeof(ifmr));
847
 
        strncpy(ifmr.ifm_name, netdev_get_name(netdev_), sizeof ifmr.ifm_name);
 
843
        strncpy(ifmr.ifm_name, netdev_get_kernel_name(netdev_),
 
844
                sizeof ifmr.ifm_name);
848
845
 
849
846
        if (ioctl(af_inet_sock, SIOCGIFMEDIA, &ifmr) == -1) {
850
847
            VLOG_DBG_RL(&rl, "%s: ioctl(SIOCGIFMEDIA) failed: %s",
851
 
                        netdev_get_name(netdev_), strerror(errno));
 
848
                        netdev_get_name(netdev_), ovs_strerror(errno));
852
849
            return errno;
853
850
        }
854
851
 
855
 
        netdev_dev->carrier = (ifmr.ifm_status & IFM_ACTIVE) == IFM_ACTIVE;
856
 
        netdev_dev->cache_valid |= VALID_CARRIER;
 
852
        netdev->carrier = (ifmr.ifm_status & IFM_ACTIVE) == IFM_ACTIVE;
 
853
        netdev->cache_valid |= VALID_CARRIER;
857
854
 
858
855
        /* If the interface doesn't report whether the media is active,
859
856
         * just assume it is active. */
860
857
        if ((ifmr.ifm_status & IFM_AVALID) == 0) {
861
 
            netdev_dev->carrier = true;
 
858
            netdev->carrier = true;
862
859
        }
863
860
    }
864
 
    *carrier = netdev_dev->carrier;
 
861
    *carrier = netdev->carrier;
865
862
 
866
863
    return 0;
867
864
}
868
865
 
 
866
static void
 
867
convert_stats(struct netdev_stats *stats, const struct if_data *ifd)
 
868
{
 
869
    /*
 
870
     * note: UINT64_MAX means unsupported
 
871
     */
 
872
    stats->rx_packets = ifd->ifi_ipackets;
 
873
    stats->tx_packets = ifd->ifi_opackets;
 
874
    stats->rx_bytes = ifd->ifi_obytes;
 
875
    stats->tx_bytes = ifd->ifi_ibytes;
 
876
    stats->rx_errors = ifd->ifi_ierrors;
 
877
    stats->tx_errors = ifd->ifi_oerrors;
 
878
    stats->rx_dropped = ifd->ifi_iqdrops;
 
879
    stats->tx_dropped = UINT64_MAX;
 
880
    stats->multicast = ifd->ifi_imcasts;
 
881
    stats->collisions = ifd->ifi_collisions;
 
882
    stats->rx_length_errors = UINT64_MAX;
 
883
    stats->rx_over_errors = UINT64_MAX;
 
884
    stats->rx_crc_errors = UINT64_MAX;
 
885
    stats->rx_frame_errors = UINT64_MAX;
 
886
    stats->rx_fifo_errors = UINT64_MAX;
 
887
    stats->rx_missed_errors = UINT64_MAX;
 
888
    stats->tx_aborted_errors = UINT64_MAX;
 
889
    stats->tx_carrier_errors = UINT64_MAX;
 
890
    stats->tx_fifo_errors = UINT64_MAX;
 
891
    stats->tx_heartbeat_errors = UINT64_MAX;
 
892
    stats->tx_window_errors = UINT64_MAX;
 
893
}
 
894
 
869
895
/* Retrieves current device stats for 'netdev'. */
870
896
static int
871
897
netdev_bsd_get_stats(const struct netdev *netdev_, struct netdev_stats *stats)
872
898
{
 
899
#if defined(__FreeBSD__)
873
900
    int if_count, i;
874
901
    int mib[6];
875
902
    size_t len;
886
913
 
887
914
    if (sysctl(mib, 5, &if_count, &len, (void *)0, 0) == -1) {
888
915
        VLOG_DBG_RL(&rl, "%s: sysctl failed: %s",
889
 
                    netdev_get_name(netdev_), strerror(errno));
 
916
                    netdev_get_name(netdev_), ovs_strerror(errno));
890
917
        return errno;
891
918
    }
892
919
 
897
924
        mib[4] = i; //row
898
925
        if (sysctl(mib, 6, &ifmd, &len, (void *)0, 0) == -1) {
899
926
            VLOG_DBG_RL(&rl, "%s: sysctl failed: %s",
900
 
                        netdev_get_name(netdev_), strerror(errno));
 
927
                        netdev_get_name(netdev_), ovs_strerror(errno));
901
928
            return errno;
902
929
        } else if (!strcmp(ifmd.ifmd_name, netdev_get_name(netdev_))) {
903
 
            stats->rx_packets = ifmd.ifmd_data.ifi_ipackets;
904
 
            stats->tx_packets = ifmd.ifmd_data.ifi_opackets;
905
 
            stats->rx_bytes = ifmd.ifmd_data.ifi_ibytes;
906
 
            stats->tx_bytes = ifmd.ifmd_data.ifi_obytes;
907
 
            stats->rx_errors = ifmd.ifmd_data.ifi_ierrors;
908
 
            stats->tx_errors = ifmd.ifmd_data.ifi_oerrors;
909
 
            stats->rx_dropped = ifmd.ifmd_data.ifi_iqdrops;
910
 
            stats->tx_dropped = UINT64_MAX;
911
 
            stats->multicast = ifmd.ifmd_data.ifi_imcasts;
912
 
            stats->collisions = ifmd.ifmd_data.ifi_collisions;
913
 
 
914
 
            stats->rx_length_errors = UINT64_MAX;
915
 
            stats->rx_over_errors = UINT64_MAX;
916
 
            stats->rx_crc_errors = UINT64_MAX;
917
 
            stats->rx_frame_errors = UINT64_MAX;
918
 
            stats->rx_fifo_errors = UINT64_MAX;
919
 
            stats->rx_missed_errors = UINT64_MAX;
920
 
 
921
 
            stats->tx_aborted_errors = UINT64_MAX;
922
 
            stats->tx_carrier_errors = UINT64_MAX;
923
 
            stats->tx_fifo_errors = UINT64_MAX;
924
 
            stats->tx_heartbeat_errors = UINT64_MAX;
925
 
            stats->tx_window_errors = UINT64_MAX;
 
930
            convert_stats(stats, &ifmd.ifmd_data);
926
931
            break;
927
932
        }
928
933
    }
929
934
 
930
935
    return 0;
 
936
#elif defined(__NetBSD__)
 
937
    struct ifdatareq ifdr;
 
938
    int saved_errno;
 
939
    int ret;
 
940
 
 
941
    memset(&ifdr, 0, sizeof(ifdr));
 
942
    strncpy(ifdr.ifdr_name, netdev_get_kernel_name(netdev_),
 
943
            sizeof(ifdr.ifdr_name));
 
944
    ret = ioctl(af_link_sock, SIOCGIFDATA, &ifdr);
 
945
    saved_errno = errno;
 
946
    if (ret == -1) {
 
947
        return saved_errno;
 
948
    }
 
949
    convert_stats(stats, &ifdr.ifdr_data);
 
950
    return 0;
 
951
#else
 
952
#error not implemented
 
953
#endif
931
954
}
932
955
 
933
956
static uint32_t
1011
1034
 */
1012
1035
static int
1013
1036
netdev_bsd_get_features(const struct netdev *netdev,
1014
 
                          enum netdev_features *current, uint32_t *advertised,
1015
 
                          enum netdev_features *supported, uint32_t *peer)
 
1037
                        enum netdev_features *current, uint32_t *advertised,
 
1038
                        enum netdev_features *supported, uint32_t *peer)
1016
1039
{
1017
1040
    struct ifmediareq ifmr;
1018
1041
    int *media_list;
1030
1053
     * them. */
1031
1054
    if (ioctl(af_inet_sock, SIOCGIFMEDIA, &ifmr) == -1) {
1032
1055
        VLOG_DBG_RL(&rl, "%s: ioctl(SIOCGIFMEDIA) failed: %s",
1033
 
                    netdev_get_name(netdev), strerror(errno));
 
1056
                    netdev_get_name(netdev), ovs_strerror(errno));
1034
1057
        return errno;
1035
1058
    }
1036
1059
 
1037
1060
    media_list = xcalloc(ifmr.ifm_count, sizeof(int));
1038
1061
    ifmr.ifm_ulist = media_list;
1039
1062
 
1040
 
    if (!IFM_TYPE(ifmr.ifm_current) & IFM_ETHER) {
 
1063
    if (IFM_TYPE(ifmr.ifm_current) != IFM_ETHER) {
1041
1064
        VLOG_DBG_RL(&rl, "%s: doesn't appear to be ethernet",
1042
1065
                    netdev_get_name(netdev));
1043
1066
        error = EINVAL;
1046
1069
 
1047
1070
    if (ioctl(af_inet_sock, SIOCGIFMEDIA, &ifmr) == -1) {
1048
1071
        VLOG_DBG_RL(&rl, "%s: ioctl(SIOCGIFMEDIA) failed: %s",
1049
 
                    netdev_get_name(netdev), strerror(errno));
 
1072
                    netdev_get_name(netdev), ovs_strerror(errno));
1050
1073
        error = errno;
1051
1074
        goto cleanup;
1052
1075
    }
1080
1103
netdev_bsd_get_in4(const struct netdev *netdev_, struct in_addr *in4,
1081
1104
                   struct in_addr *netmask)
1082
1105
{
1083
 
    struct netdev_dev_bsd *netdev_dev =
1084
 
        netdev_dev_bsd_cast(netdev_get_dev(netdev_));
 
1106
    struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
1085
1107
 
1086
 
    if (!(netdev_dev->cache_valid & VALID_IN4)) {
 
1108
    if (!(netdev->cache_valid & VALID_IN4)) {
1087
1109
        const struct sockaddr_in *sin;
1088
1110
        struct ifreq ifr;
1089
1111
        int error;
1090
1112
 
1091
1113
        ifr.ifr_addr.sa_family = AF_INET;
1092
 
        error = netdev_bsd_do_ioctl(netdev_, &ifr,
1093
 
                                      SIOCGIFADDR, "SIOCGIFADDR");
 
1114
        error = netdev_bsd_do_ioctl(netdev_get_kernel_name(netdev_), &ifr,
 
1115
                                    SIOCGIFADDR, "SIOCGIFADDR");
1094
1116
        if (error) {
1095
1117
            return error;
1096
1118
        }
1097
1119
 
1098
1120
        sin = (struct sockaddr_in *) &ifr.ifr_addr;
1099
 
        netdev_dev->in4 = sin->sin_addr;
1100
 
        netdev_dev->cache_valid |= VALID_IN4;
1101
 
        error = netdev_bsd_do_ioctl(netdev_, &ifr,
1102
 
                                      SIOCGIFNETMASK, "SIOCGIFNETMASK");
 
1121
        netdev->in4 = sin->sin_addr;
 
1122
        netdev->cache_valid |= VALID_IN4;
 
1123
        error = netdev_bsd_do_ioctl(netdev_get_kernel_name(netdev_), &ifr,
 
1124
                                    SIOCGIFNETMASK, "SIOCGIFNETMASK");
1103
1125
        if (error) {
1104
1126
            return error;
1105
1127
        }
1106
1128
        *netmask = ((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr;
1107
1129
    }
1108
 
    *in4 = netdev_dev->in4;
 
1130
    *in4 = netdev->in4;
1109
1131
 
1110
1132
    return in4->s_addr == INADDR_ANY ? EADDRNOTAVAIL : 0;
1111
1133
}
1117
1139
 */
1118
1140
static int
1119
1141
netdev_bsd_set_in4(struct netdev *netdev_, struct in_addr addr,
1120
 
                     struct in_addr mask)
 
1142
                   struct in_addr mask)
1121
1143
{
1122
 
    struct netdev_dev_bsd *netdev_dev =
1123
 
        netdev_dev_bsd_cast(netdev_get_dev(netdev_));
 
1144
    struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
1124
1145
    int error;
1125
1146
 
1126
1147
    error = do_set_addr(netdev_, SIOCSIFADDR, "SIOCSIFADDR", addr);
1127
1148
    if (!error) {
1128
 
        netdev_dev->cache_valid |= VALID_IN4;
1129
 
        netdev_dev->in4 = addr;
 
1149
        netdev->cache_valid |= VALID_IN4;
 
1150
        netdev->in4 = addr;
1130
1151
        if (addr.s_addr != INADDR_ANY) {
1131
1152
            error = do_set_addr(netdev_, SIOCSIFNETMASK,
1132
1153
                                "SIOCSIFNETMASK", mask);
1133
1154
        }
1134
 
        netdev_dev_bsd_changed(netdev_dev);
 
1155
        netdev_bsd_changed(netdev);
1135
1156
    }
1136
1157
    return error;
1137
1158
}
1139
1160
static int
1140
1161
netdev_bsd_get_in6(const struct netdev *netdev_, struct in6_addr *in6)
1141
1162
{
1142
 
    struct netdev_dev_bsd *netdev_dev =
1143
 
                                netdev_dev_bsd_cast(netdev_get_dev(netdev_));
1144
 
    if (!(netdev_dev->cache_valid & VALID_IN6)) {
 
1163
    struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
 
1164
    if (!(netdev->cache_valid & VALID_IN6)) {
1145
1165
        struct ifaddrs *ifa, *head;
1146
1166
        struct sockaddr_in6 *sin6;
1147
1167
        const char *netdev_name = netdev_get_name(netdev_);
1148
1168
 
1149
1169
        if (getifaddrs(&head) != 0) {
1150
1170
            VLOG_ERR("getifaddrs on %s device failed: %s", netdev_name,
1151
 
                    strerror(errno));
 
1171
                    ovs_strerror(errno));
1152
1172
            return errno;
1153
1173
        }
1154
1174
 
1157
1177
                    !strcmp(ifa->ifa_name, netdev_name)) {
1158
1178
                sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
1159
1179
                if (sin6) {
1160
 
                    memcpy(&netdev_dev->in6, &sin6->sin6_addr, sin6->sin6_len);
1161
 
                    netdev_dev->cache_valid |= VALID_IN6;
1162
 
                    *in6 = netdev_dev->in6;
 
1180
                    memcpy(&netdev->in6, &sin6->sin6_addr, sin6->sin6_len);
 
1181
                    netdev->cache_valid |= VALID_IN6;
 
1182
                    *in6 = netdev->in6;
1163
1183
                    freeifaddrs(head);
1164
1184
                    return 0;
1165
1185
                }
1167
1187
        }
1168
1188
        return EADDRNOTAVAIL;
1169
1189
    }
1170
 
    *in6 = netdev_dev->in6;
1171
 
    return 0;
 
1190
    *in6 = netdev->in6;
 
1191
    return 0;
 
1192
}
 
1193
 
 
1194
#if defined(__NetBSD__)
 
1195
static struct netdev *
 
1196
find_netdev_by_kernel_name(const char *kernel_name)
 
1197
{
 
1198
    struct shash device_shash;
 
1199
    struct shash_node *node;
 
1200
 
 
1201
    shash_init(&device_shash);
 
1202
    netdev_get_devices(&netdev_tap_class, &device_shash);
 
1203
    SHASH_FOR_EACH(node, &device_shash) {
 
1204
        struct netdev_bsd * const dev = node->data;
 
1205
 
 
1206
        if (!strcmp(dev->kernel_name, kernel_name)) {
 
1207
            shash_destroy(&device_shash);
 
1208
            return &dev->up;
 
1209
        }
 
1210
    }
 
1211
    shash_destroy(&device_shash);
 
1212
    return NULL;
 
1213
}
 
1214
 
 
1215
static const char *
 
1216
netdev_bsd_convert_kernel_name_to_ovs_name(const char *kernel_name)
 
1217
{
 
1218
    const struct netdev * const netdev =
 
1219
      find_netdev_by_kernel_name(kernel_name);
 
1220
 
 
1221
    if (netdev == NULL) {
 
1222
        return NULL;
 
1223
    }
 
1224
    return netdev_get_name(netdev);
 
1225
}
 
1226
#endif
 
1227
 
 
1228
static int
 
1229
netdev_bsd_get_next_hop(const struct in_addr *host OVS_UNUSED,
 
1230
                        struct in_addr *next_hop OVS_UNUSED,
 
1231
                        char **netdev_name OVS_UNUSED)
 
1232
{
 
1233
#if defined(__NetBSD__)
 
1234
    static int seq = 0;
 
1235
    struct sockaddr_in sin;
 
1236
    struct sockaddr_dl sdl;
 
1237
    int s;
 
1238
    int i;
 
1239
    struct {
 
1240
        struct rt_msghdr h;
 
1241
        char space[512];
 
1242
    } buf;
 
1243
    struct rt_msghdr *rtm = &buf.h;
 
1244
    const pid_t pid = getpid();
 
1245
    char *cp;
 
1246
    ssize_t ssz;
 
1247
    bool gateway = false;
 
1248
    char *ifname = NULL;
 
1249
    int saved_errno;
 
1250
 
 
1251
    memset(next_hop, 0, sizeof(*next_hop));
 
1252
    *netdev_name = NULL;
 
1253
 
 
1254
    memset(&sin, 0, sizeof(sin));
 
1255
    sin.sin_len = sizeof(sin);
 
1256
    sin.sin_family = AF_INET;
 
1257
    sin.sin_port = 0;
 
1258
    sin.sin_addr = *host;
 
1259
 
 
1260
    memset(&sdl, 0, sizeof(sdl));
 
1261
    sdl.sdl_len = sizeof(sdl);
 
1262
    sdl.sdl_family = AF_LINK;
 
1263
 
 
1264
    s = socket(PF_ROUTE, SOCK_RAW, 0);
 
1265
    memset(&buf, 0, sizeof(buf));
 
1266
    rtm->rtm_flags = RTF_HOST|RTF_UP;
 
1267
    rtm->rtm_version = RTM_VERSION;
 
1268
    rtm->rtm_addrs = RTA_DST|RTA_IFP;
 
1269
    cp = (void *)&buf.space;
 
1270
    memcpy(cp, &sin, sizeof(sin));
 
1271
    RT_ADVANCE(cp, (struct sockaddr *)(void *)&sin);
 
1272
    memcpy(cp, &sdl, sizeof(sdl));
 
1273
    RT_ADVANCE(cp, (struct sockaddr *)(void *)&sdl);
 
1274
    rtm->rtm_msglen = cp - (char *)(void *)rtm;
 
1275
    rtm->rtm_seq = ++seq;
 
1276
    rtm->rtm_type = RTM_GET;
 
1277
    rtm->rtm_pid = pid;
 
1278
    write(s, rtm, rtm->rtm_msglen);
 
1279
    memset(&buf, 0, sizeof(buf));
 
1280
    do {
 
1281
        ssz = read(s, &buf, sizeof(buf));
 
1282
    } while (ssz > 0 && (rtm->rtm_seq != seq || rtm->rtm_pid != pid));
 
1283
    saved_errno = errno;
 
1284
    close(s);
 
1285
    if (ssz <= 0) {
 
1286
        if (ssz < 0) {
 
1287
            return saved_errno;
 
1288
        }
 
1289
        return EPIPE; /* XXX */
 
1290
    }
 
1291
    cp = (void *)&buf.space;
 
1292
    for (i = 1; i; i <<= 1) {
 
1293
        if ((rtm->rtm_addrs & i) != 0) {
 
1294
            const struct sockaddr *sa = (const void *)cp;
 
1295
 
 
1296
            if ((i == RTA_GATEWAY) && sa->sa_family == AF_INET) {
 
1297
                const struct sockaddr_in * const sin =
 
1298
                  (const struct sockaddr_in *)sa;
 
1299
 
 
1300
                *next_hop = sin->sin_addr;
 
1301
                gateway = true;
 
1302
            }
 
1303
            if ((i == RTA_IFP) && sa->sa_family == AF_LINK) {
 
1304
                const struct sockaddr_dl * const sdl =
 
1305
                  (const struct sockaddr_dl *)sa;
 
1306
                const size_t nlen = sdl->sdl_nlen;
 
1307
                char * const kernel_name = xmalloc(nlen + 1);
 
1308
                const char *name;
 
1309
 
 
1310
                memcpy(kernel_name, sdl->sdl_data, nlen);
 
1311
                kernel_name[nlen] = 0;
 
1312
                name = netdev_bsd_convert_kernel_name_to_ovs_name(kernel_name);
 
1313
                if (name == NULL) {
 
1314
                    ifname = xstrdup(kernel_name);
 
1315
                } else {
 
1316
                    ifname = xstrdup(name);
 
1317
                }
 
1318
                free(kernel_name);
 
1319
            }
 
1320
            RT_ADVANCE(cp, sa);
 
1321
        }
 
1322
    }
 
1323
    if (ifname == NULL) {
 
1324
        return ENXIO;
 
1325
    }
 
1326
    if (!gateway) {
 
1327
        *next_hop = *host;
 
1328
    }
 
1329
    *netdev_name = ifname;
 
1330
    VLOG_DBG("host " IP_FMT " next-hop " IP_FMT " if %s",
 
1331
      IP_ARGS(host->s_addr), IP_ARGS(next_hop->s_addr), *netdev_name);
 
1332
    return 0;
 
1333
#else
 
1334
    return EOPNOTSUPP;
 
1335
#endif
1172
1336
}
1173
1337
 
1174
1338
static void
1190
1354
{
1191
1355
    struct ifreq ifr;
1192
1356
    make_in4_sockaddr(&ifr.ifr_addr, addr);
1193
 
    return netdev_bsd_do_ioctl(netdev, &ifr, ioctl_nr, ioctl_name);
 
1357
    return netdev_bsd_do_ioctl(netdev_get_kernel_name(netdev), &ifr, ioctl_nr,
 
1358
                               ioctl_name);
1194
1359
}
1195
1360
 
1196
1361
static int
1202
1367
    }
1203
1368
    if (nd & NETDEV_PROMISC) {
1204
1369
        iff |= IFF_PROMISC;
 
1370
#if defined(IFF_PPROMISC)
1205
1371
        iff |= IFF_PPROMISC;
 
1372
#endif
1206
1373
    }
1207
1374
    return iff;
1208
1375
}
1221
1388
}
1222
1389
 
1223
1390
static int
1224
 
netdev_bsd_update_flags(struct netdev *netdev, enum netdev_flags off,
1225
 
                          enum netdev_flags on, enum netdev_flags *old_flagsp)
 
1391
netdev_bsd_update_flags(struct netdev *netdev_, enum netdev_flags off,
 
1392
                        enum netdev_flags on, enum netdev_flags *old_flagsp)
1226
1393
{
 
1394
    struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
1227
1395
    int old_flags, new_flags;
1228
1396
    int error;
1229
1397
 
1230
 
    error = get_flags(netdev, &old_flags);
 
1398
    error = get_flags(netdev_, &old_flags);
1231
1399
    if (!error) {
1232
1400
        *old_flagsp = iff_to_nd_flags(old_flags);
1233
1401
        new_flags = (old_flags & ~nd_to_iff_flags(off)) | nd_to_iff_flags(on);
1234
1402
        if (new_flags != old_flags) {
1235
 
            error = set_flags(netdev, new_flags);
1236
 
            netdev_dev_bsd_changed(netdev_dev_bsd_cast(netdev_get_dev(netdev)));
 
1403
            error = set_flags(netdev_get_kernel_name(netdev_), new_flags);
 
1404
            netdev_bsd_changed(netdev);
1237
1405
        }
1238
1406
    }
1239
1407
    return error;
1242
1410
static unsigned int
1243
1411
netdev_bsd_change_seq(const struct netdev *netdev)
1244
1412
{
1245
 
    return netdev_dev_bsd_cast(netdev_get_dev(netdev))->change_seq;
 
1413
    return netdev_bsd_cast(netdev)->change_seq;
1246
1414
}
1247
1415
 
1248
1416
 
1257
1425
    NULL, /* get_config */
1258
1426
    NULL, /* set_config */
1259
1427
    NULL, /* get_tunnel_config */
1260
 
    netdev_bsd_open_system,
1261
 
    netdev_bsd_close,
1262
 
 
1263
 
    netdev_bsd_listen,
1264
 
 
1265
 
    netdev_bsd_recv,
1266
 
    netdev_bsd_recv_wait,
1267
 
    netdev_bsd_drain,
 
1428
 
 
1429
    netdev_bsd_rx_open,
1268
1430
 
1269
1431
    netdev_bsd_send,
1270
1432
    netdev_bsd_send_wait,
1298
1460
    netdev_bsd_set_in4,
1299
1461
    netdev_bsd_get_in6,
1300
1462
    NULL, /* add_router */
1301
 
    NULL, /* get_next_hop */
 
1463
    netdev_bsd_get_next_hop,
1302
1464
    NULL, /* get_status */
1303
1465
    NULL, /* arp_lookup */
1304
1466
 
1318
1480
    NULL, /* get_config */
1319
1481
    NULL, /* set_config */
1320
1482
    NULL, /* get_tunnel_config */
1321
 
    netdev_bsd_open_system,
1322
 
    netdev_bsd_close,
1323
 
 
1324
 
    netdev_bsd_listen,
1325
 
 
1326
 
    netdev_bsd_recv,
1327
 
    netdev_bsd_recv_wait,
1328
 
    netdev_bsd_drain,
 
1483
 
 
1484
    netdev_bsd_rx_open,
1329
1485
 
1330
1486
    netdev_bsd_send,
1331
1487
    netdev_bsd_send_wait,
1359
1515
    netdev_bsd_set_in4,
1360
1516
    netdev_bsd_get_in6,
1361
1517
    NULL, /* add_router */
1362
 
    NULL, /* get_next_hop */
 
1518
    netdev_bsd_get_next_hop,
1363
1519
    NULL, /* get_status */
1364
1520
    NULL, /* arp_lookup */
1365
1521
 
1367
1523
 
1368
1524
    netdev_bsd_change_seq
1369
1525
};
 
1526
 
 
1527
static const struct netdev_rx_class netdev_rx_bsd_class = {
 
1528
    netdev_rx_bsd_destroy,
 
1529
    netdev_rx_bsd_recv,
 
1530
    netdev_rx_bsd_wait,
 
1531
    netdev_rx_bsd_drain,
 
1532
};
1370
1533
 
1371
1534
 
1372
1535
static void
1386
1549
    struct ifreq ifr;
1387
1550
    int error;
1388
1551
 
1389
 
    error = netdev_bsd_do_ioctl(netdev, &ifr, SIOCGIFFLAGS, "SIOCGIFFLAGS");
 
1552
    error = netdev_bsd_do_ioctl(netdev_get_kernel_name(netdev), &ifr,
 
1553
                                SIOCGIFFLAGS, "SIOCGIFFLAGS");
1390
1554
 
1391
 
    *flags = 0xFFFF0000 & (ifr.ifr_flagshigh << 16);
1392
 
    *flags |= 0x0000FFFF & ifr.ifr_flags;
 
1555
    *flags = ifr_get_flags(&ifr);
1393
1556
 
1394
1557
    return error;
1395
1558
}
1396
1559
 
1397
1560
static int
1398
 
set_flags(struct netdev *netdev, int flags)
 
1561
set_flags(const char *name, int flags)
1399
1562
{
1400
1563
    struct ifreq ifr;
1401
1564
 
1402
 
    ifr.ifr_flags = 0x0000FFFF & flags;
1403
 
    ifr.ifr_flagshigh = (0xFFFF0000 & flags) >> 16;
 
1565
    ifr_set_flags(&ifr, flags);
1404
1566
 
1405
 
    return netdev_bsd_do_ioctl(netdev, &ifr, SIOCSIFFLAGS, "SIOCSIFFLAGS");
 
1567
    return netdev_bsd_do_ioctl(name, &ifr, SIOCSIFFLAGS, "SIOCSIFFLAGS");
1406
1568
}
1407
1569
 
1408
1570
static int
1409
1571
get_ifindex(const struct netdev *netdev_, int *ifindexp)
1410
1572
{
1411
 
    struct netdev_dev_bsd *netdev_dev =
1412
 
                                netdev_dev_bsd_cast(netdev_get_dev(netdev_));
 
1573
    struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
1413
1574
    *ifindexp = 0;
1414
 
    if (!(netdev_dev->cache_valid & VALID_IFINDEX)) {
 
1575
    if (!(netdev->cache_valid & VALID_IFINDEX)) {
1415
1576
        int ifindex = if_nametoindex(netdev_get_name(netdev_));
1416
1577
        if (ifindex <= 0) {
1417
1578
            return errno;
1418
1579
        }
1419
 
        netdev_dev->cache_valid |= VALID_IFINDEX;
1420
 
        netdev_dev->ifindex = ifindex;
 
1580
        netdev->cache_valid |= VALID_IFINDEX;
 
1581
        netdev->ifindex = ifindex;
1421
1582
    }
1422
 
    *ifindexp = netdev_dev->ifindex;
 
1583
    *ifindexp = netdev->ifindex;
1423
1584
    return 0;
1424
1585
}
1425
1586
 
1432
1593
 
1433
1594
    if (getifaddrs(&head) != 0) {
1434
1595
        VLOG_ERR("getifaddrs on %s device failed: %s", netdev_name,
1435
 
                strerror(errno));
 
1596
                ovs_strerror(errno));
1436
1597
        return errno;
1437
1598
    }
1438
1599
 
1455
1616
}
1456
1617
 
1457
1618
static int
1458
 
set_etheraddr(const char *netdev_name, int hwaddr_family,
1459
 
              int hwaddr_len, const uint8_t mac[ETH_ADDR_LEN])
 
1619
set_etheraddr(const char *netdev_name OVS_UNUSED, int hwaddr_family OVS_UNUSED,
 
1620
              int hwaddr_len OVS_UNUSED,
 
1621
              const uint8_t mac[ETH_ADDR_LEN] OVS_UNUSED)
1460
1622
{
 
1623
#if defined(__FreeBSD__)
1461
1624
    struct ifreq ifr;
1462
1625
 
1463
1626
    memset(&ifr, 0, sizeof ifr);
1467
1630
    memcpy(ifr.ifr_addr.sa_data, mac, hwaddr_len);
1468
1631
    if (ioctl(af_inet_sock, SIOCSIFLLADDR, &ifr) < 0) {
1469
1632
        VLOG_ERR("ioctl(SIOCSIFLLADDR) on %s device failed: %s",
1470
 
                 netdev_name, strerror(errno));
1471
 
        return errno;
1472
 
    }
1473
 
    return 0;
 
1633
                 netdev_name, ovs_strerror(errno));
 
1634
        return errno;
 
1635
    }
 
1636
    return 0;
 
1637
#elif defined(__NetBSD__)
 
1638
    struct if_laddrreq req;
 
1639
    struct sockaddr_dl *sdl;
 
1640
    struct sockaddr_storage oldaddr;
 
1641
    int ret;
 
1642
 
 
1643
    /*
 
1644
     * get the old address, add new one, and then remove old one.
 
1645
     */
 
1646
 
 
1647
    if (hwaddr_len != ETH_ADDR_LEN) {
 
1648
        /* just to be safe about sockaddr storage size */
 
1649
        return EOPNOTSUPP;
 
1650
    }
 
1651
    memset(&req, 0, sizeof(req));
 
1652
    strncpy(req.iflr_name, netdev_name, sizeof(req.iflr_name));
 
1653
    req.addr.ss_len = sizeof(req.addr);
 
1654
    req.addr.ss_family = hwaddr_family;
 
1655
    sdl = (struct sockaddr_dl *)&req.addr;
 
1656
    sdl->sdl_alen = hwaddr_len;
 
1657
    ret = ioctl(af_link_sock, SIOCGLIFADDR, &req);
 
1658
    if (ret == -1) {
 
1659
        return errno;
 
1660
    }
 
1661
    if (!memcmp(&sdl->sdl_data[sdl->sdl_nlen], mac, hwaddr_len)) {
 
1662
        return 0;
 
1663
    }
 
1664
    oldaddr = req.addr;
 
1665
 
 
1666
    memset(&req, 0, sizeof(req));
 
1667
    strncpy(req.iflr_name, netdev_name, sizeof(req.iflr_name));
 
1668
    req.flags = IFLR_ACTIVE;
 
1669
    sdl = (struct sockaddr_dl *)&req.addr;
 
1670
    sdl->sdl_len = offsetof(struct sockaddr_dl, sdl_data) + hwaddr_len;
 
1671
    sdl->sdl_alen = hwaddr_len;
 
1672
    sdl->sdl_family = hwaddr_family;
 
1673
    memcpy(sdl->sdl_data, mac, hwaddr_len);
 
1674
    ret = ioctl(af_link_sock, SIOCALIFADDR, &req);
 
1675
    if (ret == -1) {
 
1676
        return errno;
 
1677
    }
 
1678
 
 
1679
    memset(&req, 0, sizeof(req));
 
1680
    strncpy(req.iflr_name, netdev_name, sizeof(req.iflr_name));
 
1681
    req.addr = oldaddr;
 
1682
    ret = ioctl(af_link_sock, SIOCDLIFADDR, &req);
 
1683
    if (ret == -1) {
 
1684
        return errno;
 
1685
    }
 
1686
    return 0;
 
1687
#else
 
1688
#error not implemented
 
1689
#endif
1474
1690
}
1475
1691
 
1476
1692
static int
1477
 
netdev_bsd_do_ioctl(const struct netdev *netdev, struct ifreq *ifr,
1478
 
                    unsigned long cmd, const char *cmd_name)
 
1693
netdev_bsd_do_ioctl(const char *name, struct ifreq *ifr, unsigned long cmd,
 
1694
                    const char *cmd_name)
1479
1695
{
1480
 
    strncpy(ifr->ifr_name, netdev_get_name(netdev), sizeof ifr->ifr_name);
 
1696
    strncpy(ifr->ifr_name, name, sizeof ifr->ifr_name);
1481
1697
    if (ioctl(af_inet_sock, cmd, ifr) == -1) {
1482
 
        VLOG_DBG_RL(&rl, "%s: ioctl(%s) failed: %s",
1483
 
                    netdev_get_name(netdev), cmd_name, strerror(errno));
 
1698
        VLOG_DBG_RL(&rl, "%s: ioctl(%s) failed: %s", name, cmd_name,
 
1699
                    ovs_strerror(errno));
1484
1700
        return errno;
1485
1701
    }
1486
1702
    return 0;
1487
1703
}
 
1704
 
 
1705
static int
 
1706
ifr_get_flags(const struct ifreq *ifr)
 
1707
{
 
1708
#ifdef HAVE_STRUCT_IFREQ_IFR_FLAGSHIGH
 
1709
    return (ifr->ifr_flagshigh << 16) | ifr->ifr_flags;
 
1710
#else
 
1711
    return ifr->ifr_flags;
 
1712
#endif
 
1713
}
 
1714
 
 
1715
static void
 
1716
ifr_set_flags(struct ifreq *ifr, int flags)
 
1717
{
 
1718
    ifr->ifr_flags = flags;
 
1719
#ifdef HAVE_STRUCT_IFREQ_IFR_FLAGSHIGH
 
1720
    ifr->ifr_flagshigh = flags >> 16;
 
1721
#endif
 
1722
}