Since netdev can have multiple IP address use generic api netdev_get_addr_list(). This also make it easier to handle IPv4 and IPv6 address across vswitchd layers.
Signed-off-by: Pravin B Shelar <pshe...@nicira.com> Acked-by: Ben Pfaff <b...@ovn.org> --- lib/netdev-bsd.c | 61 ++++-------------------------------- lib/netdev-dpdk.c | 1 - lib/netdev-dummy.c | 15 --------- lib/netdev-linux.c | 87 ++++++--------------------------------------------- lib/netdev-provider.h | 14 --------- lib/netdev-vport.c | 1 - lib/netdev.c | 66 ++++++++++++++------------------------ lib/netdev.h | 2 -- 8 files changed, 40 insertions(+), 207 deletions(-) diff --git a/lib/netdev-bsd.c b/lib/netdev-bsd.c index 7a45b2d..75bd5a3 100644 --- a/lib/netdev-bsd.c +++ b/lib/netdev-bsd.c @@ -91,8 +91,6 @@ struct netdev_bsd { int ifindex; struct eth_addr etheraddr; - struct in_addr in4; - struct in_addr netmask; int mtu; int carrier; @@ -105,12 +103,11 @@ struct netdev_bsd { enum { - VALID_IFINDEX = 1 << 0, + VALID_IFINDEX = 1 << 0, VALID_ETHERADDR = 1 << 1, - VALID_IN4 = 1 << 2, - VALID_IN6 = 1 << 3, - VALID_MTU = 1 << 4, - VALID_CARRIER = 1 << 5 + VALID_IN = 1 << 2, + VALID_MTU = 1 << 3, + VALID_CARRIER = 1 << 4 }; #define PCAP_SNAPLEN 2048 @@ -1173,46 +1170,6 @@ cleanup: } /* - * 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, - struct in_addr *netmask) -{ - struct netdev_bsd *netdev = netdev_bsd_cast(netdev_); - int error = 0; - - ovs_mutex_lock(&netdev->mutex); - if (!(netdev->cache_valid & VALID_IN4)) { - struct ifreq ifr; - - ifr.ifr_addr.sa_family = AF_INET; - error = af_inet_ifreq_ioctl(netdev_get_kernel_name(netdev_), &ifr, - SIOCGIFADDR, "SIOCGIFADDR"); - if (!error) { - const struct sockaddr_in *sin; - - sin = ALIGNED_CAST(struct sockaddr_in *, &ifr.ifr_addr); - netdev->in4 = sin->sin_addr; - netdev->cache_valid |= VALID_IN4; - error = af_inet_ifreq_ioctl(netdev_get_kernel_name(netdev_), &ifr, - SIOCGIFNETMASK, "SIOCGIFNETMASK"); - if (!error) { - *netmask = sin->sin_addr; - } - } - } - if (!error) { - *in4 = netdev->in4; - *netmask = netdev->netmask; - } - ovs_mutex_unlock(&netdev->mutex); - - return error ? error : in4->s_addr == INADDR_ANY ? EADDRNOTAVAIL : 0; -} - -/* * Assigns 'addr' as 'netdev''s IPv4 address and 'mask' as its netmask. If * 'addr' is INADDR_ANY, 'netdev''s IPv4 address is cleared. Returns a * positive errno value. @@ -1230,11 +1187,6 @@ netdev_bsd_set_in4(struct netdev *netdev_, struct in_addr 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_change_seq_changed(netdev_); } @@ -1250,12 +1202,12 @@ netdev_bsd_get_addr_list(const struct netdev *netdev_, struct netdev_bsd *netdev = netdev_bsd_cast(netdev_); int error; - if (!(netdev->cache_valid & VALID_IN6)) { + if (!(netdev->cache_valid & VALID_IN)) { netdev_get_addrs_list_flush(); } error = netdev_get_addrs(netdev_get_name(netdev_), addr, mask, n_cnt); if (!error) { - netdev->cache_valid |= VALID_IN6; + netdev->cache_valid |= VALID_IN; } return error; } @@ -1577,7 +1529,6 @@ netdev_bsd_update_flags(struct netdev *netdev_, enum netdev_flags off, NULL, /* queue_dump_done */ \ NULL, /* dump_queue_stats */ \ \ - netdev_bsd_get_in4, \ netdev_bsd_set_in4, \ netdev_bsd_get_addr_list, \ NULL, /* add_router */ \ diff --git a/lib/netdev-dpdk.c b/lib/netdev-dpdk.c index fd96f7b..7c4cd07 100644 --- a/lib/netdev-dpdk.c +++ b/lib/netdev-dpdk.c @@ -2691,7 +2691,6 @@ static const struct dpdk_qos_ops egress_policer_ops = { NULL, /* queue_dump_done */ \ NULL, /* dump_queue_stats */ \ \ - NULL, /* get_in4 */ \ NULL, /* set_in4 */ \ NULL, /* get_addr_list */ \ NULL, /* add_router */ \ diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c index c3c206f..8be1ba7 100644 --- a/lib/netdev-dummy.c +++ b/lib/netdev-dummy.c @@ -717,20 +717,6 @@ netdev_dummy_get_config(const struct netdev *netdev_, struct smap *args) } static int -netdev_dummy_get_in4(const struct netdev *netdev_, - struct in_addr *address, struct in_addr *netmask) -{ - struct netdev_dummy *netdev = netdev_dummy_cast(netdev_); - - ovs_mutex_lock(&netdev->mutex); - *address = netdev->address; - *netmask = netdev->netmask; - ovs_mutex_unlock(&netdev->mutex); - - return address->s_addr ? 0 : EADDRNOTAVAIL; -} - -static int netdev_dummy_get_addr_list(const struct netdev *netdev_, struct in6_addr **paddr, struct in6_addr **pmask, int *n_addr) { @@ -1282,7 +1268,6 @@ static const struct netdev_class dummy_class = { netdev_dummy_queue_dump_done, netdev_dummy_dump_queue_stats, - netdev_dummy_get_in4, /* get_in4 */ NULL, /* set_in4 */ netdev_dummy_get_addr_list, NULL, /* add_router */ diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 48aa83b..994a27c 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -220,13 +220,12 @@ struct rtnl_link_stats64 { enum { VALID_IFINDEX = 1 << 0, VALID_ETHERADDR = 1 << 1, - VALID_IN4 = 1 << 2, - VALID_IN6 = 1 << 3, - VALID_MTU = 1 << 4, - VALID_POLICING = 1 << 5, - VALID_VPORT_STAT_ERROR = 1 << 6, - VALID_DRVINFO = 1 << 7, - VALID_FEATURES = 1 << 8, + VALID_IN = 1 << 2, + VALID_MTU = 1 << 3, + VALID_POLICING = 1 << 4, + VALID_VPORT_STAT_ERROR = 1 << 5, + VALID_DRVINFO = 1 << 6, + VALID_FEATURES = 1 << 7, }; /* Traffic control. */ @@ -482,7 +481,6 @@ struct netdev_linux { * when the corresponding VALID_* bit in 'cache_valid' is set. */ int ifindex; struct eth_addr etheraddr; - struct in_addr address, netmask; int mtu; unsigned int ifi_flags; long long int carrier_resets; @@ -495,8 +493,6 @@ struct netdev_linux { int netdev_policing_error; /* Cached error code from set policing. */ int get_features_error; /* Cached error code from ETHTOOL_GSET. */ int get_ifindex_error; /* Cached error code from SIOCGIFINDEX. */ - int in4_error; /* Cached error code from reading in4 addr. */ - int in6_error; /* Cached error code from reading in6 addr. */ enum netdev_features current; /* Cached from ETHTOOL_GSET. */ enum netdev_features advertised; /* Cached from ETHTOOL_GSET. */ @@ -531,8 +527,6 @@ static void netdev_linux_run(void); static int netdev_linux_do_ethtool(const char *name, struct ethtool_cmd *, int cmd, const char *cmd_name); -static int netdev_linux_get_ipv4(const struct netdev *, struct in_addr *, - int cmd, const char *cmd_name); static int get_flags(const struct netdev *, unsigned int *flags); static int set_flags(const char *, unsigned int flags); static int update_flags(struct netdev_linux *netdev, enum netdev_flags off, @@ -726,7 +720,7 @@ netdev_linux_changed(struct netdev_linux *dev, dev->ifi_flags = ifi_flags; dev->cache_valid &= mask; - if (!(mask & (VALID_IN4 | VALID_IN6))) { + if (!(mask & VALID_IN)) { netdev_get_addrs_list_flush(); } } @@ -738,9 +732,9 @@ netdev_linux_update(struct netdev_linux *dev, { if (rtnetlink_type_is_rtnlgrp_link(change->nlmsg_type)){ if (change->nlmsg_type == RTM_NEWLINK) { - /* Keep drv-info, in4, in6. */ + /* Keep drv-info, and ip addresses. */ netdev_linux_changed(dev, change->ifi_flags, - VALID_DRVINFO | VALID_IN4 | VALID_IN6); + VALID_DRVINFO | VALID_IN); /* Update netdev from rtnl-change msg. */ if (change->mtu) { @@ -763,8 +757,7 @@ netdev_linux_update(struct netdev_linux *dev, } } else if (rtnetlink_type_is_rtnlgrp_addr(change->nlmsg_type)) { /* Invalidates in4, in6. */ - netdev_linux_changed(dev, dev->ifi_flags, - ~(VALID_IN4 | VALID_IN6)); + netdev_linux_changed(dev, dev->ifi_flags, ~VALID_IN); } else { OVS_NOT_REACHED(); } @@ -2475,40 +2468,6 @@ netdev_linux_dump_queue_stats(const struct netdev *netdev_, } static int -netdev_linux_get_in4(const struct netdev *netdev_, - struct in_addr *address, struct in_addr *netmask) -{ - struct netdev_linux *netdev = netdev_linux_cast(netdev_); - int error; - - ovs_mutex_lock(&netdev->mutex); - if (!(netdev->cache_valid & VALID_IN4)) { - error = netdev_linux_get_ipv4(netdev_, &netdev->address, - SIOCGIFADDR, "SIOCGIFADDR"); - if (!error) { - error = netdev_linux_get_ipv4(netdev_, &netdev->netmask, - SIOCGIFNETMASK, "SIOCGIFNETMASK"); - } - netdev->in4_error = error; - netdev->cache_valid |= VALID_IN4; - } else { - error = netdev->in4_error; - } - - if (!error) { - if (netdev->address.s_addr != INADDR_ANY) { - *address = netdev->address; - *netmask = netdev->netmask; - } else { - error = EADDRNOTAVAIL; - } - } - ovs_mutex_unlock(&netdev->mutex); - - return error; -} - -static int netdev_linux_set_in4(struct netdev *netdev_, struct in_addr address, struct in_addr netmask) { @@ -2518,20 +2477,12 @@ netdev_linux_set_in4(struct netdev *netdev_, struct in_addr address, ovs_mutex_lock(&netdev->mutex); error = do_set_addr(netdev_, SIOCSIFADDR, "SIOCSIFADDR", address); if (!error) { - netdev->address = address; - netdev->netmask = netmask; if (address.s_addr != INADDR_ANY) { error = do_set_addr(netdev_, SIOCSIFNETMASK, "SIOCSIFNETMASK", netmask); } } - if (!error) { - netdev->cache_valid |= VALID_IN4; - netdev->in4_error = 0; - } else { - netdev->cache_valid &= ~VALID_IN4; - } ovs_mutex_unlock(&netdev->mutex); return error; @@ -2848,7 +2799,6 @@ netdev_linux_update_flags(struct netdev *netdev_, enum netdev_flags off, netdev_linux_queue_dump_done, \ netdev_linux_dump_queue_stats, \ \ - netdev_linux_get_in4, \ netdev_linux_set_in4, \ netdev_linux_get_addr_list, \ netdev_linux_add_router, \ @@ -5593,23 +5543,6 @@ netdev_linux_do_ethtool(const char *name, struct ethtool_cmd *ecmd, return error; } -static int -netdev_linux_get_ipv4(const struct netdev *netdev, struct in_addr *ip, - int cmd, const char *cmd_name) -{ - struct ifreq ifr; - int error; - - ifr.ifr_addr.sa_family = AF_INET; - error = af_inet_ifreq_ioctl(netdev_get_name(netdev), &ifr, cmd, cmd_name); - if (!error) { - const struct sockaddr_in *sin = ALIGNED_CAST(struct sockaddr_in *, - &ifr.ifr_addr); - *ip = sin->sin_addr; - } - return error; -} - /* Returns an AF_PACKET raw socket or a negative errno value. */ static int af_packet_sock(void) diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h index b66ed9d..4419629 100644 --- a/lib/netdev-provider.h +++ b/lib/netdev-provider.h @@ -617,20 +617,6 @@ struct netdev_class { void *aux), void *aux); - /* If 'netdev' has an assigned IPv4 address, sets '*address' to that - * address and '*netmask' to the associated netmask. - * - * The following error values have well-defined meanings: - * - * - EADDRNOTAVAIL: 'netdev' has no assigned IPv4 address. - * - * - EOPNOTSUPP: No IPv4 network stack attached to 'netdev'. - * - * This function may be set to null if it would always return EOPNOTSUPP - * anyhow. */ - int (*get_in4)(const struct netdev *netdev, struct in_addr *address, - struct in_addr *netmask); - /* Assigns 'addr' as 'netdev''s IPv4 address and 'mask' as its netmask. If * 'addr' is INADDR_ANY, 'netdev''s IPv4 address is cleared. * diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c index 3d81c6c..2e509d3 100644 --- a/lib/netdev-vport.c +++ b/lib/netdev-vport.c @@ -1520,7 +1520,6 @@ netdev_vport_range(struct unixctl_conn *conn, int argc, NULL, /* queue_dump_done */ \ NULL, /* dump_queue_stats */ \ \ - NULL, /* get_in4 */ \ NULL, /* set_in4 */ \ NULL, /* get_addr_list */ \ NULL, /* add_router */ \ diff --git a/lib/netdev.c b/lib/netdev.c index 19432e5..95fdbc7 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -1022,39 +1022,6 @@ netdev_set_advertisements(struct netdev *netdev, : EOPNOTSUPP); } -/* If 'netdev' has an assigned IPv4 address, sets '*address' to that address - * and '*netmask' to its netmask and returns 0. Otherwise, returns a positive - * errno value and sets '*address' to 0 (INADDR_ANY). - * - * The following error values have well-defined meanings: - * - * - EADDRNOTAVAIL: 'netdev' has no assigned IPv4 address. - * - * - EOPNOTSUPP: No IPv4 network stack attached to 'netdev'. - * - * 'address' or 'netmask' or both may be null, in which case the address or - * netmask is not reported. */ -int -netdev_get_in4(const struct netdev *netdev, - struct in_addr *address_, struct in_addr *netmask_) -{ - struct in_addr address; - struct in_addr netmask; - int error; - - error = (netdev->netdev_class->get_in4 - ? netdev->netdev_class->get_in4(netdev, - &address, &netmask) - : EOPNOTSUPP); - if (address_) { - address_->s_addr = error ? 0 : address.s_addr; - } - if (netmask_) { - netmask_->s_addr = error ? 0 : netmask.s_addr; - } - return error; -} - /* Assigns 'addr' as 'netdev''s IPv4 address and 'mask' as its netmask. If * 'addr' is INADDR_ANY, 'netdev''s IPv4 address is cleared. Returns a * positive errno value. */ @@ -1072,18 +1039,33 @@ netdev_set_in4(struct netdev *netdev, struct in_addr addr, struct in_addr mask) int netdev_get_in4_by_name(const char *device_name, struct in_addr *in4) { - struct netdev *netdev; - int error; + struct in6_addr *mask, *addr6; + int err, n_in6, i; + struct netdev *dev; - error = netdev_open(device_name, "system", &netdev); - if (error) { - in4->s_addr = htonl(0); - return error; + err = netdev_open(device_name, NULL, &dev); + if (err) { + return err; } - error = netdev_get_in4(netdev, in4, NULL); - netdev_close(netdev); - return error; + err = netdev_get_addr_list(dev, &addr6, &mask, &n_in6); + if (err) { + goto out; + } + + for (i = 0; i < n_in6; i++) { + if (IN6_IS_ADDR_V4MAPPED(&addr6[i])) { + in4->s_addr = in6_addr_get_mapped_ipv4(&addr6[i]); + goto out; + } + } + err = -ENOENT; +out: + free(addr6); + free(mask); + netdev_close(dev); + return err; + } /* Adds 'router' as a default IP gateway for the TCP/IP stack that corresponds diff --git a/lib/netdev.h b/lib/netdev.h index 1d2725d..05968b2 100644 --- a/lib/netdev.h +++ b/lib/netdev.h @@ -252,8 +252,6 @@ int netdev_turn_flags_off(struct netdev *, enum netdev_flags, void netdev_restore_flags(struct netdev_saved_flags *); /* TCP/IP stack interface. */ -int netdev_get_in4(const struct netdev *, struct in_addr *address, - struct in_addr *netmask); int netdev_set_in4(struct netdev *, struct in_addr addr, struct in_addr mask); int netdev_get_in4_by_name(const char *device_name, struct in_addr *in4); int netdev_get_addr_list(const struct netdev *netdev, struct in6_addr **addr, -- 1.8.3.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev