/* SPDX-License-Identifier: LGPL-2.1-only */
/*
 * Copyright (c) 2018 Wang Jian <jianjian.wang1@gmail.com>
 */

/**
 * @ingroup link
 * @defgroup geneve Geneve
 * Generic Network Virtualization Encapsulation
 *
 * @details
 * \b Link Type Name: "geneve"
 *
 * @route_doc{link_geneve, Geneve Documentation}
 *
 * @{
 */
#include "nl-default.h"

#include <netlink/netlink.h>
#include <netlink/utils.h>
#include <netlink/object.h>
#include <netlink/route/rtnl.h>
#include <netlink/route/link/geneve.h>

#include "nl-route.h"
#include "link-api.h"

/** @cond SKIP */
#define GENEVE_ATTR_ID          (1<<0)
#define GENEVE_ATTR_REMOTE      (1<<1)
#define GENEVE_ATTR_REMOTE6     (1<<2)
#define GENEVE_ATTR_TTL         (1<<3)
#define GENEVE_ATTR_TOS         (1<<4)
#define GENEVE_ATTR_LABEL       (1<<5)
#define GENEVE_ATTR_PORT        (1<<6)
#define GENEVE_ATTR_FLAGS       (1<<7)
#define GENEVE_ATTR_UDP_CSUM    (1<<8)
#define GENEVE_ATTR_UDP_ZERO_CSUM6_TX   (1<<9)
#define GENEVE_ATTR_UDP_ZERO_CSUM6_RX   (1<<10)

struct geneve_info
{
        uint32_t        id;
        uint32_t        remote;
        struct in6_addr remote6;
        uint8_t         ttl;
        uint8_t         tos;
        uint32_t        label;
        uint16_t        port;
        uint8_t         flags;
        uint8_t         udp_csum;
        uint8_t         udp_zero_csum6_tx;
        uint8_t         udp_zero_csum6_rx;
        uint32_t        mask;
};

/** @endcond */

static struct nla_policy geneve_policy[IFLA_GENEVE_MAX + 1] = {
        [IFLA_GENEVE_ID] = { .type = NLA_U32 },
        [IFLA_GENEVE_REMOTE]    = { .minlen = sizeof(uint32_t) },
        [IFLA_GENEVE_REMOTE6]   = { .minlen = sizeof(struct in6_addr) },
        [IFLA_GENEVE_TTL]       = { .type = NLA_U8 },
        [IFLA_GENEVE_TOS]       = { .type = NLA_U8 },
        [IFLA_GENEVE_LABEL]     = { .type = NLA_U32 },
        [IFLA_GENEVE_PORT]      = { .type = NLA_U16 },
        [IFLA_GENEVE_COLLECT_METADATA]  = { .type = NLA_FLAG },
        [IFLA_GENEVE_UDP_CSUM]  = { .type = NLA_U8 },
        [IFLA_GENEVE_UDP_ZERO_CSUM6_TX] = { .type = NLA_U8 },
        [IFLA_GENEVE_UDP_ZERO_CSUM6_RX] = { .type = NLA_U8 },
};

static int geneve_alloc(struct rtnl_link *link)
{
        struct geneve_info *geneve;

        if (link->l_info)
                memset(link->l_info, 0, sizeof(*geneve));
        else {
                if ((geneve = calloc(1, sizeof(*geneve))) == NULL)
                                return -NLE_NOMEM;
                link->l_info = geneve;
        }

        return 0;
}

static int geneve_parse(struct rtnl_link *link, struct nlattr *data,
                        struct nlattr *xstats)
{
        struct nlattr *tb[IFLA_GENEVE_MAX + 1];
        struct geneve_info *geneve;
        int err = 0;

        NL_DBG(3, "Parsing Geneve link info\n");

        err = nla_parse_nested(tb, IFLA_GENEVE_MAX, data, geneve_policy);
        if (err < 0)
                return err;

        err = geneve_alloc(link);
        if (err < 0)
                return err;

        geneve = link->l_info;

        if (tb[IFLA_GENEVE_ID]) {
                geneve->id = nla_get_u32(tb[IFLA_GENEVE_ID]);
                geneve->mask |= GENEVE_ATTR_ID;
        }

        if (tb[IFLA_GENEVE_REMOTE]) {
                nla_memcpy(&geneve->remote, tb[IFLA_GENEVE_REMOTE],
                                sizeof(geneve->remote));
                geneve->mask |= GENEVE_ATTR_REMOTE;
                geneve->mask &= ~GENEVE_ATTR_REMOTE6;
        }
        if (tb[IFLA_GENEVE_REMOTE6]) {
                nla_memcpy(&geneve->remote6, tb[IFLA_GENEVE_REMOTE6],
                                sizeof(geneve->remote6));
                geneve->mask |= GENEVE_ATTR_REMOTE6;
                geneve->mask &= ~GENEVE_ATTR_REMOTE;
        }

        if (tb[IFLA_GENEVE_TTL]) {
                geneve->ttl = nla_get_u8(tb[IFLA_GENEVE_TTL]);
                geneve->mask |= GENEVE_ATTR_TTL;
        }

        if (tb[IFLA_GENEVE_TOS]) {
                geneve->tos = nla_get_u8(tb[IFLA_GENEVE_TOS]);
                geneve->mask |= GENEVE_ATTR_TOS;
        }

        if (tb[IFLA_GENEVE_LABEL]) {
                geneve->label = nla_get_u32(tb[IFLA_GENEVE_LABEL]);
                geneve->mask |= GENEVE_ATTR_LABEL;
        }

        if (tb[IFLA_GENEVE_PORT]) {
                geneve->port  = nla_get_u16(tb[IFLA_GENEVE_PORT]);
                geneve->mask |= GENEVE_ATTR_PORT;
        }

        if (tb[IFLA_GENEVE_COLLECT_METADATA])
                geneve->flags |= RTNL_LINK_GENEVE_F_COLLECT_METADATA;

        if (tb[IFLA_GENEVE_UDP_CSUM]) {
                geneve->udp_csum = nla_get_u8(tb[IFLA_GENEVE_UDP_CSUM]);
                geneve->mask |= GENEVE_ATTR_UDP_CSUM;
        }

        if (tb[IFLA_GENEVE_UDP_ZERO_CSUM6_TX]) {
                geneve->udp_zero_csum6_tx = nla_get_u8(tb[IFLA_GENEVE_UDP_ZERO_CSUM6_TX]);
                geneve->mask |= GENEVE_ATTR_UDP_ZERO_CSUM6_TX;
        }

        if (tb[IFLA_GENEVE_UDP_ZERO_CSUM6_RX]) {
                geneve->udp_zero_csum6_rx = nla_get_u8(tb[IFLA_GENEVE_UDP_ZERO_CSUM6_RX]);
                geneve->mask |= GENEVE_ATTR_UDP_ZERO_CSUM6_RX;
        }

        return err;
}

static void geneve_free(struct rtnl_link *link)
{
        struct geneve_info *geneve = link->l_info;

        free(geneve);
        link->l_info = NULL;
}

static void geneve_dump_line(struct rtnl_link *link, struct nl_dump_params *p)
{
        struct geneve_info *geneve = link->l_info;

        nl_dump(p, "geneve-id %u", geneve->id);
}

static void geneve_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
{
        struct geneve_info *geneve = link->l_info;
        char addr[INET6_ADDRSTRLEN];

        nl_dump_line(p, "    geneve-id %u\n", geneve->id);

        if (geneve->mask & GENEVE_ATTR_REMOTE) {
                nl_dump(p, "     remote ");
                nl_dump_line(p, "%s\n",
                             _nl_inet_ntop(AF_INET, &geneve->remote, addr));
        } else if (geneve->mask & GENEVE_ATTR_REMOTE6) {
                nl_dump(p, "      remote ");
                nl_dump_line(p, "%s\n",
                             _nl_inet_ntop(AF_INET6, &geneve->remote6, addr));
        }

        if (geneve->mask & GENEVE_ATTR_TTL) {
                nl_dump(p, "      ttl ");
                nl_dump_line(p, "%u\n", geneve->ttl);
        }

        if (geneve->mask & GENEVE_ATTR_TOS) {
                nl_dump(p, "      tos ");
                nl_dump_line(p, "%u\n", geneve->tos);
        }

        if (geneve->mask & GENEVE_ATTR_PORT) {
                nl_dump(p, "      port ");
                nl_dump_line(p, "%u\n", ntohs(geneve->port));
        }

        if (geneve->mask & GENEVE_ATTR_LABEL) {
                nl_dump(p, "      label ");
                nl_dump_line(p, "%u\n", ntohl(geneve->label));
        }

        if (geneve->mask & GENEVE_ATTR_UDP_CSUM) {
                nl_dump(p, "      UDP checksum ");
                if (geneve->udp_csum)
                        nl_dump_line(p, "enabled (%#x)\n", geneve->udp_csum);
                else
                        nl_dump_line(p, "disabled\n");
        }

        if (geneve->mask & GENEVE_ATTR_UDP_ZERO_CSUM6_TX) {
                nl_dump(p, "      udp-zero-csum6-tx ");
                if (geneve->udp_zero_csum6_tx)
                        nl_dump_line(p, "enabled (%#x)\n", geneve->udp_zero_csum6_tx);
                else
                        nl_dump_line(p, "disabled\n");
        }

        if (geneve->mask & GENEVE_ATTR_UDP_ZERO_CSUM6_RX) {
                nl_dump(p, "      udp-zero-csum6-rx ");
                if (geneve->udp_zero_csum6_rx)
                        nl_dump_line(p, "enabled (%#x)\n", geneve->udp_zero_csum6_rx);
                else
                        nl_dump_line(p, "disabled\n");
        }

        if (geneve->flags & RTNL_LINK_GENEVE_F_COLLECT_METADATA)
                nl_dump(p, "      collect-metadata\n");
}

static int geneve_clone(struct rtnl_link *dst, struct rtnl_link *src)
{
        struct geneve_info *gdst, *gsrc;
        int err;

        gsrc = src->l_info;
        dst->l_info = NULL;
        err = rtnl_link_set_type(dst, "geneve");
        if (err < 0)
                return err;

        gdst = dst->l_info;

        if (!gsrc || !gdst)
                return -NLE_NOMEM;

        memcpy(gdst, gsrc, sizeof(struct geneve_info));

        return 0;
}

static int geneve_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
{
        struct geneve_info  *geneve = link->l_info;
        struct nlattr *data;

        if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
                return -NLE_MSGSIZE;

        if (geneve->mask & GENEVE_ATTR_ID)
                NLA_PUT_U32(msg, IFLA_GENEVE_ID, geneve->id);

        if (geneve->mask & GENEVE_ATTR_REMOTE)
                NLA_PUT(msg, IFLA_GENEVE_REMOTE,
                                sizeof(geneve->remote), &geneve->remote);

        if (geneve->mask & GENEVE_ATTR_REMOTE6)
                NLA_PUT(msg, IFLA_GENEVE_REMOTE6,
                                sizeof(geneve->remote6), &geneve->remote6);

        if (geneve->mask & GENEVE_ATTR_TTL)
                NLA_PUT_U8(msg, IFLA_GENEVE_TTL, geneve->ttl);

        if (geneve->mask & GENEVE_ATTR_TOS)
                NLA_PUT_U8(msg, IFLA_GENEVE_TOS, geneve->tos);

        if (geneve->mask & GENEVE_ATTR_LABEL)
                NLA_PUT_U32(msg, IFLA_GENEVE_LABEL, geneve->label);

        if (geneve->mask & GENEVE_ATTR_PORT)
                NLA_PUT_U32(msg, IFLA_GENEVE_PORT, geneve->port);

        if (geneve->mask & GENEVE_ATTR_UDP_CSUM)
                NLA_PUT_U8(msg, IFLA_GENEVE_UDP_CSUM, geneve->udp_csum);

        if (geneve->mask & GENEVE_ATTR_UDP_ZERO_CSUM6_TX)
                NLA_PUT_U8(msg, IFLA_GENEVE_UDP_ZERO_CSUM6_TX, geneve->udp_zero_csum6_tx);

        if (geneve->mask & GENEVE_ATTR_UDP_ZERO_CSUM6_RX)
                NLA_PUT_U8(msg, IFLA_GENEVE_UDP_ZERO_CSUM6_RX, geneve->udp_zero_csum6_rx);

        if (geneve->flags & RTNL_LINK_GENEVE_F_COLLECT_METADATA)
                NLA_PUT_FLAG(msg, IFLA_GENEVE_COLLECT_METADATA);

        nla_nest_end(msg, data);

nla_put_failure:

        return 0;
}

static struct rtnl_link_info_ops geneve_info_ops = {
        .io_name        = "geneve",
        .io_alloc       = geneve_alloc,
        .io_parse       = geneve_parse,
        .io_dump        = {
                [NL_DUMP_LINE]          = geneve_dump_line,
                [NL_DUMP_DETAILS]       = geneve_dump_details,
        },
        .io_clone       = geneve_clone,
        .io_put_attrs   = geneve_put_attrs,
        .io_free        = geneve_free,
};


/** @cond SKIP */
#define IS_GENEVE_LINK_ASSERT(link) \
        if ((link)->l_info_ops != &geneve_info_ops) { \
                APPBUG("Link is not a geneve link. set type \"geneve\" first."); \
                return -NLE_OPNOTSUPP; \
        }
/** @endcond */

/**
 * @name Geneve Object
 * @{
 */

/**
 * Allocate link object of type Geneve
 *
 * @return Allocated link object or NULL.
 */
struct rtnl_link *rtnl_link_geneve_alloc(void)
{
        struct rtnl_link *link;

        if (!(link = rtnl_link_alloc()))
                return NULL;

        if (rtnl_link_set_type(link, "geneve") < 0) {
                rtnl_link_put(link);
                return NULL;
        }

        return link;
}

/**
 * Check if link is a Geneve link
 * @arg link    Link object
 *
 * @return True if link is a Geneve link, otherwisee false is returned.
 */
int rtnl_link_is_geneve(struct rtnl_link *link)
{
        return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "geneve");
}

/**
 * Set Geneve Network Indentifier
 * @arg link    Link object
 * @arg id      Geneve network identifier
 *
 * @return 0 on success or a negative error code
 */
int rtnl_link_geneve_set_id(struct rtnl_link *link, uint32_t id)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        if (id > RTNL_GENEVE_ID_MAX)
                return -NLE_INVAL;

        geneve->id = id;
        geneve->mask |= GENEVE_ATTR_ID;

        return 0;
}

/**
 * Get Geneve Network Identifier
 * @arg link    Link object
 * @arg id      Pointer to store network identifier
 *
 * @return 0 on success or a negative error code
 */
int rtnl_link_geneve_get_id(struct rtnl_link *link, uint32_t *id)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        if (!id)
                return -NLE_INVAL;

        if (geneve->mask & GENEVE_ATTR_ID)
                *id = geneve->id;
        else
                return -NLE_AGAIN;

        return 0;
}

/**
 * Set Geneve unicast destination IP address
 * @arg link    Link object
 * @arg addr    The unicast destination IP address
 *
 * @return 0 on success or a negative error code
 */
int rtnl_link_geneve_set_remote(struct rtnl_link *link, struct nl_addr *addr)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        if ((nl_addr_get_family(addr) == AF_INET) &&
                (nl_addr_get_len(addr) == sizeof(geneve->remote))) {
                memcpy(&geneve->remote, nl_addr_get_binary_addr(addr),
                                sizeof(geneve->remote));
                geneve->mask |= GENEVE_ATTR_REMOTE;
                geneve->mask &= ~GENEVE_ATTR_REMOTE6;
        } else if ((nl_addr_get_family(addr) == AF_INET6) &&
                        (nl_addr_get_len(addr) == sizeof(geneve->remote6))) {
                memcpy(&geneve->remote6, nl_addr_get_binary_addr(addr),
                                sizeof(geneve->remote6));
                geneve->mask |= GENEVE_ATTR_REMOTE6;
                geneve->mask &= ~GENEVE_ATTR_REMOTE;
        } else
                return -NLE_INVAL;

        return 0;
}

/**
 * Get Geneve unicast destination IP address
 * @arg link    Link object
 * @arg addr    Pointer to store unicast destination IP addree
 *
 * @return 0 on success or a a negative error code
 */
int rtnl_link_geneve_get_remote(struct rtnl_link *link, struct nl_addr **addr)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        if (!addr)
                return -NLE_INVAL;

        if (geneve->mask & GENEVE_ATTR_REMOTE)
                *addr = nl_addr_build(AF_INET, &geneve->remote, sizeof(geneve->remote));
        else if (geneve->mask & GENEVE_ATTR_REMOTE6)
                *addr = nl_addr_build(AF_INET6, &geneve->remote6, sizeof(geneve->remote6));
        else
                return -NLE_AGAIN;

        return 0;
}

/**
 * Set IP TTL value to use for Geneve
 * @arg link    Link object
 * @arg ttl     TTL value
 *
 * @return 0 on success or a negative error code
 */
int rtnl_link_geneve_set_ttl(struct rtnl_link *link, uint8_t ttl)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        geneve->ttl = ttl;
        geneve->mask |= GENEVE_ATTR_TTL;

        return 0;
}

/**
 * Get IP TTL value to use for Geneve
 * @arg link    Link object
 *
 * @return TTL value on success or a negative error code
 */
int rtnl_link_geneve_get_ttl(struct rtnl_link *link)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        if (!(geneve->mask & GENEVE_ATTR_TTL))
                return -NLE_AGAIN;

        return geneve->ttl;
}

/**
 * Set IP ToS value to use for Geneve
 * @arg link    Link object
 * @arg tos     ToS value
 *
 * @return 0 on success or a negative error code
 */
int rtnl_link_geneve_set_tos(struct rtnl_link *link, uint8_t tos)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        geneve->tos = tos;
        geneve->mask |= GENEVE_ATTR_TOS;

        return 0;
}

/**
 * Get IP ToS value to use for Geneve
 * @arg link    Link object
 *
 * @return ToS value on success or a negative error code
 */
int rtnl_link_geneve_get_tos(struct rtnl_link *link)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        if (!(geneve->mask & GENEVE_ATTR_TOS))
                return -NLE_AGAIN;

        return geneve->tos;
}

/**
 * Set UDP destination port to use for Geneve
 * @arg link    Link object
 * @arg port    Destination port
 *
 * @return 0 on success or a negative error code
 */

int rtnl_link_geneve_set_port(struct rtnl_link *link,  uint32_t port)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        geneve->port = htons(port);
        geneve->mask |= GENEVE_ATTR_PORT;

        return 0;
}

/**
 * Get UDP destination port to use for Geneve
 * @arg link    Link object
 * @arg port    Pointer to store destination port
 *
 * @return 0 on success or a negative error code
 */
int rtnl_link_geneve_get_port(struct rtnl_link *link, uint32_t *port)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        if (!port)
                return -NLE_INVAL;

        if (!(geneve->mask & GENEVE_ATTR_PORT))
                return -NLE_NOATTR;

        *port = ntohs(geneve->port);

        return 0;
}

/**
 * Set flow label to use for Geneve
 * @arg link    Link object
 * @arg label   Destination label
 *
 * @return 0 on success or a negative error code
 */
int rtnl_link_geneve_set_label(struct rtnl_link *link, uint32_t label)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        geneve->label = htonl(label);
        geneve->mask |= GENEVE_ATTR_LABEL;

        return 0;
}

/**
 * Get flow label to use for Geneve
 * @arg link    Link object
 * @arg label   Pointer to store destination label
 *
 * @return 0 on success or a negative error code
 */
int rtnl_link_geneve_get_label(struct rtnl_link *link, uint32_t *label)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        if (!label)
                return -NLE_INVAL;
        if (!(geneve->mask & GENEVE_ATTR_LABEL))
                return -NLE_NOATTR;

        *label = ntohl(geneve->label);

        return 0;
}

/**
 * Set UDP checksum status to use for Geneve
 * @arg link    Link object
 * @arg csum    Status value
 *
 * @return 0 on success or a negative error code
 */
int rtnl_link_geneve_set_udp_csum(struct rtnl_link *link, uint8_t csum)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        geneve->udp_csum = csum;
        geneve->mask |= GENEVE_ATTR_UDP_CSUM;

        return 0;
}

/**
 * Get UDP checksum status to use for Geneve
 * @arg link    Link object
 *
 * @return status value on success or a negative error code
 */
int rtnl_link_geneve_get_udp_csum(struct rtnl_link *link)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        if (!(geneve->mask & GENEVE_ATTR_UDP_CSUM))
                return -NLE_NOATTR;

        return geneve->udp_csum;
}

/**
 * Set skip UDP checksum transmitted over IPv6 status to use for Geneve
 * @arg link    Link object
 * @arg csum    Status value
 *
 * @return 0 on success or a negative error code
 */
int rtnl_link_geneve_set_udp_zero_csum6_tx(struct rtnl_link *link, uint8_t csum)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        geneve->udp_zero_csum6_tx = csum;
        geneve->mask |= GENEVE_ATTR_UDP_ZERO_CSUM6_TX;

        return 0;
}

/**
 * Get skip UDP checksum transmitted over IPv6 status to use for Geneve
 * @arg link    Link object
 *
 * @return Status value on success or a negative error code
 */
int rtnl_link_geneve_get_udp_zero_csum6_tx(struct rtnl_link *link)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        if (!(geneve->mask & GENEVE_ATTR_UDP_ZERO_CSUM6_TX))
                return -NLE_NOATTR;

        return geneve->udp_zero_csum6_tx;
}

/**
 * Set skip UDP checksum received over IPv6 status to use for Geneve
 * @arg link    Link object
 * @arg csum    Status value
 *
 * @return 0 on success or a negative error code
 */
int rtnl_link_geneve_set_udp_zero_csum6_rx(struct rtnl_link *link, uint8_t csum)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        geneve->udp_zero_csum6_rx = csum;
        geneve->mask |= GENEVE_ATTR_UDP_ZERO_CSUM6_RX;

        return 0;
}

/**
 * Get skip UDP checksum received over IPv6  status to use for Geneve
 * @arg link    Link object
 *
 * @return Status value on success or a negative error code
 */
int rtnl_link_geneve_get_udp_zero_csum6_rx(struct rtnl_link *link)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        if (!(geneve->mask & GENEVE_ATTR_UDP_ZERO_CSUM6_RX))
                return -NLE_NOATTR;

        return geneve->udp_zero_csum6_rx;
}

/**
 * Set Geneve flags
 * @arg link    Link object
 * @arg flags   Which flags to set
 * @arg enable  Boolean enabling or disabling flag
 *
 * @return 0 on success or a negative error code
 */
int rtnl_link_geneve_set_flags(struct rtnl_link *link, uint8_t flags, int enable)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        if (flags & ~RTNL_LINK_GENEVE_F_COLLECT_METADATA)
                return -NLE_INVAL;

        if (enable)
                geneve->flags = flags;
        else
                geneve->flags &= ~flags;

        return 0;
}

/**
 * Get Geneve flags
 * @arg link    Link object
 * @arg flags   Pointer to store flags
 *
 * @return 0 on success or a negative error code
 */
int rtnl_link_geneve_get_flags(struct rtnl_link *link, uint8_t *flags)
{
        struct geneve_info *geneve = link->l_info;

        IS_GENEVE_LINK_ASSERT(link);

        *flags = geneve->flags;
        return 0;
}

/** @} */
static void _nl_init geneve_init(void)
{
        rtnl_link_register_info(&geneve_info_ops);
}

static void _nl_exit geneve_exit(void)
{
        rtnl_link_unregister_info(&geneve_info_ops);
}

/** @} */
