From d533736e2258457c090d396586da5c2ea32e5836 Mon Sep 17 00:00:00 2001 From: Brandon Carpenter Date: Fri, 30 Sep 2016 15:44:25 -0700 Subject: [PATCH] vxlan: add support for additional VXLAN attributes. Includes all VXLAN attributes as of Linux kernel 4.7.5. In particular it adds the following attributes: * IFLA_VXLAN_PORT, * IFLA_VXLAN_UDP_CSUM, * IFLA_VXLAN_UDP_ZERO_CSUM6_TX, * IFLA_VXLAN_UDP_ZERO_CSUM6_RX, * IFLA_VXLAN_REMCSUM_TX, * IFLA_VXLAN_REMCSUM_RX, * IFLA_VXLAN_GBP, * IFLA_VXLAN_REMCSUM_NOPARTIAL, * IFLA_VXLAN_COLLECT_METADATA, * IFLA_VXLAN_LABEL, * IFLA_VXLAN_GPE https://github.com/thom311/libnl/pull/110 --- include/linux-private/linux/if_link.h | 180 ++++++ include/netlink/route/link/vxlan.h | 61 +- lib/route/link/vxlan.c | 846 +++++++++++++++++++++++++- libnl-route-3.sym | 40 ++ 4 files changed, 1104 insertions(+), 23 deletions(-) diff --git a/include/linux-private/linux/if_link.h b/include/linux-private/linux/if_link.h index cd7213d..15bbeb8 100644 --- a/include/linux-private/linux/if_link.h +++ b/include/linux-private/linux/if_link.h @@ -35,6 +35,8 @@ struct rtnl_link_stats { /* for cslip etc */ __u32 rx_compressed; __u32 tx_compressed; + + __u32 rx_nohandler; /* dropped, no handler found */ }; /* The main device statistics structure */ @@ -68,6 +70,8 @@ struct rtnl_link_stats64 { /* 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 */ @@ -148,6 +152,10 @@ enum { 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 }; @@ -215,6 +223,7 @@ enum in6_addr_gen_mode { IN6_ADDR_GEN_MODE_EUI64, IN6_ADDR_GEN_MODE_NONE, IN6_ADDR_GEN_MODE_STABLE_PRIVACY, + IN6_ADDR_GEN_MODE_RANDOM, }; /* Bridge section */ @@ -227,11 +236,51 @@ enum { 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, @@ -251,6 +300,20 @@ enum { 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) @@ -346,6 +409,14 @@ enum { #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, @@ -418,6 +489,9 @@ enum { 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) @@ -427,6 +501,42 @@ struct ifla_vxlan_port_range { __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 { @@ -454,6 +564,10 @@ 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, }; @@ -479,6 +593,8 @@ enum { 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, }; @@ -505,6 +621,10 @@ enum { 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, }; @@ -537,6 +657,11 @@ struct ifla_vf_spoofchk { __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 */ @@ -554,6 +679,24 @@ struct ifla_vf_rss_query_en { __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: @@ -654,9 +797,46 @@ enum { 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 */ diff --git a/include/netlink/route/link/vxlan.h b/include/netlink/route/link/vxlan.h index f7f7b60..40ce623 100644 --- a/include/netlink/route/link/vxlan.h +++ b/include/netlink/route/link/vxlan.h @@ -23,16 +23,16 @@ extern "C" { extern struct rtnl_link *rtnl_link_vxlan_alloc(void); -extern int rtnl_link_is_vxlan(struct rtnl_link *); +extern int rtnl_link_is_vxlan(struct rtnl_link *); -extern int rtnl_link_vxlan_set_id(struct rtnl_link *, uint32_t); -extern int rtnl_link_vxlan_get_id(struct rtnl_link *, uint32_t *); +extern int rtnl_link_vxlan_set_id(struct rtnl_link *, uint32_t); +extern int rtnl_link_vxlan_get_id(struct rtnl_link *, uint32_t *); extern int rtnl_link_vxlan_set_group(struct rtnl_link *, struct nl_addr *); extern int rtnl_link_vxlan_get_group(struct rtnl_link *, struct nl_addr **); -extern int rtnl_link_vxlan_set_link(struct rtnl_link *, uint32_t); -extern int rtnl_link_vxlan_get_link(struct rtnl_link *, uint32_t *); +extern int rtnl_link_vxlan_set_link(struct rtnl_link *, uint32_t); +extern int rtnl_link_vxlan_get_link(struct rtnl_link *, uint32_t *); extern int rtnl_link_vxlan_set_local(struct rtnl_link *, struct nl_addr *); extern int rtnl_link_vxlan_get_local(struct rtnl_link *, struct nl_addr **); @@ -79,6 +79,57 @@ extern int rtnl_link_vxlan_get_l3miss(struct rtnl_link *); extern int rtnl_link_vxlan_enable_l3miss(struct rtnl_link *); extern int rtnl_link_vxlan_disable_l3miss(struct rtnl_link *); +extern int rtnl_link_vxlan_set_port(struct rtnl_link *, uint32_t); +extern int rtnl_link_vxlan_get_port(struct rtnl_link *, uint32_t *); + +extern int rtnl_link_vxlan_set_udp_csum(struct rtnl_link *, uint8_t); +extern int rtnl_link_vxlan_get_udp_csum(struct rtnl_link *); +extern int rtnl_link_vxlan_enable_udp_csum(struct rtnl_link *); +extern int rtnl_link_vxlan_disable_udp_csum(struct rtnl_link *); + +extern int rtnl_link_vxlan_set_udp_zero_csum6_tx(struct rtnl_link *, uint8_t); +extern int rtnl_link_vxlan_get_udp_zero_csum6_tx(struct rtnl_link *); +extern int rtnl_link_vxlan_enable_udp_zero_csum6_tx(struct rtnl_link *); +extern int rtnl_link_vxlan_disable_udp_zero_csum6_tx(struct rtnl_link *); + +extern int rtnl_link_vxlan_set_udp_zero_csum6_rx(struct rtnl_link *, uint8_t); +extern int rtnl_link_vxlan_get_udp_zero_csum6_rx(struct rtnl_link *); +extern int rtnl_link_vxlan_enable_udp_zero_csum6_rx(struct rtnl_link *); +extern int rtnl_link_vxlan_disable_udp_zero_csum6_rx(struct rtnl_link *); + +extern int rtnl_link_vxlan_set_remcsum_tx(struct rtnl_link *, uint8_t); +extern int rtnl_link_vxlan_get_remcsum_tx(struct rtnl_link *); +extern int rtnl_link_vxlan_enable_remcsum_tx(struct rtnl_link *); +extern int rtnl_link_vxlan_disable_remcsum_tx(struct rtnl_link *); + +extern int rtnl_link_vxlan_set_remcsum_rx(struct rtnl_link *, uint8_t); +extern int rtnl_link_vxlan_get_remcsum_rx(struct rtnl_link *); +extern int rtnl_link_vxlan_enable_remcsum_rx(struct rtnl_link *); +extern int rtnl_link_vxlan_disable_remcsum_rx(struct rtnl_link *); + +extern int rtnl_link_vxlan_set_gbp(struct rtnl_link *, int); +extern int rtnl_link_vxlan_get_gbp(struct rtnl_link *); +extern int rtnl_link_vxlan_enable_gbp(struct rtnl_link *); +extern int rtnl_link_vxlan_disable_gbp(struct rtnl_link *); + +extern int rtnl_link_vxlan_set_remcsum_nopartial(struct rtnl_link *, int); +extern int rtnl_link_vxlan_get_remcsum_nopartial(struct rtnl_link *); +extern int rtnl_link_vxlan_enable_remcsum_nopartial(struct rtnl_link *); +extern int rtnl_link_vxlan_disable_remcsum_nopartial(struct rtnl_link *); + +extern int rtnl_link_vxlan_set_collect_metadata(struct rtnl_link *, uint8_t); +extern int rtnl_link_vxlan_get_collect_metadata(struct rtnl_link *); +extern int rtnl_link_vxlan_enable_collect_metadata(struct rtnl_link *); +extern int rtnl_link_vxlan_disable_collect_metadata(struct rtnl_link *); + +extern int rtnl_link_vxlan_set_label(struct rtnl_link *, uint32_t); +extern int rtnl_link_vxlan_get_label(struct rtnl_link *, uint32_t *); + +extern int rtnl_link_vxlan_set_gpe(struct rtnl_link *, int); +extern int rtnl_link_vxlan_get_gpe(struct rtnl_link *); +extern int rtnl_link_vxlan_enable_gpe(struct rtnl_link *); +extern int rtnl_link_vxlan_disable_gpe(struct rtnl_link *); + #ifdef __cplusplus } #endif diff --git a/lib/route/link/vxlan.c b/lib/route/link/vxlan.c index 6f854e2..0028213 100644 --- a/lib/route/link/vxlan.c +++ b/lib/route/link/vxlan.c @@ -34,22 +34,34 @@ #include /** @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 { @@ -69,13 +81,21 @@ 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 }, @@ -83,6 +103,7 @@ static struct nla_policy vxlan_policy[IFLA_VXLAN_MAX+1] = { [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 }, @@ -91,6 +112,16 @@ static struct nla_policy vxlan_policy[IFLA_VXLAN_MAX+1] = { [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) @@ -213,6 +244,55 @@ static int vxlan_parse(struct rtnl_link *link, struct nlattr *data, 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: @@ -361,6 +441,73 @@ static void vxlan_dump_details(struct rtnl_link *link, struct nl_dump_params *p) 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) @@ -438,6 +585,39 @@ static int vxlan_put_attrs(struct nl_msg *msg, struct rtnl_link *link) 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: @@ -463,12 +643,28 @@ static int vxlan_compare(struct rtnl_link *link_a, struct rtnl_link *link_b, 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; @@ -1218,7 +1414,7 @@ int rtnl_link_vxlan_get_l3miss(struct rtnl_link *link) } /** - * 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 @@ -1239,6 +1435,620 @@ int rtnl_link_vxlan_disable_l3miss(struct rtnl_link *link) 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) diff --git a/libnl-route-3.sym b/libnl-route-3.sym index 448a617..db0393d 100644 --- a/libnl-route-3.sym +++ b/libnl-route-3.sym @@ -482,44 +482,84 @@ global: rtnl_link_vlan_str2flags; rtnl_link_vlan_unset_flags; rtnl_link_vxlan_alloc; + rtnl_link_vxlan_disable_collect_metadata; + rtnl_link_vxlan_disable_gbp; + rtnl_link_vxlan_disable_gpe; rtnl_link_vxlan_disable_l2miss; rtnl_link_vxlan_disable_l3miss; rtnl_link_vxlan_disable_learning; rtnl_link_vxlan_disable_proxy; + rtnl_link_vxlan_disable_remcsum_nopartial; + rtnl_link_vxlan_disable_remcsum_rx; + rtnl_link_vxlan_disable_remcsum_tx; rtnl_link_vxlan_disable_rsc; + rtnl_link_vxlan_disable_udp_csum; + rtnl_link_vxlan_disable_udp_zero_csum6_rx; + rtnl_link_vxlan_disable_udp_zero_csum6_tx; + rtnl_link_vxlan_enable_collect_metadata; + rtnl_link_vxlan_enable_gbp; + rtnl_link_vxlan_enable_gpe; rtnl_link_vxlan_enable_l2miss; rtnl_link_vxlan_enable_l3miss; rtnl_link_vxlan_enable_learning; rtnl_link_vxlan_enable_proxy; + rtnl_link_vxlan_enable_remcsum_nopartial; + rtnl_link_vxlan_enable_remcsum_rx; + rtnl_link_vxlan_enable_remcsum_tx; rtnl_link_vxlan_enable_rsc; + rtnl_link_vxlan_enable_udp_csum; + rtnl_link_vxlan_enable_udp_zero_csum6_rx; + rtnl_link_vxlan_enable_udp_zero_csum6_tx; rtnl_link_vxlan_get_ageing; + rtnl_link_vxlan_get_collect_metadata; + rtnl_link_vxlan_get_gbp; + rtnl_link_vxlan_get_gpe; rtnl_link_vxlan_get_group; rtnl_link_vxlan_get_id; rtnl_link_vxlan_get_l2miss; rtnl_link_vxlan_get_l3miss; + rtnl_link_vxlan_get_label; rtnl_link_vxlan_get_learning; rtnl_link_vxlan_get_limit; rtnl_link_vxlan_get_link; rtnl_link_vxlan_get_local; + rtnl_link_vxlan_get_port; rtnl_link_vxlan_get_port_range; rtnl_link_vxlan_get_proxy; + rtnl_link_vxlan_get_remcsum_nopartial; + rtnl_link_vxlan_get_remcsum_rx; + rtnl_link_vxlan_get_remcsum_tx; rtnl_link_vxlan_get_rsc; rtnl_link_vxlan_get_tos; rtnl_link_vxlan_get_ttl; + rtnl_link_vxlan_get_udp_csum; + rtnl_link_vxlan_get_udp_zero_csum6_rx; + rtnl_link_vxlan_get_udp_zero_csum6_tx; rtnl_link_vxlan_set_ageing; + rtnl_link_vxlan_set_collect_metadata; + rtnl_link_vxlan_set_gbp; + rtnl_link_vxlan_set_gpe; rtnl_link_vxlan_set_group; rtnl_link_vxlan_set_id; rtnl_link_vxlan_set_l2miss; rtnl_link_vxlan_set_l3miss; + rtnl_link_vxlan_set_label; rtnl_link_vxlan_set_learning; rtnl_link_vxlan_set_limit; rtnl_link_vxlan_set_link; rtnl_link_vxlan_set_local; + rtnl_link_vxlan_set_port; rtnl_link_vxlan_set_port_range; rtnl_link_vxlan_set_proxy; + rtnl_link_vxlan_set_remcsum_nopartial; + rtnl_link_vxlan_set_remcsum_rx; + rtnl_link_vxlan_set_remcsum_tx; rtnl_link_vxlan_set_rsc; rtnl_link_vxlan_set_tos; rtnl_link_vxlan_set_ttl; + rtnl_link_vxlan_set_udp_csum; + rtnl_link_vxlan_set_udp_zero_csum6_rx; + rtnl_link_vxlan_set_udp_zero_csum6_tx; rtnl_meta_value_alloc_id; rtnl_meta_value_alloc_int; rtnl_meta_value_alloc_var; -- 2.40.0