network: Rename ModemManager .network section WRT tech, not project...

and use dedicated knobs for every option used in
former SimpleConnectProperties.
New section is [MobileNetwork] with the following configuration options:

APN=
AllowedAuthenticationMechanisms==
User=
Password=
IPFamily=
AllowRoaming=
PIN=
OperatorId=
This commit is contained in:
Oleksandr Andrushchenko
2026-03-04 12:42:19 +01:00
committed by Zbigniew Jędrzejewski-Szmek
parent a22ad0efcc
commit 899992bc1e
8 changed files with 256 additions and 171 deletions
+10 -3
View File
@@ -493,9 +493,16 @@ CAN.ClassicDataLengthCode, config_parse_can_control_mode,
CAN.Termination, config_parse_can_termination, 0, 0
IPoIB.Mode, config_parse_ipoib_mode, 0, offsetof(Network, ipoib_mode)
IPoIB.IgnoreUserspaceMulticastGroups, config_parse_tristate, 0, offsetof(Network, ipoib_umcast)
ModemManager.SimpleConnectProperties, config_parse_strv, 0, offsetof(Network, mm_simple_connect_props)
ModemManager.RouteMetric, config_parse_mm_route_metric, 0, 0
ModemManager.UseGateway, config_parse_tristate, 0, offsetof(Network, mm_use_gateway)
MobileNetwork.APN, config_parse_string, CONFIG_PARSE_STRING_SAFE_AND_ASCII, offsetof(Network, mm_apn)
MobileNetwork.AllowRoaming, config_parse_bool, 0, offsetof(Network, mm_allow_roaming)
MobileNetwork.AllowedAuthenticationMechanisms, config_parse_mm_allowed_auth, 0, offsetof(Network, mm_allowed_auth)
MobileNetwork.IPFamily, config_parse_mm_ip_family, 0, offsetof(Network, mm_ip_family)
MobileNetwork.OperatorId, config_parse_string, CONFIG_PARSE_STRING_SAFE_AND_ASCII, offsetof(Network, mm_operator_id)
MobileNetwork.User, config_parse_string, CONFIG_PARSE_STRING_SAFE_AND_ASCII, offsetof(Network, mm_user)
MobileNetwork.Password, config_parse_string, CONFIG_PARSE_STRING_SAFE_AND_ASCII, offsetof(Network, mm_password)
MobileNetwork.PIN, config_parse_string, CONFIG_PARSE_STRING_SAFE_AND_ASCII, offsetof(Network, mm_pin)
MobileNetwork.RouteMetric, config_parse_mm_route_metric, 0, 0
MobileNetwork.UseGateway, config_parse_tristate, 0, offsetof(Network, mm_use_gateway)
QDisc.Parent, config_parse_qdisc_parent, _QDISC_KIND_INVALID, 0
QDisc.Handle, config_parse_qdisc_handle, _QDISC_KIND_INVALID, 0
BFIFO.Parent, config_parse_qdisc_parent, QDISC_KIND_BFIFO, 0
+9 -2
View File
@@ -513,6 +513,9 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.ipoib_mode = _IP_OVER_INFINIBAND_MODE_INVALID,
.ipoib_umcast = -1,
.mm_allow_roaming = true,
.mm_allowed_auth = MM_BEARER_ALLOWED_AUTH_UNKNOWN,
.mm_ip_family = MM_BEARER_IP_FAMILY_NONE,
.mm_use_gateway = -1,
};
@@ -553,7 +556,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
"LLDP\0"
"TrafficControlQueueingDiscipline\0"
"CAN\0"
"ModemManager\0"
"MobileNetwork\0"
"QDisc\0"
"BFIFO\0"
"CAKE\0"
@@ -851,7 +854,11 @@ static Network *network_free(Network *network) {
hashmap_free(network->tclasses_by_section);
/* ModemManager */
strv_free(network->mm_simple_connect_props);
free(network->mm_apn);
free(network->mm_operator_id);
free(network->mm_user);
free(network->mm_password);
free(network->mm_pin);
return mfree(network);
}
+9 -1
View File
@@ -21,6 +21,7 @@
#include "networkd-ndisc.h"
#include "networkd-radv.h"
#include "networkd-sysctl.h"
#include "networkd-wwan-bus.h"
#include "resolve-util.h"
typedef enum KeepConfiguration {
@@ -416,7 +417,14 @@ typedef struct Network {
char **ntp;
/* ModemManager support */
char **mm_simple_connect_props;
char *mm_apn;
bool mm_allow_roaming;
MMBearerAllowedAuth mm_allowed_auth;
MMBearerIpFamily mm_ip_family;
char *mm_operator_id;
char *mm_user;
char *mm_password;
char *mm_pin;
int mm_use_gateway;
uint32_t mm_route_metric;
bool mm_route_metric_set;
+40 -102
View File
@@ -59,7 +59,6 @@
#include "networkd-manager.h"
#include "networkd-wwan.h"
#include "networkd-wwan-bus.h"
#include "parse-util.h"
#include "string-util.h"
#include "strv.h"
@@ -507,78 +506,6 @@ static int modem_connect_handler(sd_bus_message *message, void *userdata, sd_bus
return 0;
}
static MMBearerIpFamily prop_iptype_lookup(const char *key) {
static const struct {
MMBearerIpFamily family;
const char *str;
} table[] = {
{ MM_BEARER_IP_FAMILY_NONE, "none" },
{ MM_BEARER_IP_FAMILY_IPV4, "ipv4" },
{ MM_BEARER_IP_FAMILY_IPV6, "ipv6" },
{ MM_BEARER_IP_FAMILY_IPV4V6, "ipv4v6" },
{ MM_BEARER_IP_FAMILY_ANY, "any" },
{}
};
assert(key);
FOREACH_ELEMENT(item, table)
if (streq(item->str, key))
return item->family;
log_warning("ModemManager: ignoring unknown ip-type: %s, using any", key);
return MM_BEARER_IP_FAMILY_ANY;
}
static MMBearerAllowedAuth prop_auth_lookup(const char *key) {
static const struct {
MMBearerAllowedAuth auth;
const char *str;
} table[] = {
{ MM_BEARER_ALLOWED_AUTH_NONE, "none" },
{ MM_BEARER_ALLOWED_AUTH_PAP, "pap" },
{ MM_BEARER_ALLOWED_AUTH_CHAP, "chap" },
{ MM_BEARER_ALLOWED_AUTH_MSCHAP, "mschap" },
{ MM_BEARER_ALLOWED_AUTH_MSCHAPV2, "mschapv2" },
{ MM_BEARER_ALLOWED_AUTH_EAP, "eap" },
{}
};
assert(key);
FOREACH_ELEMENT(item, table)
if (streq(item->str, key))
return item->auth;
log_warning("ModemManager: ignoring unknown allowed-auth: %s, using none", key);
return MM_BEARER_ALLOWED_AUTH_NONE;
}
static const char* prop_type_lookup(const char *key) {
static const struct {
const char *prop;
const char *type;
} table[] = {
{ "apn", "s" },
{ "allowed-auth", "u" },
{ "user", "s" },
{ "password", "s" },
{ "ip-type", "u" },
{ "allow-roaming", "b" },
{ "pin", "s" },
{ "operator-id", "s" },
{}
};
if (!key)
return NULL;
FOREACH_ELEMENT(item, table)
if (streq(item->prop, key))
return item->type;
return NULL;
}
static int bus_call_method_async_props(
sd_bus *bus,
sd_bus_slot **slot,
@@ -591,6 +518,7 @@ static int bus_call_method_async_props(
Link *link) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
Network *network = ASSERT_PTR(ASSERT_PTR(link)->network);
int r;
assert(bus);
@@ -603,38 +531,48 @@ static int bus_call_method_async_props(
if (r < 0)
return bus_log_create_error(r);
STRV_FOREACH(prop, link->network->mm_simple_connect_props) {
const char *type;
_cleanup_free_ char *left = NULL, *right = NULL;
r = split_pair(*prop, "=", &left, &right);
if (network->mm_apn) {
r = sd_bus_message_append(m, "{sv}", "apn", "s", network->mm_apn);
if (r < 0)
return log_warning_errno(SYNTHETIC_ERRNO(r),
"ModemManager: failed to parse simple connect option: %s, file: %s",
*prop, link->network->filename);
return bus_log_create_error(r);
}
type = prop_type_lookup(left);
if (!type)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
"ModemManager: unknown simple connect option: %s, file: %s",
*prop, link->network->filename);
r = sd_bus_message_append(m, "{sv}", "allow-roaming", "b", network->mm_allow_roaming);
if (r < 0)
return bus_log_create_error(r);
if (streq(left, "ip-type")) {
MMBearerIpFamily ip_type = prop_iptype_lookup(right);
if (network->mm_allowed_auth != MM_BEARER_ALLOWED_AUTH_UNKNOWN) {
r = sd_bus_message_append(m, "{sv}", "allowed-auth", "u", (uint32_t) network->mm_allowed_auth);
if (r < 0)
return bus_log_create_error(r);
}
r = sd_bus_message_append(m, "{sv}", left, type, (uint32_t)ip_type);
} if (streq(left, "allowed-auth")) {
MMBearerAllowedAuth auth = prop_auth_lookup(right);
if (network->mm_ip_family != MM_BEARER_IP_FAMILY_NONE) {
r = sd_bus_message_append(m, "{sv}", "ip-type", "u", (uint32_t) network->mm_ip_family);
if (r < 0)
return bus_log_create_error(r);
}
r = sd_bus_message_append(m, "{sv}", left, type, (uint32_t)auth);
} else if (streq(type, "b")) {
r = parse_boolean(right);
if (r < 0)
return -EINVAL;
r = sd_bus_message_append(m, "{sv}", left, type, r);
} else if (streq(type, "s"))
r = sd_bus_message_append(m, "{sv}", left, type, right);
if (network->mm_operator_id) {
r = sd_bus_message_append(m, "{sv}", "operator-id", "s", network->mm_operator_id);
if (r < 0)
return bus_log_create_error(r);
}
if (network->mm_user) {
r = sd_bus_message_append(m, "{sv}", "user", "s", network->mm_user);
if (r < 0)
return bus_log_create_error(r);
}
if (network->mm_password) {
r = sd_bus_message_append(m, "{sv}", "password", "s", network->mm_password);
if (r < 0)
return bus_log_create_error(r);
}
if (network->mm_pin) {
r = sd_bus_message_append(m, "{sv}", "pin", "s", network->mm_pin);
if (r < 0)
return bus_log_create_error(r);
}
@@ -675,9 +613,9 @@ static void modem_simple_connect(Modem *modem) {
return (void) log_debug("ModemManager: no .network file provided for %s",
modem->port_name);
/* Check if we are provided with simple connection properties */
if (!link->network->mm_simple_connect_props)
return (void) log_debug("ModemManager: no simple connect properties provided for %s",
/* Check if we are provided with at least APN which is required. */
if (!link->network->mm_apn)
return (void) log_debug("ModemManager: not enough simple connect properties provided for %s",
modem->port_name);
log_info("ModemManager: starting simple connect on %s %s interface %s",
+101 -1
View File
@@ -2,6 +2,7 @@
#include "alloc-util.h"
#include "bus-util.h"
#include "extract-word.h"
#include "hashmap.h"
#include "networkd-address.h"
#include "networkd-dhcp4.h"
@@ -620,7 +621,7 @@ int config_parse_mm_route_metric(
void *data,
void *userdata) {
Network *network = userdata;
Network *network = ASSERT_PTR(userdata);
int r;
assert(filename);
@@ -639,3 +640,102 @@ int config_parse_mm_route_metric(
network->mm_route_metric_set = true;
return 0;
}
int config_parse_mm_allowed_auth(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
static const struct {
MMBearerAllowedAuth auth;
const char *str;
} allowed_auth_map[] = {
{ MM_BEARER_ALLOWED_AUTH_NONE, "none" },
{ MM_BEARER_ALLOWED_AUTH_PAP, "pap" },
{ MM_BEARER_ALLOWED_AUTH_CHAP, "chap" },
{ MM_BEARER_ALLOWED_AUTH_MSCHAP, "mschap" },
{ MM_BEARER_ALLOWED_AUTH_MSCHAPV2, "mschapv2" },
{ MM_BEARER_ALLOWED_AUTH_EAP, "eap" },
};
MMBearerAllowedAuth *allowed_auth = ASSERT_PTR(data);
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
if (isempty(rvalue)) {
*allowed_auth = MM_BEARER_ALLOWED_AUTH_UNKNOWN;
return 0;
}
for (const char *p = rvalue;;) {
_cleanup_free_ char *auth = NULL;
r = extract_first_word(&p, &auth, /* separators */ NULL, /* flags */ 0);
if (r < 0)
return log_syntax_parse_error(unit, filename, line, r, lvalue, rvalue);
if (r == 0)
return 0;
bool found = false;
FOREACH_ELEMENT(i, allowed_auth_map)
if (streq(auth, i->str)) {
*allowed_auth |= i->auth;
found = true;
break;
}
if (!found)
log_syntax(unit, LOG_WARNING, filename, line, -EINVAL,
"Unknown auth value '%s', ignoring", auth);
}
}
int config_parse_mm_ip_family(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
static const struct {
MMBearerIpFamily family;
const char *str;
} ip_family_map[] = {
{ MM_BEARER_IP_FAMILY_IPV4, "ipv4" },
{ MM_BEARER_IP_FAMILY_IPV6, "ipv6" },
{ MM_BEARER_IP_FAMILY_IPV4V6, "both" },
{ MM_BEARER_IP_FAMILY_ANY, "any" },
};
MMBearerIpFamily *ip_family = ASSERT_PTR(data);
assert(filename);
assert(lvalue);
assert(rvalue);
if (isempty(rvalue)) {
*ip_family = MM_BEARER_IP_FAMILY_NONE;
return 0;
}
FOREACH_ELEMENT(i, ip_family_map)
if (streq(rvalue, i->str)) {
*ip_family = i->family;
return 0;
}
return log_syntax_parse_error(unit, filename, line, -EINVAL, lvalue, rvalue);
}
+2
View File
@@ -77,4 +77,6 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Modem*, modem_free);
int modem_get_by_path(Manager *m, const char *path, Modem **ret);
int link_get_modem(Link *link, Modem **ret);
CONFIG_PARSER_PROTOTYPE(config_parse_mm_allowed_auth);
CONFIG_PARSER_PROTOTYPE(config_parse_mm_ip_family);
CONFIG_PARSER_PROTOTYPE(config_parse_mm_route_metric);