return 1;
}
+static int address_set_netlink_message(const Address *address, sd_netlink_message *req, Link *link) {
+ uint32_t flags;
+ int r;
+
+ assert(address);
+ assert(req);
+ assert(link);
+
+ r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not set prefixlen: %m");
+
+ /* On remove, only IFA_F_MANAGETEMPADDR flag for IPv6 addresses are used. But anyway, set all
+ * flags here unconditionally. Without setting the flag, the template addresses generated by
+ * kernel will not be removed automatically when the main address is removed. */
+ flags = address->flags | IFA_F_PERMANENT;
+ r = sd_rtnl_message_addr_set_flags(req, flags & 0xff);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not set flags: %m");
+
+ if (flags & ~0xff) {
+ r = sd_netlink_message_append_u32(req, IFA_FLAGS, flags);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not set extended flags: %m");
+ }
+
+ r = netlink_message_append_in_addr_union(req, IFA_LOCAL, address->family, &address->in_addr);
+ if (r < 0)
+ return log_link_error_errno(link, r, "Could not append IFA_LOCAL attribute: %m");
+
+ return 0;
+}
+
int address_remove(
const Address *address,
Link *link,
if (r < 0)
return log_link_error_errno(link, r, "Could not allocate RTM_DELADDR message: %m");
- r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen);
+ r = address_set_netlink_message(address, req, link);
if (r < 0)
- return log_link_error_errno(link, r, "Could not set prefixlen: %m");
-
- r = netlink_message_append_in_addr_union(req, IFA_LOCAL, address->family, &address->in_addr);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFA_LOCAL attribute: %m");
+ return r;
r = netlink_call_async(link->manager->rtnl, NULL, req,
callback ?: address_remove_handler,
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
Address *acquired_address, *a;
- uint32_t flags;
bool update;
int r;
if (r < 0)
return log_link_error_errno(link, r, "Could not allocate RTM_NEWADDR message: %m");
- r = sd_rtnl_message_addr_set_prefixlen(req, address->prefixlen);
+ r = address_set_netlink_message(address, req, link);
if (r < 0)
- return log_link_error_errno(link, r, "Could not set prefixlen: %m");
-
- flags = address->flags | IFA_F_PERMANENT;
- r = sd_rtnl_message_addr_set_flags(req, flags & 0xff);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not set flags: %m");
-
- if (flags & ~0xff) {
- r = sd_netlink_message_append_u32(req, IFA_FLAGS, flags);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not set extended flags: %m");
- }
+ return r;
r = sd_rtnl_message_addr_set_scope(req, address->scope);
if (r < 0)
return log_link_error_errno(link, r, "Could not set scope: %m");
- r = netlink_message_append_in_addr_union(req, IFA_LOCAL, address->family, &address->in_addr);
- if (r < 0)
- return log_link_error_errno(link, r, "Could not append IFA_LOCAL attribute: %m");
-
if (in_addr_is_null(address->family, &address->in_addr_peer) == 0) {
r = netlink_message_append_in_addr_union(req, IFA_ADDRESS, address->family, &address->in_addr_peer);
if (r < 0)