From: Alex Wang Date: Thu, 23 Jul 2015 23:25:32 +0000 (-0700) Subject: netdev-linux: Make netdev_linux_get_in6() conform to API definition. X-Git-Tag: v2.4.0~21 X-Git-Url: http://git.cascardo.eti.br/?p=cascardo%2Fovs.git;a=commitdiff_plain;h=11df5f06e4ce0db686c136caa2584fe26e5f1fb4 netdev-linux: Make netdev_linux_get_in6() conform to API definition. The get_in6() API defined in netdev-provider.h requires the return of error values when the 'netdev' has no assigned IPv6 address or the 'netdev' does not support IPv6. However, the netdev_linux_get_in6() implementation does not follow this (always return 0). And this causes the a bug in deleting vlan interfaces created for vlan splinter. This commit makes netdev_linux_get_in6() conform to the API definition and returns the specified error value when failing to get IPv6 address. VMware-BZ: #1485521 Reported-by: Ronald Lee Signed-off-by: Alex Wang Acked-by: Ben Pfaff --- diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 08c624ec5..bdc672d0f 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -458,6 +458,7 @@ 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 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. */ @@ -2481,12 +2482,14 @@ parse_if_inet6_line(const char *line, ifname); } -/* If 'netdev' has an assigned IPv6 address, sets '*in6' to that address (if - * 'in6' is non-null) and returns true. Otherwise, returns false. */ +/* If 'netdev' has an assigned IPv6 address, sets '*in6' to that address. + * Otherwise, sets '*in6' to 'in6addr_any' and returns the corresponding + * error. */ static int netdev_linux_get_in6(const struct netdev *netdev_, struct in6_addr *in6) { struct netdev_linux *netdev = netdev_linux_cast(netdev_); + int error; ovs_mutex_lock(&netdev->mutex); if (!(netdev->cache_valid & VALID_IN6)) { @@ -2494,6 +2497,7 @@ netdev_linux_get_in6(const struct netdev *netdev_, struct in6_addr *in6) char line[128]; netdev->in6 = in6addr_any; + netdev->in6_error = EADDRNOTAVAIL; file = fopen("/proc/net/if_inet6", "r"); if (file != NULL) { @@ -2505,17 +2509,21 @@ netdev_linux_get_in6(const struct netdev *netdev_, struct in6_addr *in6) && !strcmp(name, ifname)) { netdev->in6 = in6_tmp; + netdev->in6_error = 0; break; } } fclose(file); + } else { + netdev->in6_error = EOPNOTSUPP; } netdev->cache_valid |= VALID_IN6; } *in6 = netdev->in6; + error = netdev->in6_error; ovs_mutex_unlock(&netdev->mutex); - return 0; + return error; } static void