diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index d824c5d6b..4e41bc9b2 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -1954,7 +1954,8 @@ nmp_object_new_from_nl (NMPlatform *platform, const NMPCache *cache, struct nl_m static gboolean _nl_msg_new_link_set_afspec (struct nl_msg *msg, - int addr_gen_mode) + int addr_gen_mode, + NMUtilsIPv6IfaceId *iid) { struct nlattr *af_spec; struct nlattr *af_attr; @@ -1964,11 +1965,19 @@ _nl_msg_new_link_set_afspec (struct nl_msg *msg, if (!(af_spec = nla_nest_start (msg, IFLA_AF_SPEC))) goto nla_put_failure; - if (addr_gen_mode >= 0) { + if (addr_gen_mode >= 0 || iid) { if (!(af_attr = nla_nest_start (msg, AF_INET6))) goto nla_put_failure; - NLA_PUT_U8 (msg, IFLA_INET6_ADDR_GEN_MODE, addr_gen_mode); + if (addr_gen_mode >= 0) + NLA_PUT_U8 (msg, IFLA_INET6_ADDR_GEN_MODE, addr_gen_mode); + + if (iid) { + struct in6_addr i6_token = { .s6_addr = { 0, } }; + + nm_utils_ipv6_addr_set_interface_identifier (&i6_token, *iid); + NLA_PUT (msg, IFLA_INET6_TOKEN, sizeof (struct in6_addr), &i6_token); + } nla_nest_end (msg, af_attr); } @@ -4329,8 +4338,22 @@ link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enable 0, 0); if ( !nlmsg - || !_nl_msg_new_link_set_afspec (nlmsg, - mode)) + || !_nl_msg_new_link_set_afspec (nlmsg, mode, NULL)) + g_return_val_if_reached (FALSE); + + return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS; +} + +static gboolean +link_set_token (NMPlatform *platform, int ifindex, NMUtilsIPv6IfaceId iid) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + + _LOGD ("link: change %d: token: set IPv6 address generation token to %s", + ifindex, nm_utils_inet6_interface_identifier_to_token (iid, NULL)); + + nlmsg = _nl_msg_new_link (RTM_NEWLINK, 0, ifindex, NULL, 0, 0); + if (!nlmsg || !_nl_msg_new_link_set_afspec (nlmsg, -1, &iid)) g_return_val_if_reached (FALSE); return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS; @@ -6442,6 +6465,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->link_get_udev_device = link_get_udev_device; platform_class->link_set_user_ipv6ll_enabled = link_set_user_ipv6ll_enabled; + platform_class->link_set_token = link_set_token; platform_class->link_set_address = link_set_address; platform_class->link_get_permanent_address = link_get_permanent_address; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 68b687a8f..a6afcf33a 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -899,6 +899,29 @@ nm_platform_link_uses_arp (NMPlatform *self, int ifindex) return !NM_FLAGS_HAS (_link_get_flags (self, ifindex), IFF_NOARP); } +/** + * nm_platform_link_set_ipv6_token: + * @self: platform instance + * @ifindex: Interface index + * @iid: Tokenized interface identifier + * + * Sets then IPv6 tokenized interface identifier. + * + * Returns: %TRUE a tokenized identifier was available + */ +gboolean +nm_platform_link_set_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid) +{ + _CHECK_SELF (self, klass, FALSE); + + g_return_val_if_fail (ifindex >= 0, FALSE); + g_return_val_if_fail (iid.id, FALSE); + + if (klass->link_set_token) + return klass->link_set_token (self, ifindex, iid); + return FALSE; +} + const char * nm_platform_link_get_udi (NMPlatform *self, int ifindex) { diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index f0f2eecfa..72f4f6720 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -520,6 +520,7 @@ typedef struct { GObject *(*link_get_udev_device) (NMPlatform *self, int ifindex); gboolean (*link_set_user_ipv6ll_enabled) (NMPlatform *, int ifindex, gboolean enabled); + gboolean (*link_set_token) (NMPlatform *, int ifindex, NMUtilsIPv6IfaceId iid); gboolean (*link_get_permanent_address) (NMPlatform *, int ifindex, @@ -753,6 +754,7 @@ const char *nm_platform_link_get_udi (NMPlatform *self, int ifindex); GObject *nm_platform_link_get_udev_device (NMPlatform *self, int ifindex); gboolean nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolean enabled); +gboolean nm_platform_link_set_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid); gboolean nm_platform_link_get_permanent_address (NMPlatform *self, int ifindex, guint8 *buf, size_t *length); gboolean nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length);