eb45563864145dc6d168f8b59057bd0464c21e78
[sliver-openvswitch.git] / lib / netdev-bsd.c
1 /*
2  * Copyright (c) 2011 Gaetano Catalli.
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-provider.h"
20 #include <stdlib.h>
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <sys/types.h>
24 #include <sys/time.h>
25 #include <sys/ioctl.h>
26 #include <sys/socket.h>
27 #include <sys/sockio.h>
28 #include <ifaddrs.h>
29 #include <pcap/pcap.h>
30 #include <net/if.h>
31 #include <net/if_dl.h>
32 #include <net/if_media.h>
33 #include <net/if_tap.h>
34 #include <netinet/in.h>
35 #ifdef HAVE_NET_IF_MIB_H
36 #include <net/if_mib.h>
37 #endif
38 #include <poll.h>
39 #include <string.h>
40 #include <unistd.h>
41 #include <sys/sysctl.h>
42
43 #include "rtbsd.h"
44 #include "coverage.h"
45 #include "dynamic-string.h"
46 #include "fatal-signal.h"
47 #include "ofpbuf.h"
48 #include "openflow/openflow.h"
49 #include "packets.h"
50 #include "poll-loop.h"
51 #include "socket-util.h"
52 #include "shash.h"
53 #include "svec.h"
54 #include "util.h"
55 #include "vlog.h"
56
57 VLOG_DEFINE_THIS_MODULE(netdev_bsd);
58
59 \f
60 struct netdev_rx_bsd {
61     struct netdev_rx up;
62
63     /* Packet capture descriptor for a system network device.
64      * For a tap device this is NULL. */
65     pcap_t *pcap_handle;
66
67     /* Selectable file descriptor for the network device.
68      * This descriptor will be used for polling operations. */
69     int fd;
70 };
71
72 static const struct netdev_rx_class netdev_rx_bsd_class;
73
74 struct netdev_bsd {
75     struct netdev up;
76     unsigned int cache_valid;
77     unsigned int change_seq;
78
79     int ifindex;
80     uint8_t etheraddr[ETH_ADDR_LEN];
81     struct in_addr in4;
82     struct in6_addr in6;
83     int mtu;
84     int carrier;
85
86     int tap_fd;         /* TAP character device, if any, otherwise -1. */
87
88     /* Used for sending packets on non-tap devices. */
89     pcap_t *pcap;
90     int fd;
91 };
92
93
94 enum {
95     VALID_IFINDEX = 1 << 0,
96     VALID_ETHERADDR = 1 << 1,
97     VALID_IN4 = 1 << 2,
98     VALID_IN6 = 1 << 3,
99     VALID_MTU = 1 << 4,
100     VALID_CARRIER = 1 << 5
101 };
102
103 /* An AF_INET socket (used for ioctl operations). */
104 static int af_inet_sock = -1;
105
106 #define PCAP_SNAPLEN 2048
107
108
109 /*
110  * Notifier used to invalidate device informations in case of status change.
111  *
112  * It will be registered with a 'rtbsd_notifier_register()' when the first
113  * device will be created with the call of either 'netdev_bsd_tap_create()' or
114  * 'netdev_bsd_system_create()'.
115  *
116  * The callback associated with this notifier ('netdev_bsd_cache_cb()') will
117  * invalidate cached information about the device.
118  */
119 static struct rtbsd_notifier netdev_bsd_cache_notifier;
120 static int cache_notifier_refcount;
121
122 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 20);
123
124 static int netdev_bsd_do_ioctl(const char *, struct ifreq *, unsigned long cmd,
125                                const char *cmd_name);
126 static void destroy_tap(int fd, const char *name);
127 static int get_flags(const struct netdev *, int *flagsp);
128 static int set_flags(const char *, int flags);
129 static int do_set_addr(struct netdev *netdev,
130                        int ioctl_nr, const char *ioctl_name,
131                        struct in_addr addr);
132 static int get_etheraddr(const char *netdev_name, uint8_t ea[ETH_ADDR_LEN]);
133 static int set_etheraddr(const char *netdev_name, int hwaddr_family,
134                          int hwaddr_len, const uint8_t[ETH_ADDR_LEN]);
135 static int get_ifindex(const struct netdev *, int *ifindexp);
136
137 static int ifr_get_flags(const struct ifreq *);
138 static void ifr_set_flags(struct ifreq *, int flags);
139
140 static int netdev_bsd_init(void);
141
142 static bool
143 is_netdev_bsd_class(const struct netdev_class *netdev_class)
144 {
145     return netdev_class->init == netdev_bsd_init;
146 }
147
148 static struct netdev_bsd *
149 netdev_bsd_cast(const struct netdev *netdev)
150 {
151     ovs_assert(is_netdev_bsd_class(netdev_get_class(netdev)));
152     return CONTAINER_OF(netdev, struct netdev_bsd, up);
153 }
154
155 static struct netdev_rx_bsd *
156 netdev_rx_bsd_cast(const struct netdev_rx *rx)
157 {
158     netdev_rx_assert_class(rx, &netdev_rx_bsd_class);
159     return CONTAINER_OF(rx, struct netdev_rx_bsd, up);
160 }
161
162 /* Initialize the AF_INET socket used for ioctl operations */
163 static int
164 netdev_bsd_init(void)
165 {
166     static int status = -1;
167
168     if (status >= 0) {  /* already initialized */
169         return status;
170     }
171
172     af_inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
173     status = af_inet_sock >= 0 ? 0 : errno;
174
175     if (status) {
176         VLOG_ERR("failed to create inet socket: %s", strerror(status));
177     }
178
179     return status;
180 }
181
182 /*
183  * Perform periodic work needed by netdev. In BSD netdevs it checks for any
184  * interface status changes, and eventually calls all the user callbacks.
185  */
186 static void
187 netdev_bsd_run(void)
188 {
189     rtbsd_notifier_run();
190 }
191
192 /*
193  * Arranges for poll_block() to wake up if the "run" member function needs to
194  * be called.
195  */
196 static void
197 netdev_bsd_wait(void)
198 {
199     rtbsd_notifier_wait();
200 }
201
202 static void
203 netdev_bsd_changed(struct netdev_bsd *dev)
204 {
205     dev->change_seq++;
206     if (!dev->change_seq) {
207         dev->change_seq++;
208     }
209 }
210
211 /* Invalidate cache in case of interface status change. */
212 static void
213 netdev_bsd_cache_cb(const struct rtbsd_change *change,
214                     void *aux OVS_UNUSED)
215 {
216     struct netdev_bsd *dev;
217
218     if (change) {
219         struct netdev *base_dev = netdev_from_name(change->if_name);
220
221         if (base_dev) {
222             const struct netdev_class *netdev_class =
223                                                 netdev_get_class(base_dev);
224
225             if (is_netdev_bsd_class(netdev_class)) {
226                 dev = netdev_bsd_cast(base_dev);
227                 dev->cache_valid = 0;
228                 netdev_bsd_changed(dev);
229             }
230         }
231     } else {
232         /*
233          * XXX the API is lacking, we should be able to iterate on the list of
234          * netdevs without having to store the info in a temp shash.
235          */
236         struct shash device_shash;
237         struct shash_node *node;
238
239         shash_init(&device_shash);
240         netdev_get_devices(&netdev_bsd_class, &device_shash);
241         SHASH_FOR_EACH (node, &device_shash) {
242             dev = node->data;
243             dev->cache_valid = 0;
244             netdev_bsd_changed(dev);
245         }
246         shash_destroy(&device_shash);
247     }
248 }
249
250 static int
251 cache_notifier_ref(void)
252 {
253     int ret = 0;
254
255     if (!cache_notifier_refcount) {
256         ret = rtbsd_notifier_register(&netdev_bsd_cache_notifier,
257                                                 netdev_bsd_cache_cb, NULL);
258         if (ret) {
259             return ret;
260         }
261     }
262     cache_notifier_refcount++;
263     return 0;
264 }
265
266 static int
267 cache_notifier_unref(void)
268 {
269     cache_notifier_refcount--;
270     if (cache_notifier_refcount == 0) {
271         rtbsd_notifier_unregister(&netdev_bsd_cache_notifier);
272     }
273     return 0;
274 }
275
276 /* Allocate a netdev_bsd structure */
277 static int
278 netdev_bsd_create_system(const struct netdev_class *class, const char *name,
279                   struct netdev **netdevp)
280 {
281     struct netdev_bsd *netdev;
282     enum netdev_flags flags;
283     int error;
284
285     error = cache_notifier_ref();
286     if (error) {
287         return error;
288     }
289
290     netdev = xzalloc(sizeof *netdev);
291     netdev->change_seq = 1;
292     netdev_init(&netdev->up, name, class);
293     netdev->tap_fd = -1;
294
295     /* Verify that the netdev really exists by attempting to read its flags */
296     error = netdev_get_flags(&netdev->up, &flags);
297     if (error == ENXIO) {
298         netdev_uninit(&netdev->up, false);
299         free(netdev);
300         cache_notifier_unref();
301         return error;
302     }
303
304     *netdevp = &netdev->up;
305     return 0;
306 }
307
308 /*
309  * Allocate a netdev_bsd structure with 'tap' class.
310  */
311 static int
312 netdev_bsd_create_tap(const struct netdev_class *class, const char *name,
313                   struct netdev **netdevp)
314 {
315     struct netdev_bsd *netdev = NULL;
316     int error = 0;
317     struct ifreq ifr;
318
319     error = cache_notifier_ref();
320     if (error) {
321         goto error;
322     }
323
324     /* allocate the device structure and set the internal flag */
325     netdev = xzalloc(sizeof *netdev);
326
327     memset(&ifr, 0, sizeof(ifr));
328
329     /* Create a tap device by opening /dev/tap.  The TAPGIFNAME ioctl is used
330      * to retrieve the name of the tap device. */
331     netdev->tap_fd = open("/dev/tap", O_RDWR);
332     netdev->change_seq = 1;
333     if (netdev->tap_fd < 0) {
334         error = errno;
335         VLOG_WARN("opening \"/dev/tap\" failed: %s", strerror(error));
336         goto error_undef_notifier;
337     }
338
339     /* Retrieve tap name (e.g. tap0) */
340     if (ioctl(netdev->tap_fd, TAPGIFNAME, &ifr) == -1) {
341         /* XXX Need to destroy the device? */
342         error = errno;
343         goto error_undef_notifier;
344     }
345
346     /* Change the name of the tap device */
347 #if defined(SIOCSIFNAME)
348     ifr.ifr_data = (void *)name;
349     if (ioctl(af_inet_sock, SIOCSIFNAME, &ifr) == -1) {
350         error = errno;
351         destroy_tap(netdev->tap_fd, ifr.ifr_name);
352         goto error_undef_notifier;
353     }
354 #else
355     /*
356      * XXX
357      * NetBSD doesn't support inteface renaming.
358      */
359     VLOG_INFO("tap %s is created for bridge %s", ifr.ifr_name, name);
360     name = ifr.ifr_name; /* XXX */
361 #endif
362
363     /* set non-blocking. */
364     error = set_nonblocking(netdev->tap_fd);
365     if (error) {
366         destroy_tap(netdev->tap_fd, name);
367         goto error_undef_notifier;
368     }
369
370     /* Turn device UP */
371     ifr_set_flags(&ifr, IFF_UP);
372     strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
373     if (ioctl(af_inet_sock, SIOCSIFFLAGS, &ifr) == -1) {
374         error = errno;
375         destroy_tap(netdev->tap_fd, name);
376         goto error_undef_notifier;
377     }
378
379     /* initialize the device structure and
380      * link the structure to its netdev */
381     netdev_init(&netdev->up, name, class);
382     *netdevp = &netdev->up;
383
384     return 0;
385
386 error_undef_notifier:
387     cache_notifier_unref();
388 error:
389     free(netdev);
390     return error;
391 }
392
393 static void
394 netdev_bsd_destroy(struct netdev *netdev_)
395 {
396     struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
397
398     cache_notifier_unref();
399
400     if (netdev->tap_fd >= 0) {
401         destroy_tap(netdev->tap_fd, netdev_get_name(netdev_));
402     }
403     if (netdev->pcap) {
404         pcap_close(netdev->pcap);
405     }
406     free(netdev);
407 }
408
409 static int
410 netdev_bsd_open_pcap(const char *name, pcap_t **pcapp, int *fdp)
411 {
412     char errbuf[PCAP_ERRBUF_SIZE];
413     pcap_t *pcap = NULL;
414     int one = 1;
415     int error;
416     int fd;
417
418     /* Open the pcap device.  The device is opened in non-promiscuous mode
419      * because the interface flags are manually set by the caller. */
420     errbuf[0] = '\0';
421     pcap = pcap_open_live(name, PCAP_SNAPLEN, 0, 1000, errbuf);
422     if (!pcap) {
423         VLOG_ERR_RL(&rl, "%s: pcap_open_live failed: %s", name, errbuf);
424         error = EIO;
425         goto error;
426     }
427     if (errbuf[0] != '\0') {
428         VLOG_WARN_RL(&rl, "%s: pcap_open_live: %s", name, errbuf);
429     }
430
431     /* Get the underlying fd. */
432     fd = pcap_get_selectable_fd(pcap);
433     if (fd == -1) {
434         VLOG_WARN_RL(&rl, "%s: no selectable file descriptor", name);
435         error = errno;
436         goto error;
437     }
438
439     /* Set non-blocking mode. Also the BIOCIMMEDIATE ioctl must be called
440      * on the file descriptor returned by pcap_get_selectable_fd to achieve
441      * a real non-blocking behaviour.*/
442     error = pcap_setnonblock(pcap, 1, errbuf);
443     if (error == -1) {
444         error = errno;
445         goto error;
446     }
447
448     /* This call assure that reads return immediately upon packet
449      * reception.  Otherwise, a read will block until either the kernel
450      * buffer becomes full or a timeout occurs. */
451     if (ioctl(fd, BIOCIMMEDIATE, &one) < 0 ) {
452         VLOG_ERR_RL(&rl, "ioctl(BIOCIMMEDIATE) on %s device failed: %s",
453                     name, strerror(errno));
454         error = errno;
455         goto error;
456     }
457
458     /* Capture only incoming packets. */
459     error = pcap_setdirection(pcap, PCAP_D_IN);
460     if (error == -1) {
461         error = errno;
462         goto error;
463     }
464
465     *pcapp = pcap;
466     *fdp = fd;
467     return 0;
468
469 error:
470     if (pcap) {
471         pcap_close(pcap);
472     }
473     *pcapp = NULL;
474     *fdp = -1;
475     return error;
476 }
477
478 static int
479 netdev_bsd_rx_open(struct netdev *netdev_, struct netdev_rx **rxp)
480 {
481     struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
482
483     struct netdev_rx_bsd *rx;
484     pcap_t *pcap;
485     int fd;
486
487     if (!strcmp(netdev_get_type(netdev_), "tap")) {
488         pcap = NULL;
489         fd = netdev->tap_fd;
490     } else {
491         int error = netdev_bsd_open_pcap(netdev_get_name(netdev_), &pcap, &fd);
492         if (error) {
493             return error;
494         }
495
496         netdev_bsd_changed(netdev);
497     }
498
499     rx = xmalloc(sizeof *rx);
500     netdev_rx_init(&rx->up, netdev_, &netdev_rx_bsd_class);
501     rx->pcap_handle = pcap;
502     rx->fd = fd;
503
504     *rxp = &rx->up;
505     return 0;
506 }
507
508 static void
509 netdev_rx_bsd_destroy(struct netdev_rx *rx_)
510 {
511     struct netdev_rx_bsd *rx = netdev_rx_bsd_cast(rx_);
512
513     if (rx->pcap_handle) {
514         pcap_close(rx->pcap_handle);
515     }
516     free(rx);
517 }
518
519 /* The recv callback of the netdev class returns the number of bytes of the
520  * received packet.
521  *
522  * This can be done by the pcap_next() function. Unfortunately pcap_next() does
523  * not make difference between a missing packet on the capture interface and
524  * an error during the file capture.  We can use the pcap_dispatch() function
525  * instead, which is able to distinguish between errors and null packet.
526  *
527  * To make pcap_dispatch() returns the number of bytes read from the interface
528  * we need to define the following callback and argument.
529  */
530 struct pcap_arg {
531     void *data;
532     int size;
533     int retval;
534 };
535
536 /*
537  * This callback will be executed on every captured packet.
538  *
539  * If the packet captured by pcap_dispatch() does not fit the pcap buffer,
540  * pcap returns a truncated packet and we follow this behavior.
541  *
542  * The argument args->retval is the packet size in bytes.
543  */
544 static void
545 proc_pkt(u_char *args_, const struct pcap_pkthdr *hdr, const u_char *packet)
546 {
547     struct pcap_arg *args = (struct pcap_arg *)args_;
548
549     if (args->size < hdr->len) {
550         VLOG_WARN_RL(&rl, "packet truncated");
551         args->retval = args->size;
552     } else {
553         args->retval = hdr->len;
554     }
555
556     /* copy the packet to our buffer */
557     memcpy(args->data, packet, args->retval);
558 }
559
560 /*
561  * This function attempts to receive a packet from the specified network
562  * device. It is assumed that the network device is a system device or a tap
563  * device opened as a system one. In this case the read operation is performed
564  * from rx->pcap.
565  */
566 static int
567 netdev_rx_bsd_recv_pcap(struct netdev_rx_bsd *rx, void *data, size_t size)
568 {
569     struct pcap_arg arg;
570     int ret;
571
572     /* prepare the pcap argument to store the packet */
573     arg.size = size;
574     arg.data = data;
575
576     for (;;) {
577         ret = pcap_dispatch(rx->pcap_handle, 1, proc_pkt, (u_char *) &arg);
578
579         if (ret > 0) {
580             return arg.retval;  /* arg.retval < 0 is handled in the caller */
581         }
582         if (ret == -1) {
583             if (errno == EINTR) {
584                  continue;
585             }
586         }
587
588         return -EAGAIN;
589     }
590 }
591
592 /*
593  * This function attempts to receive a packet from the specified network
594  * device. It is assumed that the network device is a tap device and
595  * 'rx->fd' is initialized with the tap file descriptor.
596  */
597 static int
598 netdev_rx_bsd_recv_tap(struct netdev_rx_bsd *rx, void *data, size_t size)
599 {
600     for (;;) {
601         ssize_t retval = read(rx->fd, data, size);
602         if (retval >= 0) {
603             return retval;
604         } else if (errno != EINTR) {
605             if (errno != EAGAIN) {
606                 VLOG_WARN_RL(&rl, "error receiving Ethernet packet on %s: %s",
607                              strerror(errno), netdev_rx_get_name(&rx->up));
608             }
609             return -errno;
610         }
611     }
612 }
613
614
615 static int
616 netdev_rx_bsd_recv(struct netdev_rx *rx_, void *data, size_t size)
617 {
618     struct netdev_rx_bsd *rx = netdev_rx_bsd_cast(rx_);
619
620     return (rx->pcap_handle
621             ? netdev_rx_bsd_recv_pcap(rx, data, size)
622             : netdev_rx_bsd_recv_tap(rx, data, size));
623 }
624
625 /*
626  * Registers with the poll loop to wake up from the next call to poll_block()
627  * when a packet is ready to be received with netdev_rx_recv() on 'rx'.
628  */
629 static void
630 netdev_rx_bsd_wait(struct netdev_rx *rx_)
631 {
632     struct netdev_rx_bsd *rx = netdev_rx_bsd_cast(rx_);
633
634     poll_fd_wait(rx->fd, POLLIN);
635 }
636
637 /* Discards all packets waiting to be received from 'rx'. */
638 static int
639 netdev_rx_bsd_drain(struct netdev_rx *rx_)
640 {
641     struct ifreq ifr;
642     struct netdev_rx_bsd *rx = netdev_rx_bsd_cast(rx_);
643
644     strcpy(ifr.ifr_name, netdev_rx_get_name(rx_));
645     if (ioctl(rx->fd, BIOCFLUSH, &ifr) == -1) {
646         VLOG_DBG_RL(&rl, "%s: ioctl(BIOCFLUSH) failed: %s",
647                     netdev_rx_get_name(rx_), strerror(errno));
648         return errno;
649     }
650     return 0;
651 }
652
653 /*
654  * Send a packet on the specified network device. The device could be either a
655  * system or a tap device.
656  */
657 static int
658 netdev_bsd_send(struct netdev *netdev_, const void *data, size_t size)
659 {
660     struct netdev_bsd *dev = netdev_bsd_cast(netdev_);
661     const char *name = netdev_get_name(netdev_);
662
663     if (dev->tap_fd < 0 && !dev->pcap) {
664         int error = netdev_bsd_open_pcap(name, &dev->pcap, &dev->fd);
665         if (error) {
666             return error;
667         }
668     }
669
670     for (;;) {
671         ssize_t retval;
672         if (dev->tap_fd >= 0) {
673             retval = write(dev->tap_fd, data, size);
674         } else {
675             retval = pcap_inject(dev->pcap, data, size);
676         }
677         if (retval < 0) {
678             if (errno == EINTR) {
679                 continue;
680             } else if (errno != EAGAIN) {
681                 VLOG_WARN_RL(&rl, "error sending Ethernet packet on %s: %s",
682                              name, strerror(errno));
683             }
684             return errno;
685         } else if (retval != size) {
686             VLOG_WARN_RL(&rl, "sent partial Ethernet packet (%zd bytes of "
687                          "%zu) on %s", retval, size, name);
688            return EMSGSIZE;
689         } else {
690             return 0;
691         }
692     }
693 }
694
695 /*
696  * Registers with the poll loop to wake up from the next call to poll_block()
697  * when the packet transmission queue has sufficient room to transmit a packet
698  * with netdev_send().
699  */
700 static void
701 netdev_bsd_send_wait(struct netdev *netdev_)
702 {
703     struct netdev_bsd *dev = netdev_bsd_cast(netdev_);
704
705     if (dev->tap_fd >= 0) {
706         /* TAP device always accepts packets. */
707         poll_immediate_wake();
708     } else if (dev->pcap) {
709         poll_fd_wait(dev->fd, POLLOUT);
710     } else {
711         /* We haven't even tried to send a packet yet. */
712         poll_immediate_wake();
713     }
714 }
715
716 /*
717  * Attempts to set 'netdev''s MAC address to 'mac'.  Returns 0 if successful,
718  * otherwise a positive errno value.
719  */
720 static int
721 netdev_bsd_set_etheraddr(struct netdev *netdev_,
722                          const uint8_t mac[ETH_ADDR_LEN])
723 {
724     struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
725     int error;
726
727     if (!(netdev->cache_valid & VALID_ETHERADDR)
728         || !eth_addr_equals(netdev->etheraddr, mac)) {
729         error = set_etheraddr(netdev_get_name(netdev_), AF_LINK, ETH_ADDR_LEN,
730                               mac);
731         if (!error) {
732             netdev->cache_valid |= VALID_ETHERADDR;
733             memcpy(netdev->etheraddr, mac, ETH_ADDR_LEN);
734             netdev_bsd_changed(netdev);
735         }
736     } else {
737         error = 0;
738     }
739     return error;
740 }
741
742 /*
743  * Returns a pointer to 'netdev''s MAC address.  The caller must not modify or
744  * free the returned buffer.
745  */
746 static int
747 netdev_bsd_get_etheraddr(const struct netdev *netdev_,
748                          uint8_t mac[ETH_ADDR_LEN])
749 {
750     struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
751
752     if (!(netdev->cache_valid & VALID_ETHERADDR)) {
753         int error = get_etheraddr(netdev_get_name(netdev_),
754                                   netdev->etheraddr);
755         if (error) {
756             return error;
757         }
758         netdev->cache_valid |= VALID_ETHERADDR;
759     }
760     memcpy(mac, netdev->etheraddr, ETH_ADDR_LEN);
761
762     return 0;
763 }
764
765 /*
766  * Returns the maximum size of transmitted (and received) packets on 'netdev',
767  * in bytes, not including the hardware header; thus, this is typically 1500
768  * bytes for Ethernet devices.
769  */
770 static int
771 netdev_bsd_get_mtu(const struct netdev *netdev_, int *mtup)
772 {
773     struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
774
775     if (!(netdev->cache_valid & VALID_MTU)) {
776         struct ifreq ifr;
777         int error;
778
779         error = netdev_bsd_do_ioctl(netdev_get_name(netdev_), &ifr, SIOCGIFMTU,
780                                     "SIOCGIFMTU");
781         if (error) {
782             return error;
783         }
784         netdev->mtu = ifr.ifr_mtu;
785         netdev->cache_valid |= VALID_MTU;
786     }
787
788     *mtup = netdev->mtu;
789     return 0;
790 }
791
792 static int
793 netdev_bsd_get_ifindex(const struct netdev *netdev)
794 {
795     int ifindex, error;
796
797     error = get_ifindex(netdev, &ifindex);
798     return error ? -error : ifindex;
799 }
800
801 static int
802 netdev_bsd_get_carrier(const struct netdev *netdev_, bool *carrier)
803 {
804     struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
805
806     if (!(netdev->cache_valid & VALID_CARRIER)) {
807         struct ifmediareq ifmr;
808
809         memset(&ifmr, 0, sizeof(ifmr));
810         strncpy(ifmr.ifm_name, netdev_get_name(netdev_), sizeof ifmr.ifm_name);
811
812         if (ioctl(af_inet_sock, SIOCGIFMEDIA, &ifmr) == -1) {
813             VLOG_DBG_RL(&rl, "%s: ioctl(SIOCGIFMEDIA) failed: %s",
814                         netdev_get_name(netdev_), strerror(errno));
815             return errno;
816         }
817
818         netdev->carrier = (ifmr.ifm_status & IFM_ACTIVE) == IFM_ACTIVE;
819         netdev->cache_valid |= VALID_CARRIER;
820
821         /* If the interface doesn't report whether the media is active,
822          * just assume it is active. */
823         if ((ifmr.ifm_status & IFM_AVALID) == 0) {
824             netdev->carrier = true;
825         }
826     }
827     *carrier = netdev->carrier;
828
829     return 0;
830 }
831
832 /* Retrieves current device stats for 'netdev'. */
833 static int
834 netdev_bsd_get_stats(const struct netdev *netdev_ OVS_UNUSED,
835                      struct netdev_stats *stats)
836 {
837 #if defined(__FreeBSD__)
838     int if_count, i;
839     int mib[6];
840     size_t len;
841     struct ifmibdata ifmd;
842
843
844     mib[0] = CTL_NET;
845     mib[1] = PF_LINK;
846     mib[2] = NETLINK_GENERIC;
847     mib[3] = IFMIB_SYSTEM;
848     mib[4] = IFMIB_IFCOUNT;
849
850     len = sizeof(if_count);
851
852     if (sysctl(mib, 5, &if_count, &len, (void *)0, 0) == -1) {
853         VLOG_DBG_RL(&rl, "%s: sysctl failed: %s",
854                     netdev_get_name(netdev_), strerror(errno));
855         return errno;
856     }
857
858     mib[5] = IFDATA_GENERAL;
859     mib[3] = IFMIB_IFDATA;
860     len = sizeof(ifmd);
861     for (i = 1; i <= if_count; i++) {
862         mib[4] = i; //row
863         if (sysctl(mib, 6, &ifmd, &len, (void *)0, 0) == -1) {
864             VLOG_DBG_RL(&rl, "%s: sysctl failed: %s",
865                         netdev_get_name(netdev_), strerror(errno));
866             return errno;
867         } else if (!strcmp(ifmd.ifmd_name, netdev_get_name(netdev_))) {
868             stats->rx_packets = ifmd.ifmd_data.ifi_ipackets;
869             stats->tx_packets = ifmd.ifmd_data.ifi_opackets;
870             stats->rx_bytes = ifmd.ifmd_data.ifi_ibytes;
871             stats->tx_bytes = ifmd.ifmd_data.ifi_obytes;
872             stats->rx_errors = ifmd.ifmd_data.ifi_ierrors;
873             stats->tx_errors = ifmd.ifmd_data.ifi_oerrors;
874             stats->rx_dropped = ifmd.ifmd_data.ifi_iqdrops;
875             stats->tx_dropped = UINT64_MAX;
876             stats->multicast = ifmd.ifmd_data.ifi_imcasts;
877             stats->collisions = ifmd.ifmd_data.ifi_collisions;
878
879             stats->rx_length_errors = UINT64_MAX;
880             stats->rx_over_errors = UINT64_MAX;
881             stats->rx_crc_errors = UINT64_MAX;
882             stats->rx_frame_errors = UINT64_MAX;
883             stats->rx_fifo_errors = UINT64_MAX;
884             stats->rx_missed_errors = UINT64_MAX;
885
886             stats->tx_aborted_errors = UINT64_MAX;
887             stats->tx_carrier_errors = UINT64_MAX;
888             stats->tx_fifo_errors = UINT64_MAX;
889             stats->tx_heartbeat_errors = UINT64_MAX;
890             stats->tx_window_errors = UINT64_MAX;
891             break;
892         }
893     }
894
895     return 0;
896 #else
897     /* XXXnotyet */
898     memset(stats, 0, sizeof(*stats));
899     return 0;
900 #endif
901 }
902
903 static uint32_t
904 netdev_bsd_parse_media(int media)
905 {
906     uint32_t supported = 0;
907     bool half_duplex = media & IFM_HDX ? true : false;
908
909     switch (IFM_SUBTYPE(media)) {
910     case IFM_10_2:
911     case IFM_10_5:
912     case IFM_10_STP:
913     case IFM_10_T:
914         supported |= half_duplex ? NETDEV_F_10MB_HD : NETDEV_F_10MB_FD;
915         supported |= NETDEV_F_COPPER;
916         break;
917
918     case IFM_10_FL:
919         supported |= half_duplex ? NETDEV_F_10MB_HD : NETDEV_F_10MB_FD;
920         supported |= NETDEV_F_FIBER;
921         break;
922
923     case IFM_100_T2:
924     case IFM_100_T4:
925     case IFM_100_TX:
926     case IFM_100_VG:
927         supported |= half_duplex ? NETDEV_F_100MB_HD : NETDEV_F_100MB_FD;
928         supported |= NETDEV_F_COPPER;
929         break;
930
931     case IFM_100_FX:
932         supported |= half_duplex ? NETDEV_F_100MB_HD : NETDEV_F_100MB_FD;
933         supported |= NETDEV_F_FIBER;
934         break;
935
936     case IFM_1000_CX:
937     case IFM_1000_T:
938         supported |= half_duplex ? NETDEV_F_1GB_HD : NETDEV_F_1GB_FD;
939         supported |= NETDEV_F_COPPER;
940         break;
941
942     case IFM_1000_LX:
943     case IFM_1000_SX:
944         supported |= half_duplex ? NETDEV_F_1GB_HD : NETDEV_F_1GB_FD;
945         supported |= NETDEV_F_FIBER;
946         break;
947
948     case IFM_10G_CX4:
949         supported |= NETDEV_F_10GB_FD;
950         supported |= NETDEV_F_COPPER;
951         break;
952
953     case IFM_10G_LR:
954     case IFM_10G_SR:
955         supported |= NETDEV_F_10GB_FD;
956         supported |= NETDEV_F_FIBER;
957         break;
958
959     default:
960         return 0;
961     }
962
963     if (IFM_SUBTYPE(media) == IFM_AUTO) {
964         supported |= NETDEV_F_AUTONEG;
965     }
966     /*
967     if (media & IFM_ETH_FMASK) {
968         supported |= NETDEV_F_PAUSE;
969     }
970     */
971
972     return supported;
973 }
974
975 /*
976  * Stores the features supported by 'netdev' into each of '*current',
977  * '*advertised', '*supported', and '*peer' that are non-null.  Each value is a
978  * bitmap of "enum ofp_port_features" bits, in host byte order.  Returns 0 if
979  * successful, otherwise a positive errno value.  On failure, all of the
980  * passed-in values are set to 0.
981  */
982 static int
983 netdev_bsd_get_features(const struct netdev *netdev,
984                         enum netdev_features *current, uint32_t *advertised,
985                         enum netdev_features *supported, uint32_t *peer)
986 {
987     struct ifmediareq ifmr;
988     int *media_list;
989     int i;
990     int error;
991
992
993     /* XXX Look into SIOCGIFCAP instead of SIOCGIFMEDIA */
994
995     memset(&ifmr, 0, sizeof(ifmr));
996     strncpy(ifmr.ifm_name, netdev_get_name(netdev), sizeof ifmr.ifm_name);
997
998     /* We make two SIOCGIFMEDIA ioctl calls.  The first to determine the
999      * number of supported modes, and a second with a buffer to retrieve
1000      * them. */
1001     if (ioctl(af_inet_sock, SIOCGIFMEDIA, &ifmr) == -1) {
1002         VLOG_DBG_RL(&rl, "%s: ioctl(SIOCGIFMEDIA) failed: %s",
1003                     netdev_get_name(netdev), strerror(errno));
1004         return errno;
1005     }
1006
1007     media_list = xcalloc(ifmr.ifm_count, sizeof(int));
1008     ifmr.ifm_ulist = media_list;
1009
1010     if (IFM_TYPE(ifmr.ifm_current) != IFM_ETHER) {
1011         VLOG_DBG_RL(&rl, "%s: doesn't appear to be ethernet",
1012                     netdev_get_name(netdev));
1013         error = EINVAL;
1014         goto cleanup;
1015     }
1016
1017     if (ioctl(af_inet_sock, SIOCGIFMEDIA, &ifmr) == -1) {
1018         VLOG_DBG_RL(&rl, "%s: ioctl(SIOCGIFMEDIA) failed: %s",
1019                     netdev_get_name(netdev), strerror(errno));
1020         error = errno;
1021         goto cleanup;
1022     }
1023
1024     /* Current settings. */
1025     *current = netdev_bsd_parse_media(ifmr.ifm_active);
1026
1027     /* Advertised features. */
1028     *advertised = netdev_bsd_parse_media(ifmr.ifm_current);
1029
1030     /* Supported features. */
1031     *supported = 0;
1032     for (i = 0; i < ifmr.ifm_count; i++) {
1033         *supported |= netdev_bsd_parse_media(ifmr.ifm_ulist[i]);
1034     }
1035
1036     /* Peer advertisements. */
1037     *peer = 0;                  /* XXX */
1038
1039     error = 0;
1040 cleanup:
1041     free(media_list);
1042     return error;
1043 }
1044
1045 /*
1046  * If 'netdev' has an assigned IPv4 address, sets '*in4' to that address (if
1047  * 'in4' is non-null) and returns true.  Otherwise, returns false.
1048  */
1049 static int
1050 netdev_bsd_get_in4(const struct netdev *netdev_, struct in_addr *in4,
1051                    struct in_addr *netmask)
1052 {
1053     struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
1054
1055     if (!(netdev->cache_valid & VALID_IN4)) {
1056         const struct sockaddr_in *sin;
1057         struct ifreq ifr;
1058         int error;
1059
1060         ifr.ifr_addr.sa_family = AF_INET;
1061         error = netdev_bsd_do_ioctl(netdev_get_name(netdev_), &ifr,
1062                                     SIOCGIFADDR, "SIOCGIFADDR");
1063         if (error) {
1064             return error;
1065         }
1066
1067         sin = (struct sockaddr_in *) &ifr.ifr_addr;
1068         netdev->in4 = sin->sin_addr;
1069         netdev->cache_valid |= VALID_IN4;
1070         error = netdev_bsd_do_ioctl(netdev_get_name(netdev_), &ifr,
1071                                     SIOCGIFNETMASK, "SIOCGIFNETMASK");
1072         if (error) {
1073             return error;
1074         }
1075         *netmask = ((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr;
1076     }
1077     *in4 = netdev->in4;
1078
1079     return in4->s_addr == INADDR_ANY ? EADDRNOTAVAIL : 0;
1080 }
1081
1082 /*
1083  * Assigns 'addr' as 'netdev''s IPv4 address and 'mask' as its netmask.  If
1084  * 'addr' is INADDR_ANY, 'netdev''s IPv4 address is cleared.  Returns a
1085  * positive errno value.
1086  */
1087 static int
1088 netdev_bsd_set_in4(struct netdev *netdev_, struct in_addr addr,
1089                    struct in_addr mask)
1090 {
1091     struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
1092     int error;
1093
1094     error = do_set_addr(netdev_, SIOCSIFADDR, "SIOCSIFADDR", addr);
1095     if (!error) {
1096         netdev->cache_valid |= VALID_IN4;
1097         netdev->in4 = addr;
1098         if (addr.s_addr != INADDR_ANY) {
1099             error = do_set_addr(netdev_, SIOCSIFNETMASK,
1100                                 "SIOCSIFNETMASK", mask);
1101         }
1102         netdev_bsd_changed(netdev);
1103     }
1104     return error;
1105 }
1106
1107 static int
1108 netdev_bsd_get_in6(const struct netdev *netdev_, struct in6_addr *in6)
1109 {
1110     struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
1111     if (!(netdev->cache_valid & VALID_IN6)) {
1112         struct ifaddrs *ifa, *head;
1113         struct sockaddr_in6 *sin6;
1114         const char *netdev_name = netdev_get_name(netdev_);
1115
1116         if (getifaddrs(&head) != 0) {
1117             VLOG_ERR("getifaddrs on %s device failed: %s", netdev_name,
1118                     strerror(errno));
1119             return errno;
1120         }
1121
1122         for (ifa = head; ifa; ifa = ifa->ifa_next) {
1123             if (ifa->ifa_addr->sa_family == AF_INET6 &&
1124                     !strcmp(ifa->ifa_name, netdev_name)) {
1125                 sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
1126                 if (sin6) {
1127                     memcpy(&netdev->in6, &sin6->sin6_addr, sin6->sin6_len);
1128                     netdev->cache_valid |= VALID_IN6;
1129                     *in6 = netdev->in6;
1130                     freeifaddrs(head);
1131                     return 0;
1132                 }
1133             }
1134         }
1135         return EADDRNOTAVAIL;
1136     }
1137     *in6 = netdev->in6;
1138     return 0;
1139 }
1140
1141 static void
1142 make_in4_sockaddr(struct sockaddr *sa, struct in_addr addr)
1143 {
1144     struct sockaddr_in sin;
1145     memset(&sin, 0, sizeof sin);
1146     sin.sin_family = AF_INET;
1147     sin.sin_addr = addr;
1148     sin.sin_port = 0;
1149
1150     memset(sa, 0, sizeof *sa);
1151     memcpy(sa, &sin, sizeof sin);
1152 }
1153
1154 static int
1155 do_set_addr(struct netdev *netdev,
1156             int ioctl_nr, const char *ioctl_name, struct in_addr addr)
1157 {
1158     struct ifreq ifr;
1159     make_in4_sockaddr(&ifr.ifr_addr, addr);
1160     return netdev_bsd_do_ioctl(netdev, &ifr, ioctl_nr, ioctl_name);
1161 }
1162
1163 static int
1164 nd_to_iff_flags(enum netdev_flags nd)
1165 {
1166     int iff = 0;
1167     if (nd & NETDEV_UP) {
1168         iff |= IFF_UP;
1169     }
1170     if (nd & NETDEV_PROMISC) {
1171         iff |= IFF_PROMISC;
1172 #if defined(IFF_PPROMISC)
1173         iff |= IFF_PPROMISC;
1174 #endif
1175     }
1176     return iff;
1177 }
1178
1179 static int
1180 iff_to_nd_flags(int iff)
1181 {
1182     enum netdev_flags nd = 0;
1183     if (iff & IFF_UP) {
1184         nd |= NETDEV_UP;
1185     }
1186     if (iff & IFF_PROMISC) {
1187         nd |= NETDEV_PROMISC;
1188     }
1189     return nd;
1190 }
1191
1192 static int
1193 netdev_bsd_update_flags(struct netdev *netdev_, enum netdev_flags off,
1194                         enum netdev_flags on, enum netdev_flags *old_flagsp)
1195 {
1196     struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
1197     int old_flags, new_flags;
1198     int error;
1199
1200     error = get_flags(netdev_, &old_flags);
1201     if (!error) {
1202         *old_flagsp = iff_to_nd_flags(old_flags);
1203         new_flags = (old_flags & ~nd_to_iff_flags(off)) | nd_to_iff_flags(on);
1204         if (new_flags != old_flags) {
1205             error = set_flags(netdev_get_name(netdev_), new_flags);
1206             netdev_bsd_changed(netdev);
1207         }
1208     }
1209     return error;
1210 }
1211
1212 static unsigned int
1213 netdev_bsd_change_seq(const struct netdev *netdev)
1214 {
1215     return netdev_bsd_cast(netdev)->change_seq;
1216 }
1217
1218
1219 const struct netdev_class netdev_bsd_class = {
1220     "system",
1221
1222     netdev_bsd_init,
1223     netdev_bsd_run,
1224     netdev_bsd_wait,
1225     netdev_bsd_create_system,
1226     netdev_bsd_destroy,
1227     NULL, /* get_config */
1228     NULL, /* set_config */
1229     NULL, /* get_tunnel_config */
1230
1231     netdev_bsd_rx_open,
1232
1233     netdev_bsd_send,
1234     netdev_bsd_send_wait,
1235
1236     netdev_bsd_set_etheraddr,
1237     netdev_bsd_get_etheraddr,
1238     netdev_bsd_get_mtu,
1239     NULL, /* set_mtu */
1240     netdev_bsd_get_ifindex,
1241     netdev_bsd_get_carrier,
1242     NULL, /* get_carrier_resets */
1243     NULL, /* set_miimon_interval */
1244     netdev_bsd_get_stats,
1245     NULL, /* set_stats */
1246
1247     netdev_bsd_get_features,
1248     NULL, /* set_advertisement */
1249     NULL, /* set_policing */
1250     NULL, /* get_qos_type */
1251     NULL, /* get_qos_capabilities */
1252     NULL, /* get_qos */
1253     NULL, /* set_qos */
1254     NULL, /* get_queue */
1255     NULL, /* set_queue */
1256     NULL, /* delete_queue */
1257     NULL, /* get_queue_stats */
1258     NULL, /* dump_queue */
1259     NULL, /* dump_queue_stats */
1260
1261     netdev_bsd_get_in4,
1262     netdev_bsd_set_in4,
1263     netdev_bsd_get_in6,
1264     NULL, /* add_router */
1265     NULL, /* get_next_hop */
1266     NULL, /* get_status */
1267     NULL, /* arp_lookup */
1268
1269     netdev_bsd_update_flags,
1270
1271     netdev_bsd_change_seq
1272 };
1273
1274 const struct netdev_class netdev_tap_class = {
1275     "tap",
1276
1277     netdev_bsd_init,
1278     netdev_bsd_run,
1279     netdev_bsd_wait,
1280     netdev_bsd_create_tap,
1281     netdev_bsd_destroy,
1282     NULL, /* get_config */
1283     NULL, /* set_config */
1284     NULL, /* get_tunnel_config */
1285
1286     netdev_bsd_rx_open,
1287
1288     netdev_bsd_send,
1289     netdev_bsd_send_wait,
1290
1291     netdev_bsd_set_etheraddr,
1292     netdev_bsd_get_etheraddr,
1293     netdev_bsd_get_mtu,
1294     NULL, /* set_mtu */
1295     netdev_bsd_get_ifindex,
1296     netdev_bsd_get_carrier,
1297     NULL, /* get_carrier_resets */
1298     NULL, /* set_miimon_interval */
1299     netdev_bsd_get_stats,
1300     NULL, /* set_stats */
1301
1302     netdev_bsd_get_features,
1303     NULL, /* set_advertisement */
1304     NULL, /* set_policing */
1305     NULL, /* get_qos_type */
1306     NULL, /* get_qos_capabilities */
1307     NULL, /* get_qos */
1308     NULL, /* set_qos */
1309     NULL, /* get_queue */
1310     NULL, /* set_queue */
1311     NULL, /* delete_queue */
1312     NULL, /* get_queue_stats */
1313     NULL, /* dump_queue */
1314     NULL, /* dump_queue_stats */
1315
1316     netdev_bsd_get_in4,
1317     netdev_bsd_set_in4,
1318     netdev_bsd_get_in6,
1319     NULL, /* add_router */
1320     NULL, /* get_next_hop */
1321     NULL, /* get_status */
1322     NULL, /* arp_lookup */
1323
1324     netdev_bsd_update_flags,
1325
1326     netdev_bsd_change_seq
1327 };
1328
1329 static const struct netdev_rx_class netdev_rx_bsd_class = {
1330     netdev_rx_bsd_destroy,
1331     netdev_rx_bsd_recv,
1332     netdev_rx_bsd_wait,
1333     netdev_rx_bsd_drain,
1334 };
1335 \f
1336
1337 static void
1338 destroy_tap(int fd, const char *name)
1339 {
1340     struct ifreq ifr;
1341
1342     close(fd);
1343     strcpy(ifr.ifr_name, name);
1344     /* XXX What to do if this call fails? */
1345     ioctl(af_inet_sock, SIOCIFDESTROY, &ifr);
1346 }
1347
1348 static int
1349 get_flags(const struct netdev *netdev, int *flags)
1350 {
1351     struct ifreq ifr;
1352     int error;
1353
1354     error = netdev_bsd_do_ioctl(netdev->name, &ifr,
1355                                 SIOCGIFFLAGS, "SIOCGIFFLAGS");
1356
1357     *flags = ifr_get_flags(&ifr);
1358
1359     return error;
1360 }
1361
1362 static int
1363 set_flags(const char *name, int flags)
1364 {
1365     struct ifreq ifr;
1366
1367     ifr_set_flags(&ifr, flags);
1368
1369     return netdev_bsd_do_ioctl(name, &ifr, SIOCSIFFLAGS, "SIOCSIFFLAGS");
1370 }
1371
1372 static int
1373 get_ifindex(const struct netdev *netdev_, int *ifindexp)
1374 {
1375     struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
1376     *ifindexp = 0;
1377     if (!(netdev->cache_valid & VALID_IFINDEX)) {
1378         int ifindex = if_nametoindex(netdev_get_name(netdev_));
1379         if (ifindex <= 0) {
1380             return errno;
1381         }
1382         netdev->cache_valid |= VALID_IFINDEX;
1383         netdev->ifindex = ifindex;
1384     }
1385     *ifindexp = netdev->ifindex;
1386     return 0;
1387 }
1388
1389 static int
1390 get_etheraddr(const char *netdev_name, uint8_t ea[ETH_ADDR_LEN])
1391 {
1392     struct ifaddrs *head;
1393     struct ifaddrs *ifa;
1394     struct sockaddr_dl *sdl;
1395
1396     if (getifaddrs(&head) != 0) {
1397         VLOG_ERR("getifaddrs on %s device failed: %s", netdev_name,
1398                 strerror(errno));
1399         return errno;
1400     }
1401
1402     for (ifa = head; ifa; ifa = ifa->ifa_next) {
1403         if (ifa->ifa_addr->sa_family == AF_LINK) {
1404             if (!strcmp(ifa->ifa_name, netdev_name)) {
1405                 sdl = (struct sockaddr_dl *)ifa->ifa_addr;
1406                 if (sdl) {
1407                     memcpy(ea, LLADDR(sdl), sdl->sdl_alen);
1408                     freeifaddrs(head);
1409                     return 0;
1410                 }
1411             }
1412         }
1413     }
1414
1415     VLOG_ERR("could not find ethernet address for %s device", netdev_name);
1416     freeifaddrs(head);
1417     return ENODEV;
1418 }
1419
1420 static int
1421 set_etheraddr(const char *netdev_name OVS_UNUSED, int hwaddr_family OVS_UNUSED,
1422               int hwaddr_len OVS_UNUSED,
1423               const uint8_t mac[ETH_ADDR_LEN] OVS_UNUSED)
1424 {
1425 #if defined(__NetBSD__)
1426     return ENOTSUP; /* XXX */
1427 #else
1428     struct ifreq ifr;
1429
1430     memset(&ifr, 0, sizeof ifr);
1431     strncpy(ifr.ifr_name, netdev_name, sizeof ifr.ifr_name);
1432     ifr.ifr_addr.sa_family = hwaddr_family;
1433     ifr.ifr_addr.sa_len = hwaddr_len;
1434     memcpy(ifr.ifr_addr.sa_data, mac, hwaddr_len);
1435     if (ioctl(af_inet_sock, SIOCSIFLLADDR, &ifr) < 0) {
1436         VLOG_ERR("ioctl(SIOCSIFLLADDR) on %s device failed: %s",
1437                  netdev_name, strerror(errno));
1438         return errno;
1439     }
1440     return 0;
1441 #endif
1442 }
1443
1444 static int
1445 netdev_bsd_do_ioctl(const char *name, struct ifreq *ifr, unsigned long cmd,
1446                     const char *cmd_name)
1447 {
1448     strncpy(ifr->ifr_name, name, sizeof ifr->ifr_name);
1449     if (ioctl(af_inet_sock, cmd, ifr) == -1) {
1450         VLOG_DBG_RL(&rl, "%s: ioctl(%s) failed: %s", name, cmd_name,
1451                     strerror(errno));
1452         return errno;
1453     }
1454     return 0;
1455 }
1456
1457 static int
1458 ifr_get_flags(const struct ifreq *ifr)
1459 {
1460 #ifdef HAVE_STRUCT_IFREQ_IFR_FLAGSHIGH
1461     return (ifr.ifr_flagshigh << 16) | ifr.ifr_flags;
1462 #else
1463     return ifr.ifr_flags;
1464 #endif
1465 }
1466
1467 static void
1468 ifr_set_flags(struct ifreq *ifr, int flags)
1469 {
1470     ifr->ifr_flags = flags;
1471 #ifdef HAVE_STRUCT_IFREQ_IFR_FLAGSHIGH
1472     ifr->ifr_flagshigh = flags >> 16;
1473 #endif
1474 }