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 25/27] network: Send DHCP decline in case of
address conflict (Christian Spielberger)
2. [PATCH v3 21/27] acd: Add D-Bus property for address conflict
(Christian Spielberger)
3. [PATCH v3 26/27] acd: Report address lost case per D-Bus also
(Christian Spielberger)
4. [PATCH v3 27/27] network: Also send DHCP DECLINE after second
DHCP try (Christian Spielberger)
5. [PATCH v3 16/27] acd: Add handling of received arp packets
(Christian Spielberger)
----------------------------------------------------------------------
Message: 1
Date: Tue, 15 May 2018 12:35:32 +0200
From: Christian Spielberger <[email protected]>
To: Daniel Wagner <[email protected]>
Cc: [email protected], Christian Spielberger
<[email protected]>
Subject: [PATCH v3 25/27] network: Send DHCP decline in case of
address conflict
Message-ID:
<1526380534-23540-26-git-send-email-christian.spielber...@gmail.com>
Try DHCP two times, then fallback is IPv4LL. Also invoke __connman_dhcp_decline
which sends a DHCP decline.
---
src/network.c | 37 ++++++++++++++++++++++++++++++++++---
1 file changed, 34 insertions(+), 3 deletions(-)
diff --git a/src/network.c b/src/network.c
index af23c65..7df5ccb 100644
--- a/src/network.c
+++ b/src/network.c
@@ -50,6 +50,8 @@
*/
#define RTR_SOLICITATION_INTERVAL 4
+#define DHCP_RETRY_TIMEOUT 10
+
static GSList *network_list = NULL;
static GSList *driver_list = NULL;
@@ -304,10 +306,39 @@ 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)
{
struct connman_network *network = user_data;
- (void) network;
+ struct connman_service *service;
+ struct connman_ipconfig *ipconfig_ipv4;
+ enum connman_ipconfig_method method;
- /* Start IPv4LL ACD. */
- start_ipv4ll(network);
+ 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;
+ }
+
+ method = __connman_ipconfig_get_method(ipconfig_ipv4);
+ connman_info("%s conflict counts=%u", __FUNCTION__,
+ acd_host_get_conflicts_count(acd));
+
+ if (method == CONNMAN_IPCONFIG_METHOD_DHCP &&
+ acd_host_get_conflicts_count(acd) < 2) {
+ connman_info("%s Sending DHCP decline", __FUNCTION__);
+ __connman_dhcp_decline(ipconfig_ipv4);
+
+ connman_network_set_connected_dhcp_later(network,
DHCP_RETRY_TIMEOUT);
+ __connman_ipconfig_set_local(ipconfig_ipv4, NULL);
+ } else {
+ if (method == CONNMAN_IPCONFIG_METHOD_DHCP) {
+ __connman_ipconfig_set_method(ipconfig_ipv4,
+ CONNMAN_IPCONFIG_METHOD_AUTO);
+ }
+ /* Start IPv4LL ACD. */
+ start_ipv4ll(network);
+ }
}
static void acd_host_ipv4_maxconflict(struct acd_host *acd, gpointer user_data)
--
2.7.4
------------------------------
Message: 2
Date: Tue, 15 May 2018 12:35:28 +0200
From: Christian Spielberger <[email protected]>
To: Daniel Wagner <[email protected]>
Cc: [email protected], Christian Spielberger
<[email protected]>
Subject: [PATCH v3 21/27] acd: Add D-Bus property for address conflict
Message-ID:
<1526380534-23540-22-git-send-email-christian.spielber...@gmail.com>
Adds a D-Bus property called LastAddressConflict and a signal to notify if
the property changes.
---
doc/service-api.txt | 32 ++++++++++++++++++++
include/acd.h | 4 ++-
include/network.h | 5 ++++
include/service.h | 1 +
src/acd.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
src/network.c | 12 +++++++-
src/service.c | 11 +++++++
7 files changed, 146 insertions(+), 3 deletions(-)
diff --git a/doc/service-api.txt b/doc/service-api.txt
index 4026e7e..c0d5adb 100644
--- a/doc/service-api.txt
+++ b/doc/service-api.txt
@@ -520,3 +520,35 @@ Properties string State [readonly]
Same values as mDNS property. The mDNS
represents the actual system configuration
while this allows user configuration.
+
+ dict LastAddressConflict [readonly]
+
+ This property contains information about the previously
detected
+ address conflict. If there has been no address conflict
then
+ IPv4 Address is "0.0.0.0", Ethernet Address is
"00:00:00:00:00:00",
+ Timestamp is zero and Resolved is true.
+
+ dict IPv4 [readonly]
+
+ string Address [readonly]
+
+ The IPv4 address which had a conflict.
+
+ dict Ethernet [readonly]
+
+ string Address [readonly]
+
+ The ethernet device address (MAC address) of
the conflicting
+ host.
+
+ int64 Timestamp [readonly]
+
+ A timestamp when the conflict was detected in
microseconds
+ since January 1, 1970 UTC.
+
+ bool Resolved [readonly]
+
+ Set to false when an address conflict occurs.
+ If a previous conflict could be resolved by
probing another
+ IPv4 address (which is not an IPv4LL) then this
boolean is set
+ to true.
diff --git a/include/acd.h b/include/acd.h
index 34e2539..6898ccb 100644
--- a/include/acd.h
+++ b/include/acd.h
@@ -35,7 +35,7 @@ extern "C" {
struct acd_host;
-struct acd_host *acd_host_new(int ifindex);
+struct acd_host *acd_host_new(int ifindex, const char* path);
int acd_host_start(struct acd_host *acd, uint32_t ip);
void acd_host_stop(struct acd_host *acd);
@@ -53,6 +53,8 @@ void acd_host_register_event(struct acd_host *acd,
acd_host_cb_t func,
gpointer user_data);
+void acd_host_append_dbus_property(struct acd_host *acd, DBusMessageIter
*dict);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/network.h b/include/network.h
index 4fc20c1..ee5d2f6 100644
--- a/include/network.h
+++ b/include/network.h
@@ -25,6 +25,8 @@
#include <stdbool.h>
#include <stdint.h>
+#include <dbus/dbus.h>
+
#include <connman/device.h>
#include <connman/ipconfig.h>
@@ -162,6 +164,9 @@ struct connman_network_driver {
int connman_network_driver_register(struct connman_network_driver *driver);
void connman_network_driver_unregister(struct connman_network_driver *driver);
+void connman_network_append_acddbus(DBusMessageIter *dict,
+ struct connman_network *network);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/service.h b/include/service.h
index 958e7fd..c958375 100644
--- a/include/service.h
+++ b/include/service.h
@@ -117,6 +117,7 @@ enum connman_service_type connman_service_get_type(struct
connman_service *servi
char *connman_service_get_interface(struct connman_service *service);
const char *connman_service_get_domainname(struct connman_service *service);
+const char *connman_service_get_dbuspath(struct connman_service *service);
char **connman_service_get_nameservers(struct connman_service *service);
char **connman_service_get_timeservers_config(struct connman_service *service);
char **connman_service_get_timeservers(struct connman_service *service);
diff --git a/src/acd.c b/src/acd.c
index 7f945c7..ae6ec79 100644
--- a/src/acd.c
+++ b/src/acd.c
@@ -35,6 +35,7 @@
#include <connman/acd.h>
#include <connman/log.h>
#include <connman/inet.h>
+#include <connman/dbus.h>
#include <glib.h>
#include "src/shared/arp.h"
@@ -59,6 +60,13 @@ struct acd_host {
uint8_t mac_address[6];
uint32_t requested_ip; /* host byte order */
+ /* address conflict fields */
+ uint32_t ac_ip; /* host byte order */
+ uint8_t ac_mac[6];
+ gint64 ac_timestamp;
+ bool ac_resolved;
+ const char *path;
+
bool listen_on;
int listener_sockfd;
unsigned int retry_times;
@@ -87,6 +95,9 @@ static gboolean send_announce_packet(gpointer acd_data);
static gboolean acd_announce_timeout(gpointer acd_data);
static gboolean acd_defend_timeout(gpointer acd_data);
+/* for D-Bus property */
+static void report_conflict(struct acd_host *acd);
+
static void debug(struct acd_host *acd, const char *format, ...)
{
char str[256];
@@ -100,7 +111,7 @@ static void debug(struct acd_host *acd, const char *format,
...)
va_end(ap);
}
-struct acd_host *acd_host_new(int ifindex)
+struct acd_host *acd_host_new(int ifindex, const char *path)
{
struct acd_host *acd;
@@ -140,6 +151,12 @@ struct acd_host *acd_host_new(int ifindex)
acd->ipv4_conflict_cb = NULL;
acd->ipv4_max_conflicts_cb = NULL;
+ acd->ac_ip = 0;
+ memset(acd->ac_mac, 0, sizeof(acd->ac_mac));
+ acd->ac_timestamp = 0;
+ acd->ac_resolved = true;
+ acd->path = path;
+
return acd;
error:
@@ -221,6 +238,11 @@ static gboolean acd_listener_event(GIOChannel *channel,
GIOCondition condition,
return TRUE;
}
+static bool is_link_local(uint32_t ip)
+{
+ return (ip & LINKLOCAL_ADDR) == LINKLOCAL_ADDR;
+}
+
static int acd_recv_arp_packet(struct acd_host *acd)
{
ssize_t cnt;
@@ -290,6 +312,13 @@ static int acd_recv_arp_packet(struct acd_host *acd)
}
if (acd->conflicts < MAX_CONFLICTS) {
+ if (!is_link_local(acd->requested_ip)) {
+ acd->ac_ip = acd->requested_ip;
+ memcpy(acd->ac_mac, arp.arp_sha, sizeof(acd->ac_mac));
+ acd->ac_timestamp = g_get_real_time();
+ acd->ac_resolved = false;
+ report_conflict(acd);
+ }
acd_host_stop(acd);
/* we need a new request_ip */
@@ -445,6 +474,11 @@ static gboolean acd_announce_timeout(gpointer acd_data)
debug(acd, "switching to monitor mode");
acd->state = ACD_STATE_MONITOR;
+ if (!acd->ac_resolved && !is_link_local(acd->requested_ip)) {
+ acd->ac_resolved = true;
+ report_conflict(acd);
+ }
+
if (acd->ipv4_available_cb)
acd->ipv4_available_cb(acd,
acd->ipv4_available_data);
@@ -493,3 +527,51 @@ void acd_host_register_event(struct acd_host *acd,
}
}
+static void append_ac_mac(DBusMessageIter *iter, void *user_data)
+{
+ struct acd_host *acd = user_data;
+ char mac[32];
+ uint8_t *m = acd->ac_mac;
+ const char *str = mac;
+
+ snprintf(mac, sizeof(mac), "%02x:%02x:%02x:%02x:%02x:%02x",
+ m[0], m[1], m[2], m[3], m[4], m[5]);
+ connman_dbus_dict_append_basic(iter, "Address", DBUS_TYPE_STRING, &str);
+}
+
+static void append_ac_ipv4(DBusMessageIter *iter, void *user_data)
+{
+ struct acd_host *acd = user_data;
+ struct in_addr addr;
+ char *a;
+
+ addr.s_addr = htonl(acd->ac_ip);
+ a = inet_ntoa(addr);
+ if (!a)
+ a = "";
+ connman_dbus_dict_append_basic(iter, "Address", DBUS_TYPE_STRING, &a);
+}
+
+static void append_ac_property(DBusMessageIter *iter, void *user_data)
+{
+ struct acd_host *acd = user_data;
+
+ connman_dbus_dict_append_dict(iter, "IPv4", append_ac_ipv4, acd);
+ connman_dbus_dict_append_dict(iter, "Ethernet", append_ac_mac, acd);
+ connman_dbus_dict_append_basic(iter, "Timestamp", DBUS_TYPE_INT64,
+ &acd->ac_timestamp);
+ connman_dbus_dict_append_basic(iter, "Resolved", DBUS_TYPE_BOOLEAN,
+ &acd->ac_resolved);
+}
+
+void acd_host_append_dbus_property(struct acd_host *acd, DBusMessageIter *dict)
+{
+ connman_dbus_dict_append_dict(dict, "LastAddressConflict",
+ append_ac_property, acd);
+}
+
+static void report_conflict(struct acd_host *acd)
+{
+ connman_dbus_property_changed_dict(acd->path, CONNMAN_SERVICE_INTERFACE,
+ "LastAddressConflict", append_ac_property, acd);
+}
diff --git a/src/network.c b/src/network.c
index 92c36c0..ddcad65 100644
--- a/src/network.c
+++ b/src/network.c
@@ -158,6 +158,15 @@ static void set_configuration(struct connman_network
*network,
type);
}
+void connman_network_append_acddbus(DBusMessageIter *dict,
+ struct connman_network *network)
+{
+ if (!network->acd_host)
+ return;
+
+ acd_host_append_dbus_property(network->acd_host, dict);
+}
+
static int start_acd(struct connman_network *network);
static void remove_ipv4ll_timeout(struct connman_network *network)
@@ -339,7 +348,8 @@ static int start_acd(struct connman_network *network)
int index;
index = __connman_ipconfig_get_index(ipconfig_ipv4);
- network->acd_host = acd_host_new(index);
+ network->acd_host = acd_host_new(index,
+ connman_service_get_dbuspath(service));
if (!network->acd_host) {
connman_error("Could not create ACD data structure");
return -EINVAL;
diff --git a/src/service.c b/src/service.c
index 733c072..03bfb7b 100644
--- a/src/service.c
+++ b/src/service.c
@@ -2538,6 +2538,9 @@ static void append_properties(DBusMessageIter *dict,
dbus_bool_t limited,
connman_dbus_dict_append_dict(dict, "Provider",
append_provider, service);
+
+ if (service->network)
+ connman_network_append_acddbus(dict, service->network);
}
static void append_struct_service(DBusMessageIter *iter,
@@ -2669,6 +2672,14 @@ const char *connman_service_get_domainname(struct
connman_service *service)
return service->domainname;
}
+const char *connman_service_get_dbuspath(struct connman_service *service)
+{
+ if (!service)
+ return NULL;
+
+ return service->path;
+}
+
char **connman_service_get_nameservers(struct connman_service *service)
{
if (!service)
--
2.7.4
------------------------------
Message: 3
Date: Tue, 15 May 2018 12:35:33 +0200
From: Christian Spielberger <[email protected]>
To: Daniel Wagner <[email protected]>
Cc: [email protected], Christian Spielberger
<[email protected]>
Subject: [PATCH v3 26/27] acd: Report address lost case per D-Bus also
Message-ID:
<1526380534-23540-27-git-send-email-christian.spielber...@gmail.com>
We also want to report an address conflict if we loose our IPv4 address because
another host is using the same one.
---
src/acd.c | 32 +++++++++++++++++++-------------
1 file changed, 19 insertions(+), 13 deletions(-)
diff --git a/src/acd.c b/src/acd.c
index 0266bac..c48b07c 100644
--- a/src/acd.c
+++ b/src/acd.c
@@ -96,7 +96,7 @@ static gboolean acd_announce_timeout(gpointer acd_data);
static gboolean acd_defend_timeout(gpointer acd_data);
/* for D-Bus property */
-static void report_conflict(struct acd_host *acd);
+static void report_conflict(struct acd_host *acd, const struct ether_arp* arp);
static void debug(struct acd_host *acd, const char *format, ...)
{
@@ -306,19 +306,18 @@ static int acd_recv_arp_packet(struct acd_host *acd)
return 0;
debug(acd, "LOST IPv4 address %s", inet_ntoa(addr));
+ if (!is_link_local(acd->requested_ip))
+ report_conflict(acd, &arp);
+
if (acd->ipv4_lost_cb)
acd->ipv4_lost_cb(acd, acd->ipv4_lost_data);
return 0;
}
if (acd->conflicts < MAX_CONFLICTS) {
- if (!is_link_local(acd->requested_ip)) {
- acd->ac_ip = acd->requested_ip;
- memcpy(acd->ac_mac, arp.arp_sha, sizeof(acd->ac_mac));
- acd->ac_timestamp = g_get_real_time();
- acd->ac_resolved = false;
- report_conflict(acd);
- }
+ if (!is_link_local(acd->requested_ip))
+ report_conflict(acd, &arp);
+
acd_host_stop(acd);
/* we need a new request_ip */
@@ -474,10 +473,8 @@ static gboolean acd_announce_timeout(gpointer acd_data)
debug(acd, "switching to monitor mode");
acd->state = ACD_STATE_MONITOR;
- if (!acd->ac_resolved && !is_link_local(acd->requested_ip)) {
- acd->ac_resolved = true;
- report_conflict(acd);
- }
+ if (!acd->ac_resolved && !is_link_local(acd->requested_ip))
+ report_conflict(acd, NULL);
if (acd->ipv4_available_cb)
acd->ipv4_available_cb(acd,
@@ -570,8 +567,17 @@ void acd_host_append_dbus_property(struct acd_host *acd,
DBusMessageIter *dict)
append_ac_property, acd);
}
-static void report_conflict(struct acd_host *acd)
+static void report_conflict(struct acd_host *acd, const struct ether_arp* arp)
{
+ if (arp) {
+ acd->ac_ip = acd->requested_ip;
+ memcpy(acd->ac_mac, arp->arp_sha, sizeof(acd->ac_mac));
+ acd->ac_timestamp = g_get_real_time();
+ acd->ac_resolved = false;
+ } else {
+ acd->ac_resolved = true;
+ }
+
connman_dbus_property_changed_dict(acd->path, CONNMAN_SERVICE_INTERFACE,
"LastAddressConflict", append_ac_property, acd);
}
--
2.7.4
------------------------------
Message: 4
Date: Tue, 15 May 2018 12:35:34 +0200
From: Christian Spielberger <[email protected]>
To: Daniel Wagner <[email protected]>
Cc: [email protected], Christian Spielberger
<[email protected]>
Subject: [PATCH v3 27/27] network: Also send DHCP DECLINE after second
DHCP try
Message-ID:
<1526380534-23540-28-git-send-email-christian.spielber...@gmail.com>
DHCP is tried two times. We want to send also a DECLINE after second try fails
with an address conflict.
---
src/network.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/network.c b/src/network.c
index 7df5ccb..c3a7cbf 100644
--- a/src/network.c
+++ b/src/network.c
@@ -335,6 +335,7 @@ static void acd_host_ipv4_conflict(struct acd_host *acd,
gpointer user_data)
if (method == CONNMAN_IPCONFIG_METHOD_DHCP) {
__connman_ipconfig_set_method(ipconfig_ipv4,
CONNMAN_IPCONFIG_METHOD_AUTO);
+ __connman_dhcp_decline(ipconfig_ipv4);
}
/* Start IPv4LL ACD. */
start_ipv4ll(network);
--
2.7.4
------------------------------
Message: 5
Date: Tue, 15 May 2018 12:35:23 +0200
From: Christian Spielberger <[email protected]>
To: Daniel Wagner <[email protected]>
Cc: [email protected], Christian Spielberger
<[email protected]>
Subject: [PATCH v3 16/27] acd: Add handling of received arp packets
Message-ID:
<1526380534-23540-17-git-send-email-christian.spielber...@gmail.com>
Adds implementation of acd_recv_arp_packet. This is the main logic for ACD. As
long as ACD is activated received ARP packets are checked for potential address
conflicts.
---
src/acd.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 90 insertions(+), 1 deletion(-)
diff --git a/src/acd.c b/src/acd.c
index a7468be..6f2a7ab 100644
--- a/src/acd.c
+++ b/src/acd.c
@@ -45,6 +45,13 @@ enum acd_state {
ACD_STATE_DEFEND,
};
+static const char* acd_state_texts[] = {
+ "PROBE",
+ "ANNOUNCE",
+ "MONITOR",
+ "DEFEND"
+};
+
struct acd_host {
enum acd_state state;
int ifindex;
@@ -216,7 +223,89 @@ static gboolean acd_listener_event(GIOChannel *channel,
GIOCondition condition,
static int acd_recv_arp_packet(struct acd_host *acd)
{
- (void) acd;
+ ssize_t cnt;
+ struct ether_arp arp;
+ uint32_t ip_n; /* network byte order */
+ struct in_addr addr;
+ int source_conflict;
+ int target_conflict;
+ bool probe;
+ char* confltxt;
+ uint8_t* mac;
+ uint8_t* omac;
+
+ memset(&arp, 0, sizeof(arp));
+ cnt = read(acd->listener_sockfd, &arp, sizeof(arp));
+ if (cnt != sizeof(arp))
+ return -EINVAL;
+
+ if (arp.arp_op != htons(ARPOP_REPLY) &&
+ arp.arp_op != htons(ARPOP_REQUEST))
+ return -EINVAL;
+
+ if (memcmp(arp.arp_sha, acd->mac_address, ETH_ALEN) == 0)
+ return 0;
+
+ ip_n = htonl(acd->requested_ip);
+ source_conflict = !memcmp(arp.arp_spa, &ip_n, sizeof(uint32_t));
+ probe = !memcmp(arp.arp_spa, "\0\0\0\0", sizeof(uint32_t));
+ target_conflict = probe &&
+ !memcmp(arp.arp_tpa, &ip_n, sizeof(uint32_t));
+
+ if (!source_conflict && !target_conflict)
+ return 0;
+
+ acd->conflicts++;
+
+ confltxt = target_conflict ? "target" : "source";
+
+ addr.s_addr = ip_n;
+ debug(acd, "IPv4 %d %s conflicts detected for address %s. "
+ "State=%s", acd->conflicts, confltxt, inet_ntoa(addr),
+ acd_state_texts[acd->state]);
+ mac = acd->mac_address;
+ omac = arp.arp_sha;
+ debug(acd, "Our MAC: %02x:%02x:%02x:%02x:%02x:%02x"
+ " other MAC: %02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0], mac[1], mac[2],mac[3], mac[4], mac[5],
+ omac[0], omac[1], omac[2],omac[3], omac[4], omac[5]);
+
+ if (acd->state == ACD_STATE_MONITOR) {
+ if (!source_conflict)
+ return 0;
+
+ acd->state = ACD_STATE_DEFEND;
+ debug(acd, "DEFEND mode conflicts: %d", acd->conflicts);
+ /* Try to defend with a single announce. */
+ send_announce_packet(acd);
+ return 0;
+ } else if (acd->state == ACD_STATE_DEFEND) {
+ if (!source_conflict)
+ return 0;
+
+ debug(acd, "LOST IPv4 address %s", inet_ntoa(addr));
+ if (acd->ipv4_lost_cb)
+ acd->ipv4_lost_cb(acd, acd->ipv4_lost_data);
+ return 0;
+ }
+
+ if (acd->conflicts < MAX_CONFLICTS) {
+ acd_host_stop(acd);
+
+ /* we need a new request_ip */
+ if (acd->ipv4_conflict_cb)
+ acd->ipv4_conflict_cb(acd, acd->ipv4_conflict_data);
+ } else {
+ acd_host_stop(acd);
+
+ /*
+ * Here we got a lot of conflicts, RFC3927 and RFC5227 state
that we
+ * have to wait RATE_LIMIT_INTERVAL before retrying.
+ */
+ if (acd->ipv4_max_conflicts_cb)
+ acd->ipv4_max_conflicts_cb(acd,
acd->ipv4_max_conflicts_data);
+ }
+
return 0;
}
--
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 10
***************************************