#define ADDRESSES_PER_LINK_MAX 2048U
#define STATIC_ADDRESSES_PER_NETWORK_MAX 1024U
+static int address_flags_to_string_alloc(uint32_t flags, int family, char **ret) {
+ _cleanup_free_ char *str = NULL;
+ static const struct {
+ uint32_t flag;
+ const char *name;
+ } map[] = {
+ { IFA_F_SECONDARY, "secondary" }, /* This is also called "temporary" for ipv6. */
+ { IFA_F_NODAD, "nodad" },
+ { IFA_F_OPTIMISTIC, "optimistic" },
+ { IFA_F_DADFAILED, "dadfailed" },
+ { IFA_F_HOMEADDRESS, "home-address" },
+ { IFA_F_DEPRECATED, "deprecated" },
+ { IFA_F_TENTATIVE, "tentative" },
+ { IFA_F_PERMANENT, "permanent" },
+ { IFA_F_MANAGETEMPADDR, "manage-temporary-address" },
+ { IFA_F_NOPREFIXROUTE, "no-prefixroute" },
+ { IFA_F_MCAUTOJOIN, "auto-join" },
+ { IFA_F_STABLE_PRIVACY, "stable-privacy" },
+ };
+
+ assert(IN_SET(family, AF_INET, AF_INET6));
+ assert(ret);
+
+ for (size_t i = 0; i < ELEMENTSOF(map); i++) {
+ if (!FLAGS_SET(flags, map[i].flag))
+ continue;
+ if (map[i].flag == IFA_F_SECONDARY && family == AF_INET6) {
+ if (!strextend_with_separator(&str, ",", "temporary"))
+ return -ENOMEM;
+ } else {
+ if (!strextend_with_separator(&str, ",", map[i].name))
+ return -ENOMEM;
+ }
+ }
+
+ *ret = TAKE_PTR(str);
+ return 0;
+}
+
int generate_ipv6_eui_64_address(const Link *link, struct in6_addr *ret) {
assert(link);
assert(ret);
}
static void log_address_debug(const Address *address, const char *str, const Link *link) {
- _cleanup_free_ char *addr = NULL, *peer = NULL;
+ _cleanup_free_ char *addr = NULL, *peer = NULL, *flags_str = NULL;
char valid_buf[FORMAT_TIMESPAN_MAX], preferred_buf[FORMAT_TIMESPAN_MAX];
const char *valid_str = NULL, *preferred_str = NULL;
bool has_peer;
address->cinfo.ifa_prefered * USEC_PER_SEC,
USEC_PER_SEC);
- log_link_debug(link, "%s address: %s%s%s/%u (valid %s%s, preferred %s%s)",
+ (void) address_flags_to_string_alloc(address->flags, address->family, &flags_str);
+
+ log_link_debug(link, "%s address: %s%s%s/%u (valid %s%s, preferred %s%s), flags: %s",
str, strnull(addr), has_peer ? " peer " : "",
has_peer ? strnull(peer) : "", address->prefixlen,
valid_str ? "for " : "forever", strempty(valid_str),
- preferred_str ? "for " : "forever", strempty(preferred_str));
+ preferred_str ? "for " : "forever", strempty(preferred_str),
+ strna(flags_str));
}
static int address_set_netlink_message(const Address *address, sd_netlink_message *req, Link *link) {