/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include <errno.h>
#include <net/if.h>
#include <linux/if_arp.h>
#include <linux/if_vlan.h>

#include "parse-util.h"
#include "vlan-util.h"
#include "vlan.h"

static int netdev_vlan_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *req) {
        struct ifla_vlan_flags flags = {};
        VLan *v;
        int r;

        assert(netdev);
        assert(link);
        assert(req);

        v = VLAN(netdev);

        assert(v);

        r = sd_netlink_message_append_u16(req, IFLA_VLAN_ID, v->id);
        if (r < 0)
                return r;

        if (v->protocol >= 0) {
                r = sd_netlink_message_append_u16(req, IFLA_VLAN_PROTOCOL, htobe16(v->protocol));
                if (r < 0)
                        return r;
        }

        if (v->gvrp != -1) {
                flags.mask |= VLAN_FLAG_GVRP;
                SET_FLAG(flags.flags, VLAN_FLAG_GVRP, v->gvrp);
        }

        if (v->mvrp != -1) {
                flags.mask |= VLAN_FLAG_MVRP;
                SET_FLAG(flags.flags, VLAN_FLAG_MVRP, v->mvrp);
        }

        if (v->reorder_hdr != -1) {
                flags.mask |= VLAN_FLAG_REORDER_HDR;
                SET_FLAG(flags.flags, VLAN_FLAG_REORDER_HDR, v->reorder_hdr);
        }

        if (v->loose_binding != -1) {
                flags.mask |= VLAN_FLAG_LOOSE_BINDING;
                SET_FLAG(flags.flags, VLAN_FLAG_LOOSE_BINDING, v->loose_binding);
        }

        r = sd_netlink_message_append_data(req, IFLA_VLAN_FLAGS, &flags, sizeof(struct ifla_vlan_flags));
        if (r < 0)
                return r;

        if (!set_isempty(v->egress_qos_maps)) {
                struct ifla_vlan_qos_mapping *m;

                r = sd_netlink_message_open_container(req, IFLA_VLAN_EGRESS_QOS);
                if (r < 0)
                        return r;

                SET_FOREACH(m, v->egress_qos_maps) {
                        r = sd_netlink_message_append_data(req, IFLA_VLAN_QOS_MAPPING, m, sizeof(struct ifla_vlan_qos_mapping));
                        if (r < 0)
                                return r;
                }

                r = sd_netlink_message_close_container(req);
                if (r < 0)
                        return r;
        }

        if (!set_isempty(v->ingress_qos_maps)) {
                struct ifla_vlan_qos_mapping *m;

                r = sd_netlink_message_open_container(req, IFLA_VLAN_INGRESS_QOS);
                if (r < 0)
                        return r;

                SET_FOREACH(m, v->ingress_qos_maps) {
                        r = sd_netlink_message_append_data(req, IFLA_VLAN_QOS_MAPPING, m, sizeof(struct ifla_vlan_qos_mapping));
                        if (r < 0)
                                return r;
                }

                r = sd_netlink_message_close_container(req);
                if (r < 0)
                        return r;
        }

        return 0;
}

static void vlan_qos_maps_hash_func(const struct ifla_vlan_qos_mapping *x, struct siphash *state) {
        siphash24_compress(&x->from, sizeof(x->from), state);
        siphash24_compress(&x->to, sizeof(x->to), state);
}

static int vlan_qos_maps_compare_func(const struct ifla_vlan_qos_mapping *a, const struct ifla_vlan_qos_mapping *b) {
        int r;

        r = CMP(a->from, b->from);
        if (r != 0)
                return r;

        return CMP(a->to, b->to);
}

DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
                vlan_qos_maps_hash_ops,
                struct ifla_vlan_qos_mapping,
                vlan_qos_maps_hash_func,
                vlan_qos_maps_compare_func,
                free);

int config_parse_vlan_qos_maps(
                const char *unit,
                const char *filename,
                unsigned line,
                const char *section,
                unsigned section_line,
                const char *lvalue,
                int ltype,
                const char *rvalue,
                void *data,
                void *userdata) {

        Set **s = ASSERT_PTR(data);
        int r;

        assert(filename);
        assert(lvalue);
        assert(rvalue);

        if (isempty(rvalue)) {
                *s = set_free(*s);
                return 0;
        }

        for (const char *p = rvalue;;) {
                _cleanup_free_ struct ifla_vlan_qos_mapping *m = NULL;
                _cleanup_free_ char *w = NULL;

                r = extract_first_word(&p, &w, NULL, EXTRACT_CUNESCAPE|EXTRACT_UNQUOTE);
                if (r == -ENOMEM)
                        return log_oom();
                if (r < 0) {
                        log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse %s, ignoring: %s", lvalue, rvalue);
                        return 0;
                }
                if (r == 0)
                        return 0;

                m = new0(struct ifla_vlan_qos_mapping, 1);
                if (!m)
                        return log_oom();

                r = parse_range(w, &m->from, &m->to);
                if (r < 0) {
                        log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse %s, ignoring: %s", lvalue, w);
                        continue;
                }

                if (m->to > m->from || m->to == 0 || m->from == 0) {
                        log_syntax(unit, LOG_WARNING, filename, line, 0, "Invalid %s, ignoring: %s", lvalue, w);
                        continue;
                }

                r = set_ensure_consume(s, &vlan_qos_maps_hash_ops, TAKE_PTR(m));
                if (r < 0) {
                        log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to store %s, ignoring: %s", lvalue, w);
                        continue;
                }
        }
}

static int netdev_vlan_verify(NetDev *netdev, const char *filename) {
        VLan *v;

        assert(netdev);
        assert(filename);

        v = VLAN(netdev);

        assert(v);

        if (v->id == VLANID_INVALID) {
                log_netdev_warning(netdev, "VLAN without valid Id (%"PRIu16") configured in %s.", v->id, filename);
                return -EINVAL;
        }

        return 0;
}

static void vlan_done(NetDev *n) {
        VLan *v;

        v = VLAN(n);

        assert(v);

        set_free(v->egress_qos_maps);
        set_free(v->ingress_qos_maps);
}

static void vlan_init(NetDev *netdev) {
        VLan *v = VLAN(netdev);

        assert(netdev);
        assert(v);

        v->id = VLANID_INVALID;
        v->protocol = -1;
        v->gvrp = -1;
        v->mvrp = -1;
        v->loose_binding = -1;
        v->reorder_hdr = -1;
}

const NetDevVTable vlan_vtable = {
        .object_size = sizeof(VLan),
        .init = vlan_init,
        .sections = NETDEV_COMMON_SECTIONS "VLAN\0",
        .fill_message_create = netdev_vlan_fill_message_create,
        .create_type = NETDEV_CREATE_STACKED,
        .config_verify = netdev_vlan_verify,
        .done = vlan_done,
        .iftype = ARPHRD_ETHER,
};
