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