55
61
VLOG_DEFINE_THIS_MODULE(netdev_bsd);
59
* This file implements objects to access interfaces.
60
* Externally, interfaces are represented by two structures:
61
* + struct netdev_dev, representing a network device,
62
* containing e.g. name and a refcount;
63
* We can have private variables by embedding the
64
* struct netdev_dev into our own structure
65
* (e.g. netdev_dev_bsd)
67
* + struct netdev, representing an instance of an open netdev_dev.
68
* The structure contains a pointer to the 'struct netdev'
69
* representing the device. Again, private information
70
* such as file descriptor etc. are stored in our
71
* own struct netdev_bsd which includes a struct netdev.
73
* Both 'struct netdev' and 'struct netdev_dev' are referenced
74
* in containers which hold pointers to the data structures.
75
* We can reach our own struct netdev_XXX_bsd by putting a
76
* struct netdev_XXX within our own struct, and using CONTAINER_OF
77
* to access the parent structure.
64
struct netdev_rx_bsd {
67
/* Packet capture descriptor for a system network device.
68
* For a tap device this is NULL. */
71
/* Selectable file descriptor for the network device.
72
* This descriptor will be used for polling operations. */
76
static const struct netdev_rx_class netdev_rx_bsd_class;
79
78
struct netdev_bsd {
82
int netdev_fd; /* Selectable file descriptor for the network device.
83
This descriptor will be used for polling operations */
85
pcap_t *pcap_handle; /* Packet capture descriptor for a system network
89
struct netdev_dev_bsd {
90
struct netdev_dev netdev_dev;
91
80
unsigned int cache_valid;
92
81
unsigned int change_seq;
323
353
/* allocate the device structure and set the internal flag */
324
netdev_dev = xzalloc(sizeof *netdev_dev);
354
netdev = xzalloc(sizeof *netdev);
326
356
memset(&ifr, 0, sizeof(ifr));
328
358
/* Create a tap device by opening /dev/tap. The TAPGIFNAME ioctl is used
329
359
* to retrieve the name of the tap device. */
330
netdev_dev->tap_fd = open("/dev/tap", O_RDWR);
331
netdev_dev->change_seq = 1;
332
if (netdev_dev->tap_fd < 0) {
360
netdev->tap_fd = open("/dev/tap", O_RDWR);
361
netdev->change_seq = 1;
362
if (netdev->tap_fd < 0) {
334
VLOG_WARN("opening \"/dev/tap\" failed: %s", strerror(error));
364
VLOG_WARN("opening \"/dev/tap\" failed: %s", ovs_strerror(error));
335
365
goto error_undef_notifier;
338
368
/* Retrieve tap name (e.g. tap0) */
339
if (ioctl(netdev_dev->tap_fd, TAPGIFNAME, &ifr) == -1) {
369
if (ioctl(netdev->tap_fd, TAPGIFNAME, &ifr) == -1) {
340
370
/* XXX Need to destroy the device? */
342
372
goto error_undef_notifier;
345
375
/* Change the name of the tap device */
376
#if defined(SIOCSIFNAME)
346
377
ifr.ifr_data = (void *)name;
347
378
if (ioctl(af_inet_sock, SIOCSIFNAME, &ifr) == -1) {
349
destroy_tap(netdev_dev->tap_fd, ifr.ifr_name);
380
destroy_tap(netdev->tap_fd, ifr.ifr_name);
350
381
goto error_undef_notifier;
383
kernel_name = xstrdup(name);
386
* NetBSD doesn't support inteface renaming.
388
VLOG_INFO("tap %s is created for bridge %s", ifr.ifr_name, name);
389
kernel_name = xstrdup(ifr.ifr_name);
353
392
/* set non-blocking. */
354
error = set_nonblocking(netdev_dev->tap_fd);
393
error = set_nonblocking(netdev->tap_fd);
356
destroy_tap(netdev_dev->tap_fd, name);
395
destroy_tap(netdev->tap_fd, kernel_name);
357
396
goto error_undef_notifier;
360
399
/* Turn device UP */
361
ifr.ifr_flags = (uint16_t)IFF_UP;
362
ifr.ifr_flagshigh = 0;
363
strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
400
ifr_set_flags(&ifr, IFF_UP);
401
strncpy(ifr.ifr_name, kernel_name, sizeof ifr.ifr_name);
364
402
if (ioctl(af_inet_sock, SIOCSIFFLAGS, &ifr) == -1) {
366
destroy_tap(netdev_dev->tap_fd, name);
404
destroy_tap(netdev->tap_fd, kernel_name);
367
405
goto error_undef_notifier;
370
408
/* initialize the device structure and
371
409
* link the structure to its netdev */
372
netdev_dev_init(&netdev_dev->netdev_dev, name, class);
373
*netdev_devp = &netdev_dev->netdev_dev;
410
netdev_init(&netdev->up, name, class);
411
netdev->kernel_name = kernel_name;
412
*netdevp = &netdev->up;
377
416
error_undef_notifier:
378
417
cache_notifier_unref();
385
netdev_bsd_destroy(struct netdev_dev *netdev_dev_)
425
netdev_bsd_destroy(struct netdev *netdev_)
387
struct netdev_dev_bsd *netdev_dev = netdev_dev_bsd_cast(netdev_dev_);
427
struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
389
429
cache_notifier_unref();
391
if (netdev_dev->tap_fd >= 0 &&
392
!strcmp(netdev_dev_get_type(netdev_dev_), "tap")) {
393
destroy_tap(netdev_dev->tap_fd, netdev_dev_get_name(netdev_dev_));
400
netdev_bsd_open_system(struct netdev_dev *netdev_dev_, struct netdev **netdevp)
402
struct netdev_bsd *netdev;
404
enum netdev_flags flags;
406
/* Allocate network device. */
407
netdev = xcalloc(1, sizeof *netdev);
408
netdev->netdev_fd = -1;
409
netdev_init(&netdev->netdev, netdev_dev_);
411
/* Verify that the netdev really exists by attempting to read its flags */
412
error = netdev_get_flags(&netdev->netdev, &flags);
413
if (error == ENXIO) {
417
*netdevp = &netdev->netdev;
421
netdev_uninit(&netdev->netdev, true);
427
/* Close a 'netdev'. */
429
netdev_bsd_close(struct netdev *netdev_)
431
struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
433
if (netdev->netdev_fd >= 0 && strcmp(netdev_get_type(netdev_), "tap")) {
434
pcap_close(netdev->pcap_handle);
431
if (netdev->tap_fd >= 0) {
432
destroy_tap(netdev->tap_fd, netdev_get_kernel_name(netdev_));
435
pcap_close(netdev->pcap);
437
free(netdev->kernel_name);
441
netdev_bsd_listen(struct netdev *netdev_)
442
netdev_bsd_open_pcap(const char *name, pcap_t **pcapp, int *fdp)
443
struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
444
struct netdev_dev_bsd *netdev_dev =
445
netdev_dev_bsd_cast(netdev_get_dev(netdev_));
447
444
char errbuf[PCAP_ERRBUF_SIZE];
452
if (netdev->netdev_fd >= 0) {
456
if (!strcmp(netdev_get_type(netdev_), "tap") &&
457
!netdev_dev->tap_opened) {
458
netdev->netdev_fd = netdev_dev->tap_fd;
459
netdev_dev->tap_opened = true;
463
/* open the pcap device. The device is opened in non-promiscuous mode
450
/* Open the pcap device. The device is opened in non-promiscuous mode
464
451
* because the interface flags are manually set by the caller. */
465
452
errbuf[0] = '\0';
466
netdev->pcap_handle = pcap_open_live(netdev_get_name(netdev_), PCAP_SNAPLEN,
468
if (netdev->pcap_handle == NULL) {
469
VLOG_ERR("%s: pcap_open_live failed: %s",
470
netdev_get_name(netdev_), errbuf);
453
pcap = pcap_open_live(name, PCAP_SNAPLEN, 0, 1000, errbuf);
455
VLOG_ERR_RL(&rl, "%s: pcap_open_live failed: %s", name, errbuf);
473
} else if (errbuf[0] != '\0') {
474
VLOG_WARN("%s: pcap_open_live: %s",
475
netdev_get_name(netdev_), errbuf);
478
netdev_dev_bsd_changed(netdev_dev_bsd_cast(netdev_get_dev(netdev_)));
480
/* initialize netdev->netdev_fd */
481
fd = pcap_get_selectable_fd(netdev->pcap_handle);
459
if (errbuf[0] != '\0') {
460
VLOG_WARN_RL(&rl, "%s: pcap_open_live: %s", name, errbuf);
463
/* Get the underlying fd. */
464
fd = pcap_get_selectable_fd(pcap);
466
VLOG_WARN_RL(&rl, "%s: no selectable file descriptor", name);
487
471
/* Set non-blocking mode. Also the BIOCIMMEDIATE ioctl must be called
488
472
* on the file descriptor returned by pcap_get_selectable_fd to achieve
489
473
* a real non-blocking behaviour.*/
490
error = pcap_setnonblock(netdev->pcap_handle, 1, errbuf);
496
/* This call assure that reads return immediately upon packet reception.
497
* Otherwise, a read will block until either the kernel buffer becomes
498
* full or a timeout occurs. */
499
if(ioctl(fd, BIOCIMMEDIATE, &one) < 0 ) {
500
VLOG_ERR("ioctl(BIOCIMMEDIATE) on %s device failed: %s",
501
netdev_get_name(netdev_), strerror(errno));
506
/* Capture only incoming packets */
507
error = pcap_setdirection(netdev->pcap_handle, PCAP_D_IN);
513
netdev->netdev_fd = fd;
474
error = pcap_setnonblock(pcap, 1, errbuf);
480
/* This call assure that reads return immediately upon packet
481
* reception. Otherwise, a read will block until either the kernel
482
* buffer becomes full or a timeout occurs. */
483
if (ioctl(fd, BIOCIMMEDIATE, &one) < 0 ) {
484
VLOG_ERR_RL(&rl, "ioctl(BIOCIMMEDIATE) on %s device failed: %s",
485
name, ovs_strerror(errno));
490
/* Capture only incoming packets. */
491
error = pcap_setdirection(pcap, PCAP_D_IN);
518
close(netdev->netdev_fd);
511
netdev_bsd_rx_open(struct netdev *netdev_, struct netdev_rx **rxp)
513
struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
515
struct netdev_rx_bsd *rx;
519
if (!strcmp(netdev_get_type(netdev_), "tap")) {
523
int error = netdev_bsd_open_pcap(netdev_get_kernel_name(netdev_),
529
netdev_bsd_changed(netdev);
532
rx = xmalloc(sizeof *rx);
533
netdev_rx_init(&rx->up, netdev_, &netdev_rx_bsd_class);
534
rx->pcap_handle = pcap;
542
netdev_rx_bsd_destroy(struct netdev_rx *rx_)
544
struct netdev_rx_bsd *rx = netdev_rx_bsd_cast(rx_);
546
if (rx->pcap_handle) {
547
pcap_close(rx->pcap_handle);
524
552
/* The recv callback of the netdev class returns the number of bytes of the
525
553
* received packet.
630
* According with the nature of the device a different function must be called.
631
* If the device is the bridge local port the 'netdev_bsd_recv_tap' function
632
* must be called, otherwise the 'netdev_bsd_recv_system' function is called.
634
* type!="tap" ---> system device.
635
* type=="tap" && netdev_fd == tap_fd ---> internal tap device
636
* type=="tap" && netdev_fd != tap_fd ---> internal tap device
641
netdev_bsd_recv(struct netdev *netdev_, void* data, size_t size)
649
netdev_rx_bsd_recv(struct netdev_rx *rx_, void *data, size_t size)
643
struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
644
struct netdev_dev_bsd * netdev_dev =
645
netdev_dev_bsd_cast(netdev_get_dev(netdev_));
651
struct netdev_rx_bsd *rx = netdev_rx_bsd_cast(rx_);
647
if (!strcmp(netdev_get_type(netdev_), "tap") &&
648
netdev->netdev_fd == netdev_dev->tap_fd) {
649
return netdev_bsd_recv_tap(netdev, data, size);
651
return netdev_bsd_recv_system(netdev, data, size);
653
return (rx->pcap_handle
654
? netdev_rx_bsd_recv_pcap(rx, data, size)
655
: netdev_rx_bsd_recv_tap(rx, data, size));
657
659
* Registers with the poll loop to wake up from the next call to poll_block()
658
* when a packet is ready to be received with netdev_recv() on 'netdev'.
660
* when a packet is ready to be received with netdev_rx_recv() on 'rx'.
661
netdev_bsd_recv_wait(struct netdev *netdev_)
663
netdev_rx_bsd_wait(struct netdev_rx *rx_)
663
struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
665
struct netdev_rx_bsd *rx = netdev_rx_bsd_cast(rx_);
665
if (netdev->netdev_fd >= 0) {
666
poll_fd_wait(netdev->netdev_fd, POLLIN);
667
poll_fd_wait(rx->fd, POLLIN);
670
/* Discards all packets waiting to be received from 'netdev'. */
670
/* Discards all packets waiting to be received from 'rx'. */
672
netdev_bsd_drain(struct netdev *netdev_)
672
netdev_rx_bsd_drain(struct netdev_rx *rx_)
674
674
struct ifreq ifr;
675
struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
675
struct netdev_rx_bsd *rx = netdev_rx_bsd_cast(rx_);
677
strcpy(ifr.ifr_name, netdev_get_name(netdev_));
678
if (ioctl(netdev->netdev_fd, BIOCFLUSH, &ifr) == -1) {
677
strcpy(ifr.ifr_name, netdev_get_kernel_name(netdev_rx_get_netdev(rx_)));
678
if (ioctl(rx->fd, BIOCFLUSH, &ifr) == -1) {
679
679
VLOG_DBG_RL(&rl, "%s: ioctl(BIOCFLUSH) failed: %s",
680
netdev_get_name(netdev_), strerror(errno));
680
netdev_rx_get_name(rx_), ovs_strerror(errno));
691
691
netdev_bsd_send(struct netdev *netdev_, const void *data, size_t size)
693
struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
694
struct netdev_dev_bsd * netdev_dev =
695
netdev_dev_bsd_cast(netdev_get_dev(netdev_));
693
struct netdev_bsd *dev = netdev_bsd_cast(netdev_);
694
const char *name = netdev_get_name(netdev_);
697
if (netdev->netdev_fd < 0) {
696
if (dev->tap_fd < 0 && !dev->pcap) {
697
int error = netdev_bsd_open_pcap(name, &dev->pcap, &dev->fd);
703
if (!strcmp(netdev_get_type(netdev_), "tap") &&
704
netdev_dev->tap_fd == netdev->netdev_fd) {
705
retval = write(netdev->netdev_fd, data, size);
705
if (dev->tap_fd >= 0) {
706
retval = write(dev->tap_fd, data, size);
707
retval = pcap_inject(netdev->pcap_handle, data, size);
708
retval = pcap_inject(dev->pcap, data, size);
709
710
if (retval < 0) {
710
711
if (errno == EINTR) {
712
713
} else if (errno != EAGAIN) {
713
714
VLOG_WARN_RL(&rl, "error sending Ethernet packet on %s: %s",
714
netdev_get_name(netdev_), strerror(errno));
715
name, ovs_strerror(errno));
717
718
} else if (retval != size) {
718
719
VLOG_WARN_RL(&rl, "sent partial Ethernet packet (%zd bytes of "
719
"%zu) on %s", retval, size,
720
netdev_get_name(netdev_));
720
"%zu) on %s", retval, size, name);
755
754
netdev_bsd_set_etheraddr(struct netdev *netdev_,
756
const uint8_t mac[ETH_ADDR_LEN])
755
const uint8_t mac[ETH_ADDR_LEN])
758
struct netdev_dev_bsd *netdev_dev =
759
netdev_dev_bsd_cast(netdev_get_dev(netdev_));
757
struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
762
if (!(netdev_dev->cache_valid & VALID_ETHERADDR)
763
|| !eth_addr_equals(netdev_dev->etheraddr, mac)) {
764
error = set_etheraddr(netdev_get_name(netdev_), AF_LINK, ETH_ADDR_LEN,
760
if (!(netdev->cache_valid & VALID_ETHERADDR)
761
|| !eth_addr_equals(netdev->etheraddr, mac)) {
762
error = set_etheraddr(netdev_get_kernel_name(netdev_), AF_LINK,
767
netdev_dev->cache_valid |= VALID_ETHERADDR;
768
memcpy(netdev_dev->etheraddr, mac, ETH_ADDR_LEN);
769
netdev_dev_bsd_changed(netdev_dev);
765
netdev->cache_valid |= VALID_ETHERADDR;
766
memcpy(netdev->etheraddr, mac, ETH_ADDR_LEN);
767
netdev_bsd_changed(netdev);
838
835
netdev_bsd_get_carrier(const struct netdev *netdev_, bool *carrier)
840
struct netdev_dev_bsd *netdev_dev =
841
netdev_dev_bsd_cast(netdev_get_dev(netdev_));
837
struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
843
if (!(netdev_dev->cache_valid & VALID_CARRIER)) {
839
if (!(netdev->cache_valid & VALID_CARRIER)) {
844
840
struct ifmediareq ifmr;
846
842
memset(&ifmr, 0, sizeof(ifmr));
847
strncpy(ifmr.ifm_name, netdev_get_name(netdev_), sizeof ifmr.ifm_name);
843
strncpy(ifmr.ifm_name, netdev_get_kernel_name(netdev_),
844
sizeof ifmr.ifm_name);
849
846
if (ioctl(af_inet_sock, SIOCGIFMEDIA, &ifmr) == -1) {
850
847
VLOG_DBG_RL(&rl, "%s: ioctl(SIOCGIFMEDIA) failed: %s",
851
netdev_get_name(netdev_), strerror(errno));
848
netdev_get_name(netdev_), ovs_strerror(errno));
855
netdev_dev->carrier = (ifmr.ifm_status & IFM_ACTIVE) == IFM_ACTIVE;
856
netdev_dev->cache_valid |= VALID_CARRIER;
852
netdev->carrier = (ifmr.ifm_status & IFM_ACTIVE) == IFM_ACTIVE;
853
netdev->cache_valid |= VALID_CARRIER;
858
855
/* If the interface doesn't report whether the media is active,
859
856
* just assume it is active. */
860
857
if ((ifmr.ifm_status & IFM_AVALID) == 0) {
861
netdev_dev->carrier = true;
858
netdev->carrier = true;
864
*carrier = netdev_dev->carrier;
861
*carrier = netdev->carrier;
867
convert_stats(struct netdev_stats *stats, const struct if_data *ifd)
870
* note: UINT64_MAX means unsupported
872
stats->rx_packets = ifd->ifi_ipackets;
873
stats->tx_packets = ifd->ifi_opackets;
874
stats->rx_bytes = ifd->ifi_obytes;
875
stats->tx_bytes = ifd->ifi_ibytes;
876
stats->rx_errors = ifd->ifi_ierrors;
877
stats->tx_errors = ifd->ifi_oerrors;
878
stats->rx_dropped = ifd->ifi_iqdrops;
879
stats->tx_dropped = UINT64_MAX;
880
stats->multicast = ifd->ifi_imcasts;
881
stats->collisions = ifd->ifi_collisions;
882
stats->rx_length_errors = UINT64_MAX;
883
stats->rx_over_errors = UINT64_MAX;
884
stats->rx_crc_errors = UINT64_MAX;
885
stats->rx_frame_errors = UINT64_MAX;
886
stats->rx_fifo_errors = UINT64_MAX;
887
stats->rx_missed_errors = UINT64_MAX;
888
stats->tx_aborted_errors = UINT64_MAX;
889
stats->tx_carrier_errors = UINT64_MAX;
890
stats->tx_fifo_errors = UINT64_MAX;
891
stats->tx_heartbeat_errors = UINT64_MAX;
892
stats->tx_window_errors = UINT64_MAX;
869
895
/* Retrieves current device stats for 'netdev'. */
871
897
netdev_bsd_get_stats(const struct netdev *netdev_, struct netdev_stats *stats)
899
#if defined(__FreeBSD__)
897
924
mib[4] = i; //row
898
925
if (sysctl(mib, 6, &ifmd, &len, (void *)0, 0) == -1) {
899
926
VLOG_DBG_RL(&rl, "%s: sysctl failed: %s",
900
netdev_get_name(netdev_), strerror(errno));
927
netdev_get_name(netdev_), ovs_strerror(errno));
902
929
} else if (!strcmp(ifmd.ifmd_name, netdev_get_name(netdev_))) {
903
stats->rx_packets = ifmd.ifmd_data.ifi_ipackets;
904
stats->tx_packets = ifmd.ifmd_data.ifi_opackets;
905
stats->rx_bytes = ifmd.ifmd_data.ifi_ibytes;
906
stats->tx_bytes = ifmd.ifmd_data.ifi_obytes;
907
stats->rx_errors = ifmd.ifmd_data.ifi_ierrors;
908
stats->tx_errors = ifmd.ifmd_data.ifi_oerrors;
909
stats->rx_dropped = ifmd.ifmd_data.ifi_iqdrops;
910
stats->tx_dropped = UINT64_MAX;
911
stats->multicast = ifmd.ifmd_data.ifi_imcasts;
912
stats->collisions = ifmd.ifmd_data.ifi_collisions;
914
stats->rx_length_errors = UINT64_MAX;
915
stats->rx_over_errors = UINT64_MAX;
916
stats->rx_crc_errors = UINT64_MAX;
917
stats->rx_frame_errors = UINT64_MAX;
918
stats->rx_fifo_errors = UINT64_MAX;
919
stats->rx_missed_errors = UINT64_MAX;
921
stats->tx_aborted_errors = UINT64_MAX;
922
stats->tx_carrier_errors = UINT64_MAX;
923
stats->tx_fifo_errors = UINT64_MAX;
924
stats->tx_heartbeat_errors = UINT64_MAX;
925
stats->tx_window_errors = UINT64_MAX;
930
convert_stats(stats, &ifmd.ifmd_data);
936
#elif defined(__NetBSD__)
937
struct ifdatareq ifdr;
941
memset(&ifdr, 0, sizeof(ifdr));
942
strncpy(ifdr.ifdr_name, netdev_get_kernel_name(netdev_),
943
sizeof(ifdr.ifdr_name));
944
ret = ioctl(af_link_sock, SIOCGIFDATA, &ifdr);
949
convert_stats(stats, &ifdr.ifdr_data);
952
#error not implemented
1080
1103
netdev_bsd_get_in4(const struct netdev *netdev_, struct in_addr *in4,
1081
1104
struct in_addr *netmask)
1083
struct netdev_dev_bsd *netdev_dev =
1084
netdev_dev_bsd_cast(netdev_get_dev(netdev_));
1106
struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
1086
if (!(netdev_dev->cache_valid & VALID_IN4)) {
1108
if (!(netdev->cache_valid & VALID_IN4)) {
1087
1109
const struct sockaddr_in *sin;
1088
1110
struct ifreq ifr;
1091
1113
ifr.ifr_addr.sa_family = AF_INET;
1092
error = netdev_bsd_do_ioctl(netdev_, &ifr,
1093
SIOCGIFADDR, "SIOCGIFADDR");
1114
error = netdev_bsd_do_ioctl(netdev_get_kernel_name(netdev_), &ifr,
1115
SIOCGIFADDR, "SIOCGIFADDR");
1098
1120
sin = (struct sockaddr_in *) &ifr.ifr_addr;
1099
netdev_dev->in4 = sin->sin_addr;
1100
netdev_dev->cache_valid |= VALID_IN4;
1101
error = netdev_bsd_do_ioctl(netdev_, &ifr,
1102
SIOCGIFNETMASK, "SIOCGIFNETMASK");
1121
netdev->in4 = sin->sin_addr;
1122
netdev->cache_valid |= VALID_IN4;
1123
error = netdev_bsd_do_ioctl(netdev_get_kernel_name(netdev_), &ifr,
1124
SIOCGIFNETMASK, "SIOCGIFNETMASK");
1106
1128
*netmask = ((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr;
1108
*in4 = netdev_dev->in4;
1110
1132
return in4->s_addr == INADDR_ANY ? EADDRNOTAVAIL : 0;
1168
1188
return EADDRNOTAVAIL;
1170
*in6 = netdev_dev->in6;
1194
#if defined(__NetBSD__)
1195
static struct netdev *
1196
find_netdev_by_kernel_name(const char *kernel_name)
1198
struct shash device_shash;
1199
struct shash_node *node;
1201
shash_init(&device_shash);
1202
netdev_get_devices(&netdev_tap_class, &device_shash);
1203
SHASH_FOR_EACH(node, &device_shash) {
1204
struct netdev_bsd * const dev = node->data;
1206
if (!strcmp(dev->kernel_name, kernel_name)) {
1207
shash_destroy(&device_shash);
1211
shash_destroy(&device_shash);
1216
netdev_bsd_convert_kernel_name_to_ovs_name(const char *kernel_name)
1218
const struct netdev * const netdev =
1219
find_netdev_by_kernel_name(kernel_name);
1221
if (netdev == NULL) {
1224
return netdev_get_name(netdev);
1229
netdev_bsd_get_next_hop(const struct in_addr *host OVS_UNUSED,
1230
struct in_addr *next_hop OVS_UNUSED,
1231
char **netdev_name OVS_UNUSED)
1233
#if defined(__NetBSD__)
1235
struct sockaddr_in sin;
1236
struct sockaddr_dl sdl;
1243
struct rt_msghdr *rtm = &buf.h;
1244
const pid_t pid = getpid();
1247
bool gateway = false;
1248
char *ifname = NULL;
1251
memset(next_hop, 0, sizeof(*next_hop));
1252
*netdev_name = NULL;
1254
memset(&sin, 0, sizeof(sin));
1255
sin.sin_len = sizeof(sin);
1256
sin.sin_family = AF_INET;
1258
sin.sin_addr = *host;
1260
memset(&sdl, 0, sizeof(sdl));
1261
sdl.sdl_len = sizeof(sdl);
1262
sdl.sdl_family = AF_LINK;
1264
s = socket(PF_ROUTE, SOCK_RAW, 0);
1265
memset(&buf, 0, sizeof(buf));
1266
rtm->rtm_flags = RTF_HOST|RTF_UP;
1267
rtm->rtm_version = RTM_VERSION;
1268
rtm->rtm_addrs = RTA_DST|RTA_IFP;
1269
cp = (void *)&buf.space;
1270
memcpy(cp, &sin, sizeof(sin));
1271
RT_ADVANCE(cp, (struct sockaddr *)(void *)&sin);
1272
memcpy(cp, &sdl, sizeof(sdl));
1273
RT_ADVANCE(cp, (struct sockaddr *)(void *)&sdl);
1274
rtm->rtm_msglen = cp - (char *)(void *)rtm;
1275
rtm->rtm_seq = ++seq;
1276
rtm->rtm_type = RTM_GET;
1278
write(s, rtm, rtm->rtm_msglen);
1279
memset(&buf, 0, sizeof(buf));
1281
ssz = read(s, &buf, sizeof(buf));
1282
} while (ssz > 0 && (rtm->rtm_seq != seq || rtm->rtm_pid != pid));
1283
saved_errno = errno;
1289
return EPIPE; /* XXX */
1291
cp = (void *)&buf.space;
1292
for (i = 1; i; i <<= 1) {
1293
if ((rtm->rtm_addrs & i) != 0) {
1294
const struct sockaddr *sa = (const void *)cp;
1296
if ((i == RTA_GATEWAY) && sa->sa_family == AF_INET) {
1297
const struct sockaddr_in * const sin =
1298
(const struct sockaddr_in *)sa;
1300
*next_hop = sin->sin_addr;
1303
if ((i == RTA_IFP) && sa->sa_family == AF_LINK) {
1304
const struct sockaddr_dl * const sdl =
1305
(const struct sockaddr_dl *)sa;
1306
const size_t nlen = sdl->sdl_nlen;
1307
char * const kernel_name = xmalloc(nlen + 1);
1310
memcpy(kernel_name, sdl->sdl_data, nlen);
1311
kernel_name[nlen] = 0;
1312
name = netdev_bsd_convert_kernel_name_to_ovs_name(kernel_name);
1314
ifname = xstrdup(kernel_name);
1316
ifname = xstrdup(name);
1323
if (ifname == NULL) {
1329
*netdev_name = ifname;
1330
VLOG_DBG("host " IP_FMT " next-hop " IP_FMT " if %s",
1331
IP_ARGS(host->s_addr), IP_ARGS(next_hop->s_addr), *netdev_name);
1386
1549
struct ifreq ifr;
1389
error = netdev_bsd_do_ioctl(netdev, &ifr, SIOCGIFFLAGS, "SIOCGIFFLAGS");
1552
error = netdev_bsd_do_ioctl(netdev_get_kernel_name(netdev), &ifr,
1553
SIOCGIFFLAGS, "SIOCGIFFLAGS");
1391
*flags = 0xFFFF0000 & (ifr.ifr_flagshigh << 16);
1392
*flags |= 0x0000FFFF & ifr.ifr_flags;
1555
*flags = ifr_get_flags(&ifr);
1398
set_flags(struct netdev *netdev, int flags)
1561
set_flags(const char *name, int flags)
1400
1563
struct ifreq ifr;
1402
ifr.ifr_flags = 0x0000FFFF & flags;
1403
ifr.ifr_flagshigh = (0xFFFF0000 & flags) >> 16;
1565
ifr_set_flags(&ifr, flags);
1405
return netdev_bsd_do_ioctl(netdev, &ifr, SIOCSIFFLAGS, "SIOCSIFFLAGS");
1567
return netdev_bsd_do_ioctl(name, &ifr, SIOCSIFFLAGS, "SIOCSIFFLAGS");
1409
1571
get_ifindex(const struct netdev *netdev_, int *ifindexp)
1411
struct netdev_dev_bsd *netdev_dev =
1412
netdev_dev_bsd_cast(netdev_get_dev(netdev_));
1573
struct netdev_bsd *netdev = netdev_bsd_cast(netdev_);
1414
if (!(netdev_dev->cache_valid & VALID_IFINDEX)) {
1575
if (!(netdev->cache_valid & VALID_IFINDEX)) {
1415
1576
int ifindex = if_nametoindex(netdev_get_name(netdev_));
1416
1577
if (ifindex <= 0) {
1419
netdev_dev->cache_valid |= VALID_IFINDEX;
1420
netdev_dev->ifindex = ifindex;
1580
netdev->cache_valid |= VALID_IFINDEX;
1581
netdev->ifindex = ifindex;
1422
*ifindexp = netdev_dev->ifindex;
1583
*ifindexp = netdev->ifindex;
1467
1630
memcpy(ifr.ifr_addr.sa_data, mac, hwaddr_len);
1468
1631
if (ioctl(af_inet_sock, SIOCSIFLLADDR, &ifr) < 0) {
1469
1632
VLOG_ERR("ioctl(SIOCSIFLLADDR) on %s device failed: %s",
1470
netdev_name, strerror(errno));
1633
netdev_name, ovs_strerror(errno));
1637
#elif defined(__NetBSD__)
1638
struct if_laddrreq req;
1639
struct sockaddr_dl *sdl;
1640
struct sockaddr_storage oldaddr;
1644
* get the old address, add new one, and then remove old one.
1647
if (hwaddr_len != ETH_ADDR_LEN) {
1648
/* just to be safe about sockaddr storage size */
1651
memset(&req, 0, sizeof(req));
1652
strncpy(req.iflr_name, netdev_name, sizeof(req.iflr_name));
1653
req.addr.ss_len = sizeof(req.addr);
1654
req.addr.ss_family = hwaddr_family;
1655
sdl = (struct sockaddr_dl *)&req.addr;
1656
sdl->sdl_alen = hwaddr_len;
1657
ret = ioctl(af_link_sock, SIOCGLIFADDR, &req);
1661
if (!memcmp(&sdl->sdl_data[sdl->sdl_nlen], mac, hwaddr_len)) {
1666
memset(&req, 0, sizeof(req));
1667
strncpy(req.iflr_name, netdev_name, sizeof(req.iflr_name));
1668
req.flags = IFLR_ACTIVE;
1669
sdl = (struct sockaddr_dl *)&req.addr;
1670
sdl->sdl_len = offsetof(struct sockaddr_dl, sdl_data) + hwaddr_len;
1671
sdl->sdl_alen = hwaddr_len;
1672
sdl->sdl_family = hwaddr_family;
1673
memcpy(sdl->sdl_data, mac, hwaddr_len);
1674
ret = ioctl(af_link_sock, SIOCALIFADDR, &req);
1679
memset(&req, 0, sizeof(req));
1680
strncpy(req.iflr_name, netdev_name, sizeof(req.iflr_name));
1682
ret = ioctl(af_link_sock, SIOCDLIFADDR, &req);
1688
#error not implemented
1477
netdev_bsd_do_ioctl(const struct netdev *netdev, struct ifreq *ifr,
1478
unsigned long cmd, const char *cmd_name)
1693
netdev_bsd_do_ioctl(const char *name, struct ifreq *ifr, unsigned long cmd,
1694
const char *cmd_name)
1480
strncpy(ifr->ifr_name, netdev_get_name(netdev), sizeof ifr->ifr_name);
1696
strncpy(ifr->ifr_name, name, sizeof ifr->ifr_name);
1481
1697
if (ioctl(af_inet_sock, cmd, ifr) == -1) {
1482
VLOG_DBG_RL(&rl, "%s: ioctl(%s) failed: %s",
1483
netdev_get_name(netdev), cmd_name, strerror(errno));
1698
VLOG_DBG_RL(&rl, "%s: ioctl(%s) failed: %s", name, cmd_name,
1699
ovs_strerror(errno));
1706
ifr_get_flags(const struct ifreq *ifr)
1708
#ifdef HAVE_STRUCT_IFREQ_IFR_FLAGSHIGH
1709
return (ifr->ifr_flagshigh << 16) | ifr->ifr_flags;
1711
return ifr->ifr_flags;
1716
ifr_set_flags(struct ifreq *ifr, int flags)
1718
ifr->ifr_flags = flags;
1719
#ifdef HAVE_STRUCT_IFREQ_IFR_FLAGSHIGH
1720
ifr->ifr_flagshigh = flags >> 16;