Send connman mailing list submissions to
        connman@lists.01.org

To subscribe or unsubscribe via the World Wide Web, visit
        https://lists.01.org/mailman/listinfo/connman
or, via email, send a message with subject or body 'help' to
        connman-requ...@lists.01.org

You can reach the person managing the list at
        connman-ow...@lists.01.org

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


Today's Topics:

   1. [PATCH v3 09/27] acd: Add struct acd_host (Christian Spielberger)
   2. [PATCH v3 10/27] acd: Add functions start/stop_listening
      (Christian Spielberger)
   3. [PATCH v3 12/27] acd: Add send_announce_packet
      (Christian Spielberger)
   4. [PATCH v3 11/27] acd: Add send_probe_packet
      (Christian Spielberger)
   5. [PATCH v3 20/27] network: Add ipv4ll as fallback for acd
      (Christian Spielberger)


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

Message: 1
Date: Tue, 15 May 2018 12:35:16 +0200
From: Christian Spielberger <christian.spielber...@gmail.com>
To: Daniel Wagner <w...@monom.org>
Cc: connman@lists.01.org, Christian Spielberger
        <christian.spielber...@gmail.com>
Subject: [PATCH v3 09/27] acd: Add struct acd_host
Message-ID:
        <1526380534-23540-10-git-send-email-christian.spielber...@gmail.com>

Adds an enum for the ACD state machine, the ACD struct, a function for
allocation and initialization of the struct.
---
 include/acd.h |  4 ++++
 src/acd.c     | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 76 insertions(+)

diff --git a/include/acd.h b/include/acd.h
index baca508..db2452d 100644
--- a/include/acd.h
+++ b/include/acd.h
@@ -26,12 +26,16 @@
 #ifndef __CONNMAN_ACD_H
 #define __CONNMAN_ACD_H
 
+#include <stdint.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 struct acd_host;
 
+struct acd_host *acd_host_new(int ifindex);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/acd.c b/src/acd.c
index 70505b3..3a060a7 100644
--- a/src/acd.c
+++ b/src/acd.c
@@ -22,3 +22,75 @@
  *      Copyright (C) 2009-2014  Intel Corporation. All rights reserved.
  *
  */
+
+#include "connman.h"
+#include <connman/acd.h>
+#include <connman/log.h>
+#include <connman/inet.h>
+#include <glib.h>
+#include "src/shared/arp.h"
+
+enum acd_state {
+       ACD_STATE_PROBE,
+       ACD_STATE_ANNOUNCE,
+       ACD_STATE_MONITOR,
+       ACD_STATE_DEFEND,
+};
+
+struct acd_host {
+       enum acd_state state;
+       int ifindex;
+       char *interface;
+       uint8_t mac_address[6];
+       uint32_t requested_ip; /* host byte order */
+
+       bool listen_on;
+       int listener_sockfd;
+       unsigned int retry_times;
+       unsigned int conflicts;
+       guint timeout;
+       guint listener_watch;
+};
+
+struct acd_host *acd_host_new(int ifindex)
+{
+       struct acd_host *acd;
+
+       if (ifindex < 0) {
+               connman_error("Invalid interface index %d", ifindex);
+               return NULL;
+       }
+
+       acd = g_try_new0(struct acd_host, 1);
+       if (!acd) {
+               connman_error("Could not allocate ACD data structure");
+               return NULL;
+       }
+
+       acd->interface = connman_inet_ifname(ifindex);
+       if (!acd->interface) {
+               connman_error("Interface with index %d is not available", 
ifindex);
+               goto error;
+       }
+
+       if (!connman_inet_is_ifup(ifindex)) {
+               connman_error("Interface with index %d and name %s is down", 
ifindex,
+                               acd->interface);
+               goto error;
+       }
+
+       __connman_inet_get_interface_mac_address(ifindex, acd->mac_address);
+
+       acd->listener_sockfd = -1;
+       acd->listen_on = false;
+       acd->ifindex = ifindex;
+       acd->listener_watch = 0;
+       acd->retry_times = 0;
+
+       return acd;
+
+error:
+       g_free(acd->interface);
+       g_free(acd);
+       return NULL;
+}
-- 
2.7.4



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

Message: 2
Date: Tue, 15 May 2018 12:35:17 +0200
From: Christian Spielberger <christian.spielber...@gmail.com>
To: Daniel Wagner <w...@monom.org>
Cc: connman@lists.01.org, Christian Spielberger
        <christian.spielber...@gmail.com>
Subject: [PATCH v3 10/27] acd: Add functions start/stop_listening
Message-ID:
        <1526380534-23540-11-git-send-email-christian.spielber...@gmail.com>

Adds functions for starting and stopping of the ARP listening which is essential
for ACD. Adds also the callback function for processing received ARP packets
which does nothing for the moment.
---
 include/acd.h |   2 ++
 src/acd.c     | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 112 insertions(+)

diff --git a/include/acd.h b/include/acd.h
index db2452d..211d825 100644
--- a/include/acd.h
+++ b/include/acd.h
@@ -35,6 +35,8 @@ extern "C" {
 struct acd_host;
 
 struct acd_host *acd_host_new(int ifindex);
+int acd_host_start(struct acd_host *acd, uint32_t ip);
+void acd_host_stop(struct acd_host *acd);
 
 #ifdef __cplusplus
 }
diff --git a/src/acd.c b/src/acd.c
index 3a060a7..57fde9c 100644
--- a/src/acd.c
+++ b/src/acd.c
@@ -23,6 +23,11 @@
  *
  */
 
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdarg.h>
+
 #include "connman.h"
 #include <connman/acd.h>
 #include <connman/log.h>
@@ -52,6 +57,25 @@ struct acd_host {
        guint listener_watch;
 };
 
+static int start_listening(struct acd_host *acd);
+static void stop_listening(struct acd_host *acd);
+static gboolean acd_listener_event(GIOChannel *channel, GIOCondition condition,
+                                                       gpointer acd_data);
+static int acd_recv_arp_packet(struct acd_host *acd);
+
+static void debug(struct acd_host *acd, const char *format, ...)
+{
+       char str[256];
+       va_list ap;
+
+       va_start(ap, format);
+
+       if (vsnprintf(str, sizeof(str), format, ap) > 0)
+               connman_info("ACD index %d: %s", acd->ifindex, str);
+
+       va_end(ap);
+}
+
 struct acd_host *acd_host_new(int ifindex)
 {
        struct acd_host *acd;
@@ -94,3 +118,89 @@ error:
        g_free(acd);
        return NULL;
 }
+
+static int start_listening(struct acd_host *acd)
+{
+       GIOChannel *listener_channel;
+       int listener_sockfd;
+
+       if (acd->listen_on)
+               return 0;
+
+       debug(acd, "start listening");
+
+       listener_sockfd = arp_socket(acd->ifindex);
+       if (listener_sockfd < 0)
+               return -EIO;
+
+       listener_channel = g_io_channel_unix_new(listener_sockfd);
+       if (!listener_channel) {
+               /* Failed to create listener channel */
+               close(listener_sockfd);
+               return -EIO;
+       }
+
+       acd->listen_on = true;
+       acd->listener_sockfd = listener_sockfd;
+
+       g_io_channel_set_close_on_unref(listener_channel, TRUE);
+       acd->listener_watch =
+                       g_io_add_watch_full(listener_channel, G_PRIORITY_HIGH,
+                               G_IO_IN | G_IO_NVAL | G_IO_ERR | G_IO_HUP,
+                                               acd_listener_event, acd,
+                                                               NULL);
+       g_io_channel_unref(listener_channel);
+
+       return 0;
+}
+
+static void stop_listening(struct acd_host *acd)
+{
+       if (!acd->listen_on)
+               return;
+
+       if (acd->listener_watch > 0)
+               g_source_remove(acd->listener_watch);
+       acd->listen_on = FALSE;
+       acd->listener_sockfd = -1;
+       acd->listener_watch = 0;
+}
+
+static gboolean acd_listener_event(GIOChannel *channel, GIOCondition condition,
+                                                       gpointer acd_data)
+{
+       struct acd_host *acd = acd_data;
+
+       if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+               acd->listener_watch = 0;
+               return FALSE;
+       }
+
+       if (!acd->listen_on)
+               return FALSE;
+
+       acd_recv_arp_packet(acd);
+
+       return TRUE;
+}
+
+static int acd_recv_arp_packet(struct acd_host *acd)
+{
+       (void) acd;
+       return 0;
+}
+
+int acd_host_start(struct acd_host *acd, uint32_t ip)
+{
+       int err;
+       err = start_listening(acd);
+       if (err)
+               return err;
+
+       return 0;
+}
+
+void acd_host_stop(struct acd_host *acd)
+{
+       stop_listening(acd);
+}
-- 
2.7.4



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

Message: 3
Date: Tue, 15 May 2018 12:35:19 +0200
From: Christian Spielberger <christian.spielber...@gmail.com>
To: Daniel Wagner <w...@monom.org>
Cc: connman@lists.01.org, Christian Spielberger
        <christian.spielber...@gmail.com>
Subject: [PATCH v3 12/27] acd: Add send_announce_packet
Message-ID:
        <1526380534-23540-13-git-send-email-christian.spielber...@gmail.com>

Adding function for sending announce packets and only function headers of
the timeout callbacks acd_announce_timeout for repeated announce packets and
acd_defend_timeout for switching from DEFEND state back to MONITOR state.
---
 src/acd.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 48 insertions(+), 1 deletion(-)

diff --git a/src/acd.c b/src/acd.c
index 574b2b0..306e081 100644
--- a/src/acd.c
+++ b/src/acd.c
@@ -65,6 +65,8 @@ static int acd_recv_arp_packet(struct acd_host *acd);
 static void send_probe_packet(gpointer acd_data);
 static gboolean acd_probe_timeout(gpointer acd_data);
 static gboolean send_announce_packet(gpointer acd_data);
+static gboolean acd_announce_timeout(gpointer acd_data);
+static gboolean acd_defend_timeout(gpointer acd_data);
 
 static void debug(struct acd_host *acd, const char *format, ...)
 {
@@ -122,6 +124,14 @@ error:
        return NULL;
 }
 
+static void remove_timeout(struct acd_host *acd)
+{
+       if (acd->timeout > 0)
+               g_source_remove(acd->timeout);
+
+       acd->timeout = 0;
+}
+
 static int start_listening(struct acd_host *acd)
 {
        GIOChannel *listener_channel;
@@ -214,6 +224,7 @@ static void send_probe_packet(gpointer acd_data)
        struct acd_host *acd = acd_data;
 
        debug(acd, "sending ARP probe request");
+       remove_timeout(acd);
        if (acd->retry_times == 1) {
                acd->state = ACD_STATE_PROBE;
                start_listening(acd);
@@ -258,6 +269,42 @@ static gboolean acd_probe_timeout(gpointer acd_data)
 
 static gboolean send_announce_packet(gpointer acd_data)
 {
-       (void) acd_data;
+       struct acd_host *acd = acd_data;
+
+       debug(acd, "sending ACD announce request");
+
+       arp_send_packet(acd->mac_address,
+                               acd->requested_ip,
+                               acd->requested_ip,
+                               acd->ifindex);
+
+       remove_timeout(acd);
+
+       if (acd->state == ACD_STATE_DEFEND)
+               acd->timeout = g_timeout_add_seconds_full(G_PRIORITY_HIGH,
+                                               DEFEND_INTERVAL,
+                                               acd_defend_timeout,
+                                               acd,
+                                               NULL);
+       else
+               acd->timeout = g_timeout_add_seconds_full(G_PRIORITY_HIGH,
+                                               ANNOUNCE_INTERVAL,
+                                               acd_announce_timeout,
+                                               acd,
+                                               NULL);
        return TRUE;
 }
+
+static gboolean acd_announce_timeout(gpointer acd_data)
+{
+       (void) acd_data;
+
+       return FALSE;
+}
+
+static gboolean acd_defend_timeout(gpointer acd_data)
+{
+       (void) acd_data;
+
+       return FALSE;
+}
-- 
2.7.4



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

Message: 4
Date: Tue, 15 May 2018 12:35:18 +0200
From: Christian Spielberger <christian.spielber...@gmail.com>
To: Daniel Wagner <w...@monom.org>
Cc: connman@lists.01.org, Christian Spielberger
        <christian.spielber...@gmail.com>
Subject: [PATCH v3 11/27] acd: Add send_probe_packet
Message-ID:
        <1526380534-23540-12-git-send-email-christian.spielber...@gmail.com>

Adds a function for sending ARP probe packets and a timeout callback function
for invoking send_probe_packet repeatedly.
---
 src/acd.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/src/acd.c b/src/acd.c
index 57fde9c..574b2b0 100644
--- a/src/acd.c
+++ b/src/acd.c
@@ -62,6 +62,9 @@ static void stop_listening(struct acd_host *acd);
 static gboolean acd_listener_event(GIOChannel *channel, GIOCondition condition,
                                                        gpointer acd_data);
 static int acd_recv_arp_packet(struct acd_host *acd);
+static void send_probe_packet(gpointer acd_data);
+static gboolean acd_probe_timeout(gpointer acd_data);
+static gboolean send_announce_packet(gpointer acd_data);
 
 static void debug(struct acd_host *acd, const char *format, ...)
 {
@@ -204,3 +207,57 @@ void acd_host_stop(struct acd_host *acd)
 {
        stop_listening(acd);
 }
+
+static void send_probe_packet(gpointer acd_data)
+{
+       guint timeout;
+       struct acd_host *acd = acd_data;
+
+       debug(acd, "sending ARP probe request");
+       if (acd->retry_times == 1) {
+               acd->state = ACD_STATE_PROBE;
+               start_listening(acd);
+       }
+       arp_send_packet(acd->mac_address, 0,
+                       acd->requested_ip, acd->ifindex);
+
+       if (acd->retry_times < PROBE_NUM) {
+               /* Add a random timeout in range of PROBE_MIN to PROBE_MAX. */
+               timeout = __connman_util_random_delay_ms(PROBE_MAX-PROBE_MIN);
+               timeout += PROBE_MIN * 1000;
+       } else
+               timeout = ANNOUNCE_WAIT * 1000;
+
+       acd->timeout = g_timeout_add_full(G_PRIORITY_HIGH,
+                                                timeout,
+                                                acd_probe_timeout,
+                                                acd,
+                                                NULL);
+}
+
+static gboolean acd_probe_timeout(gpointer acd_data)
+{
+       struct acd_host *acd = acd_data;
+
+       acd->timeout = 0;
+
+       debug(acd, "acd probe timeout (retries %d)", acd->retry_times);
+       if (acd->retry_times == PROBE_NUM) {
+               acd->state = ACD_STATE_ANNOUNCE;
+               acd->retry_times = 1;
+
+               send_announce_packet(acd);
+               return FALSE;
+       }
+
+       acd->retry_times++;
+       send_probe_packet(acd);
+
+       return FALSE;
+}
+
+static gboolean send_announce_packet(gpointer acd_data)
+{
+       (void) acd_data;
+       return TRUE;
+}
-- 
2.7.4



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

Message: 5
Date: Tue, 15 May 2018 12:35:27 +0200
From: Christian Spielberger <christian.spielber...@gmail.com>
To: Daniel Wagner <w...@monom.org>
Cc: connman@lists.01.org, Christian Spielberger
        <christian.spielber...@gmail.com>
Subject: [PATCH v3 20/27] network: Add ipv4ll as fallback for acd
Message-ID:
        <1526380534-23540-21-git-send-email-christian.spielber...@gmail.com>

    When an address conflict is detected for the static IPv4 configuration a 
free
    IPv4LL address has to be found. This patch adds functions start_ipv4ll for
    starting the IPv4LL process, start_ipv4ll_ontimeout for a delayed start of
    IPv4LL and remove_ipv4ll_timeout for stopping the delayed start.

    For IPv4LL process again we use the new ACD functions.
---
 src/network.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 66 insertions(+), 1 deletion(-)

diff --git a/src/network.c b/src/network.c
index e467a74..92c36c0 100644
--- a/src/network.c
+++ b/src/network.c
@@ -70,6 +70,7 @@ struct connman_network {
        int router_solicit_count;
        int router_solicit_refresh_count;
        struct acd_host *acd_host;
+       guint ipv4ll_timeout;
 
        struct connman_network_driver *driver;
        void *driver_data;
@@ -159,6 +160,14 @@ static void set_configuration(struct connman_network 
*network,
 
 static int start_acd(struct connman_network *network);
 
+static void remove_ipv4ll_timeout(struct connman_network *network)
+{
+       if (network->ipv4ll_timeout > 0) {
+               g_source_remove(network->ipv4ll_timeout);
+               network->ipv4ll_timeout = 0;
+       }
+}
+
 static void acd_host_ipv4_available(struct acd_host *acd, gpointer user_data)
 {
        struct connman_network *network = user_data;
@@ -196,6 +205,50 @@ err:
                                CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
 }
 
+static int start_ipv4ll(struct connman_network *network)
+{
+       struct connman_service *service;
+       struct connman_ipconfig *ipconfig_ipv4;
+       struct in_addr addr;
+       char *address;
+
+       service = connman_service_lookup_from_network(network);
+       if (!service)
+               return -EINVAL;
+
+       ipconfig_ipv4 = __connman_service_get_ip4config(service);
+       if (!ipconfig_ipv4) {
+               connman_error("Service has no IPv4 configuration");
+               return -EINVAL;
+       }
+
+       /* Apply random IPv4 address. */
+       addr.s_addr = htonl(arp_random_ip());
+       address = inet_ntoa(addr);
+       if (!address) {
+               connman_error("Could not convert IPv4LL random address %u",
+                               addr.s_addr);
+               return -EINVAL;
+       }
+       __connman_ipconfig_set_local(ipconfig_ipv4, address);
+
+       connman_info("Probing IPv4LL address %s", address);
+       return start_acd(network);
+}
+
+static gboolean start_ipv4ll_ontimeout(gpointer data)
+{
+       struct connman_network *network = data;
+
+       if (!network)
+               return FALSE;
+
+       /* Start IPv4LL ACD. */
+       start_ipv4ll(network);
+
+       return FALSE;
+}
+
 static void acd_host_ipv4_lost(struct acd_host *acd, gpointer user_data)
 {
        struct connman_network *network = user_data;
@@ -234,6 +287,7 @@ static void acd_host_ipv4_lost(struct acd_host *acd, 
gpointer user_data)
                        __connman_network_enable_ipconfig(network, 
ipconfig_ipv4);
        } else {
                /* Start IPv4LL ACD. */
+               start_ipv4ll(network);
        }
 }
 
@@ -243,16 +297,23 @@ static void acd_host_ipv4_conflict(struct acd_host *acd, 
gpointer user_data)
        (void) network;
 
        /* Start IPv4LL ACD. */
+       start_ipv4ll(network);
 }
 
 static void acd_host_ipv4_maxconflict(struct acd_host *acd, gpointer user_data)
 {
        struct connman_network *network = user_data;
-       (void) network;
 
+       remove_ipv4ll_timeout(network);
        connman_info("Had maximum number of conflicts. Next IPv4LL address will 
be "
                        "tried in %d seconds", RATE_LIMIT_INTERVAL);
        /* Wait, then start IPv4LL ACD. */
+       network->ipv4ll_timeout =
+               g_timeout_add_seconds_full(G_PRIORITY_HIGH,
+                               RATE_LIMIT_INTERVAL,
+                               start_ipv4ll_ontimeout,
+                               network,
+                               NULL);
 }
 
 static int start_acd(struct connman_network *network)
@@ -262,6 +323,8 @@ static int start_acd(struct connman_network *network)
        const char* address;
        struct in_addr addr;
 
+       remove_ipv4ll_timeout(network);
+
        service = connman_service_lookup_from_network(network);
        if (!service)
                return -EINVAL;
@@ -1128,6 +1191,7 @@ struct connman_network *connman_network_create(const char 
*identifier,
        network->type       = type;
        network->identifier = ident;
        network->acd_host = NULL;
+       network->ipv4ll_timeout = 0;
 
        network_list = g_slist_prepend(network_list, network);
 
@@ -1672,6 +1736,7 @@ int __connman_network_disconnect(struct connman_network 
*network)
 
        DBG("network %p", network);
 
+       remove_ipv4ll_timeout(network);
        if (network->acd_host)
                acd_host_stop(network->acd_host);
 
-- 
2.7.4



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

Subject: Digest Footer

_______________________________________________
connman mailing list
connman@lists.01.org
https://lists.01.org/mailman/listinfo/connman


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

End of connman Digest, Vol 31, Issue 8
**************************************

Reply via email to