/* for cslip etc */
__u32 rx_compressed;
__u32 tx_compressed;
+
+ __u32 rx_nohandler; /* dropped, no handler found */
};
/* The main device statistics structure */
/* for cslip etc */
__u64 rx_compressed;
__u64 tx_compressed;
+
+ __u64 rx_nohandler; /* dropped, no handler found */
};
/* The struct should be in sync with struct ifmap */
IFLA_PHYS_SWITCH_ID,
IFLA_LINK_NETNSID,
IFLA_PHYS_PORT_NAME,
+ IFLA_PROTO_DOWN,
+ IFLA_GSO_MAX_SEGS,
+ IFLA_GSO_MAX_SIZE,
+ IFLA_PAD,
__IFLA_MAX
};
IN6_ADDR_GEN_MODE_EUI64,
IN6_ADDR_GEN_MODE_NONE,
IN6_ADDR_GEN_MODE_STABLE_PRIVACY,
+ IN6_ADDR_GEN_MODE_RANDOM,
};
/* Bridge section */
IFLA_BR_AGEING_TIME,
IFLA_BR_STP_STATE,
IFLA_BR_PRIORITY,
+ IFLA_BR_VLAN_FILTERING,
+ IFLA_BR_VLAN_PROTOCOL,
+ IFLA_BR_GROUP_FWD_MASK,
+ IFLA_BR_ROOT_ID,
+ IFLA_BR_BRIDGE_ID,
+ IFLA_BR_ROOT_PORT,
+ IFLA_BR_ROOT_PATH_COST,
+ IFLA_BR_TOPOLOGY_CHANGE,
+ IFLA_BR_TOPOLOGY_CHANGE_DETECTED,
+ IFLA_BR_HELLO_TIMER,
+ IFLA_BR_TCN_TIMER,
+ IFLA_BR_TOPOLOGY_CHANGE_TIMER,
+ IFLA_BR_GC_TIMER,
+ IFLA_BR_GROUP_ADDR,
+ IFLA_BR_FDB_FLUSH,
+ IFLA_BR_MCAST_ROUTER,
+ IFLA_BR_MCAST_SNOOPING,
+ IFLA_BR_MCAST_QUERY_USE_IFADDR,
+ IFLA_BR_MCAST_QUERIER,
+ IFLA_BR_MCAST_HASH_ELASTICITY,
+ IFLA_BR_MCAST_HASH_MAX,
+ IFLA_BR_MCAST_LAST_MEMBER_CNT,
+ IFLA_BR_MCAST_STARTUP_QUERY_CNT,
+ IFLA_BR_MCAST_LAST_MEMBER_INTVL,
+ IFLA_BR_MCAST_MEMBERSHIP_INTVL,
+ IFLA_BR_MCAST_QUERIER_INTVL,
+ IFLA_BR_MCAST_QUERY_INTVL,
+ IFLA_BR_MCAST_QUERY_RESPONSE_INTVL,
+ IFLA_BR_MCAST_STARTUP_QUERY_INTVL,
+ IFLA_BR_NF_CALL_IPTABLES,
+ IFLA_BR_NF_CALL_IP6TABLES,
+ IFLA_BR_NF_CALL_ARPTABLES,
+ IFLA_BR_VLAN_DEFAULT_PVID,
+ IFLA_BR_PAD,
+ IFLA_BR_VLAN_STATS_ENABLED,
__IFLA_BR_MAX,
};
#define IFLA_BR_MAX (__IFLA_BR_MAX - 1)
+struct ifla_bridge_id {
+ __u8 prio[2];
+ __u8 addr[6]; /* ETH_ALEN */
+};
+
enum {
BRIDGE_MODE_UNSPEC,
BRIDGE_MODE_HAIRPIN,
IFLA_BRPORT_PROXYARP, /* proxy ARP */
IFLA_BRPORT_LEARNING_SYNC, /* mac learning sync from device */
IFLA_BRPORT_PROXYARP_WIFI, /* proxy ARP for Wi-Fi */
+ IFLA_BRPORT_ROOT_ID, /* designated root */
+ IFLA_BRPORT_BRIDGE_ID, /* designated bridge */
+ IFLA_BRPORT_DESIGNATED_PORT,
+ IFLA_BRPORT_DESIGNATED_COST,
+ IFLA_BRPORT_ID,
+ IFLA_BRPORT_NO,
+ IFLA_BRPORT_TOPOLOGY_CHANGE_ACK,
+ IFLA_BRPORT_CONFIG_PENDING,
+ IFLA_BRPORT_MESSAGE_AGE_TIMER,
+ IFLA_BRPORT_FORWARD_DELAY_TIMER,
+ IFLA_BRPORT_HOLD_TIMER,
+ IFLA_BRPORT_FLUSH,
+ IFLA_BRPORT_MULTICAST_ROUTER,
+ IFLA_BRPORT_PAD,
__IFLA_BRPORT_MAX
};
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
#define IFLA_VRF_MAX (__IFLA_VRF_MAX - 1)
+enum {
+ IFLA_VRF_PORT_UNSPEC,
+ IFLA_VRF_PORT_TABLE,
+ __IFLA_VRF_PORT_MAX
+};
+
+#define IFLA_VRF_PORT_MAX (__IFLA_VRF_PORT_MAX - 1)
+
/* MACSEC section */
enum {
IFLA_MACSEC_UNSPEC,
IFLA_VXLAN_REMCSUM_RX,
IFLA_VXLAN_GBP,
IFLA_VXLAN_REMCSUM_NOPARTIAL,
+ IFLA_VXLAN_COLLECT_METADATA,
+ IFLA_VXLAN_LABEL,
+ IFLA_VXLAN_GPE,
__IFLA_VXLAN_MAX
};
#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
__be16 high;
};
+/* GENEVE section */
+enum {
+ IFLA_GENEVE_UNSPEC,
+ IFLA_GENEVE_ID,
+ IFLA_GENEVE_REMOTE,
+ IFLA_GENEVE_TTL,
+ IFLA_GENEVE_TOS,
+ IFLA_GENEVE_PORT, /* destination port */
+ IFLA_GENEVE_COLLECT_METADATA,
+ IFLA_GENEVE_REMOTE6,
+ IFLA_GENEVE_UDP_CSUM,
+ IFLA_GENEVE_UDP_ZERO_CSUM6_TX,
+ IFLA_GENEVE_UDP_ZERO_CSUM6_RX,
+ IFLA_GENEVE_LABEL,
+ __IFLA_GENEVE_MAX
+};
+#define IFLA_GENEVE_MAX (__IFLA_GENEVE_MAX - 1)
+
+/* PPP section */
+enum {
+ IFLA_PPP_UNSPEC,
+ IFLA_PPP_DEV_FD,
+ __IFLA_PPP_MAX
+};
+#define IFLA_PPP_MAX (__IFLA_PPP_MAX - 1)
+
+/* GTP section */
+enum {
+ IFLA_GTP_UNSPEC,
+ IFLA_GTP_FD0,
+ IFLA_GTP_FD1,
+ IFLA_GTP_PDP_HASHSIZE,
+ __IFLA_GTP_MAX,
+};
+#define IFLA_GTP_MAX (__IFLA_GTP_MAX - 1)
+
/* Bonding section */
enum {
IFLA_BOND_AD_LACP_RATE,
IFLA_BOND_AD_SELECT,
IFLA_BOND_AD_INFO,
+ IFLA_BOND_AD_ACTOR_SYS_PRIO,
+ IFLA_BOND_AD_USER_PORT_KEY,
+ IFLA_BOND_AD_ACTOR_SYSTEM,
+ IFLA_BOND_TLB_DYNAMIC_LB,
__IFLA_BOND_MAX,
};
IFLA_BOND_SLAVE_PERM_HWADDR,
IFLA_BOND_SLAVE_QUEUE_ID,
IFLA_BOND_SLAVE_AD_AGGREGATOR_ID,
+ IFLA_BOND_SLAVE_AD_ACTOR_OPER_PORT_STATE,
+ IFLA_BOND_SLAVE_AD_PARTNER_OPER_PORT_STATE,
__IFLA_BOND_SLAVE_MAX,
};
IFLA_VF_RSS_QUERY_EN, /* RSS Redirection Table and Hash Key query
* on/off switch
*/
+ IFLA_VF_STATS, /* network device statistics */
+ IFLA_VF_TRUST, /* Trust VF */
+ IFLA_VF_IB_NODE_GUID, /* VF Infiniband node GUID */
+ IFLA_VF_IB_PORT_GUID, /* VF Infiniband port GUID */
__IFLA_VF_MAX,
};
__u32 setting;
};
+struct ifla_vf_guid {
+ __u32 vf;
+ __u64 guid;
+};
+
enum {
IFLA_VF_LINK_STATE_AUTO, /* link state of the uplink */
IFLA_VF_LINK_STATE_ENABLE, /* link always up */
__u32 setting;
};
+enum {
+ IFLA_VF_STATS_RX_PACKETS,
+ IFLA_VF_STATS_TX_PACKETS,
+ IFLA_VF_STATS_RX_BYTES,
+ IFLA_VF_STATS_TX_BYTES,
+ IFLA_VF_STATS_BROADCAST,
+ IFLA_VF_STATS_MULTICAST,
+ IFLA_VF_STATS_PAD,
+ __IFLA_VF_STATS_MAX,
+};
+
+#define IFLA_VF_STATS_MAX (__IFLA_VF_STATS_MAX - 1)
+
+struct ifla_vf_trust {
+ __u32 vf;
+ __u32 setting;
+};
+
/* VF ports management section
*
* Nested layout of set/get msg is:
IFLA_HSR_MULTICAST_SPEC, /* Last byte of supervision addr */
IFLA_HSR_SUPERVISION_ADDR, /* Supervision frame multicast addr */
IFLA_HSR_SEQ_NR,
+ IFLA_HSR_VERSION, /* HSR version */
__IFLA_HSR_MAX,
};
#define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1)
+/* STATS section */
+
+struct if_stats_msg {
+ __u8 family;
+ __u8 pad1;
+ __u16 pad2;
+ __u32 ifindex;
+ __u32 filter_mask;
+};
+
+/* A stats attribute can be netdev specific or a global stat.
+ * For netdev stats, lets use the prefix IFLA_STATS_LINK_*
+ */
+enum {
+ IFLA_STATS_UNSPEC, /* also used as 64bit pad attribute */
+ IFLA_STATS_LINK_64,
+ IFLA_STATS_LINK_XSTATS,
+ __IFLA_STATS_MAX,
+};
+
+#define IFLA_STATS_MAX (__IFLA_STATS_MAX - 1)
+
+#define IFLA_STATS_FILTER_BIT(ATTR) (1 << (ATTR - 1))
+
+/* These are embedded into IFLA_STATS_LINK_XSTATS:
+ * [IFLA_STATS_LINK_XSTATS]
+ * -> [LINK_XSTATS_TYPE_xxx]
+ * -> [rtnl link type specific attributes]
+ */
+enum {
+ LINK_XSTATS_TYPE_UNSPEC,
+ LINK_XSTATS_TYPE_BRIDGE,
+ __LINK_XSTATS_TYPE_MAX
+};
+#define LINK_XSTATS_TYPE_MAX (__LINK_XSTATS_TYPE_MAX - 1)
+
#endif /* _LINUX_IF_LINK_H */
#include <linux/if_link.h>
/** @cond SKIP */
-#define VXLAN_ATTR_ID (1<<0)
-#define VXLAN_ATTR_GROUP (1<<1)
-#define VXLAN_ATTR_LINK (1<<2)
-#define VXLAN_ATTR_LOCAL (1<<3)
-#define VXLAN_ATTR_TTL (1<<4)
-#define VXLAN_ATTR_TOS (1<<5)
-#define VXLAN_ATTR_LEARNING (1<<6)
-#define VXLAN_ATTR_AGEING (1<<7)
-#define VXLAN_ATTR_LIMIT (1<<8)
-#define VXLAN_ATTR_PORT_RANGE (1<<9)
-#define VXLAN_ATTR_PROXY (1<<10)
-#define VXLAN_ATTR_RSC (1<<11)
-#define VXLAN_ATTR_L2MISS (1<<12)
-#define VXLAN_ATTR_L3MISS (1<<13)
-#define VXLAN_ATTR_GROUP6 (1<<14)
-#define VXLAN_ATTR_LOCAL6 (1<<15)
+#define VXLAN_ATTR_ID (1<<0)
+#define VXLAN_ATTR_GROUP (1<<1)
+#define VXLAN_ATTR_LINK (1<<2)
+#define VXLAN_ATTR_LOCAL (1<<3)
+#define VXLAN_ATTR_TTL (1<<4)
+#define VXLAN_ATTR_TOS (1<<5)
+#define VXLAN_ATTR_LEARNING (1<<6)
+#define VXLAN_ATTR_AGEING (1<<7)
+#define VXLAN_ATTR_LIMIT (1<<8)
+#define VXLAN_ATTR_PORT_RANGE (1<<9)
+#define VXLAN_ATTR_PROXY (1<<10)
+#define VXLAN_ATTR_RSC (1<<11)
+#define VXLAN_ATTR_L2MISS (1<<12)
+#define VXLAN_ATTR_L3MISS (1<<13)
+#define VXLAN_ATTR_PORT (1<<14)
+#define VXLAN_ATTR_GROUP6 (1<<15)
+#define VXLAN_ATTR_LOCAL6 (1<<16)
+#define VXLAN_ATTR_UDP_CSUM (1<<17)
+#define VXLAN_ATTR_UDP_ZERO_CSUM6_TX (1<<18)
+#define VXLAN_ATTR_UDP_ZERO_CSUM6_RX (1<<19)
+#define VXLAN_ATTR_REMCSUM_TX (1<<20)
+#define VXLAN_ATTR_REMCSUM_RX (1<<21)
+#define VXLAN_ATTR_GBP (1<<22)
+#define VXLAN_ATTR_REMCSUM_NOPARTIAL (1<<23)
+#define VXLAN_ATTR_COLLECT_METADATA (1<<24)
+#define VXLAN_ATTR_LABEL (1<<25)
+#define VXLAN_ATTR_GPE (1<<26)
+
struct vxlan_info
{
uint8_t vxi_rsc;
uint8_t vxi_l2miss;
uint8_t vxi_l3miss;
+ uint16_t vxi_port;
+ uint8_t vxi_udp_csum;
+ uint8_t vxi_udp_zero_csum6_tx;
+ uint8_t vxi_udp_zero_csum6_rx;
+ uint8_t vxi_remcsum_tx;
+ uint8_t vxi_remcsum_rx;
+ uint8_t vxi_collect_metadata;
+ uint32_t vxi_label;
uint32_t ce_mask;
};
/** @endcond */
static struct nla_policy vxlan_policy[IFLA_VXLAN_MAX+1] = {
- [IFLA_VXLAN_ID] = { .type = NLA_U32 },
+ [IFLA_VXLAN_ID] = { .type = NLA_U32 },
[IFLA_VXLAN_GROUP] = { .minlen = sizeof(uint32_t) },
[IFLA_VXLAN_GROUP6] = { .minlen = sizeof(struct in6_addr) },
[IFLA_VXLAN_LINK] = { .type = NLA_U32 },
[IFLA_VXLAN_LOCAL6] = { .minlen = sizeof(struct in6_addr) },
[IFLA_VXLAN_TTL] = { .type = NLA_U8 },
[IFLA_VXLAN_TOS] = { .type = NLA_U8 },
+ [IFLA_VXLAN_LABEL] = { .type = NLA_U32 },
[IFLA_VXLAN_LEARNING] = { .type = NLA_U8 },
[IFLA_VXLAN_AGEING] = { .type = NLA_U32 },
[IFLA_VXLAN_LIMIT] = { .type = NLA_U32 },
[IFLA_VXLAN_RSC] = { .type = NLA_U8 },
[IFLA_VXLAN_L2MISS] = { .type = NLA_U8 },
[IFLA_VXLAN_L3MISS] = { .type = NLA_U8 },
+ [IFLA_VXLAN_COLLECT_METADATA] = { .type = NLA_U8 },
+ [IFLA_VXLAN_PORT] = { .type = NLA_U16 },
+ [IFLA_VXLAN_UDP_CSUM] = { .type = NLA_U8 },
+ [IFLA_VXLAN_UDP_ZERO_CSUM6_TX] = { .type = NLA_U8 },
+ [IFLA_VXLAN_UDP_ZERO_CSUM6_RX] = { .type = NLA_U8 },
+ [IFLA_VXLAN_REMCSUM_TX] = { .type = NLA_U8 },
+ [IFLA_VXLAN_REMCSUM_RX] = { .type = NLA_U8 },
+ [IFLA_VXLAN_GBP] = { .type = NLA_FLAG, },
+ [IFLA_VXLAN_GPE] = { .type = NLA_FLAG, },
+ [IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG },
};
static int vxlan_alloc(struct rtnl_link *link)
vxi->ce_mask |= VXLAN_ATTR_L3MISS;
}
+ if (tb[IFLA_VXLAN_PORT]) {
+ vxi->vxi_port = nla_get_u16(tb[IFLA_VXLAN_PORT]);
+ vxi->ce_mask |= VXLAN_ATTR_PORT;
+ }
+
+ if (tb[IFLA_VXLAN_UDP_CSUM]) {
+ vxi->vxi_udp_csum = nla_get_u8(tb[IFLA_VXLAN_UDP_CSUM]);
+ vxi->ce_mask |= VXLAN_ATTR_UDP_CSUM;
+ }
+
+ if (tb[IFLA_VXLAN_UDP_ZERO_CSUM6_TX]) {
+ vxi->vxi_udp_zero_csum6_tx = nla_get_u8(tb[IFLA_VXLAN_UDP_ZERO_CSUM6_TX]);
+ vxi->ce_mask |= VXLAN_ATTR_UDP_ZERO_CSUM6_TX;
+ }
+
+ if (tb[IFLA_VXLAN_UDP_ZERO_CSUM6_RX]) {
+ vxi->vxi_udp_zero_csum6_rx = nla_get_u8(tb[IFLA_VXLAN_UDP_ZERO_CSUM6_RX]);
+ vxi->ce_mask |= VXLAN_ATTR_UDP_ZERO_CSUM6_RX;
+ }
+
+ if (tb[IFLA_VXLAN_REMCSUM_TX]) {
+ vxi->vxi_remcsum_tx = nla_get_u8(tb[IFLA_VXLAN_REMCSUM_TX]);
+ vxi->ce_mask |= VXLAN_ATTR_REMCSUM_TX;
+ }
+
+ if (tb[IFLA_VXLAN_REMCSUM_RX]) {
+ vxi->vxi_remcsum_rx = nla_get_u8(tb[IFLA_VXLAN_REMCSUM_RX]);
+ vxi->ce_mask |= VXLAN_ATTR_REMCSUM_RX;
+ }
+
+ if (tb[IFLA_VXLAN_GBP])
+ vxi->ce_mask |= VXLAN_ATTR_GBP;
+
+ if (tb[IFLA_VXLAN_REMCSUM_NOPARTIAL])
+ vxi->ce_mask |= VXLAN_ATTR_REMCSUM_NOPARTIAL;
+
+ if (tb[IFLA_VXLAN_COLLECT_METADATA]) {
+ vxi->vxi_collect_metadata = nla_get_u8(tb[IFLA_VXLAN_COLLECT_METADATA]);
+ vxi->ce_mask |= VXLAN_ATTR_COLLECT_METADATA;
+ }
+
+ if (tb[IFLA_VXLAN_LABEL]) {
+ vxi->vxi_label = nla_get_u32(tb[IFLA_VXLAN_LABEL]);
+ vxi->ce_mask |= VXLAN_ATTR_LABEL;
+ }
+
+ if (tb[IFLA_VXLAN_GPE])
+ vxi->ce_mask |= VXLAN_ATTR_GPE;
+
err = 0;
errout:
else
nl_dump_line(p, "disabled\n");
}
+
+ if (vxi->ce_mask & VXLAN_ATTR_PORT) {
+ nl_dump(p, " port ");
+ nl_dump_line(p, "%u\n", ntohs(vxi->vxi_port));
+ }
+
+ if (vxi->ce_mask & VXLAN_ATTR_UDP_CSUM) {
+ nl_dump(p, " UDP checksums ");
+ if (vxi->vxi_udp_csum)
+ nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_udp_csum);
+ else
+ nl_dump_line(p, "disabled\n");
+ }
+
+ if (vxi->ce_mask & VXLAN_ATTR_UDP_ZERO_CSUM6_TX) {
+ nl_dump(p, " udp-zero-csum6-tx ");
+ if (vxi->vxi_udp_zero_csum6_tx)
+ nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_udp_zero_csum6_tx);
+ else
+ nl_dump_line(p, "disabled\n");
+ }
+
+ if (vxi->ce_mask & VXLAN_ATTR_UDP_ZERO_CSUM6_RX) {
+ nl_dump(p, " udp-zero-csum6-rx ");
+ if (vxi->vxi_udp_zero_csum6_rx)
+ nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_udp_zero_csum6_rx);
+ else
+ nl_dump_line(p, "disabled\n");
+ }
+
+ if (vxi->ce_mask & VXLAN_ATTR_REMCSUM_TX) {
+ nl_dump(p, " remcsum-tx ");
+ if (vxi->vxi_remcsum_tx)
+ nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_remcsum_tx);
+ else
+ nl_dump_line(p, "disabled\n");
+ }
+
+ if (vxi->ce_mask & VXLAN_ATTR_REMCSUM_RX) {
+ nl_dump(p, " remcsum-rx ");
+ if (vxi->vxi_remcsum_rx)
+ nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_remcsum_rx);
+ else
+ nl_dump_line(p, "disabled\n");
+ }
+
+ if (vxi->ce_mask & VXLAN_ATTR_GBP)
+ nl_dump(p, " gbp\n");
+
+ if (vxi->ce_mask & VXLAN_ATTR_REMCSUM_NOPARTIAL)
+ nl_dump(p, " rncsum-nopartial\n");
+
+ if (vxi->ce_mask & VXLAN_ATTR_COLLECT_METADATA) {
+ nl_dump(p, " remcsum-rx ");
+ if (vxi->vxi_collect_metadata)
+ nl_dump_line(p, "enabled (%#x)\n", vxi->vxi_collect_metadata);
+ else
+ nl_dump_line(p, "disabled\n");
+ }
+
+ if (vxi->ce_mask & VXLAN_ATTR_LABEL) {
+ nl_dump(p, " label ");
+ nl_dump_line(p, "%u\n", ntohl(vxi->vxi_label));
+ }
+
+ if (vxi->ce_mask & VXLAN_ATTR_GPE)
+ nl_dump(p, " gpe\n");
}
static int vxlan_clone(struct rtnl_link *dst, struct rtnl_link *src)
if (vxi->ce_mask & VXLAN_ATTR_L3MISS)
NLA_PUT_U8(msg, IFLA_VXLAN_L3MISS, vxi->vxi_l3miss);
+ if (vxi->ce_mask & VXLAN_ATTR_PORT)
+ NLA_PUT_U32(msg, IFLA_VXLAN_PORT, vxi->vxi_port);
+
+ if (vxi->ce_mask & VXLAN_ATTR_UDP_CSUM)
+ NLA_PUT_U8(msg, IFLA_VXLAN_UDP_CSUM, vxi->vxi_udp_csum);
+
+ if (vxi->ce_mask & VXLAN_ATTR_UDP_ZERO_CSUM6_TX)
+ NLA_PUT_U8(msg, IFLA_VXLAN_UDP_ZERO_CSUM6_TX, vxi->vxi_udp_zero_csum6_tx);
+
+ if (vxi->ce_mask & VXLAN_ATTR_UDP_ZERO_CSUM6_RX)
+ NLA_PUT_U8(msg, IFLA_VXLAN_UDP_ZERO_CSUM6_RX, vxi->vxi_udp_zero_csum6_rx);
+
+ if (vxi->ce_mask & VXLAN_ATTR_REMCSUM_TX)
+ NLA_PUT_U8(msg, IFLA_VXLAN_REMCSUM_TX, vxi->vxi_remcsum_tx);
+
+ if (vxi->ce_mask & VXLAN_ATTR_REMCSUM_RX)
+ NLA_PUT_U8(msg, IFLA_VXLAN_REMCSUM_RX, vxi->vxi_remcsum_rx);
+
+ if (vxi->ce_mask & VXLAN_ATTR_GBP)
+ NLA_PUT_FLAG(msg, IFLA_VXLAN_GBP);
+
+ if (vxi->ce_mask & VXLAN_ATTR_REMCSUM_NOPARTIAL)
+ NLA_PUT_FLAG(msg, IFLA_VXLAN_REMCSUM_NOPARTIAL);
+
+ if (vxi->ce_mask & VXLAN_ATTR_COLLECT_METADATA)
+ NLA_PUT_U8(msg, IFLA_VXLAN_COLLECT_METADATA, vxi->vxi_collect_metadata);
+
+ if (vxi->ce_mask & VXLAN_ATTR_LABEL)
+ NLA_PUT_U32(msg, IFLA_VXLAN_LABEL, vxi->vxi_label);
+
+ if (vxi->ce_mask & VXLAN_ATTR_GPE)
+ NLA_PUT_FLAG(msg, IFLA_VXLAN_GPE);
+
nla_nest_end(msg, data);
nla_put_failure:
diff |= VXLAN_DIFF(TTL, a->vxi_ttl != b->vxi_ttl);
diff |= VXLAN_DIFF(LEARNING, a->vxi_learning != b->vxi_learning);
diff |= VXLAN_DIFF(AGEING, a->vxi_ageing != b->vxi_ageing);
+ diff |= VXLAN_DIFF(LIMIT, a->vxi_limit != b->vxi_limit);
diff |= VXLAN_DIFF(PORT_RANGE,
a->vxi_port_range.low != b->vxi_port_range.low);
diff |= VXLAN_DIFF(PORT_RANGE,
a->vxi_port_range.high != b->vxi_port_range.high);
+ diff |= VXLAN_DIFF(PROXY, a->vxi_proxy != b->vxi_proxy);
+ diff |= VXLAN_DIFF(RSC, a->vxi_proxy != b->vxi_proxy);
+ diff |= VXLAN_DIFF(L2MISS, a->vxi_proxy != b->vxi_proxy);
+ diff |= VXLAN_DIFF(L3MISS, a->vxi_proxy != b->vxi_proxy);
+ diff |= VXLAN_DIFF(PORT, a->vxi_port != b->vxi_port);
diff |= VXLAN_DIFF(GROUP6, memcmp(&a->vxi_group6, &b->vxi_group6, sizeof(a->vxi_group6)) != 0);
diff |= VXLAN_DIFF(LOCAL6, memcmp(&a->vxi_local6, &b->vxi_local6, sizeof(a->vxi_local6)) != 0);
+ diff |= VXLAN_DIFF(UDP_CSUM, a->vxi_proxy != b->vxi_proxy);
+ diff |= VXLAN_DIFF(UDP_ZERO_CSUM6_TX, a->vxi_proxy != b->vxi_proxy);
+ diff |= VXLAN_DIFF(UDP_ZERO_CSUM6_RX, a->vxi_proxy != b->vxi_proxy);
+ diff |= VXLAN_DIFF(REMCSUM_TX, a->vxi_proxy != b->vxi_proxy);
+ diff |= VXLAN_DIFF(REMCSUM_RX, a->vxi_proxy != b->vxi_proxy);
+ diff |= VXLAN_DIFF(GBP, a->ce_mask & b->ce_mask & VXLAN_ATTR_GBP);
+ diff |= VXLAN_DIFF(REMCSUM_NOPARTIAL, a->ce_mask & b->ce_mask & VXLAN_ATTR_REMCSUM_NOPARTIAL);
+ diff |= VXLAN_DIFF(COLLECT_METADATA, a->vxi_collect_metadata != b->vxi_collect_metadata);
+ diff |= VXLAN_DIFF(LABEL, a->vxi_label != b->vxi_label);
+ diff |= VXLAN_DIFF(GPE, a->ce_mask & b->ce_mask & VXLAN_ATTR_GPE);
#undef VXLAN_DIFF
return diff;
}
/**
- * Enable netlink IP DDR miss notifications
+ * Enable netlink IP ADDR miss notifications
* @arg link Link object
*
* @return 0 on success or a negative error code
return rtnl_link_vxlan_set_l3miss(link, 0);
}
+/**
+ * Set UDP destination port to use for VXLAN
+ * @arg link Link object
+ * @arg port Destination port
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_set_port(struct rtnl_link *link, uint32_t port)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ vxi->vxi_port = htons(port);
+ vxi->ce_mask |= VXLAN_ATTR_PORT;
+
+ return 0;
+}
+
+/**
+ * Get UDP destination port to use for VXLAN
+ * @arg link Link object
+ * @arg port Pointer to store destination port
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_get_port(struct rtnl_link *link, uint32_t *port)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ if (!port)
+ return -NLE_INVAL;
+
+ if (!(vxi->ce_mask & VXLAN_ATTR_PORT))
+ return -NLE_AGAIN;
+
+ *port = ntohs(vxi->vxi_port);
+
+ return 0;
+}
+
+/**
+ * Set UDP checksum status to use for VXLAN
+ * @arg link Link object
+ * @arg csum Status value
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_set_udp_csum(struct rtnl_link *link, uint8_t csum)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ vxi->vxi_udp_csum = csum;
+ vxi->ce_mask |= VXLAN_ATTR_UDP_CSUM;
+
+ return 0;
+}
+
+/**
+ * Get UDP checksum status to use for VXLAN
+ * @arg link Link object
+ *
+ * @return Status value on success or a negative error code
+ */
+int rtnl_link_vxlan_get_udp_csum(struct rtnl_link *link)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ if (!(vxi->ce_mask & VXLAN_ATTR_UDP_CSUM))
+ return -NLE_AGAIN;
+
+ return vxi->vxi_udp_csum;
+}
+
+/**
+ * Enable UDP checksums
+ * @arg link Link object
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_enable_udp_csum(struct rtnl_link *link)
+{
+ return rtnl_link_vxlan_set_udp_csum(link, 1);
+}
+
+/**
+ * Disable UDP checksums
+ * @arg link Link object
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_disable_udp_csum(struct rtnl_link *link)
+{
+ return rtnl_link_vxlan_set_udp_csum(link, 0);
+}
+
+/**
+ * Set skip UDP checksum transmitted over IPv6 status to use for VXLAN
+ * @arg link Link object
+ * @arg csum Status value
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_set_udp_zero_csum6_tx(struct rtnl_link *link, uint8_t csum)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ vxi->vxi_udp_zero_csum6_tx = csum;
+ vxi->ce_mask |= VXLAN_ATTR_UDP_ZERO_CSUM6_TX;
+
+ return 0;
+}
+
+/**
+ * Get skip UDP checksum transmitted over IPv6 status to use for VXLAN
+ * @arg link Link object
+ *
+ * @return Status value on success or a negative error code
+ */
+int rtnl_link_vxlan_get_udp_zero_csum6_tx(struct rtnl_link *link)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ if (!(vxi->ce_mask & VXLAN_ATTR_UDP_ZERO_CSUM6_TX))
+ return -NLE_AGAIN;
+
+ return vxi->vxi_udp_zero_csum6_tx;
+}
+
+/**
+ * Enable skip UDP checksum transmitted over IPv6
+ * @arg link Link object
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_enable_udp_zero_csum6_tx(struct rtnl_link *link)
+{
+ return rtnl_link_vxlan_set_udp_zero_csum6_tx(link, 1);
+}
+
+/**
+ * Disable skip UDP checksum transmitted over IPv6
+ * @arg link Link object
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_disable_udp_zero_csum6_tx(struct rtnl_link *link)
+{
+ return rtnl_link_vxlan_set_udp_zero_csum6_tx(link, 0);
+}
+
+/**
+ * Set skip UDP checksum received over IPv6 status to use for VXLAN
+ * @arg link Link object
+ * @arg csum Status value
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_set_udp_zero_csum6_rx(struct rtnl_link *link, uint8_t csum)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ vxi->vxi_udp_zero_csum6_rx = csum;
+ vxi->ce_mask |= VXLAN_ATTR_UDP_ZERO_CSUM6_RX;
+
+ return 0;
+}
+
+/**
+ * Get skip UDP checksum received over IPv6 status to use for VXLAN
+ * @arg link Link object
+ *
+ * @return Status value on success or a negative error code
+ */
+int rtnl_link_vxlan_get_udp_zero_csum6_rx(struct rtnl_link *link)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ if (!(vxi->ce_mask & VXLAN_ATTR_UDP_ZERO_CSUM6_RX))
+ return -NLE_AGAIN;
+
+ return vxi->vxi_udp_zero_csum6_rx;
+}
+
+/**
+ * Enable skip UDP checksum received over IPv6
+ * @arg link Link object
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_enable_udp_zero_csum6_rx(struct rtnl_link *link)
+{
+ return rtnl_link_vxlan_set_udp_zero_csum6_rx(link, 1);
+}
+
+/**
+ * Disable skip UDP checksum received over IPv6
+ * @arg link Link object
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_disable_udp_zero_csum6_rx(struct rtnl_link *link)
+{
+ return rtnl_link_vxlan_set_udp_zero_csum6_rx(link, 0);
+}
+
+/**
+ * Set remote offload transmit checksum status to use for VXLAN
+ * @arg link Link object
+ * @arg csum Status value
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_set_remcsum_tx(struct rtnl_link *link, uint8_t csum)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ vxi->vxi_remcsum_tx = csum;
+ vxi->ce_mask |= VXLAN_ATTR_REMCSUM_TX;
+
+ return 0;
+}
+
+/**
+ * Get remote offload transmit checksum status to use for VXLAN
+ * @arg link Link object
+ *
+ * @return Status value on success or a negative error code
+ */
+int rtnl_link_vxlan_get_remcsum_tx(struct rtnl_link *link)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ if (!(vxi->ce_mask & VXLAN_ATTR_REMCSUM_TX))
+ return -NLE_AGAIN;
+
+ return vxi->vxi_remcsum_tx;
+}
+
+/**
+ * Enable remote offload transmit checksums
+ * @arg link Link object
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_enable_remcsum_tx(struct rtnl_link *link)
+{
+ return rtnl_link_vxlan_set_remcsum_tx(link, 1);
+}
+
+/**
+ * Disable remote offload transmit checksums
+ * @arg link Link object
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_disable_remcsum_tx(struct rtnl_link *link)
+{
+ return rtnl_link_vxlan_set_remcsum_tx(link, 0);
+}
+
+/**
+ * Set remote offload receive checksum status to use for VXLAN
+ * @arg link Link object
+ * @arg csum Status value
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_set_remcsum_rx(struct rtnl_link *link, uint8_t csum)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ vxi->vxi_remcsum_rx = csum;
+ vxi->ce_mask |= VXLAN_ATTR_REMCSUM_RX;
+
+ return 0;
+}
+
+/**
+ * Get remote offload receive checksum status to use for VXLAN
+ * @arg link Link object
+ *
+ * @return Status value on success or a negative error code
+ */
+int rtnl_link_vxlan_get_remcsum_rx(struct rtnl_link *link)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ if (!(vxi->ce_mask & VXLAN_ATTR_REMCSUM_RX))
+ return -NLE_AGAIN;
+
+ return vxi->vxi_remcsum_rx;
+}
+
+/**
+ * Enable remote offload receive checksums
+ * @arg link Link object
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_enable_remcsum_rx(struct rtnl_link *link)
+{
+ return rtnl_link_vxlan_set_remcsum_rx(link, 1);
+}
+
+/**
+ * Disable remote offload receive checksums
+ * @arg link Link object
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_disable_remcsum_rx(struct rtnl_link *link)
+{
+ return rtnl_link_vxlan_set_remcsum_rx(link, 0);
+}
+
+/**
+ * Set group-based policy extension flag to use for VXLAN
+ * @arg link Link object
+ * @arg enable Boolean enabling or disabling flag
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_set_gbp(struct rtnl_link *link, int enable)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ if (enable)
+ vxi->ce_mask |= VXLAN_ATTR_GBP;
+ else
+ vxi->ce_mask &= ~VXLAN_ATTR_GBP;
+
+ return 0;
+}
+
+/**
+ * Get group-based policy extension flag to use for VXLAN
+ * @arg link Link object
+ *
+ * @return Status value on success or a negative error code
+ */
+int rtnl_link_vxlan_get_gbp(struct rtnl_link *link)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ return !!(vxi->ce_mask & VXLAN_ATTR_GBP);
+}
+
+/**
+ * Enable group-based policy extension
+ * @arg link Link object
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_enable_gbp(struct rtnl_link *link)
+{
+ return rtnl_link_vxlan_set_gbp(link, 1);
+}
+
+/**
+ * Disable group-based policy extension
+ * @arg link Link object
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_disable_gbp(struct rtnl_link *link)
+{
+ return rtnl_link_vxlan_set_gbp(link, 0);
+}
+
+/**
+ * Set no-partial remote offload checksum flag to use for VXLAN
+ * @arg link Link object
+ * @arg enable Boolean enabling or disabling flag
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_set_remcsum_nopartial(struct rtnl_link *link, int enable)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ if (enable)
+ vxi->ce_mask |= VXLAN_ATTR_REMCSUM_NOPARTIAL;
+ else
+ vxi->ce_mask &= ~VXLAN_ATTR_REMCSUM_NOPARTIAL;
+
+ return 0;
+}
+
+/**
+ * Get no-partial remote offload checksum flag to use for VXLAN
+ * @arg link Link object
+ *
+ * @return Status value on success or a negative error code
+ */
+int rtnl_link_vxlan_get_remcsum_nopartial(struct rtnl_link *link)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ return !!(vxi->ce_mask & VXLAN_ATTR_REMCSUM_NOPARTIAL);
+}
+
+/**
+ * Enable no-partial remote offload checksum
+ * @arg link Link object
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_enable_remcsum_nopartial(struct rtnl_link *link)
+{
+ return rtnl_link_vxlan_set_remcsum_nopartial(link, 1);
+}
+
+/**
+ * Disable no-partial remote offload checksum
+ * @arg link Link object
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_disable_remcsum_nopartial(struct rtnl_link *link)
+{
+ return rtnl_link_vxlan_set_remcsum_nopartial(link, 0);
+}
+
+/**
+ * Set collect metadata status to use for VXLAN
+ * @arg link Link object
+ * @arg collect Status value
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_set_collect_metadata(struct rtnl_link *link, uint8_t collect)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ vxi->vxi_collect_metadata = collect;
+ vxi->ce_mask |= VXLAN_ATTR_COLLECT_METADATA;
+
+ return 0;
+}
+
+/**
+ * Get collect metadata status to use for VXLAN
+ * @arg link Link object
+ *
+ * @return Status value on success or a negative error code
+ */
+int rtnl_link_vxlan_get_collect_metadata(struct rtnl_link *link)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ if (!(vxi->ce_mask & VXLAN_ATTR_COLLECT_METADATA))
+ return -NLE_AGAIN;
+
+ return vxi->vxi_collect_metadata;
+}
+
+/**
+ * Enable collect metadata
+ * @arg link Link object
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_enable_collect_metadata(struct rtnl_link *link)
+{
+ return rtnl_link_vxlan_set_collect_metadata(link, 1);
+}
+
+/**
+ * Disable collect metadata
+ * @arg link Link object
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_disable_collect_metadata(struct rtnl_link *link)
+{
+ return rtnl_link_vxlan_set_collect_metadata(link, 0);
+}
+
+/**
+ * Set flow label to use for VXLAN
+ * @arg link Link object
+ * @arg label Destination label
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_set_label(struct rtnl_link *link, uint32_t label)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ vxi->vxi_label = htonl(label);
+ vxi->ce_mask |= VXLAN_ATTR_LABEL;
+
+ return 0;
+}
+
+/**
+ * Get flow label to use for VXLAN
+ * @arg link Link object
+ * @arg label Pointer to store destination label
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_get_label(struct rtnl_link *link, uint32_t *label)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ if (!label)
+ return -NLE_INVAL;
+
+ if (!(vxi->ce_mask & VXLAN_ATTR_LABEL))
+ return -NLE_AGAIN;
+
+ *label = ntohl(vxi->vxi_label);
+
+ return 0;
+}
+
+/**
+ * Set generic protocol extension flag to use for VXLAN
+ * @arg link Link object
+ * @arg enable Boolean enabling or disabling flag
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_set_gpe(struct rtnl_link *link, int enable)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ if (enable)
+ vxi->ce_mask |= VXLAN_ATTR_GPE;
+ else
+ vxi->ce_mask &= ~VXLAN_ATTR_GPE;
+
+ return 0;
+}
+
+/**
+ * Get generic protocol extension flag to use for VXLAN
+ * @arg link Link object
+ *
+ * @return Status value on success or a negative error code
+ */
+int rtnl_link_vxlan_get_gpe(struct rtnl_link *link)
+{
+ struct vxlan_info *vxi = link->l_info;
+
+ IS_VXLAN_LINK_ASSERT(link);
+
+ return !!(vxi->ce_mask & VXLAN_ATTR_GPE);
+}
+
+/**
+ * Enable generic protocol extension
+ * @arg link Link object
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_enable_gpe(struct rtnl_link *link)
+{
+ return rtnl_link_vxlan_set_gpe(link, 1);
+}
+
+/**
+ * Disable generic protocol extension
+ * @arg link Link object
+ *
+ * @return 0 on success or a negative error code
+ */
+int rtnl_link_vxlan_disable_gpe(struct rtnl_link *link)
+{
+ return rtnl_link_vxlan_set_gpe(link, 0);
+}
+
/** @} */
static void __init vxlan_init(void)