[ovs-dev,08/11] netdev: New function netdev_get_ip_by_name().

Message ID 20180413172655.31638-8-blp@ovn.org
State Accepted
Headers show
Series
  • [ovs-dev,01/11] socket-util: Fix error in comment on ss_format_address().
Related show

Commit Message

Ben Pfaff April 13, 2018, 5:26 p.m.
This is like netdev_get_in4_by_name() but accepts any IP address instead
of just an IPv4 address.

It will acquire its first user in an upcoming commit.

Signed-off-by: Ben Pfaff <blp@ovn.org>
---
 lib/netdev.c | 81 +++++++++++++++++++++++++++++++++++++++++++-----------------
 lib/netdev.h |  1 +
 2 files changed, 59 insertions(+), 23 deletions(-)

Comments

Mark Michelson April 16, 2018, 9:40 p.m. | #1
On 04/13/2018 12:26 PM, Ben Pfaff wrote:
> This is like netdev_get_in4_by_name() but accepts any IP address instead
> of just an IPv4 address.
> 
> It will acquire its first user in an upcoming commit.
> 
> Signed-off-by: Ben Pfaff <blp@ovn.org>
> ---
>   lib/netdev.c | 81 +++++++++++++++++++++++++++++++++++++++++++-----------------
>   lib/netdev.h |  1 +
>   2 files changed, 59 insertions(+), 23 deletions(-)
> 
> diff --git a/lib/netdev.c b/lib/netdev.c
> index 00192f0b00da..1c4ae2c6cdd2 100644
> --- a/lib/netdev.c
> +++ b/lib/netdev.c
> @@ -1142,39 +1142,74 @@ netdev_set_in4(struct netdev *netdev, struct in_addr addr, struct in_addr mask)
>               : EOPNOTSUPP);
>   }
>   
> -/* Obtains ad IPv4 address from device name and save the address in
> - * in4.  Returns 0 if successful, otherwise a positive errno value.
> - */
> +static int
> +netdev_get_addresses_by_name(const char *device_name,
> +                             struct in6_addr **addrsp, int *n_addrsp)
> +{
> +    struct netdev *netdev;
> +    int error = netdev_open(device_name, NULL, &netdev);
> +    if (error) {
> +        *addrsp = NULL;
> +        *n_addrsp = 0;
> +        return error;
> +    }
> +
> +    struct in6_addr *masks;
> +    error = netdev_get_addr_list(netdev, addrsp, &masks, n_addrsp);
> +    netdev_close(netdev);
> +    free(masks);
> +    return error;
> +}
> +
> +/* Obtains an IPv4 address from 'device_name' and save the address in '*in4'.
> + * Returns 0 if successful, otherwise a positive errno value. */
>   int
>   netdev_get_in4_by_name(const char *device_name, struct in_addr *in4)
>   {
> -    struct in6_addr *mask, *addr6;
> -    int err, n_in6, i;
> -    struct netdev *dev;
> +    struct in6_addr *addrs;
> +    int n;
> +    int error = netdev_get_addresses_by_name(device_name, &addrs, &n);
>   
> -    err = netdev_open(device_name, NULL, &dev);
> -    if (err) {
> -        return err;
> +    in4->s_addr = 0;
> +    if (!error) {
> +        error = ENOENT;
> +        for (int i = 0; i < n; i++) {
> +            if (IN6_IS_ADDR_V4MAPPED(&addrs[i])) {
> +                in4->s_addr = in6_addr_get_mapped_ipv4(&addrs[i]);
> +                error = 0;
> +                break;
> +            }
> +        }
>       }
> +    free(addrs);
>   
> -    err = netdev_get_addr_list(dev, &addr6, &mask, &n_in6);
> -    if (err) {
> -        goto out;
> -    }
> +    return error;
> +}
>   
> -    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;
> +/* Obtains an IPv4 or IPv6 address from 'device_name' and save the address in
> + * '*ss', representing IPv4 addressse as v6-mapped.  Returns 0 if successful,

There is no "ss" parameter. "addresses" is misspelled.

> + * otherwise a positive errno value. */
> +int
> +netdev_get_ip_by_name(const char *device_name, struct in6_addr *in6)
> +{
> +    struct in6_addr *addrs;
> +    int n;
> +    int error = netdev_get_addresses_by_name(device_name, &addrs, &n);
> +
> +    *in6 = in6addr_any;
> +    if (!error) {
> +        error = ENOENT;
> +        for (int i = 0; i < n; i++) {
> +            if (!in6_is_lla(&addrs[i])) {
> +                *in6 = addrs[i];
> +                error = 0;
> +                break;
> +            }
>           }
>       }
> -    err = -ENOENT;
> -out:
> -    free(addr6);
> -    free(mask);
> -    netdev_close(dev);
> -    return err;
> +    free(addrs);
>   
> +    return error;
>   }
>   
>   /* 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 ff1b604b24e2..441e53daeb69 100644
> --- a/lib/netdev.h
> +++ b/lib/netdev.h
> @@ -282,6 +282,7 @@ void netdev_restore_flags(struct netdev_saved_flags *);
>   /* TCP/IP stack interface. */
>   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_ip_by_name(const char *device_name, struct in6_addr *);
>   int netdev_get_addr_list(const struct netdev *netdev, struct in6_addr **addr,
>                            struct in6_addr **mask, int *n_in6);
>   
>
Ben Pfaff April 17, 2018, 3:34 p.m. | #2
On Mon, Apr 16, 2018 at 04:40:08PM -0500, Mark Michelson wrote:
> On 04/13/2018 12:26 PM, Ben Pfaff wrote:
> >+/* Obtains an IPv4 or IPv6 address from 'device_name' and save the address in
> >+ * '*ss', representing IPv4 addressse as v6-mapped.  Returns 0 if successful,
> 
> There is no "ss" parameter. "addresses" is misspelled.

Thanks for the fix.  I forgot to fix this before I sent the series, so
here's a patch:
        https://patchwork.ozlabs.org/patch/899418/

Patch

diff --git a/lib/netdev.c b/lib/netdev.c
index 00192f0b00da..1c4ae2c6cdd2 100644
--- a/lib/netdev.c
+++ b/lib/netdev.c
@@ -1142,39 +1142,74 @@  netdev_set_in4(struct netdev *netdev, struct in_addr addr, struct in_addr mask)
             : EOPNOTSUPP);
 }
 
-/* Obtains ad IPv4 address from device name and save the address in
- * in4.  Returns 0 if successful, otherwise a positive errno value.
- */
+static int
+netdev_get_addresses_by_name(const char *device_name,
+                             struct in6_addr **addrsp, int *n_addrsp)
+{
+    struct netdev *netdev;
+    int error = netdev_open(device_name, NULL, &netdev);
+    if (error) {
+        *addrsp = NULL;
+        *n_addrsp = 0;
+        return error;
+    }
+
+    struct in6_addr *masks;
+    error = netdev_get_addr_list(netdev, addrsp, &masks, n_addrsp);
+    netdev_close(netdev);
+    free(masks);
+    return error;
+}
+
+/* Obtains an IPv4 address from 'device_name' and save the address in '*in4'.
+ * Returns 0 if successful, otherwise a positive errno value. */
 int
 netdev_get_in4_by_name(const char *device_name, struct in_addr *in4)
 {
-    struct in6_addr *mask, *addr6;
-    int err, n_in6, i;
-    struct netdev *dev;
+    struct in6_addr *addrs;
+    int n;
+    int error = netdev_get_addresses_by_name(device_name, &addrs, &n);
 
-    err = netdev_open(device_name, NULL, &dev);
-    if (err) {
-        return err;
+    in4->s_addr = 0;
+    if (!error) {
+        error = ENOENT;
+        for (int i = 0; i < n; i++) {
+            if (IN6_IS_ADDR_V4MAPPED(&addrs[i])) {
+                in4->s_addr = in6_addr_get_mapped_ipv4(&addrs[i]);
+                error = 0;
+                break;
+            }
+        }
     }
+    free(addrs);
 
-    err = netdev_get_addr_list(dev, &addr6, &mask, &n_in6);
-    if (err) {
-        goto out;
-    }
+    return error;
+}
 
-    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;
+/* Obtains an IPv4 or IPv6 address from 'device_name' and save the address in
+ * '*ss', representing IPv4 addressse as v6-mapped.  Returns 0 if successful,
+ * otherwise a positive errno value. */
+int
+netdev_get_ip_by_name(const char *device_name, struct in6_addr *in6)
+{
+    struct in6_addr *addrs;
+    int n;
+    int error = netdev_get_addresses_by_name(device_name, &addrs, &n);
+
+    *in6 = in6addr_any;
+    if (!error) {
+        error = ENOENT;
+        for (int i = 0; i < n; i++) {
+            if (!in6_is_lla(&addrs[i])) {
+                *in6 = addrs[i];
+                error = 0;
+                break;
+            }
         }
     }
-    err = -ENOENT;
-out:
-    free(addr6);
-    free(mask);
-    netdev_close(dev);
-    return err;
+    free(addrs);
 
+    return error;
 }
 
 /* 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 ff1b604b24e2..441e53daeb69 100644
--- a/lib/netdev.h
+++ b/lib/netdev.h
@@ -282,6 +282,7 @@  void netdev_restore_flags(struct netdev_saved_flags *);
 /* TCP/IP stack interface. */
 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_ip_by_name(const char *device_name, struct in6_addr *);
 int netdev_get_addr_list(const struct netdev *netdev, struct in6_addr **addr,
                          struct in6_addr **mask, int *n_in6);