mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 01:47:58 +02:00
l3cfg: merge branch 'th/l3cfg-14'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/660
This commit is contained in:
commit
817ea086ee
12 changed files with 494 additions and 258 deletions
|
|
@ -190,11 +190,11 @@ typedef uint64_t _nm_bitwise nm_be64_t;
|
|||
/*****************************************************************************/
|
||||
|
||||
static inline uint32_t
|
||||
nm_add_u32_clamped(uint32_t a, uint32_t b)
|
||||
nm_add_clamped_u32(uint32_t a, uint32_t b)
|
||||
{
|
||||
uint32_t c;
|
||||
|
||||
/* returns the sum of a+b, or UINT32_MAX if the result would overflow. */
|
||||
/* returns a+b, or UINT32_MAX if the result would overflow. */
|
||||
|
||||
c = a + b;
|
||||
if (c < a)
|
||||
|
|
@ -202,6 +202,24 @@ nm_add_u32_clamped(uint32_t a, uint32_t b)
|
|||
return c;
|
||||
}
|
||||
|
||||
static inline unsigned
|
||||
nm_mult_clamped_u(unsigned a, unsigned b)
|
||||
{
|
||||
unsigned c;
|
||||
|
||||
/* returns a*b, or UINT_MAX if the result would overflow. */
|
||||
|
||||
if (b == 0)
|
||||
return 0;
|
||||
|
||||
c = a * b;
|
||||
|
||||
if (c / b != a)
|
||||
return (unsigned) -1;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
/* glib's MIN()/MAX() macros don't have function-like behavior, in that they evaluate
|
||||
* the argument possibly twice.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1636,3 +1636,203 @@ nm_utils_ip_routes_to_dbus(int addr_family,
|
|||
NM_SET_OUT(out_route_data, g_variant_builder_end(&builder_data));
|
||||
NM_SET_OUT(out_routes, g_variant_builder_end(&builder_legacy));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
char *table;
|
||||
char *rule;
|
||||
} ShareRule;
|
||||
|
||||
struct _NMUtilsShareRules {
|
||||
GArray *rules;
|
||||
};
|
||||
|
||||
static void
|
||||
_share_rule_clear(gpointer data)
|
||||
{
|
||||
ShareRule *rule = data;
|
||||
|
||||
g_free(rule->table);
|
||||
g_free(rule->rule);
|
||||
}
|
||||
|
||||
NMUtilsShareRules *
|
||||
nm_utils_share_rules_new(void)
|
||||
{
|
||||
NMUtilsShareRules *self;
|
||||
|
||||
self = g_slice_new(NMUtilsShareRules);
|
||||
*self = (NMUtilsShareRules){
|
||||
.rules = g_array_sized_new(FALSE, FALSE, sizeof(ShareRule), 10),
|
||||
};
|
||||
|
||||
g_array_set_clear_func(self->rules, _share_rule_clear);
|
||||
return self;
|
||||
}
|
||||
|
||||
void
|
||||
nm_utils_share_rules_free(NMUtilsShareRules *self)
|
||||
{
|
||||
if (!self)
|
||||
return;
|
||||
|
||||
g_array_unref(self->rules);
|
||||
nm_g_slice_free(self);
|
||||
}
|
||||
|
||||
void
|
||||
nm_utils_share_rules_add_rule_take(NMUtilsShareRules *self, const char *table, char *rule_take)
|
||||
{
|
||||
ShareRule *rule;
|
||||
|
||||
g_return_if_fail(self);
|
||||
g_return_if_fail(table);
|
||||
g_return_if_fail(rule_take);
|
||||
|
||||
rule = nm_g_array_append_new(self->rules, ShareRule);
|
||||
*rule = (ShareRule){
|
||||
.table = g_strdup(table),
|
||||
.rule = g_steal_pointer(&rule_take),
|
||||
};
|
||||
}
|
||||
|
||||
void
|
||||
nm_utils_share_rules_apply(NMUtilsShareRules *self, gboolean shared)
|
||||
{
|
||||
guint i;
|
||||
|
||||
g_return_if_fail(self);
|
||||
|
||||
if (self->rules->len == 0)
|
||||
return;
|
||||
|
||||
/* depending on whether we share or unshare, we add/remote the rules
|
||||
* in opposite order. */
|
||||
if (shared)
|
||||
i = self->rules->len - 1;
|
||||
else
|
||||
i = 0;
|
||||
|
||||
for (;;) {
|
||||
gs_free_error GError *error = NULL;
|
||||
ShareRule * rule;
|
||||
gs_free const char ** argv = NULL;
|
||||
gs_free char * cmd = NULL;
|
||||
int status;
|
||||
|
||||
rule = &g_array_index(self->rules, ShareRule, i);
|
||||
|
||||
cmd = g_strdup_printf("%s --table %s %s %s",
|
||||
IPTABLES_PATH,
|
||||
rule->table,
|
||||
shared ? "--insert" : "--delete",
|
||||
rule->rule);
|
||||
argv = nm_utils_strsplit_set(cmd, " ");
|
||||
|
||||
nm_log_info(LOGD_SHARING, "Executing: %s", cmd);
|
||||
if (!g_spawn_sync("/",
|
||||
(char **) argv,
|
||||
(char **) NM_PTRARRAY_EMPTY(const char *),
|
||||
G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&status,
|
||||
&error)) {
|
||||
nm_log_warn(LOGD_SHARING, "Error executing command: %s", error->message);
|
||||
goto next;
|
||||
}
|
||||
if (WEXITSTATUS(status)) {
|
||||
nm_log_warn(LOGD_SHARING, "** Command returned exit status %d.", WEXITSTATUS(status));
|
||||
}
|
||||
|
||||
next:
|
||||
if (shared) {
|
||||
if (i == 0)
|
||||
break;
|
||||
i--;
|
||||
} else {
|
||||
i++;
|
||||
if (i >= self->rules->len)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nm_utils_share_rules_add_all_rules(NMUtilsShareRules *self,
|
||||
const char * ip_iface,
|
||||
in_addr_t addr,
|
||||
guint plen)
|
||||
{
|
||||
in_addr_t netmask;
|
||||
in_addr_t network;
|
||||
char str_mask[NM_UTILS_INET_ADDRSTRLEN];
|
||||
char str_addr[NM_UTILS_INET_ADDRSTRLEN];
|
||||
|
||||
nm_assert(self);
|
||||
|
||||
netmask = _nm_utils_ip4_prefix_to_netmask(plen);
|
||||
_nm_utils_inet4_ntop(netmask, str_mask);
|
||||
|
||||
network = addr & netmask;
|
||||
_nm_utils_inet4_ntop(network, str_addr);
|
||||
|
||||
nm_utils_share_rules_add_rule_v(
|
||||
self,
|
||||
"nat",
|
||||
"POSTROUTING --source %s/%s ! --destination %s/%s --jump MASQUERADE",
|
||||
str_addr,
|
||||
str_mask,
|
||||
str_addr,
|
||||
str_mask);
|
||||
nm_utils_share_rules_add_rule_v(
|
||||
self,
|
||||
"filter",
|
||||
"FORWARD --destination %s/%s --out-interface %s --match state --state "
|
||||
"ESTABLISHED,RELATED --jump ACCEPT",
|
||||
str_addr,
|
||||
str_mask,
|
||||
ip_iface);
|
||||
nm_utils_share_rules_add_rule_v(self,
|
||||
"filter",
|
||||
"FORWARD --source %s/%s --in-interface %s --jump ACCEPT",
|
||||
str_addr,
|
||||
str_mask,
|
||||
ip_iface);
|
||||
nm_utils_share_rules_add_rule_v(self,
|
||||
"filter",
|
||||
"FORWARD --in-interface %s --out-interface %s --jump ACCEPT",
|
||||
ip_iface,
|
||||
ip_iface);
|
||||
nm_utils_share_rules_add_rule_v(self,
|
||||
"filter",
|
||||
"FORWARD --out-interface %s --jump REJECT",
|
||||
ip_iface);
|
||||
nm_utils_share_rules_add_rule_v(self,
|
||||
"filter",
|
||||
"FORWARD --in-interface %s --jump REJECT",
|
||||
ip_iface);
|
||||
nm_utils_share_rules_add_rule_v(
|
||||
self,
|
||||
"filter",
|
||||
"INPUT --in-interface %s --protocol udp --destination-port 67 --jump ACCEPT",
|
||||
ip_iface);
|
||||
nm_utils_share_rules_add_rule_v(
|
||||
self,
|
||||
"filter",
|
||||
"INPUT --in-interface %s --protocol tcp --destination-port 67 --jump ACCEPT",
|
||||
ip_iface);
|
||||
nm_utils_share_rules_add_rule_v(
|
||||
self,
|
||||
"filter",
|
||||
"INPUT --in-interface %s --protocol udp --destination-port 53 --jump ACCEPT",
|
||||
ip_iface);
|
||||
nm_utils_share_rules_add_rule_v(
|
||||
self,
|
||||
"filter",
|
||||
"INPUT --in-interface %s --protocol tcp --destination-port 53 --jump ACCEPT",
|
||||
ip_iface);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -224,4 +224,31 @@ NM_AUTO_DEFINE_FCN(NMDhcpLease *, _nm_auto_unref_dhcplease, nm_dhcp_lease_unref)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct _NMUtilsShareRules NMUtilsShareRules;
|
||||
|
||||
NMUtilsShareRules *nm_utils_share_rules_new(void);
|
||||
|
||||
void nm_utils_share_rules_free(NMUtilsShareRules *self);
|
||||
|
||||
void
|
||||
nm_utils_share_rules_add_rule_take(NMUtilsShareRules *self, const char *table, char *rule_take);
|
||||
|
||||
static inline void
|
||||
nm_utils_share_rules_add_rule(NMUtilsShareRules *self, const char *table, const char *rule)
|
||||
{
|
||||
nm_utils_share_rules_add_rule_take(self, table, g_strdup(rule));
|
||||
}
|
||||
|
||||
#define nm_utils_share_rules_add_rule_v(self, table, ...) \
|
||||
nm_utils_share_rules_add_rule_take((self), (table), g_strdup_printf(__VA_ARGS__))
|
||||
|
||||
void nm_utils_share_rules_add_all_rules(NMUtilsShareRules *self,
|
||||
const char * ip_iface,
|
||||
in_addr_t addr,
|
||||
guint plen);
|
||||
|
||||
void nm_utils_share_rules_apply(NMUtilsShareRules *self, gboolean shared);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#endif /* __NETWORKMANAGER_UTILS_H__ */
|
||||
|
|
|
|||
|
|
@ -11536,17 +11536,16 @@ activate_stage4_ip_config_timeout_6(NMDevice *self)
|
|||
static gboolean
|
||||
share_init(NMDevice *self, GError **error)
|
||||
{
|
||||
char * modules[] = {"ip_tables",
|
||||
"iptable_nat",
|
||||
"nf_nat_ftp",
|
||||
"nf_nat_irc",
|
||||
"nf_nat_sip",
|
||||
"nf_nat_tftp",
|
||||
"nf_nat_pptp",
|
||||
"nf_nat_h323",
|
||||
NULL};
|
||||
char **iter;
|
||||
int errsv;
|
||||
const char *const modules[] = {"ip_tables",
|
||||
"iptable_nat",
|
||||
"nf_nat_ftp",
|
||||
"nf_nat_irc",
|
||||
"nf_nat_sip",
|
||||
"nf_nat_tftp",
|
||||
"nf_nat_pptp",
|
||||
"nf_nat_h323"};
|
||||
guint i;
|
||||
int errsv;
|
||||
|
||||
if (nm_platform_sysctl_get_int32(nm_device_get_platform(self),
|
||||
NMP_SYSCTL_PATHID_ABSOLUTE("/proc/sys/net/ipv4/ip_forward"),
|
||||
|
|
@ -11584,35 +11583,24 @@ share_init(NMDevice *self, GError **error)
|
|||
nm_strerror_native(errsv));
|
||||
}
|
||||
|
||||
for (iter = modules; *iter; iter++)
|
||||
nm_utils_modprobe(NULL, FALSE, *iter, NULL);
|
||||
for (i = 0; i < G_N_ELEMENTS(modules); i++)
|
||||
nm_utils_modprobe(NULL, FALSE, modules[i], NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define add_share_rule(req, table, ...) \
|
||||
G_STMT_START \
|
||||
{ \
|
||||
char *_cmd = g_strdup_printf(__VA_ARGS__); \
|
||||
nm_act_request_add_share_rule(req, table, _cmd); \
|
||||
g_free(_cmd); \
|
||||
} \
|
||||
G_STMT_END
|
||||
|
||||
static gboolean
|
||||
start_sharing(NMDevice *self, NMIP4Config *config, GError **error)
|
||||
{
|
||||
NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
|
||||
NMActRequest * req;
|
||||
char str_addr[INET_ADDRSTRLEN];
|
||||
char str_mask[INET_ADDRSTRLEN];
|
||||
guint32 netmask, network;
|
||||
const NMPlatformIP4Address *ip4_addr = NULL;
|
||||
const char * ip_iface;
|
||||
GError * local = NULL;
|
||||
NMConnection * conn;
|
||||
NMSettingConnection * s_con;
|
||||
gboolean announce_android_metered;
|
||||
NMUtilsShareRules * share_rules;
|
||||
|
||||
g_return_val_if_fail(config, FALSE);
|
||||
|
||||
|
|
@ -11637,57 +11625,13 @@ start_sharing(NMDevice *self, NMIP4Config *config, GError **error)
|
|||
req = nm_device_get_act_request(self);
|
||||
g_return_val_if_fail(req, FALSE);
|
||||
|
||||
netmask = _nm_utils_ip4_prefix_to_netmask(ip4_addr->plen);
|
||||
_nm_utils_inet4_ntop(netmask, str_mask);
|
||||
share_rules = nm_utils_share_rules_new();
|
||||
|
||||
network = ip4_addr->address & netmask;
|
||||
_nm_utils_inet4_ntop(network, str_addr);
|
||||
nm_utils_share_rules_add_all_rules(share_rules, ip_iface, ip4_addr->address, ip4_addr->plen);
|
||||
|
||||
add_share_rule(req,
|
||||
"nat",
|
||||
"POSTROUTING --source %s/%s ! --destination %s/%s --jump MASQUERADE",
|
||||
str_addr,
|
||||
str_mask,
|
||||
str_addr,
|
||||
str_mask);
|
||||
add_share_rule(req,
|
||||
"filter",
|
||||
"FORWARD --destination %s/%s --out-interface %s --match state --state "
|
||||
"ESTABLISHED,RELATED --jump ACCEPT",
|
||||
str_addr,
|
||||
str_mask,
|
||||
ip_iface);
|
||||
add_share_rule(req,
|
||||
"filter",
|
||||
"FORWARD --source %s/%s --in-interface %s --jump ACCEPT",
|
||||
str_addr,
|
||||
str_mask,
|
||||
ip_iface);
|
||||
add_share_rule(req,
|
||||
"filter",
|
||||
"FORWARD --in-interface %s --out-interface %s --jump ACCEPT",
|
||||
ip_iface,
|
||||
ip_iface);
|
||||
add_share_rule(req, "filter", "FORWARD --out-interface %s --jump REJECT", ip_iface);
|
||||
add_share_rule(req, "filter", "FORWARD --in-interface %s --jump REJECT", ip_iface);
|
||||
add_share_rule(req,
|
||||
"filter",
|
||||
"INPUT --in-interface %s --protocol udp --destination-port 67 --jump ACCEPT",
|
||||
ip_iface);
|
||||
add_share_rule(req,
|
||||
"filter",
|
||||
"INPUT --in-interface %s --protocol tcp --destination-port 67 --jump ACCEPT",
|
||||
ip_iface);
|
||||
add_share_rule(req,
|
||||
"filter",
|
||||
"INPUT --in-interface %s --protocol udp --destination-port 53 --jump ACCEPT",
|
||||
ip_iface);
|
||||
add_share_rule(req,
|
||||
"filter",
|
||||
"INPUT --in-interface %s --protocol tcp --destination-port 53 --jump ACCEPT",
|
||||
ip_iface);
|
||||
nm_utils_share_rules_apply(share_rules, TRUE);
|
||||
|
||||
nm_act_request_set_shared(req, TRUE);
|
||||
nm_act_request_set_shared(req, share_rules);
|
||||
|
||||
conn = nm_act_request_get_applied_connection(req);
|
||||
s_con = nm_connection_get_setting_connection(conn);
|
||||
|
|
@ -11722,7 +11666,7 @@ start_sharing(NMDevice *self, NMIP4Config *config, GError **error)
|
|||
"could not start dnsmasq due to %s",
|
||||
local->message);
|
||||
g_error_free(local);
|
||||
nm_act_request_set_shared(req, FALSE);
|
||||
nm_act_request_set_shared(req, NULL);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,14 +22,8 @@
|
|||
#include "nm-libnm-core-intern/nm-auth-subject.h"
|
||||
|
||||
typedef struct {
|
||||
char *table;
|
||||
char *rule;
|
||||
} ShareRule;
|
||||
|
||||
typedef struct {
|
||||
CList call_ids_lst_head;
|
||||
gboolean shared;
|
||||
GSList * share_rules;
|
||||
CList call_ids_lst_head;
|
||||
NMUtilsShareRules *share_rules;
|
||||
} NMActRequestPrivate;
|
||||
|
||||
struct _NMActRequest {
|
||||
|
|
@ -254,109 +248,32 @@ nm_act_request_clear_secrets(NMActRequest *self)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
clear_share_rules(NMActRequest *req)
|
||||
{
|
||||
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE(req);
|
||||
GSList * iter;
|
||||
|
||||
for (iter = priv->share_rules; iter; iter = g_slist_next(iter)) {
|
||||
ShareRule *rule = (ShareRule *) iter->data;
|
||||
|
||||
g_free(rule->table);
|
||||
g_free(rule->rule);
|
||||
g_free(rule);
|
||||
}
|
||||
|
||||
g_slist_free(priv->share_rules);
|
||||
priv->share_rules = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
nm_act_request_set_shared(NMActRequest *req, gboolean shared)
|
||||
{
|
||||
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE(req);
|
||||
GSList * list, *iter;
|
||||
|
||||
g_return_if_fail(NM_IS_ACT_REQUEST(req));
|
||||
|
||||
NM_ACT_REQUEST_GET_PRIVATE(req)->shared = shared;
|
||||
|
||||
/* Tear the rules down in reverse order when sharing is stopped */
|
||||
list = g_slist_copy(priv->share_rules);
|
||||
if (!shared)
|
||||
list = g_slist_reverse(list);
|
||||
|
||||
/* Send the rules to iptables */
|
||||
for (iter = list; iter; iter = g_slist_next(iter)) {
|
||||
ShareRule * rule = (ShareRule *) iter->data;
|
||||
char * envp[1] = {NULL};
|
||||
gs_strfreev char **argv = NULL;
|
||||
gs_free char * cmd = NULL;
|
||||
|
||||
cmd = g_strdup_printf("%s --table %s %s %s",
|
||||
IPTABLES_PATH,
|
||||
rule->table,
|
||||
shared ? "--insert" : "--delete",
|
||||
rule->rule);
|
||||
if (!cmd)
|
||||
continue;
|
||||
|
||||
argv = g_strsplit(cmd, " ", 0);
|
||||
if (argv && argv[0]) {
|
||||
int status;
|
||||
GError *error = NULL;
|
||||
|
||||
nm_log_info(LOGD_SHARING, "Executing: %s", cmd);
|
||||
if (!g_spawn_sync("/",
|
||||
argv,
|
||||
envp,
|
||||
G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&status,
|
||||
&error)) {
|
||||
nm_log_warn(LOGD_SHARING, "Error executing command: %s", error->message);
|
||||
g_clear_error(&error);
|
||||
} else if (WEXITSTATUS(status)) {
|
||||
nm_log_warn(LOGD_SHARING,
|
||||
"** Command returned exit status %d.",
|
||||
WEXITSTATUS(status));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_slist_free(list);
|
||||
|
||||
/* Clear the share rule list when sharing is stopped */
|
||||
if (!shared)
|
||||
clear_share_rules(req);
|
||||
}
|
||||
|
||||
gboolean
|
||||
NMUtilsShareRules *
|
||||
nm_act_request_get_shared(NMActRequest *req)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_ACT_REQUEST(req), FALSE);
|
||||
|
||||
return NM_ACT_REQUEST_GET_PRIVATE(req)->shared;
|
||||
return NM_ACT_REQUEST_GET_PRIVATE(req)->share_rules;
|
||||
}
|
||||
|
||||
void
|
||||
nm_act_request_add_share_rule(NMActRequest *req, const char *table, const char *table_rule)
|
||||
nm_act_request_set_shared(NMActRequest *req, NMUtilsShareRules *rules)
|
||||
{
|
||||
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE(req);
|
||||
ShareRule * rule;
|
||||
|
||||
g_return_if_fail(NM_IS_ACT_REQUEST(req));
|
||||
g_return_if_fail(table != NULL);
|
||||
g_return_if_fail(table_rule != NULL);
|
||||
|
||||
rule = g_malloc0(sizeof(ShareRule));
|
||||
rule->table = g_strdup(table);
|
||||
rule->rule = g_strdup(table_rule);
|
||||
priv->share_rules = g_slist_prepend(priv->share_rules, rule);
|
||||
if (priv->share_rules == rules)
|
||||
return;
|
||||
|
||||
if (priv->share_rules) {
|
||||
nm_utils_share_rules_apply(priv->share_rules, FALSE);
|
||||
priv->share_rules = NULL;
|
||||
}
|
||||
if (rules) {
|
||||
priv->share_rules = rules;
|
||||
nm_utils_share_rules_apply(priv->share_rules, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -589,10 +506,9 @@ dispose(GObject *object)
|
|||
c_list_for_each_entry_safe (call_id, call_id_safe, &priv->call_ids_lst_head, call_ids_lst)
|
||||
_do_cancel_secrets(self, call_id, TRUE);
|
||||
|
||||
/* Clear any share rules */
|
||||
if (priv->share_rules) {
|
||||
nm_act_request_set_shared(NM_ACT_REQUEST(object), FALSE);
|
||||
clear_share_rules(NM_ACT_REQUEST(object));
|
||||
nm_utils_share_rules_apply(priv->share_rules, FALSE);
|
||||
nm_clear_pointer(&priv->share_rules, nm_utils_share_rules_free);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS(nm_act_request_parent_class)->dispose(object);
|
||||
|
|
|
|||
|
|
@ -36,11 +36,15 @@ NMSettingsConnection *nm_act_request_get_settings_connection(NMActRequest *req);
|
|||
|
||||
NMConnection *nm_act_request_get_applied_connection(NMActRequest *req);
|
||||
|
||||
gboolean nm_act_request_get_shared(NMActRequest *req);
|
||||
/*****************************************************************************/
|
||||
|
||||
void nm_act_request_set_shared(NMActRequest *req, gboolean shared);
|
||||
struct _NMUtilsShareRules;
|
||||
|
||||
void nm_act_request_add_share_rule(NMActRequest *req, const char *table, const char *rule);
|
||||
struct _NMUtilsShareRules *nm_act_request_get_shared(NMActRequest *req);
|
||||
|
||||
void nm_act_request_set_shared(NMActRequest *req, struct _NMUtilsShareRules *rules);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Secrets handling */
|
||||
|
||||
|
|
|
|||
|
|
@ -2600,7 +2600,7 @@ nm_l3_config_data_merge(NML3ConfigData * self,
|
|||
if (r_src->metric_any) {
|
||||
_ensure_r();
|
||||
r.rx.metric_any = FALSE;
|
||||
r.rx.metric = nm_add_u32_clamped(r.rx.metric, default_route_metric_x[IS_IPv4]);
|
||||
r.rx.metric = nm_add_clamped_u32(r.rx.metric, default_route_metric_x[IS_IPv4]);
|
||||
}
|
||||
|
||||
if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(r_src)) {
|
||||
|
|
|
|||
|
|
@ -11,8 +11,16 @@
|
|||
|
||||
#define ADDR_IPV4LL_PREFIX_LEN 16
|
||||
|
||||
#define TIMED_OUT_TIME_FACTOR 5u
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
TIMED_OUT_STATE_IS_NOT_TIMED_OUT,
|
||||
TIMED_OUT_STATE_IS_TIMED_OUT,
|
||||
TIMED_OUT_STATE_HAVE_TIMER_RUNNING,
|
||||
} TimedOutState;
|
||||
|
||||
struct _NML3IPv4LLRegistration {
|
||||
NML3IPv4LL *self;
|
||||
CList reg_lst;
|
||||
|
|
@ -29,24 +37,26 @@ struct _NML3IPv4LL {
|
|||
CList reg_lst_head;
|
||||
NML3CfgCommitTypeHandle *l3cfg_commit_handle;
|
||||
GSource * state_change_on_idle_source;
|
||||
GSource * timed_out_source;
|
||||
const NML3ConfigData * l3cd;
|
||||
const NMPObject * plobj;
|
||||
struct {
|
||||
nm_le64_t value;
|
||||
nm_le64_t generation;
|
||||
} seed;
|
||||
gint64 timed_out_expiry_msec;
|
||||
gulong l3cfg_signal_notify_id;
|
||||
gint64 last_good_at_msec : 1;
|
||||
NML3IPv4LLState state;
|
||||
NMEtherAddr seed_mac;
|
||||
NMEtherAddr mac;
|
||||
bool seed_set : 1;
|
||||
bool seed_reset_generation : 1;
|
||||
bool mac_set : 1;
|
||||
bool link_seen_not_ready : 1;
|
||||
bool notify_on_idle : 1;
|
||||
bool reg_changed : 1;
|
||||
bool l3cd_timeout_msec_changed : 1;
|
||||
|
||||
/* not yet used. */
|
||||
bool seed_reset_generation : 1;
|
||||
};
|
||||
|
||||
G_STATIC_ASSERT(G_STRUCT_OFFSET(NML3IPv4LL, ref_count) == sizeof(gpointer));
|
||||
|
|
@ -77,6 +87,8 @@ static void _ipv4ll_state_change_on_idle(NML3IPv4LL *self);
|
|||
|
||||
static void _ipv4ll_state_change(NML3IPv4LL *self, gboolean is_on_idle_handler);
|
||||
|
||||
static void _ipv4ll_set_timed_out_update(NML3IPv4LL *self, TimedOutState new_state);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NM_UTILS_ENUM2STR_DEFINE(nm_l3_ipv4ll_state_to_string,
|
||||
|
|
@ -140,6 +152,22 @@ nm_l3_ipv4ll_get_state(NML3IPv4LL *self)
|
|||
return self->state;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_ipv4ll_is_timed_out(NML3IPv4LL *self)
|
||||
{
|
||||
_ASSERT(self);
|
||||
|
||||
return self->timed_out_expiry_msec != 0 && !self->timed_out_source;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_l3_ipv4ll_is_timed_out(NML3IPv4LL *self)
|
||||
{
|
||||
nm_assert(NM_IS_L3_IPV4LL(self));
|
||||
|
||||
return _ipv4ll_is_timed_out(self);
|
||||
}
|
||||
|
||||
in_addr_t
|
||||
nm_l3_ipv4ll_get_addr(NML3IPv4LL *self)
|
||||
{
|
||||
|
|
@ -156,6 +184,20 @@ nm_l3_ipv4ll_get_l3cd(NML3IPv4LL *self)
|
|||
return self->l3cd;
|
||||
}
|
||||
|
||||
static void
|
||||
_ipv4ll_emit_signal_notify(NML3IPv4LL *self)
|
||||
{
|
||||
NML3ConfigNotifyData notify_data;
|
||||
|
||||
self->notify_on_idle = FALSE;
|
||||
|
||||
notify_data.notify_type = NM_L3_CONFIG_NOTIFY_TYPE_IPV4LL_EVENT;
|
||||
notify_data.ipv4ll_event = (typeof(notify_data.ipv4ll_event)){
|
||||
.ipv4ll = self,
|
||||
};
|
||||
_nm_l3cfg_emit_signal_notify(self->l3cfg, ¬ify_data);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static NML3IPv4LLRegistration *
|
||||
|
|
@ -272,23 +314,6 @@ _acd_info_is_good(const NML3AcdAddrInfo *acd_info)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_plobj_link_is_ready(const NMPObject *plobj)
|
||||
{
|
||||
const NMPlatformLink *pllink;
|
||||
|
||||
if (!plobj)
|
||||
return FALSE;
|
||||
|
||||
pllink = NMP_OBJECT_CAST_LINK(plobj);
|
||||
if (!NM_FLAGS_HAS(pllink->n_ifi_flags, IFF_UP))
|
||||
return FALSE;
|
||||
if (pllink->l_address.len != ETH_ALEN)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static NMPlatformIP4Address *
|
||||
|
|
@ -693,6 +718,67 @@ _ipv4ll_platform_find_addr(NML3IPv4LL *self, const NML3AcdAddrInfo **out_acd_inf
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
_ipv4ll_set_timed_out_timeout_cb(gpointer user_data)
|
||||
{
|
||||
NML3IPv4LL *self = user_data;
|
||||
|
||||
_ipv4ll_set_timed_out_update(self, TIMED_OUT_STATE_IS_TIMED_OUT);
|
||||
if (self->notify_on_idle)
|
||||
_ipv4ll_emit_signal_notify(self);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
_ipv4ll_set_timed_out_update(NML3IPv4LL *self, TimedOutState new_state)
|
||||
{
|
||||
gboolean before;
|
||||
|
||||
before = _ipv4ll_is_timed_out(self);
|
||||
|
||||
switch (new_state) {
|
||||
case TIMED_OUT_STATE_IS_TIMED_OUT:
|
||||
if (self->timed_out_expiry_msec == 0) {
|
||||
nm_assert(!self->timed_out_source);
|
||||
self->timed_out_expiry_msec = 1;
|
||||
}
|
||||
nm_clear_g_source_inst(&self->timed_out_source);
|
||||
break;
|
||||
case TIMED_OUT_STATE_IS_NOT_TIMED_OUT:
|
||||
self->timed_out_expiry_msec = 0;
|
||||
nm_clear_g_source_inst(&self->timed_out_source);
|
||||
break;
|
||||
case TIMED_OUT_STATE_HAVE_TIMER_RUNNING:
|
||||
{
|
||||
gint64 now_msec = nm_utils_get_monotonic_timestamp_msec();
|
||||
guint timeout_msec;
|
||||
gint64 expiry_msec;
|
||||
|
||||
nm_assert(self->reg_timeout_msec > 0u);
|
||||
|
||||
timeout_msec = nm_mult_clamped_u(TIMED_OUT_TIME_FACTOR, self->reg_timeout_msec);
|
||||
expiry_msec = now_msec + timeout_msec;
|
||||
|
||||
if (self->timed_out_expiry_msec == 0 || self->timed_out_expiry_msec < expiry_msec) {
|
||||
self->timed_out_expiry_msec = expiry_msec;
|
||||
nm_clear_g_source_inst(&self->timed_out_source);
|
||||
self->timed_out_source = nm_g_timeout_source_new(timeout_msec,
|
||||
G_PRIORITY_DEFAULT,
|
||||
_ipv4ll_set_timed_out_timeout_cb,
|
||||
self,
|
||||
NULL);
|
||||
g_source_attach(self->timed_out_source, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (before != _ipv4ll_is_timed_out(self)) {
|
||||
self->notify_on_idle = TRUE;
|
||||
_LOGT("state: set timed-out-is-bad=%d", (!before));
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_ipv4ll_set_state(NML3IPv4LL *self, NML3IPv4LLState state)
|
||||
{
|
||||
|
|
@ -731,6 +817,8 @@ _ipv4ll_state_change(NML3IPv4LL *self, gboolean is_on_idle_handler)
|
|||
if (self->reg_changed) {
|
||||
guint timeout_msec = self->reg_timeout_msec;
|
||||
|
||||
self->reg_changed = FALSE;
|
||||
|
||||
if (c_list_is_empty(&self->reg_lst_head))
|
||||
timeout_msec = 0;
|
||||
else {
|
||||
|
|
@ -749,12 +837,14 @@ _ipv4ll_state_change(NML3IPv4LL *self, gboolean is_on_idle_handler)
|
|||
}
|
||||
|
||||
if (self->reg_timeout_msec == 0) {
|
||||
_ipv4ll_set_timed_out_update(self, TIMED_OUT_STATE_IS_NOT_TIMED_OUT);
|
||||
if (_ipv4ll_set_state(self, NM_L3_IPV4LL_STATE_DISABLED))
|
||||
_l3cd_config_remove(self);
|
||||
goto out_notify;
|
||||
}
|
||||
|
||||
if (!self->mac_set) {
|
||||
_ipv4ll_set_timed_out_update(self, TIMED_OUT_STATE_HAVE_TIMER_RUNNING);
|
||||
if (_ipv4ll_set_state(self, NM_L3_IPV4LL_STATE_WAIT_FOR_LINK))
|
||||
_l3cd_config_remove(self);
|
||||
else
|
||||
|
|
@ -773,7 +863,12 @@ _ipv4ll_state_change(NML3IPv4LL *self, gboolean is_on_idle_handler)
|
|||
|
||||
if (pladdr) {
|
||||
/* we have an externally configured address. Check whether we can use it. */
|
||||
goto out_set_external_pladdr;
|
||||
self->addr = pladdr->address;
|
||||
self->notify_on_idle = TRUE;
|
||||
_ipv4ll_set_state(self, NM_L3_IPV4LL_STATE_EXTERNAL);
|
||||
_l3cd_config_add(self);
|
||||
_ipv4ll_set_timed_out_update(self, TIMED_OUT_STATE_IS_NOT_TIMED_OUT);
|
||||
goto out_notify;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -782,29 +877,24 @@ _ipv4ll_state_change(NML3IPv4LL *self, gboolean is_on_idle_handler)
|
|||
_ipv4ll_addrgen(self, generate_new_addr);
|
||||
acd_info = _ipv4ll_l3cfg_get_acd_addr_info(self, self->addr);
|
||||
if (_acd_info_is_good(acd_info))
|
||||
goto out_is_good;
|
||||
break;
|
||||
generate_new_addr = TRUE;
|
||||
}
|
||||
|
||||
out_set_external_pladdr:
|
||||
self->addr = pladdr->address;
|
||||
_ipv4ll_set_state(self, NM_L3_IPV4LL_STATE_EXTERNAL);
|
||||
_l3cd_config_add(self);
|
||||
self->notify_on_idle = TRUE;
|
||||
goto out_notify;
|
||||
|
||||
out_is_good:
|
||||
nm_assert(_acd_info_is_good(acd_info));
|
||||
switch (acd_info ? acd_info->state : NM_L3_ACD_ADDR_STATE_INIT) {
|
||||
case NM_L3_ACD_ADDR_STATE_INIT:
|
||||
case NM_L3_ACD_ADDR_STATE_PROBING:
|
||||
new_state = NM_L3_IPV4LL_STATE_PROBING;
|
||||
_ipv4ll_set_timed_out_update(self, TIMED_OUT_STATE_HAVE_TIMER_RUNNING);
|
||||
goto out_is_good_1;
|
||||
case NM_L3_ACD_ADDR_STATE_READY:
|
||||
new_state = NM_L3_IPV4LL_STATE_READY;
|
||||
_ipv4ll_set_timed_out_update(self, TIMED_OUT_STATE_HAVE_TIMER_RUNNING);
|
||||
goto out_is_good_1;
|
||||
case NM_L3_ACD_ADDR_STATE_DEFENDING:
|
||||
new_state = NM_L3_IPV4LL_STATE_DEFENDING;
|
||||
_ipv4ll_set_timed_out_update(self, TIMED_OUT_STATE_IS_NOT_TIMED_OUT);
|
||||
goto out_is_good_1;
|
||||
case NM_L3_ACD_ADDR_STATE_EXTERNAL_REMOVED:
|
||||
case NM_L3_ACD_ADDR_STATE_USED:
|
||||
|
|
@ -823,17 +913,9 @@ out_is_good_1:
|
|||
|
||||
out_notify:
|
||||
if (self->notify_on_idle) {
|
||||
if (is_on_idle_handler) {
|
||||
NML3ConfigNotifyData notify_data;
|
||||
|
||||
self->notify_on_idle = FALSE;
|
||||
|
||||
notify_data.notify_type = NM_L3_CONFIG_NOTIFY_TYPE_IPV4LL_EVENT;
|
||||
notify_data.ipv4ll_event = (typeof(notify_data.ipv4ll_event)){
|
||||
.ipv4ll = self,
|
||||
};
|
||||
_nm_l3cfg_emit_signal_notify(self->l3cfg, ¬ify_data);
|
||||
} else
|
||||
if (is_on_idle_handler)
|
||||
_ipv4ll_emit_signal_notify(self);
|
||||
else
|
||||
_ipv4ll_state_change_on_idle(self);
|
||||
}
|
||||
}
|
||||
|
|
@ -861,36 +943,9 @@ _ipv4ll_state_change_on_idle(NML3IPv4LL *self)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
nm_l3_ipv4ll_restart(NML3IPv4LL *self)
|
||||
{
|
||||
nm_assert(NM_IS_L3_IPV4LL(self));
|
||||
|
||||
self->seed_reset_generation = TRUE;
|
||||
_ipv4ll_state_change(self, FALSE);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_l3cfg_notify_cb(NML3Cfg *l3cfg, const NML3ConfigNotifyData *notify_data, NML3IPv4LL *self)
|
||||
{
|
||||
if (notify_data->notify_type == NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE) {
|
||||
const NMPObject *obj = notify_data->platform_change.obj;
|
||||
|
||||
/* we only process the link changes on the idle handler. That means, we may miss
|
||||
* events. If we saw the link down for a moment, remember it. Note that netlink
|
||||
* anyway can loose signals, so we might still miss to see the link down. This
|
||||
* is as good as we get it. */
|
||||
if (NMP_OBJECT_GET_TYPE(obj) == NMP_OBJECT_TYPE_LINK) {
|
||||
if (notify_data->platform_change.change_type == NM_PLATFORM_SIGNAL_REMOVED)
|
||||
self->link_seen_not_ready = TRUE;
|
||||
else if (!_plobj_link_is_ready(obj))
|
||||
self->link_seen_not_ready = TRUE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (notify_data->notify_type == NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE_ON_IDLE) {
|
||||
/* NMl3Cfg only reloads the platform link during the idle handler. Pick it up now. */
|
||||
_ipv4ll_update_link(self, nm_l3cfg_get_plobj(l3cfg, FALSE));
|
||||
|
|
@ -938,8 +993,6 @@ nm_l3_ipv4ll_new(NML3Cfg *l3cfg)
|
|||
.notify_on_idle = TRUE,
|
||||
.l3cfg_signal_notify_id =
|
||||
g_signal_connect(l3cfg, NM_L3CFG_SIGNAL_NOTIFY, G_CALLBACK(_l3cfg_notify_cb), self),
|
||||
.last_good_at_msec = 0,
|
||||
.link_seen_not_ready = FALSE,
|
||||
.seed_set = FALSE,
|
||||
.seed_reset_generation = FALSE,
|
||||
};
|
||||
|
|
@ -975,6 +1028,9 @@ nm_l3_ipv4ll_unref(NML3IPv4LL *self)
|
|||
if (--self->ref_count > 0)
|
||||
return;
|
||||
|
||||
if (nm_l3cfg_get_ipv4ll(self->l3cfg) == self)
|
||||
_nm_l3cfg_unregister_ipv4ll(self->l3cfg);
|
||||
|
||||
_LOGT("finalize");
|
||||
|
||||
nm_assert(c_list_is_empty(&self->reg_lst_head));
|
||||
|
|
@ -992,6 +1048,7 @@ nm_l3_ipv4ll_unref(NML3IPv4LL *self)
|
|||
nm_assert(!self->l3cfg_commit_handle);
|
||||
|
||||
nm_clear_g_source_inst(&self->state_change_on_idle_source);
|
||||
nm_clear_g_source_inst(&self->timed_out_source);
|
||||
|
||||
nm_clear_g_signal_handler(self->l3cfg, &self->l3cfg_signal_notify_id);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,23 @@ typedef enum _nm_packed {
|
|||
|
||||
const char *nm_l3_ipv4ll_state_to_string(NML3IPv4LLState val, char *buf, gsize len);
|
||||
|
||||
static inline gboolean
|
||||
nm_l3_ipv4ll_state_is_good(NML3IPv4LLState state)
|
||||
{
|
||||
switch (state) {
|
||||
case NM_L3_IPV4LL_STATE_UNKNOWN:
|
||||
case NM_L3_IPV4LL_STATE_DISABLED:
|
||||
case NM_L3_IPV4LL_STATE_WAIT_FOR_LINK:
|
||||
case NM_L3_IPV4LL_STATE_PROBING:
|
||||
return FALSE;
|
||||
case NM_L3_IPV4LL_STATE_EXTERNAL:
|
||||
case NM_L3_IPV4LL_STATE_READY:
|
||||
case NM_L3_IPV4LL_STATE_DEFENDING:
|
||||
return TRUE;
|
||||
}
|
||||
return nm_assert_unreachable_val(FALSE);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct _NML3IPv4LL NML3IPv4LL;
|
||||
|
|
@ -92,12 +109,10 @@ nm_l3_ipv4ll_register_get_instance(NML3IPv4LLRegistration *reg)
|
|||
|
||||
NML3IPv4LLState nm_l3_ipv4ll_get_state(NML3IPv4LL *self);
|
||||
|
||||
gboolean nm_l3_ipv4ll_is_timed_out(NML3IPv4LL *self);
|
||||
|
||||
in_addr_t nm_l3_ipv4ll_get_addr(NML3IPv4LL *self);
|
||||
|
||||
const NML3ConfigData *nm_l3_ipv4ll_get_l3cd(NML3IPv4LL *self);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void nm_l3_ipv4ll_restart(NML3IPv4LL *self);
|
||||
|
||||
#endif /* __NM_L3_IPV4LL_H__ */
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
G_STATIC_ASSERT(NM_ACD_TIMEOUT_RFC5227_MSEC == N_ACD_TIMEOUT_RFC5227);
|
||||
|
||||
#define ACD_SUPPORTED_ETH_ALEN ETH_ALEN
|
||||
#define ACD_ENSURE_RATELIMIT_MSEC ((guint32) 4000u)
|
||||
#define ACD_WAIT_PROBING_EXTRA_TIME_MSEC ((guint32)(1000u + ACD_ENSURE_RATELIMIT_MSEC))
|
||||
|
|
@ -145,6 +147,8 @@ typedef struct _NML3CfgPrivate {
|
|||
GArray *property_emit_list;
|
||||
GArray *l3_config_datas;
|
||||
|
||||
NML3IPv4LL *ipv4ll;
|
||||
|
||||
const NML3ConfigData *combined_l3cd_merged;
|
||||
|
||||
const NML3ConfigData *combined_l3cd_commited;
|
||||
|
|
@ -3606,6 +3610,47 @@ nm_l3cfg_has_commited_ip6_addresses_pending_dad(NML3Cfg *self)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
NML3IPv4LL *
|
||||
nm_l3cfg_get_ipv4ll(NML3Cfg *self)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_L3CFG(self), NULL);
|
||||
|
||||
return self->priv.p->ipv4ll;
|
||||
}
|
||||
|
||||
NML3IPv4LL *
|
||||
nm_l3cfg_access_ipv4ll(NML3Cfg *self)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_L3CFG(self), NULL);
|
||||
|
||||
if (self->priv.p->ipv4ll)
|
||||
return nm_l3_ipv4ll_ref(self->priv.p->ipv4ll);
|
||||
|
||||
/* We return the reference. But the NML3IPv4LL instance
|
||||
* will call _nm_l3cfg_unregister_ipv4ll() when it gets
|
||||
* destroyed.
|
||||
*
|
||||
* We don't have weak references, but NML3Cfg and NML3IPv4LL
|
||||
* cooperate to handle this reference. */
|
||||
self->priv.p->ipv4ll = nm_l3_ipv4ll_new(self);
|
||||
return self->priv.p->ipv4ll;
|
||||
}
|
||||
|
||||
void
|
||||
_nm_l3cfg_unregister_ipv4ll(NML3Cfg *self)
|
||||
{
|
||||
nm_assert(NM_IS_L3CFG(self));
|
||||
|
||||
/* we don't own the refernce to "self->priv.p->ipv4ll", but
|
||||
* when that instance gets destroyed, we get called back to
|
||||
* forget about it. Basically, it's like a weak pointer. */
|
||||
|
||||
nm_assert(self->priv.p->ipv4ll);
|
||||
self->priv.p->ipv4ll = NULL;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
|
|
@ -3673,6 +3718,7 @@ finalize(GObject *object)
|
|||
NML3Cfg *self = NM_L3CFG(object);
|
||||
|
||||
nm_assert(!self->priv.p->l3_config_datas);
|
||||
nm_assert(!self->priv.p->ipv4ll);
|
||||
|
||||
nm_assert(c_list_is_empty(&self->priv.p->commit_type_lst_head));
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "nm-l3-config-data.h"
|
||||
|
||||
#define NM_L3CFG_CONFIG_PRIORITY_IPV4LL 0
|
||||
#define NM_ACD_TIMEOUT_RFC5227_MSEC 9000u
|
||||
|
||||
#define NM_TYPE_L3CFG (nm_l3cfg_get_type())
|
||||
#define NM_L3CFG(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_L3CFG, NML3Cfg))
|
||||
|
|
@ -344,4 +345,12 @@ gboolean nm_l3cfg_has_commited_ip6_addresses_pending_dad(NML3Cfg *self);
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
struct _NML3IPv4LL *nm_l3cfg_get_ipv4ll(NML3Cfg *self);
|
||||
|
||||
struct _NML3IPv4LL *nm_l3cfg_access_ipv4ll(NML3Cfg *self);
|
||||
|
||||
void _nm_l3cfg_unregister_ipv4ll(NML3Cfg *self);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#endif /* __NM_L3CFG_H__ */
|
||||
|
|
|
|||
|
|
@ -2086,7 +2086,7 @@ nm_platform_ip4_route_get_effective_metric(const NMPlatformIP4Route *r)
|
|||
{
|
||||
nm_assert(r);
|
||||
|
||||
return r->metric_any ? nm_add_u32_clamped(NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4, r->metric)
|
||||
return r->metric_any ? nm_add_clamped_u32(NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4, r->metric)
|
||||
: r->metric;
|
||||
}
|
||||
|
||||
|
|
@ -2095,7 +2095,7 @@ nm_platform_ip6_route_get_effective_metric(const NMPlatformIP6Route *r)
|
|||
{
|
||||
nm_assert(r);
|
||||
|
||||
return r->metric_any ? nm_add_u32_clamped(NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6, r->metric)
|
||||
return r->metric_any ? nm_add_clamped_u32(NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6, r->metric)
|
||||
: r->metric;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue