mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-28 15:40:10 +01:00
platform: add netlink support for bond port options
sysfs is deprecated and kernel will not add new bond port options to sysfs. Netlink is a stable API and therefore is the right method to communicate with kernel in order to set the link options. (cherry picked from commitbb435674b5) (cherry picked from commit1bce7f0dec)
This commit is contained in:
parent
836d7511e8
commit
ee592c02dd
7 changed files with 250 additions and 33 deletions
|
|
@ -223,24 +223,18 @@ controller_update_port_connection(NMDevice *self,
|
|||
NMConnection *connection,
|
||||
GError **error)
|
||||
{
|
||||
NMSettingBondPort *s_port;
|
||||
int ifindex_port = nm_device_get_ifindex(port);
|
||||
NMConnection *applied_connection = nm_device_get_applied_connection(self);
|
||||
uint queue_id = NM_BOND_PORT_QUEUE_ID_DEF;
|
||||
gs_free char *queue_id_str = NULL;
|
||||
NMSettingBondPort *s_port;
|
||||
int ifindex_port = nm_device_get_ifindex(port);
|
||||
NMConnection *applied_connection = nm_device_get_applied_connection(self);
|
||||
const NMPlatformLink *pllink;
|
||||
|
||||
g_return_val_if_fail(ifindex_port > 0, FALSE);
|
||||
|
||||
s_port = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_BOND_PORT);
|
||||
pllink = nm_platform_link_get(nm_device_get_platform(port), ifindex_port);
|
||||
|
||||
queue_id_str =
|
||||
nm_platform_sysctl_slave_get_option(nm_device_get_platform(self), ifindex_port, "queue_id");
|
||||
if (queue_id_str) {
|
||||
queue_id =
|
||||
_nm_utils_ascii_str_to_int64(queue_id_str, 10, 0, 65535, NM_BOND_PORT_QUEUE_ID_DEF);
|
||||
g_object_set(s_port, NM_SETTING_BOND_PORT_QUEUE_ID, queue_id, NULL);
|
||||
} else
|
||||
_LOGW(LOGD_BOND, "failed to read bond port setting '%s'", NM_SETTING_BOND_PORT_QUEUE_ID);
|
||||
if (pllink && pllink->port_kind == NM_PORT_KIND_BOND)
|
||||
g_object_set(s_port, NM_SETTING_BOND_PORT_QUEUE_ID, pllink->port_data.bond.queue_id, NULL);
|
||||
|
||||
g_object_set(nm_connection_get_setting_connection(connection),
|
||||
NM_SETTING_CONNECTION_MASTER,
|
||||
|
|
@ -501,23 +495,11 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
|
|||
static void
|
||||
commit_port_options(NMDevice *bond_device, NMDevice *port, NMSettingBondPort *s_port)
|
||||
{
|
||||
char queue_id_str[IFNAMSIZ + NM_STRLEN(":") + 5 + 100];
|
||||
|
||||
/*
|
||||
* The queue-id of bond port is read only, we should modify bond interface using:
|
||||
* echo "eth1:2" > /sys/class/net/bond0/bonding/queue_id
|
||||
* Kernel allows parital editing, so no need to care about other bond ports.
|
||||
*/
|
||||
g_snprintf(queue_id_str,
|
||||
sizeof(queue_id_str),
|
||||
"%s:%" G_GUINT32_FORMAT,
|
||||
nm_device_get_iface(port),
|
||||
s_port ? nm_setting_bond_port_get_queue_id(s_port) : NM_BOND_PORT_QUEUE_ID_DEF);
|
||||
|
||||
nm_platform_sysctl_master_set_option(nm_device_get_platform(bond_device),
|
||||
nm_device_get_ifindex(bond_device),
|
||||
"queue_id",
|
||||
queue_id_str);
|
||||
nm_platform_link_change(
|
||||
nm_device_get_platform(port),
|
||||
nm_device_get_ifindex(port),
|
||||
&((NMPlatformLinkBondPort){.queue_id = s_port ? nm_setting_bond_port_get_queue_id(s_port)
|
||||
: NM_BOND_PORT_QUEUE_ID_DEF}));
|
||||
}
|
||||
|
||||
static NMTernary
|
||||
|
|
|
|||
|
|
@ -667,6 +667,29 @@ link_supports_sriov(NMPlatform *platform, int ifindex)
|
|||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
link_change(NMPlatform *platform,
|
||||
int ifindex,
|
||||
NMPortKind port_kind,
|
||||
const NMPlatformLinkPortData *port_data)
|
||||
{
|
||||
NMFakePlatformLink *device = link_get(platform, ifindex);
|
||||
nm_auto_nmpobj NMPObject *obj_tmp = NULL;
|
||||
|
||||
switch (port_kind) {
|
||||
case NM_PORT_KIND_BOND:
|
||||
obj_tmp = nmp_object_clone(device->obj, FALSE);
|
||||
obj_tmp->link.port_kind = NM_PORT_KIND_BOND;
|
||||
obj_tmp->link.port_data.bond.queue_id = port_data->bond.queue_id;
|
||||
link_set_obj(platform, device, obj_tmp);
|
||||
return TRUE;
|
||||
case NM_PORT_KIND_NONE:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return nm_assert_unreachable_val(TRUE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
link_enslave(NMPlatform *platform, int master, int slave)
|
||||
{
|
||||
|
|
@ -1322,6 +1345,7 @@ nm_fake_platform_class_init(NMFakePlatformClass *klass)
|
|||
platform_class->link_set_address = link_set_address;
|
||||
platform_class->link_set_mtu = link_set_mtu;
|
||||
|
||||
platform_class->link_change = link_change;
|
||||
platform_class->link_change_flags = link_change_flags;
|
||||
|
||||
platform_class->link_get_driver_info = link_get_driver_info;
|
||||
|
|
|
|||
|
|
@ -257,6 +257,21 @@ test_slave(int master, int type, SignalData *master_changed)
|
|||
else
|
||||
g_assert(!nm_platform_link_is_up(NM_PLATFORM_GET, ifindex));
|
||||
|
||||
if (NM_IN_SET(link_type, NM_LINK_TYPE_BOND)) {
|
||||
const NMPlatformLink *link;
|
||||
NMPlatformLinkBondPort bond_port;
|
||||
|
||||
bond_port = (NMPlatformLinkBondPort){
|
||||
.queue_id = 5,
|
||||
};
|
||||
g_assert(nm_platform_link_change(NM_PLATFORM_GET, ifindex, &bond_port));
|
||||
accept_signals(link_changed, 1, 3);
|
||||
|
||||
link = nmtstp_link_get(NM_PLATFORM_GET, ifindex, SLAVE_NAME);
|
||||
g_assert(link);
|
||||
g_assert_cmpint(link->port_data.bond.queue_id, ==, 5);
|
||||
}
|
||||
|
||||
test_link_changed_signal_arg1 = FALSE;
|
||||
test_link_changed_signal_arg2 = FALSE;
|
||||
g_signal_connect(NM_PLATFORM_GET,
|
||||
|
|
|
|||
|
|
@ -93,6 +93,14 @@ G_STATIC_ASSERT(sizeof(int) == sizeof(gint32));
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef enum _nm_packed {
|
||||
/* No type, empty value */
|
||||
NM_PORT_KIND_NONE,
|
||||
NM_PORT_KIND_BOND,
|
||||
} NMPortKind;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
|
||||
/* No type, used as error value */
|
||||
|
|
|
|||
|
|
@ -3241,9 +3241,11 @@ _new_from_nl_link(NMPlatform *platform,
|
|||
|
||||
if (tb[IFLA_LINKINFO]) {
|
||||
static const struct nla_policy policy_link_info[] = {
|
||||
[IFLA_INFO_KIND] = {.type = NLA_STRING},
|
||||
[IFLA_INFO_DATA] = {.type = NLA_NESTED},
|
||||
[IFLA_INFO_XSTATS] = {.type = NLA_NESTED},
|
||||
[IFLA_INFO_KIND] = {.type = NLA_STRING},
|
||||
[IFLA_INFO_DATA] = {.type = NLA_NESTED},
|
||||
[IFLA_INFO_XSTATS] = {.type = NLA_NESTED},
|
||||
[IFLA_INFO_SLAVE_KIND] = {.type = NLA_STRING},
|
||||
[IFLA_INFO_SLAVE_DATA] = {.type = NLA_NESTED},
|
||||
};
|
||||
struct nlattr *li[G_N_ELEMENTS(policy_link_info)];
|
||||
|
||||
|
|
@ -3254,6 +3256,33 @@ _new_from_nl_link(NMPlatform *platform,
|
|||
nl_info_kind = nla_get_string(li[IFLA_INFO_KIND]);
|
||||
|
||||
nl_info_data = li[IFLA_INFO_DATA];
|
||||
|
||||
if (li[IFLA_INFO_SLAVE_KIND]) {
|
||||
const char *s = nla_get_string(li[IFLA_INFO_SLAVE_KIND]);
|
||||
|
||||
if (nm_streq(s, "bond"))
|
||||
obj->link.port_kind = NM_PORT_KIND_BOND;
|
||||
}
|
||||
|
||||
if (li[IFLA_INFO_SLAVE_DATA]) {
|
||||
static const struct nla_policy policy_bond_port[] = {
|
||||
[IFLA_BOND_SLAVE_QUEUE_ID] = {.type = NLA_U16},
|
||||
};
|
||||
struct nlattr *bp[G_N_ELEMENTS(policy_bond_port)];
|
||||
|
||||
switch (obj->link.port_kind) {
|
||||
case NM_PORT_KIND_BOND:
|
||||
if (nla_parse_nested_arr(bp, li[IFLA_INFO_SLAVE_DATA], policy_bond_port) < 0)
|
||||
return NULL;
|
||||
|
||||
if (bp[IFLA_BOND_SLAVE_QUEUE_ID])
|
||||
obj->link.port_data.bond.queue_id = nla_get_u16(bp[IFLA_BOND_SLAVE_QUEUE_ID]);
|
||||
|
||||
break;
|
||||
case NM_PORT_KIND_NONE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (tb[IFLA_STATS64]) {
|
||||
|
|
@ -8061,6 +8090,48 @@ link_delete(NMPlatform *platform, int ifindex)
|
|||
return do_delete_object(platform, &obj_id, nlmsg);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
link_change(NMPlatform *platform,
|
||||
int ifindex,
|
||||
NMPortKind port_kind,
|
||||
const NMPlatformLinkPortData *port_data)
|
||||
{
|
||||
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
|
||||
struct nlattr *nl_info;
|
||||
struct nlattr *nl_port_data;
|
||||
|
||||
nlmsg = _nl_msg_new_link(RTM_NEWLINK, 0, ifindex, NULL);
|
||||
if (!nlmsg)
|
||||
return FALSE;
|
||||
|
||||
switch (port_kind) {
|
||||
case NM_PORT_KIND_BOND:
|
||||
|
||||
nm_assert(port_data);
|
||||
|
||||
if (!(nl_info = nla_nest_start(nlmsg, IFLA_LINKINFO)))
|
||||
goto nla_put_failure;
|
||||
|
||||
nm_assert(nm_streq0("bond", nm_link_type_to_rtnl_type_string(NM_LINK_TYPE_BOND)));
|
||||
NLA_PUT_STRING(nlmsg, IFLA_INFO_SLAVE_KIND, "bond");
|
||||
|
||||
if (!(nl_port_data = nla_nest_start(nlmsg, IFLA_INFO_SLAVE_DATA)))
|
||||
goto nla_put_failure;
|
||||
|
||||
NLA_PUT_U16(nlmsg, IFLA_BOND_SLAVE_QUEUE_ID, port_data->bond.queue_id);
|
||||
|
||||
nla_nest_end(nlmsg, nl_port_data);
|
||||
nla_nest_end(nlmsg, nl_info);
|
||||
break;
|
||||
case NM_PORT_KIND_NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
return do_change_link(platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) == 0;
|
||||
nla_put_failure:
|
||||
g_return_val_if_reached(FALSE);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
link_refresh(NMPlatform *platform, int ifindex)
|
||||
{
|
||||
|
|
@ -10837,6 +10908,8 @@ nm_linux_platform_class_init(NMLinuxPlatformClass *klass)
|
|||
platform_class->link_change_extra = link_change_extra;
|
||||
platform_class->link_delete = link_delete;
|
||||
|
||||
platform_class->link_change = link_change;
|
||||
|
||||
platform_class->link_refresh = link_refresh;
|
||||
|
||||
platform_class->link_set_netns = link_set_netns;
|
||||
|
|
|
|||
|
|
@ -61,6 +61,31 @@ G_STATIC_ASSERT(sizeof(((NMPlatformLink *) NULL)->l_address.data) == _NM_UTILS_H
|
|||
G_STATIC_ASSERT(sizeof(((NMPlatformLink *) NULL)->l_perm_address.data) == _NM_UTILS_HWADDR_LEN_MAX);
|
||||
G_STATIC_ASSERT(sizeof(((NMPlatformLink *) NULL)->l_broadcast.data) == _NM_UTILS_HWADDR_LEN_MAX);
|
||||
|
||||
static const char *
|
||||
_nmp_link_port_data_to_string(NMPortKind port_kind,
|
||||
const NMPlatformLinkPortData *port_data,
|
||||
char *sbuf,
|
||||
gsize sbuf_len)
|
||||
{
|
||||
const char *sbuf0 = sbuf;
|
||||
|
||||
nm_assert(port_data);
|
||||
|
||||
switch (port_kind) {
|
||||
case NM_PORT_KIND_NONE:
|
||||
nm_strbuf_append_c(&sbuf, &sbuf_len, '\0');
|
||||
goto out;
|
||||
case NM_PORT_KIND_BOND:
|
||||
nm_strbuf_append(&sbuf, &sbuf_len, "port bond queue-id %u", port_data->bond.queue_id);
|
||||
goto out;
|
||||
}
|
||||
|
||||
nm_strbuf_append(&sbuf, &sbuf_len, "invalid-port-type %d", (int) port_kind);
|
||||
|
||||
out:
|
||||
return sbuf0;
|
||||
}
|
||||
|
||||
static const char *
|
||||
_nmp_link_address_to_string(const NMPLinkAddress *addr,
|
||||
char buf[static(_NM_UTILS_HWADDR_LEN_MAX * 3)])
|
||||
|
|
@ -2092,6 +2117,31 @@ nm_platform_link_set_name(NMPlatform *self, int ifindex, const char *name)
|
|||
return klass->link_set_name(self, ifindex, name);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_platform_link_change(NMPlatform *self, int ifindex, NMPlatformLinkBondPort *bond_port)
|
||||
{
|
||||
_CHECK_SELF(self, klass, FALSE);
|
||||
|
||||
g_return_val_if_fail(ifindex >= 0, FALSE);
|
||||
|
||||
if (_LOGD_ENABLED()) {
|
||||
nm_auto_free_gstring GString *str = g_string_new("");
|
||||
|
||||
if (bond_port)
|
||||
g_string_append_printf(str, "bond-port queue-id %d", bond_port->queue_id);
|
||||
|
||||
if (str->len > 0 && str->str[str->len - 1] == ' ')
|
||||
g_string_truncate(str, str->len - 1);
|
||||
|
||||
_LOG3D("link: change: %s", str->str);
|
||||
}
|
||||
|
||||
return klass->link_change(self,
|
||||
ifindex,
|
||||
bond_port ? NM_PORT_KIND_BOND : NM_PORT_KIND_NONE,
|
||||
(const NMPlatformLinkPortData *) bond_port);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_platform_link_get_physical_port_id:
|
||||
* @self: platform instance
|
||||
|
|
@ -5893,6 +5943,7 @@ nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gsize len)
|
|||
char *s;
|
||||
gsize l;
|
||||
char str_addrmode[30];
|
||||
char str_port_data[200];
|
||||
char str_address[_NM_UTILS_HWADDR_LEN_MAX * 3];
|
||||
char str_perm_address[_NM_UTILS_HWADDR_LEN_MAX * 3];
|
||||
char str_broadcast[_NM_UTILS_HWADDR_LEN_MAX * 3];
|
||||
|
|
@ -5936,6 +5987,11 @@ nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gsize len)
|
|||
_nmp_link_address_to_string(&link->l_perm_address, str_perm_address);
|
||||
_nmp_link_address_to_string(&link->l_broadcast, str_broadcast);
|
||||
|
||||
_nmp_link_port_data_to_string(link->port_kind,
|
||||
&link->port_data,
|
||||
str_port_data,
|
||||
sizeof(str_port_data));
|
||||
|
||||
str_link_type = nm_link_type_to_string(link->type);
|
||||
|
||||
g_snprintf(
|
||||
|
|
@ -5957,6 +6013,7 @@ nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gsize len)
|
|||
"%s%s" /* l_broadcast */
|
||||
"%s%s" /* inet6_token */
|
||||
"%s%s" /* driver */
|
||||
"%s%s" /* port_data */
|
||||
" rx:%" G_GUINT64_FORMAT ",%" G_GUINT64_FORMAT " tx:%" G_GUINT64_FORMAT
|
||||
",%" G_GUINT64_FORMAT,
|
||||
link->ifindex,
|
||||
|
|
@ -5989,6 +6046,7 @@ nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gsize len)
|
|||
: "",
|
||||
link->driver ? " driver " : "",
|
||||
link->driver ?: "",
|
||||
NM_PRINT_FMT_QUOTED2(str_port_data[0] != '\0', " ", str_port_data, ""),
|
||||
link->rx_packets,
|
||||
link->rx_bytes,
|
||||
link->tx_packets,
|
||||
|
|
@ -7927,6 +7985,7 @@ nm_platform_link_hash_update(const NMPlatformLink *obj, NMHashState *h)
|
|||
obj->arptype,
|
||||
obj->inet6_addr_gen_mode_inv,
|
||||
obj->inet6_token,
|
||||
obj->port_kind,
|
||||
obj->rx_packets,
|
||||
obj->rx_bytes,
|
||||
obj->tx_packets,
|
||||
|
|
@ -7945,6 +8004,20 @@ nm_platform_link_hash_update(const NMPlatformLink *obj, NMHashState *h)
|
|||
nm_hash_update_mem(h,
|
||||
obj->l_broadcast.data,
|
||||
NM_MIN(obj->l_broadcast.len, sizeof(obj->l_broadcast.data)));
|
||||
|
||||
switch (obj->port_kind) {
|
||||
case NM_PORT_KIND_NONE:
|
||||
break;
|
||||
case NM_PORT_KIND_BOND:
|
||||
nm_platform_link_bond_port_hash_update(&obj->port_data.bond, h);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nm_platform_link_bond_port_hash_update(const NMPlatformLinkBondPort *obj, NMHashState *h)
|
||||
{
|
||||
nm_hash_update_vals(h, obj->queue_id);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -7974,6 +8047,14 @@ nm_platform_link_cmp(const NMPlatformLink *a, const NMPlatformLink *b)
|
|||
if (a->l_broadcast.len)
|
||||
NM_CMP_FIELD_MEMCMP_LEN(a, b, l_broadcast.data, a->l_broadcast.len);
|
||||
NM_CMP_FIELD_MEMCMP(a, b, inet6_token);
|
||||
NM_CMP_FIELD(a, b, port_kind);
|
||||
switch (a->port_kind) {
|
||||
case NM_PORT_KIND_NONE:
|
||||
break;
|
||||
case NM_PORT_KIND_BOND:
|
||||
NM_CMP_RETURN(nm_platform_link_bond_port_cmp(&a->port_data.bond, &b->port_data.bond));
|
||||
break;
|
||||
}
|
||||
NM_CMP_FIELD(a, b, rx_packets);
|
||||
NM_CMP_FIELD(a, b, rx_bytes);
|
||||
NM_CMP_FIELD(a, b, tx_packets);
|
||||
|
|
@ -8053,6 +8134,15 @@ nm_platform_lnk_bond_hash_update(const NMPlatformLnkBond *obj, NMHashState *h)
|
|||
nm_hash_update(h, obj->arp_ip_target, obj->arp_ip_targets_num * sizeof(obj->arp_ip_target[0]));
|
||||
}
|
||||
|
||||
int
|
||||
nm_platform_link_bond_port_cmp(const NMPlatformLinkBondPort *a, const NMPlatformLinkBondPort *b)
|
||||
{
|
||||
NM_CMP_SELF(a, b);
|
||||
NM_CMP_FIELD(a, b, queue_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
nm_platform_lnk_bond_cmp(const NMPlatformLnkBond *a, const NMPlatformLnkBond *b)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -216,6 +216,14 @@ struct _NMPlatformObjWithIfindex {
|
|||
__NMPlatformObjWithIfindex_COMMON;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
guint16 queue_id;
|
||||
} NMPlatformLinkBondPort;
|
||||
|
||||
typedef union {
|
||||
NMPlatformLinkBondPort bond;
|
||||
} NMPlatformLinkPortData;
|
||||
|
||||
struct _NMPlatformLink {
|
||||
__NMPlatformObjWithIfindex_COMMON;
|
||||
char name[NMP_IFNAMSIZ];
|
||||
|
|
@ -266,6 +274,12 @@ struct _NMPlatformLink {
|
|||
guint64 tx_packets;
|
||||
guint64 tx_bytes;
|
||||
|
||||
/* IFLA_INFO_SLAVE_KIND */
|
||||
NMPortKind port_kind;
|
||||
|
||||
/* an interface can only hold IFLA_INFO_SLAVE_DATA for one link type */
|
||||
NMPlatformLinkPortData port_data;
|
||||
|
||||
/* @connected is mostly identical to (@n_ifi_flags & IFF_UP). Except for bridge/bond masters,
|
||||
* where we coerce the link as disconnect if it has no slaves. */
|
||||
bool connected : 1;
|
||||
|
|
@ -1226,6 +1240,10 @@ typedef struct {
|
|||
NMLinkType type,
|
||||
int ifindex,
|
||||
gconstpointer extra_data);
|
||||
gboolean (*link_change)(NMPlatform *self,
|
||||
int ifindex,
|
||||
NMPortKind port_kind,
|
||||
const NMPlatformLinkPortData *port_data);
|
||||
gboolean (*link_delete)(NMPlatform *self, int ifindex);
|
||||
gboolean (*link_refresh)(NMPlatform *self, int ifindex);
|
||||
gboolean (*link_set_netns)(NMPlatform *self, int ifindex, int netns_fd);
|
||||
|
|
@ -2073,6 +2091,8 @@ nm_platform_link_change_flags(NMPlatform *self, int ifindex, unsigned value, gbo
|
|||
return nm_platform_link_change_flags_full(self, ifindex, value, set ? value : 0u);
|
||||
}
|
||||
|
||||
gboolean nm_platform_link_change(NMPlatform *self, int ifindex, NMPlatformLinkBondPort *bond_port);
|
||||
|
||||
gboolean nm_platform_link_get_udev_property(NMPlatform *self,
|
||||
int ifindex,
|
||||
const char *name,
|
||||
|
|
@ -2563,6 +2583,11 @@ int nm_platform_tfilter_cmp(const NMPlatformTfilter *a, const NMPlatformTfilter
|
|||
int nm_platform_mptcp_addr_cmp(const NMPlatformMptcpAddr *a, const NMPlatformMptcpAddr *b);
|
||||
|
||||
void nm_platform_link_hash_update(const NMPlatformLink *obj, NMHashState *h);
|
||||
|
||||
void nm_platform_link_bond_port_hash_update(const NMPlatformLinkBondPort *obj, NMHashState *h);
|
||||
int nm_platform_link_bond_port_cmp(const NMPlatformLinkBondPort *a,
|
||||
const NMPlatformLinkBondPort *b);
|
||||
|
||||
void nm_platform_ip4_address_hash_update(const NMPlatformIP4Address *obj, NMHashState *h);
|
||||
void nm_platform_ip6_address_hash_update(const NMPlatformIP6Address *obj, NMHashState *h);
|
||||
void nm_platform_ip4_route_hash_update(const NMPlatformIP4Route *obj,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue