Send connman mailing list submissions to
        [email protected]

To subscribe or unsubscribe via email, send a message with subject or
body 'help' to
        [email protected]

You can reach the person managing the list at
        [email protected]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of connman digest..."

Today's Topics:

   1. [PATCH v1 00/11] Set IPv6 default route (Daniel Wagner)
   2. [PATCH v1 01/11] inet: Add index to debug output when sending RS
      (Daniel Wagner)
   3. [PATCH v1 02/11] inet: Improve the routing logging (Daniel Wagner)
   4. [PATCH v1 03/11] connection: Improve logging (Daniel Wagner)
   5. [PATCH v1 04/11] ipconfig: Factor out sysfs getter/setter
      (Daniel Wagner)
   6. [PATCH v1 07/11] network: Forward IPv6 gateway information to service
      (Daniel Wagner)


----------------------------------------------------------------------

Date: Sun, 29 Nov 2020 16:29:09 +0100
From: Daniel Wagner <[email protected]>
Subject: [PATCH v1 00/11] Set IPv6 default route
To: [email protected]
Cc: Daniel Wagner <[email protected]>
Message-ID: <[email protected]>

Currently, ConnMan relies on the kernel to set the IPv6 default route
(accept_ra=1). This works only if the system has one interface
active. Obviously, ConnMan should be in charge updating the routing
IPv6 routing table as well. This series addresses this problem.

I've still limited IPv6 testing environment, so I hope this works
not just for me.

- The first three few patches improve the logging.
- Patch 4 and 5 allow ConnMan to disable accept_ra
- Patch 6 to 10 add the missing code to forward the default route to
  route selection code (connection.c)
- The last patch fixes a bug in connetion, so far ConnMan would
  not clear the IPv6 default route.

Daniel Wagner (11):
  inet: Add index to debug output when sending RS
  inet: Improve the routing logging
  connection: Improve logging
  ipconfig: Factor out sysfs getter/setter
  ipconfig: Disable accept_ra on managed interfaces
  inet: Add source address to RS callback
  network: Forward IPv6 gateway information to service
  dhcpv6: Do not clear gateway address when setting IP
  network: Add IPv6 gateway when setting the IPv6 address
  connection: Reorder gateway set/unset operations
  connection: Delete IPv6 default routes

 src/6to4.c       |   3 +-
 src/connection.c |  80 +++++++++++++---------
 src/connman.h    |   3 +-
 src/dhcpv6.c     |  10 ++-
 src/inet.c       |  16 +++--
 src/ipconfig.c   | 175 ++++++++++++++++++++++-------------------------
 src/network.c    |  25 ++++++-
 7 files changed, 172 insertions(+), 140 deletions(-)

-- 
2.29.2

------------------------------

Date: Sun, 29 Nov 2020 16:29:10 +0100
From: Daniel Wagner <[email protected]>
Subject: [PATCH v1 01/11] inet: Add index to debug output when sending
        RS
To: [email protected]
Cc: Daniel Wagner <[email protected]>
Message-ID: <[email protected]>

This helps to figure out on which interface the RS was
send out.
---
 src/inet.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/inet.c b/src/inet.c
index 4c34143879b2..d5f0c9445856 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -1680,7 +1680,7 @@ int __connman_inet_ipv6_send_rs(int index, int timeout,
        if (sk < 0)
                return -errno;
 
-       DBG("sock %d", sk);
+       DBG("index %d sock %d", index, sk);
 
        ICMP6_FILTER_SETBLOCKALL(&filter);
        ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
-- 
2.29.2

------------------------------

Date: Sun, 29 Nov 2020 16:29:11 +0100
From: Daniel Wagner <[email protected]>
Subject: [PATCH v1 02/11] inet: Improve the routing logging
To: [email protected]
Cc: Daniel Wagner <[email protected]>
Message-ID: <[email protected]>

Instead having the central logging in iproute_default_modify where the
user needs to guess what is happening, move the logging one step up
and get an easy to understand entry such as
'__connman_inet_add_default_to_table ...' log output.
---
 src/inet.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/inet.c b/src/inet.c
index d5f0c9445856..584d67f3ca8c 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -2994,8 +2994,6 @@ static int iproute_default_modify(int cmd, uint32_t 
table_id, int ifindex,
        int family = connman_inet_check_ipaddress(gateway);
        char *dst = NULL;
 
-       DBG("gateway %s/%u table %u", gateway, prefixlen, table_id);
-
        switch (family) {
        case AF_INET:
                len = 4;
@@ -3067,6 +3065,7 @@ int __connman_inet_add_default_to_table(uint32_t 
table_id, int ifindex,
 {
        /* ip route add default via 1.2.3.4 dev wlan0 table 1234 */
 
+       DBG("table %d index %d gw %s", table_id, ifindex, gateway);
        return iproute_default_modify(RTM_NEWROUTE, table_id, ifindex, gateway, 
0);
 }
 
@@ -3074,6 +3073,8 @@ int __connman_inet_add_subnet_to_table(uint32_t table_id, 
int ifindex,
                                                const char *gateway, unsigned 
char prefixlen)
 {
        /* ip route add 1.2.3.4/24 dev eth0 table 1234 */
+
+       DBG("table %d index %d gw %s/%d", table_id, ifindex, gateway, 
prefixlen);
        return iproute_default_modify(RTM_NEWROUTE, table_id, ifindex, gateway, 
prefixlen);
 }
 
@@ -3082,6 +3083,7 @@ int __connman_inet_del_default_from_table(uint32_t 
table_id, int ifindex,
 {
        /* ip route del default via 1.2.3.4 dev wlan0 table 1234 */
 
+       DBG("table %d index %d gw %s", table_id, ifindex, gateway);
        return iproute_default_modify(RTM_DELROUTE, table_id, ifindex, gateway, 
0);
 }
 
@@ -3089,6 +3091,8 @@ int __connman_inet_del_subnet_from_table(uint32_t 
table_id, int ifindex,
                                                const char *gateway, unsigned 
char prefixlen)
 {
        /* ip route del 1.2.3.4/24 dev eth0 table 1234 */
+
+       DBG("table %d index %d gw %s/%d", table_id, ifindex, gateway, 
prefixlen);
        return iproute_default_modify(RTM_DELROUTE, table_id, ifindex, gateway, 
prefixlen);
 }
 
-- 
2.29.2

------------------------------

Date: Sun, 29 Nov 2020 16:29:12 +0100
From: Daniel Wagner <[email protected]>
Subject: [PATCH v1 03/11] connection: Improve logging
To: [email protected]
Cc: Daniel Wagner <[email protected]>
Message-ID: <[email protected]>

Printing pointers of the gateway infos is pretty user unfriendly for
debugging. Let's serialize the gateway_data struct into a human
parseable format so it's easy to to follow which gateway_data is
processed.
---
 src/connection.c | 60 +++++++++++++++++++++++++++++-------------------
 1 file changed, 36 insertions(+), 24 deletions(-)

diff --git a/src/connection.c b/src/connection.c
index 303e99223a70..d5c936ee3183 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -27,6 +27,7 @@
 #include <errno.h>
 #include <string.h>
 #include <net/if.h>
+#include <stdio.h>
 
 #include <gdbus.h>
 
@@ -53,6 +54,25 @@ struct gateway_data {
 
 static GHashTable *gateway_hash = NULL;
 
+#define MAX_GW2STR_BUF 1024
+static const char *gw2str(struct gateway_data *gw)
+{
+       static char buf[MAX_GW2STR_BUF];
+
+       if (!gw) {
+               snprintf(buf, MAX_GW2STR_BUF - 1, "n/a");
+       } else {
+               snprintf(buf, MAX_GW2STR_BUF - 1,
+                       "service %p index %d ipv4 %s ipv6 %s",
+                       gw->service, gw->index,
+                       gw->ipv4_gateway ? gw->ipv4_gateway->gateway : "n/a",
+                       gw->ipv6_gateway ? gw->ipv6_gateway->gateway : "n/a");
+               buf[MAX_GW2STR_BUF - 1] = '\0';
+       }
+
+       return buf;
+}
+
 static struct gateway_config *find_gateway(int index, const char *gateway)
 {
        GHashTableIter iter;
@@ -401,8 +421,7 @@ static struct gateway_data *add_gateway(struct 
connman_service *service,
         */
        old = g_hash_table_lookup(gateway_hash, service);
        if (old) {
-               DBG("Replacing gw %p ipv4 %p ipv6 %p", old,
-                       old->ipv4_gateway, old->ipv6_gateway);
+               DBG("Replacing %s", gw2str(old));
                disable_gateway(old, type);
                if (type == CONNMAN_IPCONFIG_TYPE_IPV4) {
                        data->ipv6_gateway = old->ipv6_gateway;
@@ -433,8 +452,7 @@ static void set_default_gateway(struct gateway_data *data,
        else
                do_ipv4 = do_ipv6 = true;
 
-       DBG("type %d gateway ipv4 %p ipv6 %p", type, data->ipv4_gateway,
-                                               data->ipv6_gateway);
+       DBG("type %d %s", type, gw2str(data));
 
        if (do_ipv4 && data->ipv4_gateway &&
                                        data->ipv4_gateway->vpn) {
@@ -514,8 +532,7 @@ static void unset_default_gateway(struct gateway_data *data,
        else
                do_ipv4 = do_ipv6 = true;
 
-       DBG("type %d gateway ipv4 %p ipv6 %p", type, data->ipv4_gateway,
-                                               data->ipv6_gateway);
+       DBG("type %d gateway %s", type, gw2str(data));
 
        if (do_ipv4 && data->ipv4_gateway &&
                                        data->ipv4_gateway->vpn) {
@@ -594,7 +611,7 @@ static bool choose_default_gateway(struct gateway_data 
*data,
        if (data->ipv4_gateway && candidate->ipv4_gateway) {
 
                if (!candidate->ipv4_gateway->active) {
-                       DBG("ipv4 downgrading %p", candidate);
+                       DBG("ipv4 downgrading %s", gw2str(candidate));
                        unset_default_gateway(candidate,
                                                CONNMAN_IPCONFIG_TYPE_IPV4);
                }
@@ -602,7 +619,7 @@ static bool choose_default_gateway(struct gateway_data 
*data,
                if (candidate->ipv4_gateway->active &&
                                __connman_service_compare(candidate->service,
                                                        data->service) < 0) {
-                       DBG("ipv4 downgrading this %p", data);
+                       DBG("ipv4 downgrading this %s", gw2str(data));
                        unset_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV4);
                        downgraded = true;
                }
@@ -610,7 +627,7 @@ static bool choose_default_gateway(struct gateway_data 
*data,
 
        if (data->ipv6_gateway && candidate->ipv6_gateway) {
                if (!candidate->ipv6_gateway->active) {
-                       DBG("ipv6 downgrading %p", candidate);
+                       DBG("ipv6 downgrading %s", gw2str(candidate));
                        unset_default_gateway(candidate,
                                                CONNMAN_IPCONFIG_TYPE_IPV6);
                }
@@ -618,7 +635,7 @@ static bool choose_default_gateway(struct gateway_data 
*data,
                if (candidate->ipv6_gateway->active &&
                        __connman_service_compare(candidate->service,
                                                data->service) < 0) {
-                       DBG("ipv6 downgrading this %p", data);
+                       DBG("ipv6 downgrading this %s", gw2str(data));
                        unset_default_gateway(data, CONNMAN_IPCONFIG_TYPE_IPV6);
                        downgraded = true;
                }
@@ -635,8 +652,6 @@ static void connection_newgateway(int index, const char 
*gateway)
        gpointer value, key;
        bool found = false;
 
-       DBG("index %d gateway %s", index, gateway);
-
        config = find_gateway(index, gateway);
        if (!config)
                return;
@@ -655,6 +670,8 @@ static void connection_newgateway(int index, const char 
*gateway)
        if (data->default_checked)
                return;
 
+       DBG("%s", gw2str(data));
+
        /*
         * The next checks are only done once, otherwise setting
         * the default gateway could lead into rtnl forever loop.
@@ -688,7 +705,7 @@ static void remove_gateway(gpointer user_data)
 {
        struct gateway_data *data = user_data;
 
-       DBG("gateway ipv4 %p ipv6 %p", data->ipv4_gateway, data->ipv6_gateway);
+       DBG("%s", gw2str(data));
 
        if (data->ipv4_gateway) {
                g_free(data->ipv4_gateway->gateway);
@@ -714,13 +731,14 @@ static void connection_delgateway(int index, const char 
*gateway)
        struct gateway_config *config;
        struct gateway_data *data;
 
-       DBG("index %d gateway %s", index, gateway);
-
        config = find_gateway(index, gateway);
        if (config)
                config->active = false;
 
        data = find_default_gateway();
+
+       DBG("%s", gw2str(data));
+
        if (data)
                set_default_gateway(data, CONNMAN_IPCONFIG_TYPE_ALL);
 }
@@ -838,8 +856,7 @@ int __connman_connection_gateway_add(struct connman_service 
*service,
 
        active_gateway = find_active_gateway();
 
-       DBG("active %p index %d new %p", active_gateway,
-               active_gateway ? active_gateway->index : -1, new_gateway);
+       DBG("active %s", gw2str(active_gateway));
 
        if (type == CONNMAN_IPCONFIG_TYPE_IPV4 &&
                                new_gateway->ipv4_gateway) {
@@ -916,8 +933,6 @@ void __connman_connection_gateway_remove(struct 
connman_service *service,
         bool do_ipv4 = false, do_ipv6 = false;
        int err;
 
-       DBG("service %p type %d", service, type);
-
        if (type == CONNMAN_IPCONFIG_TYPE_IPV4)
                do_ipv4 = true;
        else if (type == CONNMAN_IPCONFIG_TYPE_IPV6)
@@ -937,10 +952,7 @@ void __connman_connection_gateway_remove(struct 
connman_service *service,
        if (do_ipv6 && data->ipv6_gateway)
                set_default6 = data->ipv6_gateway->vpn;
 
-       DBG("ipv4 gateway %s ipv6 gateway %s vpn %d/%d",
-               data->ipv4_gateway ? data->ipv4_gateway->gateway : "<null>",
-               data->ipv6_gateway ? data->ipv6_gateway->gateway : "<null>",
-               set_default4, set_default6);
+       DBG("%s vpn %d/%d", gw2str(data), set_default4, set_default6);
 
        if (do_ipv4 && data->ipv4_gateway &&
                        data->ipv4_gateway->vpn && data->index >= 0)
@@ -994,7 +1006,7 @@ bool __connman_connection_update_gateway(void)
 
        default_gateway = find_default_gateway();
 
-       DBG("default %p", default_gateway);
+       DBG("%s", gw2str(default_gateway));
 
        /*
         * There can be multiple active gateways so we need to
-- 
2.29.2

------------------------------

Date: Sun, 29 Nov 2020 16:29:13 +0100
From: Daniel Wagner <[email protected]>
Subject: [PATCH v1 04/11] ipconfig: Factor out sysfs getter/setter
To: [email protected]
Cc: Daniel Wagner <[email protected]>
Message-ID: <[email protected]>

Instead handling the read/write operation in every function
move the common code into small helpers. This allows also to add a
simple logging infrastructure.

While at it also remove the unnecessary test if ifname is valid. We
are garanteed to have a valid string.
---
 src/ipconfig.c | 160 +++++++++++++++++++------------------------------
 1 file changed, 63 insertions(+), 97 deletions(-)

diff --git a/src/ipconfig.c b/src/ipconfig.c
index a1073a75b0a2..aa67f9d55679 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -258,90 +258,90 @@ static const char *scope2str(unsigned char scope)
        return "";
 }
 
-static bool get_ipv6_state(gchar *ifname)
+static int sys_get_int(const char *path, int *val)
 {
-       int disabled;
-       gchar *path;
        FILE *f;
-       bool enabled = false;
-
-       if (!ifname)
-               path = g_strdup("/proc/sys/net/ipv6/conf/all/disable_ipv6");
-       else
-               path = g_strdup_printf(
-                       "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname);
-
-       if (!path)
-               return enabled;
+       int err;
 
        f = fopen(path, "r");
+       if (!f)
+               return -errno;
 
-       g_free(path);
-
-       if (f) {
-               if (fscanf(f, "%d", &disabled) > 0)
-                       enabled = !disabled;
-               fclose(f);
-       }
+       err = fscanf(f, "%d", val);
+       fclose(f);
 
-       return enabled;
+       DBG("%s %d", path, *val);
+       return err;
 }
 
-static void set_ipv6_state(gchar *ifname, bool enable)
+static int sys_set_int(const char *path, int val)
 {
-       gchar *path;
        FILE *f;
-
-       if (!ifname)
-               path = g_strdup("/proc/sys/net/ipv6/conf/all/disable_ipv6");
-       else
-               path = g_strdup_printf(
-                       "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname);
-
-       if (!path)
-               return;
+       int err;
 
        f = fopen(path, "r+");
+       if (!f)
+               return -errno;
 
-       g_free(path);
+       err = fprintf(f, "%d", val);
+       fclose(f);
 
-       if (!f)
-               return;
+       DBG("%s %d", path, val);
+       return err;
+}
 
-       if (!enable)
-               fprintf(f, "1");
-       else
-               fprintf(f, "0");
+static int sys_ifname_get_int(const char *base_path, const char *ifname,
+                       const char *feature, int *val)
+{
+       char *path;
+       int err;
 
-       fclose(f);
+       path = g_strdup_printf("%s/%s/%s", base_path, ifname, feature);
+       err = sys_get_int(path, val);
+       g_free(path);
+
+       return err;
 }
 
-static int get_ipv6_privacy(gchar *ifname)
+static int sys_ifname_set_int(const char *base_path, const char *ifname,
+                               const char *feature, int val)
 {
-       gchar *path;
-       FILE *f;
-       int value;
+       char *path;
+       int err;
 
-       if (!ifname)
-               return 0;
+       path = g_strdup_printf("%s/%s/%s", base_path, ifname, feature);
+       err = sys_set_int(path, val);
+       g_free(path);
 
-       path = g_strdup_printf("/proc/sys/net/ipv6/conf/%s/use_tempaddr",
-                                                               ifname);
+       return err;
+}
 
-       if (!path)
-               return 0;
+#define SYS_IPV6_PATH "/proc/sys/net/ipv6/conf"
 
-       f = fopen(path, "r");
+static bool get_ipv6_state(char *ifname)
+{
+       int disabled;
 
-       g_free(path);
+       if (sys_ifname_get_int(SYS_IPV6_PATH, ifname,
+                               "disable_ipv6", &disabled) < 0)
+               return false;
 
-       if (!f)
-               return 0;
+       return !disabled;
+}
 
-       if (fscanf(f, "%d", &value) <= 0)
-               value = 0;
+static void set_ipv6_state(char *ifname, bool enable)
+{
+       sys_ifname_set_int(SYS_IPV6_PATH, ifname,
+                               "disabled_ipv6", !enable);
+}
 
-       fclose(f);
+static int get_ipv6_privacy(char *ifname)
+{
+       int value;
+
+       if (sys_ifname_get_int(SYS_IPV6_PATH, ifname,
+                               "use_tempaddr", &value) < 0)
+               return 0;
 
        return value;
 }
@@ -349,62 +349,28 @@ static int get_ipv6_privacy(gchar *ifname)
 /* Enable the IPv6 privacy extension for stateless address autoconfiguration.
  * The privacy extension is described in RFC 3041 and RFC 4941
  */
-static void set_ipv6_privacy(gchar *ifname, int value)
+static void set_ipv6_privacy(char *ifname, int value)
 {
-       gchar *path;
-       FILE *f;
-
-       if (!ifname)
-               return;
-
-       path = g_strdup_printf("/proc/sys/net/ipv6/conf/%s/use_tempaddr",
-                                                               ifname);
-
-       if (!path)
-               return;
-
        if (value < 0)
                value = 0;
 
-       f = fopen(path, "r+");
-
-       g_free(path);
-
-       if (!f)
-               return;
-
-       fprintf(f, "%d", value);
-       fclose(f);
+       sys_ifname_set_int(SYS_IPV6_PATH, ifname,
+                               "use_tempaddr", value);
 }
 
 static int get_rp_filter(void)
 {
-       FILE *f;
        int value = -EINVAL, tmp;
 
-       f = fopen("/proc/sys/net/ipv4/conf/all/rp_filter", "r");
-
-       if (f) {
-               if (fscanf(f, "%d", &tmp) == 1)
-                       value = tmp;
-               fclose(f);
-       }
+       if (sys_get_int("/proc/sys/net/ipv4/conf/all/rp_filter", &tmp) > 0)
+               value = tmp;
 
        return value;
 }
 
 static void set_rp_filter(int value)
 {
-       FILE *f;
-
-       f = fopen("/proc/sys/net/ipv4/conf/all/rp_filter", "r+");
-
-       if (!f)
-               return;
-
-       fprintf(f, "%d", value);
-
-       fclose(f);
+       sys_set_int("/proc/sys/net/ipv4/conf/all/rp_filter", value);
 }
 
 int __connman_ipconfig_set_rp_filter()
-- 
2.29.2

------------------------------

Date: Sun, 29 Nov 2020 16:29:16 +0100
From: Daniel Wagner <[email protected]>
Subject: [PATCH v1 07/11] network: Forward IPv6 gateway information to
        service
To: [email protected]
Cc: Daniel Wagner <[email protected]>
Message-ID: <[email protected]>

The check_dhcpv6 callback is called by the response of our RS. Store
the gateway in the ipconfig object.
---
 src/network.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/src/network.c b/src/network.c
index f3f096c071ac..c3a13d3d549a 100644
--- a/src/network.c
+++ b/src/network.c
@@ -748,6 +748,8 @@ static void check_dhcpv6(struct in6_addr *src_addr,
        struct connman_network *network = user_data;
        struct connman_service *service;
        GSList *prefixes;
+       struct connman_ipconfig *ipconfig;
+       char buf[INET6_ADDRSTRLEN];
 
        DBG("reply %p", reply);
 
@@ -780,7 +782,6 @@ static void check_dhcpv6(struct in6_addr *src_addr,
        }
 
        prefixes = __connman_inet_ipv6_get_prefixes(reply, length);
-
        /*
         * If IPv6 config is missing from service, then create it.
         * The ipconfig might be missing if we got a rtnl message
@@ -793,6 +794,18 @@ static void check_dhcpv6(struct in6_addr *src_addr,
        if (service) {
                connman_service_create_ip6config(service, network->index);
 
+               /*
+                * router lifetime: anything other than a zero value
+                * means the source sending the RA will be the default
+                * gateway. Note, it is a link-local address and not
+                * global unique address.
+                */
+               if (reply->nd_ra_router_lifetime &&
+                               inet_ntop(AF_INET6, src_addr, buf, 
INET6_ADDRSTRLEN)) {
+                       ipconfig = __connman_service_get_ip6config(service);
+                       __connman_ipconfig_set_gateway(ipconfig, buf);
+               }
+
                connman_network_set_associating(network, false);
 
                __connman_service_ipconfig_indicate_state(service,
-- 
2.29.2

------------------------------

Subject: Digest Footer

_______________________________________________
connman mailing list -- [email protected]
To unsubscribe send an email to [email protected]


------------------------------

End of connman Digest, Vol 61, Issue 16
***************************************

Reply via email to