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