- addattr32(n, 1024, IFLA_VXLAN_ID, vni);
- if (gaddr)
- addattr_l(n, 1024, IFLA_VXLAN_GROUP, &gaddr, 4);
- else if (daddr)
- addattr_l(n, 1024, IFLA_VXLAN_GROUP, &daddr, 4);
- if (memcmp(&gaddr6, &in6addr_any, sizeof(gaddr6)) != 0)
- addattr_l(n, 1024, IFLA_VXLAN_GROUP6, &gaddr6, sizeof(struct in6_addr));
- else if (memcmp(&daddr6, &in6addr_any, sizeof(daddr6)) != 0)
- addattr_l(n, 1024, IFLA_VXLAN_GROUP6, &daddr6, sizeof(struct in6_addr));
-
- if (saddr)
- addattr_l(n, 1024, IFLA_VXLAN_LOCAL, &saddr, 4);
- else if (memcmp(&saddr6, &in6addr_any, sizeof(saddr6)) != 0)
- addattr_l(n, 1024, IFLA_VXLAN_LOCAL6, &saddr6, sizeof(struct in6_addr));
-
- if (link)
- addattr32(n, 1024, IFLA_VXLAN_LINK, link);
- addattr8(n, 1024, IFLA_VXLAN_TTL, ttl);
- addattr8(n, 1024, IFLA_VXLAN_TOS, tos);
- addattr8(n, 1024, IFLA_VXLAN_LEARNING, learning);
- addattr8(n, 1024, IFLA_VXLAN_PROXY, proxy);
- addattr8(n, 1024, IFLA_VXLAN_RSC, rsc);
- addattr8(n, 1024, IFLA_VXLAN_L2MISS, l2miss);
- addattr8(n, 1024, IFLA_VXLAN_L3MISS, l3miss);
- addattr8(n, 1024, IFLA_VXLAN_UDP_CSUM, udpcsum);
- addattr8(n, 1024, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, udp6zerocsumtx);
- addattr8(n, 1024, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, udp6zerocsumrx);
-
- if (noage)
- addattr32(n, 1024, IFLA_VXLAN_AGEING, 0);
- else if (age)
- addattr32(n, 1024, IFLA_VXLAN_AGEING, age);
- if (maxaddr)
- addattr32(n, 1024, IFLA_VXLAN_LIMIT, maxaddr);
- if (range.low || range.high)
- addattr_l(n, 1024, IFLA_VXLAN_PORT_RANGE,
- &range, sizeof(range));
- if (dstport)
- addattr16(n, 1024, IFLA_VXLAN_PORT, htons(dstport));
+ if (VXLAN_ATTRSET(attrs, IFLA_VXLAN_ID))
+ addattr32(n, 1024, IFLA_VXLAN_ID, vni);
+
+ if (is_addrtype_inet(&saddr)) {
+ int type = (saddr.family == AF_INET) ? IFLA_VXLAN_LOCAL
+ : IFLA_VXLAN_LOCAL6;
+ addattr_l(n, 1024, type, saddr.data, saddr.bytelen);
+ selected_family = true;
+ }
+
+ if (is_addrtype_inet(&daddr)) {
+ int type = (daddr.family == AF_INET) ? IFLA_VXLAN_GROUP
+ : IFLA_VXLAN_GROUP6;
+ addattr_l(n, 1024, type, daddr.data, daddr.bytelen);
+ selected_family = true;
+ }
+
+ if (!selected_family) {
+ if (preferred_family == AF_INET) {
+ get_addr(&daddr, "default", AF_INET);
+ addattr_l(n, 1024, IFLA_VXLAN_GROUP,
+ daddr.data, daddr.bytelen);
+ } else if (preferred_family == AF_INET6) {
+ get_addr(&daddr, "default", AF_INET6);
+ addattr_l(n, 1024, IFLA_VXLAN_GROUP6,
+ daddr.data, daddr.bytelen);
+ }
+ }