Send connman mailing list submissions to
        [email protected]

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
        [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 v3 13/27] acd: Add callback function pointers
      (Christian Spielberger)
   2. [PATCH v3 14/27] acd: Add content of acd_host_start and
      acd_host_stop (Christian Spielberger)
   3. [PATCH v3 15/27] acd: Add acd_defend_timeout and
      acd_announce_timeout (Christian Spielberger)
   4. [PATCH v3 18/27] network: Init and start of acd
      (Christian Spielberger)
   5. [PATCH v3 19/27] network: Add content of acd callback
      functions (Christian Spielberger)
   6. [PATCH v3 22/27] dhcp: Add sending of DHCP decline
      (Christian Spielberger)


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

Message: 1
Date: Tue, 15 May 2018 12:35:20 +0200
From: Christian Spielberger <[email protected]>
To: Daniel Wagner <[email protected]>
Cc: [email protected], Christian Spielberger
        <[email protected]>
Subject: [PATCH v3 13/27] acd: Add callback function pointers
Message-ID:
        <1526380534-23540-14-git-send-email-christian.spielber...@gmail.com>

Adds the callback functions for higher level address conflict handling.

ipv4_available_cb will be called if there was no address conflict detected.

ipv4_lost_cb will be called if another host is using our IPv4 address and
    defending was not successfull.

ipv4_conflict_cb will be called if ACD detected a conflict during probing and
    there had been less than MAX_CONFLICTS conflicts.

ipv4_max_conflicts_cb will be called if ACD detected a conflict during probing
    and there had been at least MAX_CONFLICTS conflicts.
---
 include/acd.h |  3 +++
 src/acd.c     | 14 ++++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/include/acd.h b/include/acd.h
index 211d825..ce7bc9f 100644
--- a/include/acd.h
+++ b/include/acd.h
@@ -27,6 +27,7 @@
 #define __CONNMAN_ACD_H
 
 #include <stdint.h>
+#include <glib.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -38,6 +39,8 @@ 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);
 
+typedef void (*acd_host_cb_t) (struct acd_host *acd, gpointer user_data);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/acd.c b/src/acd.c
index 306e081..cca9f46 100644
--- a/src/acd.c
+++ b/src/acd.c
@@ -55,6 +55,15 @@ struct acd_host {
        unsigned int conflicts;
        guint timeout;
        guint listener_watch;
+
+       acd_host_cb_t ipv4_available_cb;
+       gpointer ipv4_available_data;
+       acd_host_cb_t ipv4_lost_cb;
+       gpointer ipv4_lost_data;
+       acd_host_cb_t ipv4_conflict_cb;
+       gpointer ipv4_conflict_data;
+       acd_host_cb_t ipv4_max_conflicts_cb;
+       gpointer ipv4_max_conflicts_data;
 };
 
 static int start_listening(struct acd_host *acd);
@@ -116,6 +125,11 @@ struct acd_host *acd_host_new(int ifindex)
        acd->listener_watch = 0;
        acd->retry_times = 0;
 
+       acd->ipv4_available_cb = NULL;
+       acd->ipv4_lost_cb = NULL;
+       acd->ipv4_conflict_cb = NULL;
+       acd->ipv4_max_conflicts_cb = NULL;
+
        return acd;
 
 error:
-- 
2.7.4



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

Message: 2
Date: Tue, 15 May 2018 12:35:21 +0200
From: Christian Spielberger <[email protected]>
To: Daniel Wagner <[email protected]>
Cc: [email protected], Christian Spielberger
        <[email protected]>
Subject: [PATCH v3 14/27] acd: Add content of acd_host_start and
        acd_host_stop
Message-ID:
        <1526380534-23540-15-git-send-email-christian.spielber...@gmail.com>

Adds the content of the functions for starting and stopping of ACD.
---
 src/acd.c     | 28 ++++++++++++++++++++++++++++
 src/network.c |  3 +++
 2 files changed, 31 insertions(+)

diff --git a/src/acd.c b/src/acd.c
index cca9f46..e7bef4b 100644
--- a/src/acd.c
+++ b/src/acd.c
@@ -219,17 +219,45 @@ static int acd_recv_arp_packet(struct acd_host *acd)
 
 int acd_host_start(struct acd_host *acd, uint32_t ip)
 {
+       guint timeout;
        int err;
+
+       remove_timeout(acd);
+
        err = start_listening(acd);
        if (err)
                return err;
 
+       acd->retry_times = 0;
+       acd->requested_ip = ip;
+
+       /* First wait a random delay to avoid storm of ARP requests on boot */
+       timeout = __connman_util_random_delay_ms(PROBE_WAIT);
+       acd->state = ACD_STATE_PROBE;
+
+       acd->timeout = g_timeout_add_full(G_PRIORITY_HIGH,
+                                               timeout,
+                                               acd_probe_timeout,
+                                               acd,
+                                               NULL);
+
        return 0;
 }
 
 void acd_host_stop(struct acd_host *acd)
 {
        stop_listening(acd);
+
+       remove_timeout(acd);
+
+       if (acd->listener_watch > 0) {
+               g_source_remove(acd->listener_watch);
+               acd->listener_watch = 0;
+       }
+
+       acd->state = ACD_STATE_PROBE;
+       acd->retry_times = 0;
+       acd->requested_ip = 0;
 }
 
 static void send_probe_packet(gpointer acd_data)
diff --git a/src/network.c b/src/network.c
index 134aaf0..0254275 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1537,6 +1537,9 @@ int __connman_network_disconnect(struct connman_network 
*network)
 
        DBG("network %p", network);
 
+       if (network->acd_host)
+               acd_host_stop(network->acd_host);
+
        if (!network->connected && !network->connecting &&
                                                !network->associating)
                return -ENOTCONN;
-- 
2.7.4



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

Message: 3
Date: Tue, 15 May 2018 12:35:22 +0200
From: Christian Spielberger <[email protected]>
To: Daniel Wagner <[email protected]>
Cc: [email protected], Christian Spielberger
        <[email protected]>
Subject: [PATCH v3 15/27] acd: Add acd_defend_timeout and
        acd_announce_timeout
Message-ID:
        <1526380534-23540-16-git-send-email-christian.spielber...@gmail.com>

Adds the content of acd_defend_timeout which switches from state DEFEND back
to MONITOR. Also adds content of acd_announce_timeout which sends repeated
announce packets until ANNOUNCE_NUM is reached, then switches back to state
MONITOR.
---
 src/acd.c | 29 +++++++++++++++++++++++++++--
 1 file changed, 27 insertions(+), 2 deletions(-)

diff --git a/src/acd.c b/src/acd.c
index e7bef4b..a7468be 100644
--- a/src/acd.c
+++ b/src/acd.c
@@ -23,10 +23,13 @@
  *
  */
 
+#include <netinet/if_ether.h>
+#include <net/if_arp.h>
 #include <errno.h>
 #include <unistd.h>
 #include <stdio.h>
 #include <stdarg.h>
+#include <string.h>
 
 #include "connman.h"
 #include <connman/acd.h>
@@ -339,14 +342,36 @@ static gboolean send_announce_packet(gpointer acd_data)
 
 static gboolean acd_announce_timeout(gpointer acd_data)
 {
-       (void) acd_data;
+       struct acd_host *acd = acd_data;
+
+       acd->timeout = 0;
+
+       debug(acd, "acd announce timeout (retries %d)", acd->retry_times);
+       if (acd->retry_times != ANNOUNCE_NUM) {
+               acd->retry_times++;
+               send_announce_packet(acd);
+               return FALSE;
+       }
+
+       debug(acd, "switching to monitor mode");
+       acd->state = ACD_STATE_MONITOR;
+
+       if (acd->ipv4_available_cb)
+               acd->ipv4_available_cb(acd,
+                                       acd->ipv4_available_data);
+       acd->conflicts = 0;
 
        return FALSE;
 }
 
 static gboolean acd_defend_timeout(gpointer acd_data)
 {
-       (void) acd_data;
+       struct acd_host *acd = acd_data;
+
+       debug(acd, "back to MONITOR mode");
+       acd->timeout = 0;
+       acd->conflicts = 0;
+       acd->state = ACD_STATE_MONITOR;
 
        return FALSE;
 }
-- 
2.7.4



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

Message: 4
Date: Tue, 15 May 2018 12:35:25 +0200
From: Christian Spielberger <[email protected]>
To: Daniel Wagner <[email protected]>
Cc: [email protected], Christian Spielberger
        <[email protected]>
Subject: [PATCH v3 18/27] network: Init and start of acd
Message-ID:
        <1526380534-23540-19-git-send-email-christian.spielber...@gmail.com>

Adds empty higher level ACD callback functions. Also adds content of function
start_acd which is allocation of ACD structure, registration of callback
functions and invoke ACD with a pre-defined IPv4 address.
---
 src/network.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/src/network.c b/src/network.c
index 0254275..6ad3eb5 100644
--- a/src/network.c
+++ b/src/network.c
@@ -28,6 +28,7 @@
 
 #include "connman.h"
 #include <connman/acd.h>
+#include "src/shared/arp.h"
 
 /*
  * How many times to send RS with the purpose of
@@ -156,10 +157,28 @@ static void set_configuration(struct connman_network 
*network,
                                        type);
 }
 
+static void acd_host_ipv4_available(struct acd_host *acd, gpointer user_data)
+{
+}
+
+static void acd_host_ipv4_lost(struct acd_host *acd, gpointer user_data)
+{
+}
+
+static void acd_host_ipv4_conflict(struct acd_host *acd, gpointer user_data)
+{
+}
+
+static void acd_host_ipv4_maxconflict(struct acd_host *acd, gpointer user_data)
+{
+}
+
 static int start_acd(struct connman_network *network)
 {
        struct connman_service *service;
        struct connman_ipconfig *ipconfig_ipv4;
+       const char* address;
+       struct in_addr addr;
 
        service = connman_service_lookup_from_network(network);
        if (!service)
@@ -171,6 +190,40 @@ static int start_acd(struct connman_network *network)
                return -EINVAL;
        }
 
+       if (!network->acd_host) {
+               int index;
+
+               index = __connman_ipconfig_get_index(ipconfig_ipv4);
+               network->acd_host = acd_host_new(index);
+               if (!network->acd_host) {
+                       connman_error("Could not create ACD data structure");
+                       return -EINVAL;
+               }
+
+               acd_host_register_event(network->acd_host,
+                               ACD_HOST_EVENT_IPV4_AVAILABLE,
+                               acd_host_ipv4_available, network);
+               acd_host_register_event(network->acd_host,
+                               ACD_HOST_EVENT_IPV4_LOST,
+                               acd_host_ipv4_lost, network);
+               acd_host_register_event(network->acd_host,
+                               ACD_HOST_EVENT_IPV4_CONFLICT,
+                               acd_host_ipv4_conflict, network);
+               acd_host_register_event(network->acd_host,
+                               ACD_HOST_EVENT_IPV4_MAXCONFLICT,
+                               acd_host_ipv4_maxconflict, network);
+       }
+
+       address = __connman_ipconfig_get_local(ipconfig_ipv4);
+       if (!address)
+               return -EINVAL;
+
+       connman_info("Starting ACD for address %s", address);
+       if (inet_pton(AF_INET, address, &addr) != 1)
+               connman_error("Could not convert address %s", address);
+
+       acd_host_start(network->acd_host, htonl(addr.s_addr));
+
        return 0;
 }
 
-- 
2.7.4



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

Message: 5
Date: Tue, 15 May 2018 12:35:26 +0200
From: Christian Spielberger <[email protected]>
To: Daniel Wagner <[email protected]>
Cc: [email protected], Christian Spielberger
        <[email protected]>
Subject: [PATCH v3 19/27] network: Add content of acd callback
        functions
Message-ID:
        <1526380534-23540-20-git-send-email-christian.spielber...@gmail.com>

Adds content for acd_host_ipv4_available and acdhost_ipv4_lost which is
basically applying (adding) and removing an IPv4 address to ipconfig.
---
 src/network.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 82 insertions(+)

diff --git a/src/network.c b/src/network.c
index 6ad3eb5..e467a74 100644
--- a/src/network.c
+++ b/src/network.c
@@ -157,20 +157,102 @@ static void set_configuration(struct connman_network 
*network,
                                        type);
 }
 
+static int start_acd(struct connman_network *network);
+
 static void acd_host_ipv4_available(struct acd_host *acd, gpointer user_data)
 {
+       struct connman_network *network = user_data;
+       struct connman_service *service;
+       struct connman_ipconfig *ipconfig_ipv4;
+       int err;
+
+       if (!network)
+               return;
+
+       service = connman_service_lookup_from_network(network);
+       if (!service)
+               return;
+
+       ipconfig_ipv4 = __connman_service_get_ip4config(service);
+       if (!ipconfig_ipv4) {
+               connman_error("Service has no IPv4 configuration");
+               return;
+       }
+
+       err = __connman_ipconfig_address_add(ipconfig_ipv4);
+       if (err < 0)
+               goto err;
+
+       err = __connman_ipconfig_gateway_add(ipconfig_ipv4);
+       if (err < 0)
+               goto err;
+
+       __connman_service_save(service);
+
+       return;
+
+err:
+       connman_network_set_error(__connman_service_get_network(service),
+                               CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
 }
 
 static void acd_host_ipv4_lost(struct acd_host *acd, gpointer user_data)
 {
+       struct connman_network *network = user_data;
+       struct connman_service *service;
+       struct connman_ipconfig *ipconfig_ipv4;
+       enum connman_ipconfig_type type;
+       enum connman_ipconfig_method method;
+
+       if (!network)
+               return;
+
+       service = connman_service_lookup_from_network(network);
+       if (!service)
+               return;
+
+       ipconfig_ipv4 = __connman_service_get_ip4config(service);
+       if (!ipconfig_ipv4) {
+               connman_error("Service has no IPv4 configuration");
+               return;
+       }
+
+       type = __connman_ipconfig_get_config_type(ipconfig_ipv4);
+       if (type != CONNMAN_IPCONFIG_TYPE_IPV4)
+               return;
+
+       __connman_ipconfig_address_remove(ipconfig_ipv4);
+
+       method = __connman_ipconfig_get_method(ipconfig_ipv4);
+       if (method == CONNMAN_IPCONFIG_METHOD_DHCP) {
+               /*
+                * We have one more chance for DHCP. If this fails
+                * acd_host_ipv4_conflict will be called.
+                */
+               network = __connman_service_get_network(service);
+               if (network)
+                       __connman_network_enable_ipconfig(network, 
ipconfig_ipv4);
+       } else {
+               /* Start IPv4LL ACD. */
+       }
 }
 
 static void acd_host_ipv4_conflict(struct acd_host *acd, gpointer user_data)
 {
+       struct connman_network *network = user_data;
+       (void) network;
+
+       /* Start IPv4LL ACD. */
 }
 
 static void acd_host_ipv4_maxconflict(struct acd_host *acd, gpointer user_data)
 {
+       struct connman_network *network = user_data;
+       (void) 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. */
 }
 
 static int start_acd(struct connman_network *network)
-- 
2.7.4



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

Message: 6
Date: Tue, 15 May 2018 12:35:29 +0200
From: Christian Spielberger <[email protected]>
To: Daniel Wagner <[email protected]>
Cc: [email protected], Christian Spielberger
        <[email protected]>
Subject: [PATCH v3 22/27] dhcp: Add sending of DHCP decline
Message-ID:
        <1526380534-23540-23-git-send-email-christian.spielber...@gmail.com>

Add sending of DHCP decline in case of address conflict for a DHCP lease.
---
 gdhcp/client.c | 29 ++++++++++++++++++++++++++++-
 gdhcp/gdhcp.h  |  1 +
 src/connman.h  |  1 +
 src/dhcp.c     | 24 ++++++++++++++++++++++++
 4 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/gdhcp/client.c b/gdhcp/client.c
index 826e8cc..d8a18d6 100644
--- a/gdhcp/client.c
+++ b/gdhcp/client.c
@@ -66,6 +66,7 @@ typedef enum _dhcp_client_state {
        REBOOTING,
        REQUESTING,
        BOUND,
+       DECLINED,
        RENEWING,
        REBINDING,
        RELEASED,
@@ -471,6 +472,30 @@ static int send_discover(GDHCPClient *dhcp_client, 
uint32_t requested)
                                dhcp_client->retry_times % 2);
 }
 
+int g_dhcp_client_decline(GDHCPClient *dhcp_client, uint32_t requested)
+{
+       struct dhcp_packet packet;
+
+       dhcp_client->state = DECLINED;
+       dhcp_client->retry_times = 0;
+
+       debug(dhcp_client, "sending DHCP decline");
+
+       init_packet(dhcp_client, &packet, DHCPDECLINE);
+
+       packet.xid = dhcp_client->xid;
+       packet.secs = dhcp_attempt_secs(dhcp_client);
+
+       if (requested)
+               dhcp_add_option_uint32(&packet, DHCP_REQUESTED_IP, requested);
+
+       add_send_options(dhcp_client, &packet);
+
+       return dhcp_send_raw_packet(&packet, INADDR_ANY, CLIENT_PORT,
+                               INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR,
+                               dhcp_client->ifindex, true);
+}
+
 static int send_request(GDHCPClient *dhcp_client)
 {
        struct dhcp_packet packet;
@@ -2688,6 +2713,7 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const 
char *last_address)
        int re;
        uint32_t addr;
        uint64_t rand;
+       ClientState oldstate = dhcp_client->state;
 
        remove_timeouts(dhcp_client);
 
@@ -2803,7 +2829,7 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const 
char *last_address)
                dhcp_client->start = time(NULL);
        }
 
-       if (!last_address) {
+       if (!last_address || oldstate == DECLINED) {
                addr = 0;
        } else {
                addr = ntohl(inet_addr(last_address));
@@ -3003,6 +3029,7 @@ char *g_dhcp_client_get_netmask(GDHCPClient *dhcp_client)
        case REBOOTING:
        case REQUESTING:
        case RELEASED:
+       case DECLINED:
        case IPV4LL_PROBE:
        case IPV4LL_ANNOUNCE:
        case INFORMATION_REQ:
diff --git a/gdhcp/gdhcp.h b/gdhcp/gdhcp.h
index 1285431..e3b0131 100644
--- a/gdhcp/gdhcp.h
+++ b/gdhcp/gdhcp.h
@@ -134,6 +134,7 @@ GDHCPClient *g_dhcp_client_new(GDHCPType type, int index,
 
 int g_dhcp_client_start(GDHCPClient *client, const char *last_address);
 void g_dhcp_client_stop(GDHCPClient *client);
+int g_dhcp_client_decline(GDHCPClient *client, uint32_t requested);
 
 GDHCPClient *g_dhcp_client_ref(GDHCPClient *client);
 void g_dhcp_client_unref(GDHCPClient *client);
diff --git a/src/connman.h b/src/connman.h
index c708d33..fde899a 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -467,6 +467,7 @@ int __connman_dhcp_start(struct connman_ipconfig *ipconfig,
                        struct connman_network *network, dhcp_cb callback,
                        gpointer user_data);
 void __connman_dhcp_stop(struct connman_ipconfig *ipconfig);
+void __connman_dhcp_decline(struct connman_ipconfig *ipconfig);
 int __connman_dhcp_init(void);
 void __connman_dhcp_cleanup(void);
 int __connman_dhcpv6_init(void);
diff --git a/src/dhcp.c b/src/dhcp.c
index b57a794..42e9f41 100644
--- a/src/dhcp.c
+++ b/src/dhcp.c
@@ -745,6 +745,30 @@ void __connman_dhcp_stop(struct connman_ipconfig *ipconfig)
        }
 }
 
+void __connman_dhcp_decline(struct connman_ipconfig *ipconfig)
+{
+       struct connman_dhcp *dhcp;
+       const char *address;
+       struct in_addr addr;
+
+       DBG("ipconfig_table %p ipconfig %p", ipconfig_table, ipconfig);
+
+       if (!ipconfig_table)
+               return;
+
+       dhcp = g_hash_table_lookup(ipconfig_table, ipconfig);
+       if (dhcp) {
+               address = __connman_ipconfig_get_local(ipconfig);
+               if (!address)
+                       return;
+
+               if (inet_pton(AF_INET, address, &addr) != 1)
+                       connman_error("Could not convert address %s", address);
+
+               g_dhcp_client_decline(dhcp->dhcp_client, htonl(addr.s_addr));
+       }
+}
+
 int __connman_dhcp_init(void)
 {
        DBG("");
-- 
2.7.4



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

Subject: Digest Footer

_______________________________________________
connman mailing list
[email protected]
https://lists.01.org/mailman/listinfo/connman


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

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

Reply via email to