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