@@ -107,3 +107,14 @@ Properties boolean Powered [readwrite]
This property is only valid for the WiFi technology and it's
optional. Default frequency is 2412 Mhz.
+
+ string TetheringAddress [readwrite]
+
+ The tethering interface (bridge) address.
+
+ Configures the IP address used by the tethering
+ interface. Client addresses will be allocated from
+ the same network.
+
+ If this property is not set, the tethering address is
+ selected automatically.
@@ -680,6 +680,7 @@ int __connman_tethering_init(void);
void __connman_tethering_cleanup(void);
const char *__connman_tethering_get_bridge(void);
+int __connman_tethering_set_ip(uint32_t);
int __connman_tethering_set_enabled(void);
void __connman_tethering_set_disabled(void);
void __connman_tethering_list_clients(DBusMessageIter *array);
@@ -1039,6 +1040,7 @@ void __connman_ippool_cleanup(void);
void __connman_ippool_free(struct connman_ippool *pool);
struct connman_ippool *__connman_ippool_create(int index,
+ uint32_t block,
unsigned int start,
unsigned int range,
ippool_collision_cb_t collision_cb,
@@ -322,6 +322,7 @@ void __connman_ippool_deladdr(int index, const char *address,
}
struct connman_ippool *__connman_ippool_create(int index,
+ uint32_t block,
unsigned int start,
unsigned int range,
ippool_collision_cb_t collision_cb,
@@ -329,7 +330,6 @@ struct connman_ippool *__connman_ippool_create(int index,
{
struct connman_ippool *pool;
struct address_info *info;
- uint32_t block;
DBG("");
@@ -342,7 +342,8 @@ struct connman_ippool *__connman_ippool_create(int index,
return NULL;
}
- block = get_free_block(start + range);
+ if (block == 0)
+ block = get_free_block(start + range);
if (block == 0) {
connman_warn("Could not find a free IP block");
return NULL;
@@ -373,7 +374,7 @@ struct connman_ippool *__connman_ippool_create(int index,
if (range == 0)
range = 1;
- pool->gateway = get_ip(info->start + 1);
+ pool->gateway = get_ip(info->start + (start > 1 ? start - 1 : 1));
pool->broadcast = get_ip(info->start + 255);
pool->subnet_mask = get_ip(subnet_mask_24);
pool->start_ip = get_ip(block + start);
@@ -140,7 +140,7 @@ static int start_dhcp_server(struct connman_peer *peer)
else
index = connman_device_get_index(peer->device);
- peer->ip_pool = __connman_ippool_create(index, 2, 1, NULL, NULL);
+ peer->ip_pool = __connman_ippool_create(index, 0, 2, 1, NULL, NULL);
if (!peer->ip_pool)
goto error;
@@ -69,6 +69,7 @@ struct connman_technology {
char *tethering_ident;
char *tethering_passphrase;
int tethering_freq;
+ struct connman_ipaddress *tethering_address;
bool enable_persistent; /* Save the tech state */
@@ -202,6 +203,11 @@ static void technology_save(struct connman_technology *technology)
"Tethering.Freq",
technology->tethering_freq);
+ if (technology->tethering_address)
+ g_key_file_set_string(keyfile, identifier,
+ "Tethering.Address",
+ technology->tethering_address->local);
+
done:
g_free(identifier);
@@ -232,6 +238,10 @@ int connman_technology_tethering_notify(struct connman_technology *technology,
return -EALREADY;
if (enabled) {
+ if (technology->tethering_address && technology->tethering_address->local)
+ __connman_tethering_set_ip(ntohl(inet_addr(technology->tethering_address->local)));
+ else
+ __connman_tethering_set_ip(0);
err = __connman_tethering_set_enabled();
if (err < 0)
return err;
@@ -487,6 +497,16 @@ static void technology_load(struct connman_technology *technology)
technology->tethering_freq = g_key_file_get_integer(keyfile,
identifier, "Tethering.Freq", NULL);
+ enc = g_key_file_get_string(keyfile,
+ identifier, "Tethering.Address", NULL);
+ if (enc) {
+ if (!technology->tethering_address)
+ technology->tethering_address = connman_ipaddress_alloc(AF_INET);
+
+ connman_ipaddress_set_ipv4(technology->tethering_address,
+ enc, "255.255.255.0", NULL);
+ }
+
done:
g_free(identifier);
@@ -602,6 +622,11 @@ static void append_properties(DBusMessageIter *iter,
DBUS_TYPE_INT32,
&technology->tethering_freq);
+ if (technology->tethering_address)
+ connman_dbus_dict_append_basic(&dict, "TetheringAddress",
+ DBUS_TYPE_STRING,
+ &technology->tethering_address->local);
+
connman_dbus_dict_close(iter, &dict);
}
@@ -1037,6 +1062,29 @@ static DBusMessage *set_property(DBusConnection *conn,
DBUS_TYPE_INT32,
&technology->tethering_freq);
}
+ } else if (g_str_equal(name, "TetheringAddress")) {
+ const char *address;
+
+ if (type != DBUS_TYPE_STRING)
+ return __connman_error_invalid_arguments(msg);
+
+ if (technology->type != CONNMAN_SERVICE_TYPE_WIFI)
+ return __connman_error_not_supported(msg);
+
+ dbus_message_iter_get_basic(&value, &address);
+
+ if (g_str_equal(address, "")) {
+ if (technology->tethering_address) {
+ connman_ipaddress_free(technology->tethering_address);
+ technology->tethering_address = NULL;
+ }
+ } else {
+ if (!technology->tethering_address)
+ technology->tethering_address = connman_ipaddress_alloc(AF_INET);
+
+ connman_ipaddress_set_ipv4(technology->tethering_address,
+ address, "255.255.255.0", NULL);
+ }
} else if (g_str_equal(name, "Powered")) {
dbus_bool_t enable;
@@ -1257,6 +1305,7 @@ static void technology_put(struct connman_technology *technology)
g_free(technology->regdom);
g_free(technology->tethering_ident);
g_free(technology->tethering_passphrase);
+ connman_ipaddress_free(technology->tethering_address);
g_free(technology);
}
@@ -56,6 +56,7 @@ static char *private_network_primary_dns = NULL;
static char *private_network_secondary_dns = NULL;
static volatile int tethering_enabled;
+static uint32_t tethering_ip_address;
static GDHCPServer *tethering_dhcp_server = NULL;
static struct connman_ippool *dhcp_ippool = NULL;
static DBusConnection *connection;
@@ -200,6 +201,14 @@ static void unregister_all_clients(void)
g_hash_table_foreach(clients_table, unregister_client, NULL);
}
+int __connman_tethering_set_ip(uint32_t ip)
+{
+ tethering_ip_address = ip;
+ if ((tethering_ip_address & 0xff) == 0)
+ tethering_ip_address |= 1;
+ return 0;
+}
+
int __connman_tethering_set_enabled(void)
{
int index;
@@ -225,7 +234,9 @@ int __connman_tethering_set_enabled(void)
}
index = connman_inet_ifindex(BRIDGE_NAME);
- dhcp_ippool = __connman_ippool_create(index, 2, 252,
+ dhcp_ippool = __connman_ippool_create(index, tethering_ip_address & ~0xff,
+ 1 + (tethering_ip_address & 0xff),
+ 253 - (tethering_ip_address & 0xff),
tethering_restart, NULL);
if (!dhcp_ippool) {
connman_error("Fail to create IP pool");
@@ -592,7 +603,7 @@ int __connman_private_network_request(DBusMessage *msg, const char *owner)
pn->fd = fd;
pn->interface = iface;
pn->index = index;
- pn->pool = __connman_ippool_create(pn->index, 1, 1, ippool_disconnect, pn);
+ pn->pool = __connman_ippool_create(pn->index, 0, 1, 1, ippool_disconnect, pn);
if (!pn->pool) {
errno = -ENOMEM;
goto error;
@@ -46,11 +46,11 @@ static void test_case_1(void)
__connman_ippool_init();
- pool = __connman_ippool_create(23, 1, 500, NULL, NULL);
+ pool = __connman_ippool_create(23, 0, 1, 500, NULL, NULL);
g_assert(!pool);
for (i = 0; i < 100000; i++) {
- pool = __connman_ippool_create(23, 1, 20, NULL, NULL);
+ pool = __connman_ippool_create(23, 0, 1, 20, NULL, NULL);
g_assert(pool);
__connman_ippool_free(pool);
@@ -73,7 +73,7 @@ static void test_case_2(void)
/* Test the IP range */
for (i = 1; i < 254; i++) {
- pool = __connman_ippool_create(23, 1, i, NULL, NULL);
+ pool = __connman_ippool_create(23, 0, 1, i, NULL, NULL);
g_assert(pool);
gateway = __connman_ippool_get_gateway(pool);
@@ -130,7 +130,7 @@ static void test_case_3(void)
__connman_ippool_newaddr(46, "172.16.0.1", 11);
while (TRUE) {
- pool = __connman_ippool_create(23, 1, 100, NULL, NULL);
+ pool = __connman_ippool_create(23, 0, 1, 100, NULL, NULL);
if (!pool)
break;
i += 1;
@@ -192,7 +192,7 @@ static void test_case_4(void)
/* Test the IP range collision */
flag = 0;
- pool = __connman_ippool_create(23, 1, 100, collision_cb, &flag);
+ pool = __connman_ippool_create(23, 0, 1, 100, collision_cb, &flag);
g_assert(pool);
gateway = __connman_ippool_get_gateway(pool);
@@ -223,7 +223,7 @@ static void test_case_4(void)
flag = 0;
- pool = __connman_ippool_create(23, 1, 100, collision_cb, &flag);
+ pool = __connman_ippool_create(23, 0, 1, 100, collision_cb, &flag);
g_assert(pool);
gateway = __connman_ippool_get_gateway(pool);
@@ -271,7 +271,7 @@ static void test_case_5(void)
g_assert(flag == 0);
/* pool should return 192.168.0.1 now */
- pool1 = __connman_ippool_create(26, 1, 100, collision_cb, &flag);
+ pool1 = __connman_ippool_create(26, 0, 1, 100, collision_cb, &flag);
g_assert(pool1);
gateway = __connman_ippool_get_gateway(pool1);
@@ -303,7 +303,7 @@ static void test_case_5(void)
/* pool should return 192.168.2.1 now */
flag = 0;
- pool2 = __connman_ippool_create(23, 1, 100, collision_cb, &flag);
+ pool2 = __connman_ippool_create(23, 0, 1, 100, collision_cb, &flag);
g_assert(pool2);
gateway = __connman_ippool_get_gateway(pool2);
@@ -361,7 +361,7 @@ static void test_case_6(void)
g_assert(flag == 0);
/* pool should return 192.168.2.1 now */
- pool1 = __connman_ippool_create(26, 1, 100, collision_cb, &flag);
+ pool1 = __connman_ippool_create(26, 0, 1, 100, collision_cb, &flag);
g_assert(pool1);
gateway = __connman_ippool_get_gateway(pool1);
@@ -393,7 +393,7 @@ static void test_case_6(void)
/* pool should return 192.168.3.1 now */
flag = 0;
- pool2 = __connman_ippool_create(23, 1, 100, collision_cb, &flag);
+ pool2 = __connman_ippool_create(23, 0, 1, 100, collision_cb, &flag);
g_assert(pool2);
gateway = __connman_ippool_get_gateway(pool2);
Hello, we have a use case where we need to manually configure the IP address and network used by connman for the tethering interface. For that, I've added TetheringAddress property to the Technology interface. I am attaching the patch as we have it now. If this functionality and approach makes sense to you and you have some comments, I'll update the patch as necessary so it could be merged upstream. Best Regards Roman From 38767f65169d063d7b87a06fe7692bd6a841c128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= <roman@amarulasolutions.com> Date: Thu, 28 Nov 2024 16:35:26 +0100 Subject: [PATCH] technology: Tethering address configuration Add a new TetheringAddress property to the Technology API, which, when set, configures the used router address of the tethering interface, and makes the addresses assigned to the clients come from that IP network. --- doc/technology-api.txt | 11 ++++++++++ src/connman.h | 2 ++ src/ippool.c | 7 +++--- src/peer.c | 2 +- src/technology.c | 49 ++++++++++++++++++++++++++++++++++++++++++ src/tethering.c | 15 +++++++++++-- unit/test-ippool.c | 20 ++++++++--------- 7 files changed, 90 insertions(+), 16 deletions(-)