int ifindex;
uint8_t etheraddr[ETH_ADDR_LEN];
struct in_addr in4;
+ struct in_addr netmask;
struct in6_addr in6;
int mtu;
int carrier;
af_inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
status = af_inet_sock >= 0 ? 0 : errno;
if (status) {
- VLOG_ERR("failed to create inet socket: %s", strerror(status));
+ VLOG_ERR("failed to create inet socket: %s", ovs_strerror(status));
return status;
}
af_link_sock = socket(AF_LINK, SOCK_DGRAM, 0);
status = af_link_sock >= 0 ? 0 : errno;
if (status) {
- VLOG_ERR("failed to create link socket: %s", strerror(status));
+ VLOG_ERR("failed to create link socket: %s", ovs_strerror(status));
close(af_inet_sock);
af_inet_sock = -1;
}
dev->cache_valid = 0;
netdev_bsd_changed(dev);
}
+ netdev_close(base_dev);
}
} else {
/*
shash_init(&device_shash);
netdev_get_devices(&netdev_bsd_class, &device_shash);
SHASH_FOR_EACH (node, &device_shash) {
- dev = node->data;
+ struct netdev *netdev = node->data;
+ dev = netdev_bsd_cast(netdev);
dev->cache_valid = 0;
netdev_bsd_changed(dev);
+ netdev_close(netdev);
}
shash_destroy(&device_shash);
}
/* Verify that the netdev really exists by attempting to read its flags */
error = netdev_get_flags(&netdev->up, &flags);
if (error == ENXIO) {
+ free(netdev->kernel_name);
netdev_uninit(&netdev->up, false);
free(netdev);
cache_notifier_unref();
netdev->change_seq = 1;
if (netdev->tap_fd < 0) {
error = errno;
- VLOG_WARN("opening \"/dev/tap\" failed: %s", strerror(error));
- goto error_undef_notifier;
+ VLOG_WARN("opening \"/dev/tap\" failed: %s", ovs_strerror(error));
+ goto error_unref_notifier;
}
/* Retrieve tap name (e.g. tap0) */
if (ioctl(netdev->tap_fd, TAPGIFNAME, &ifr) == -1) {
/* XXX Need to destroy the device? */
error = errno;
- goto error_undef_notifier;
+ close(netdev->tap_fd);
+ goto error_unref_notifier;
}
/* Change the name of the tap device */
if (ioctl(af_inet_sock, SIOCSIFNAME, &ifr) == -1) {
error = errno;
destroy_tap(netdev->tap_fd, ifr.ifr_name);
- goto error_undef_notifier;
+ goto error_unref_notifier;
}
kernel_name = xstrdup(name);
#else
error = set_nonblocking(netdev->tap_fd);
if (error) {
destroy_tap(netdev->tap_fd, kernel_name);
- goto error_undef_notifier;
+ goto error_unref_notifier;
}
/* Turn device UP */
if (ioctl(af_inet_sock, SIOCSIFFLAGS, &ifr) == -1) {
error = errno;
destroy_tap(netdev->tap_fd, kernel_name);
- goto error_undef_notifier;
+ goto error_unref_notifier;
}
/* initialize the device structure and
return 0;
-error_undef_notifier:
+error_unref_notifier:
cache_notifier_unref();
error:
free(netdev);
* buffer becomes full or a timeout occurs. */
if (ioctl(fd, BIOCIMMEDIATE, &one) < 0 ) {
VLOG_ERR_RL(&rl, "ioctl(BIOCIMMEDIATE) on %s device failed: %s",
- name, strerror(errno));
+ name, ovs_strerror(errno));
error = errno;
goto error;
}
} else if (errno != EINTR) {
if (errno != EAGAIN) {
VLOG_WARN_RL(&rl, "error receiving Ethernet packet on %s: %s",
- strerror(errno), netdev_rx_get_name(&rx->up));
+ ovs_strerror(errno), netdev_rx_get_name(&rx->up));
}
return -errno;
}
strcpy(ifr.ifr_name, netdev_get_kernel_name(netdev_rx_get_netdev(rx_)));
if (ioctl(rx->fd, BIOCFLUSH, &ifr) == -1) {
VLOG_DBG_RL(&rl, "%s: ioctl(BIOCFLUSH) failed: %s",
- netdev_rx_get_name(rx_), strerror(errno));
+ netdev_rx_get_name(rx_), ovs_strerror(errno));
return errno;
}
return 0;
continue;
} else if (errno != EAGAIN) {
VLOG_WARN_RL(&rl, "error sending Ethernet packet on %s: %s",
- name, strerror(errno));
+ name, ovs_strerror(errno));
}
return errno;
} else if (retval != size) {
if (ioctl(af_inet_sock, SIOCGIFMEDIA, &ifmr) == -1) {
VLOG_DBG_RL(&rl, "%s: ioctl(SIOCGIFMEDIA) failed: %s",
- netdev_get_name(netdev_), strerror(errno));
+ netdev_get_name(netdev_), ovs_strerror(errno));
return errno;
}
if (sysctl(mib, 5, &if_count, &len, (void *)0, 0) == -1) {
VLOG_DBG_RL(&rl, "%s: sysctl failed: %s",
- netdev_get_name(netdev_), strerror(errno));
+ netdev_get_name(netdev_), ovs_strerror(errno));
return errno;
}
mib[4] = i; //row
if (sysctl(mib, 6, &ifmd, &len, (void *)0, 0) == -1) {
VLOG_DBG_RL(&rl, "%s: sysctl failed: %s",
- netdev_get_name(netdev_), strerror(errno));
+ netdev_get_name(netdev_), ovs_strerror(errno));
return errno;
} else if (!strcmp(ifmd.ifmd_name, netdev_get_name(netdev_))) {
convert_stats(stats, &ifmd.ifmd_data);
* them. */
if (ioctl(af_inet_sock, SIOCGIFMEDIA, &ifmr) == -1) {
VLOG_DBG_RL(&rl, "%s: ioctl(SIOCGIFMEDIA) failed: %s",
- netdev_get_name(netdev), strerror(errno));
+ netdev_get_name(netdev), ovs_strerror(errno));
return errno;
}
if (ioctl(af_inet_sock, SIOCGIFMEDIA, &ifmr) == -1) {
VLOG_DBG_RL(&rl, "%s: ioctl(SIOCGIFMEDIA) failed: %s",
- netdev_get_name(netdev), strerror(errno));
+ netdev_get_name(netdev), ovs_strerror(errno));
error = errno;
goto cleanup;
}
}
/*
- * If 'netdev' has an assigned IPv4 address, sets '*in4' to that address (if
- * 'in4' is non-null) and returns true. Otherwise, returns false.
+ * If 'netdev' has an assigned IPv4 address, sets '*in4' to that address and
+ * '*netmask' to its netmask and returns true. Otherwise, returns false.
*/
static int
netdev_bsd_get_in4(const struct netdev *netdev_, struct in_addr *in4,
sin = (struct sockaddr_in *) &ifr.ifr_addr;
netdev->in4 = sin->sin_addr;
- netdev->cache_valid |= VALID_IN4;
error = netdev_bsd_do_ioctl(netdev_get_kernel_name(netdev_), &ifr,
SIOCGIFNETMASK, "SIOCGIFNETMASK");
if (error) {
return error;
}
- *netmask = ((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr;
+ netdev->netmask = sin->sin_addr;
+ netdev->cache_valid |= VALID_IN4;
}
*in4 = netdev->in4;
+ *netmask = netdev->netmask;
return in4->s_addr == INADDR_ANY ? EADDRNOTAVAIL : 0;
}
error = do_set_addr(netdev_, SIOCSIFADDR, "SIOCSIFADDR", addr);
if (!error) {
- netdev->cache_valid |= VALID_IN4;
- netdev->in4 = addr;
if (addr.s_addr != INADDR_ANY) {
error = do_set_addr(netdev_, SIOCSIFNETMASK,
"SIOCSIFNETMASK", mask);
+ if (!error) {
+ netdev->cache_valid |= VALID_IN4;
+ netdev->in4 = addr;
+ netdev->netmask = mask;
+ }
}
netdev_bsd_changed(netdev);
}
if (getifaddrs(&head) != 0) {
VLOG_ERR("getifaddrs on %s device failed: %s", netdev_name,
- strerror(errno));
+ ovs_strerror(errno));
return errno;
}
}
#if defined(__NetBSD__)
-static struct netdev *
-find_netdev_by_kernel_name(const char *kernel_name)
+static char *
+netdev_bsd_kernel_name_to_ovs_name(const char *kernel_name)
{
+ char *ovs_name = NULL;
struct shash device_shash;
struct shash_node *node;
shash_init(&device_shash);
netdev_get_devices(&netdev_tap_class, &device_shash);
SHASH_FOR_EACH(node, &device_shash) {
- struct netdev_bsd * const dev = node->data;
+ struct netdev *netdev = node->data;
+ struct netdev_bsd * const dev = netdev_bsd_cast(netdev);
if (!strcmp(dev->kernel_name, kernel_name)) {
- shash_destroy(&device_shash);
- return &dev->up;
+ free(ovs_name);
+ ovs_name = xstrdup(netdev_get_name(&dev->up));
}
+ netdev_close(netdev);
}
shash_destroy(&device_shash);
- return NULL;
-}
-static const char *
-netdev_bsd_convert_kernel_name_to_ovs_name(const char *kernel_name)
-{
- const struct netdev * const netdev =
- find_netdev_by_kernel_name(kernel_name);
-
- if (netdev == NULL) {
- return NULL;
- }
- return netdev_get_name(netdev);
+ return ovs_name ? ovs_name : xstrdup(kernel_name);
}
#endif
static int
-netdev_bsd_get_next_hop(const struct in_addr *host, struct in_addr *next_hop,
- char **netdev_name)
+netdev_bsd_get_next_hop(const struct in_addr *host OVS_UNUSED,
+ struct in_addr *next_hop OVS_UNUSED,
+ char **netdev_name OVS_UNUSED)
{
#if defined(__NetBSD__)
static int seq = 0;
if ((i == RTA_IFP) && sa->sa_family == AF_LINK) {
const struct sockaddr_dl * const sdl =
(const struct sockaddr_dl *)sa;
- const size_t nlen = sdl->sdl_nlen;
- char * const kernel_name = xmalloc(nlen + 1);
- const char *name;
-
- memcpy(kernel_name, sdl->sdl_data, nlen);
- kernel_name[nlen] = 0;
- name = netdev_bsd_convert_kernel_name_to_ovs_name(kernel_name);
- if (name == NULL) {
- ifname = xstrdup(kernel_name);
- } else {
- ifname = xstrdup(name);
- }
+ char *kernel_name;
+
+ kernel_name = xmemdup0(sdl->sdl_data, sdl->sdl_nlen);
+ ifname = netdev_bsd_kernel_name_to_ovs_name(kernel_name);
free(kernel_name);
}
RT_ADVANCE(cp, sa);
if (getifaddrs(&head) != 0) {
VLOG_ERR("getifaddrs on %s device failed: %s", netdev_name,
- strerror(errno));
+ ovs_strerror(errno));
return errno;
}
memcpy(ifr.ifr_addr.sa_data, mac, hwaddr_len);
if (ioctl(af_inet_sock, SIOCSIFLLADDR, &ifr) < 0) {
VLOG_ERR("ioctl(SIOCSIFLLADDR) on %s device failed: %s",
- netdev_name, strerror(errno));
+ netdev_name, ovs_strerror(errno));
return errno;
}
return 0;
strncpy(ifr->ifr_name, name, sizeof ifr->ifr_name);
if (ioctl(af_inet_sock, cmd, ifr) == -1) {
VLOG_DBG_RL(&rl, "%s: ioctl(%s) failed: %s", name, cmd_name,
- strerror(errno));
+ ovs_strerror(errno));
return errno;
}
return 0;