/* SPDX-License-Identifier: LGPL-2.1-or-later
 * Copyright © 2019 VMware, Inc. */

#include <linux/pkt_sched.h>

#include "alloc-util.h"
#include "conf-parser.h"
#include "in-addr-util.h"
#include "netlink-util.h"
#include "networkd-link.h"
#include "networkd-manager.h"
#include "networkd-network.h"
#include "networkd-queue.h"
#include "parse-util.h"
#include "qdisc.h"
#include "set.h"
#include "string-util.h"
#include "strv.h"
#include "tc-util.h"

const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX] = {
        [QDISC_KIND_BFIFO] = &bfifo_vtable,
        [QDISC_KIND_CAKE] = &cake_vtable,
        [QDISC_KIND_CODEL] = &codel_vtable,
        [QDISC_KIND_DRR] = &drr_vtable,
        [QDISC_KIND_ETS] = &ets_vtable,
        [QDISC_KIND_FQ] = &fq_vtable,
        [QDISC_KIND_FQ_CODEL] = &fq_codel_vtable,
        [QDISC_KIND_FQ_PIE] = &fq_pie_vtable,
        [QDISC_KIND_GRED] = &gred_vtable,
        [QDISC_KIND_HHF] = &hhf_vtable,
        [QDISC_KIND_HTB] = &htb_vtable,
        [QDISC_KIND_NETEM] = &netem_vtable,
        [QDISC_KIND_PIE] = &pie_vtable,
        [QDISC_KIND_QFQ] = &qfq_vtable,
        [QDISC_KIND_PFIFO] = &pfifo_vtable,
        [QDISC_KIND_PFIFO_FAST] = &pfifo_fast_vtable,
        [QDISC_KIND_PFIFO_HEAD_DROP] = &pfifo_head_drop_vtable,
        [QDISC_KIND_SFB] = &sfb_vtable,
        [QDISC_KIND_SFQ] = &sfq_vtable,
        [QDISC_KIND_TBF] = &tbf_vtable,
        [QDISC_KIND_TEQL] = &teql_vtable,
};

static int qdisc_new(QDiscKind kind, QDisc **ret) {
        _cleanup_(qdisc_freep) QDisc *qdisc = NULL;
        int r;

        if (kind == _QDISC_KIND_INVALID) {
                qdisc = new(QDisc, 1);
                if (!qdisc)
                        return -ENOMEM;

                *qdisc = (QDisc) {
                        .parent = TC_H_ROOT,
                        .kind = kind,
                };
        } else {
                assert(kind >= 0 && kind < _QDISC_KIND_MAX);
                qdisc = malloc0(qdisc_vtable[kind]->object_size);
                if (!qdisc)
                        return -ENOMEM;

                qdisc->parent = TC_H_ROOT;
                qdisc->kind = kind;

                if (QDISC_VTABLE(qdisc)->init) {
                        r = QDISC_VTABLE(qdisc)->init(qdisc);
                        if (r < 0)
                                return r;
                }
        }

        *ret = TAKE_PTR(qdisc);

        return 0;
}

int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, unsigned section_line, QDisc **ret) {
        _cleanup_(config_section_freep) ConfigSection *n = NULL;
        _cleanup_(qdisc_freep) QDisc *qdisc = NULL;
        QDisc *existing;
        int r;

        assert(network);
        assert(ret);
        assert(filename);
        assert(section_line > 0);

        r = config_section_new(filename, section_line, &n);
        if (r < 0)
                return r;

        existing = hashmap_get(network->qdiscs_by_section, n);
        if (existing) {
                if (existing->kind != _QDISC_KIND_INVALID &&
                    kind != _QDISC_KIND_INVALID &&
                    existing->kind != kind)
                        return -EINVAL;

                if (existing->kind == kind || kind == _QDISC_KIND_INVALID) {
                        *ret = existing;
                        return 0;
                }
        }

        r = qdisc_new(kind, &qdisc);
        if (r < 0)
                return r;

        if (existing) {
                qdisc->handle = existing->handle;
                qdisc->parent = existing->parent;
                qdisc->tca_kind = TAKE_PTR(existing->tca_kind);

                qdisc_free(existing);
        }

        qdisc->network = network;
        qdisc->section = TAKE_PTR(n);
        qdisc->source = NETWORK_CONFIG_SOURCE_STATIC;

        r = hashmap_ensure_put(&network->qdiscs_by_section, &config_section_hash_ops, qdisc->section, qdisc);
        if (r < 0)
                return r;

        *ret = TAKE_PTR(qdisc);
        return 0;
}

QDisc* qdisc_free(QDisc *qdisc) {
        if (!qdisc)
                return NULL;

        if (qdisc->network && qdisc->section)
                hashmap_remove(qdisc->network->qdiscs_by_section, qdisc->section);

        config_section_free(qdisc->section);

        if (qdisc->link)
                set_remove(qdisc->link->qdiscs, qdisc);

        free(qdisc->tca_kind);
        return mfree(qdisc);
}

static const char *qdisc_get_tca_kind(const QDisc *qdisc) {
        assert(qdisc);

        return (QDISC_VTABLE(qdisc) && QDISC_VTABLE(qdisc)->tca_kind) ?
                QDISC_VTABLE(qdisc)->tca_kind : qdisc->tca_kind;
}

static void qdisc_hash_func(const QDisc *qdisc, struct siphash *state) {
        assert(qdisc);
        assert(state);

        siphash24_compress(&qdisc->handle, sizeof(qdisc->handle), state);
        siphash24_compress(&qdisc->parent, sizeof(qdisc->parent), state);
        siphash24_compress_string(qdisc_get_tca_kind(qdisc), state);
}

static int qdisc_compare_func(const QDisc *a, const QDisc *b) {
        int r;

        assert(a);
        assert(b);

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

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

        return strcmp_ptr(qdisc_get_tca_kind(a), qdisc_get_tca_kind(b));
}

DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
        qdisc_hash_ops,
        QDisc,
        qdisc_hash_func,
        qdisc_compare_func,
        qdisc_free);

static int qdisc_get(Link *link, const QDisc *in, QDisc **ret) {
        QDisc *existing;

        assert(link);
        assert(in);

        existing = set_get(link->qdiscs, in);
        if (!existing)
                return -ENOENT;

        if (ret)
                *ret = existing;
        return 0;
}

static int qdisc_add(Link *link, QDisc *qdisc) {
        int r;

        assert(link);
        assert(qdisc);

        r = set_ensure_put(&link->qdiscs, &qdisc_hash_ops, qdisc);
        if (r < 0)
                return r;
        if (r == 0)
                return -EEXIST;

        qdisc->link = link;
        return 0;
}

static int qdisc_dup(const QDisc *src, QDisc **ret) {
        _cleanup_(qdisc_freep) QDisc *dst = NULL;

        assert(src);
        assert(ret);

        if (QDISC_VTABLE(src))
                dst = memdup(src, QDISC_VTABLE(src)->object_size);
        else
                dst = newdup(QDisc, src, 1);
        if (!dst)
                return -ENOMEM;

        /* clear all pointers */
        dst->network = NULL;
        dst->section = NULL;
        dst->link = NULL;
        dst->tca_kind = NULL;

        if (src->tca_kind) {
                dst->tca_kind = strdup(src->tca_kind);
                if (!dst->tca_kind)
                        return -ENOMEM;
        }

        *ret = TAKE_PTR(dst);
        return 0;
}

static void log_qdisc_debug(QDisc *qdisc, Link *link, const char *str) {
        _cleanup_free_ char *state = NULL;

        assert(qdisc);
        assert(str);

        if (!DEBUG_LOGGING)
                return;

        (void) network_config_state_to_string_alloc(qdisc->state, &state);

        log_link_debug(link, "%s %s QDisc (%s): handle=%"PRIx32":%"PRIx32", parent=%"PRIx32":%"PRIx32", kind=%s",
                       str, strna(network_config_source_to_string(qdisc->source)), strna(state),
                       TC_H_MAJ(qdisc->handle) >> 16, TC_H_MIN(qdisc->handle),
                       TC_H_MAJ(qdisc->parent) >> 16, TC_H_MIN(qdisc->parent),
                       strna(qdisc_get_tca_kind(qdisc)));
}

int link_find_qdisc(Link *link, uint32_t handle, uint32_t parent, const char *kind, QDisc **ret) {
        QDisc *qdisc;

        assert(link);

        handle = TC_H_MAJ(handle);

        SET_FOREACH(qdisc, link->qdiscs) {
                if (qdisc->handle != handle)
                        continue;

                if (qdisc->parent != parent)
                        continue;

                if (qdisc->source == NETWORK_CONFIG_SOURCE_FOREIGN)
                        continue;

                if (!qdisc_exists(qdisc))
                        continue;

                if (kind && !streq_ptr(kind, qdisc_get_tca_kind(qdisc)))
                        continue;

                if (ret)
                        *ret = qdisc;
                return 0;
        }

        return -ENOENT;
}

static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, QDisc *qdisc) {
        int r;

        assert(m);
        assert(link);

        r = sd_netlink_message_get_errno(m);
        if (r < 0 && r != -EEXIST) {
                log_link_message_error_errno(link, m, r, "Could not set QDisc");
                link_enter_failed(link);
                return 1;
        }

        if (link->tc_messages == 0) {
                log_link_debug(link, "Traffic control configured");
                link->tc_configured = true;
                link_check_ready(link);
        }

        return 1;
}

static int qdisc_configure(QDisc *qdisc, Link *link, Request *req) {
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
        int r;

        assert(qdisc);
        assert(link);
        assert(link->manager);
        assert(link->manager->rtnl);
        assert(link->ifindex > 0);
        assert(req);

        log_qdisc_debug(qdisc, link, "Configuring");

        r = sd_rtnl_message_new_traffic_control(link->manager->rtnl, &m, RTM_NEWQDISC,
                                                link->ifindex, qdisc->handle, qdisc->parent);
        if (r < 0)
                return r;

        r = sd_netlink_message_append_string(m, TCA_KIND, qdisc_get_tca_kind(qdisc));
        if (r < 0)
                return r;

        if (QDISC_VTABLE(qdisc) && QDISC_VTABLE(qdisc)->fill_message) {
                r = QDISC_VTABLE(qdisc)->fill_message(link, qdisc, m);
                if (r < 0)
                        return r;
        }

        return request_call_netlink_async(link->manager->rtnl, m, req);
}

static bool qdisc_is_ready_to_configure(QDisc *qdisc, Link *link) {
        assert(qdisc);
        assert(link);

        if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
                return false;

        /* TC_H_CLSACT == TC_H_INGRESS */
        if (!IN_SET(qdisc->parent, TC_H_ROOT, TC_H_CLSACT) &&
            link_find_tclass(link, qdisc->parent, NULL) < 0)
                return false;

        if (QDISC_VTABLE(qdisc) &&
            QDISC_VTABLE(qdisc)->is_ready &&
            QDISC_VTABLE(qdisc)->is_ready(qdisc, link) <= 0)
                return false;

        return true;
}

static int qdisc_process_request(Request *req, Link *link, QDisc *qdisc) {
        int r;

        assert(req);
        assert(link);
        assert(qdisc);

        if (!qdisc_is_ready_to_configure(qdisc, link))
                return 0;

        r = qdisc_configure(qdisc, link, req);
        if (r < 0)
                return log_link_warning_errno(link, r, "Failed to configure QDisc: %m");

        qdisc_enter_configuring(qdisc);
        return 1;
}

int link_request_qdisc(Link *link, QDisc *qdisc) {
        QDisc *existing;
        int r;

        assert(link);
        assert(qdisc);

        if (qdisc_get(link, qdisc, &existing) < 0) {
                _cleanup_(qdisc_freep) QDisc *tmp = NULL;

                r = qdisc_dup(qdisc, &tmp);
                if (r < 0)
                        return log_oom();

                r = qdisc_add(link, tmp);
                if (r < 0)
                        return log_link_warning_errno(link, r, "Failed to store QDisc: %m");

                existing = TAKE_PTR(tmp);
        } else
                existing->source = qdisc->source;

        log_qdisc_debug(existing, link, "Requesting");
        r = link_queue_request_safe(link, REQUEST_TYPE_TC_QDISC,
                                    existing, NULL,
                                    qdisc_hash_func,
                                    qdisc_compare_func,
                                    qdisc_process_request,
                                    &link->tc_messages,
                                    qdisc_handler,
                                    NULL);
        if (r < 0)
                return log_link_warning_errno(link, r, "Failed to request QDisc: %m");
        if (r == 0)
                return 0;

        qdisc_enter_requesting(existing);
        return 1;
}

int manager_rtnl_process_qdisc(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) {
        _cleanup_(qdisc_freep) QDisc *tmp = NULL;
        QDisc *qdisc = NULL;
        Link *link;
        uint16_t type;
        int ifindex, r;

        assert(rtnl);
        assert(message);
        assert(m);

        if (sd_netlink_message_is_error(message)) {
                r = sd_netlink_message_get_errno(message);
                if (r < 0)
                        log_message_warning_errno(message, r, "rtnl: failed to receive QDisc message, ignoring");

                return 0;
        }

        r = sd_netlink_message_get_type(message, &type);
        if (r < 0) {
                log_warning_errno(r, "rtnl: could not get message type, ignoring: %m");
                return 0;
        } else if (!IN_SET(type, RTM_NEWQDISC, RTM_DELQDISC)) {
                log_warning("rtnl: received unexpected message type %u when processing QDisc, ignoring.", type);
                return 0;
        }

        r = sd_rtnl_message_traffic_control_get_ifindex(message, &ifindex);
        if (r < 0) {
                log_warning_errno(r, "rtnl: could not get ifindex from message, ignoring: %m");
                return 0;
        } else if (ifindex <= 0) {
                log_warning("rtnl: received QDisc message with invalid ifindex %d, ignoring.", ifindex);
                return 0;
        }

        if (link_get_by_index(m, ifindex, &link) < 0) {
                if (!m->enumerating)
                        log_warning("rtnl: received QDisc for link '%d' we don't know about, ignoring.", ifindex);
                return 0;
        }

        r = qdisc_new(_QDISC_KIND_INVALID, &tmp);
        if (r < 0)
                return log_oom();

        r = sd_rtnl_message_traffic_control_get_handle(message, &tmp->handle);
        if (r < 0) {
                log_link_warning_errno(link, r, "rtnl: received QDisc message without handle, ignoring: %m");
                return 0;
        }

        r = sd_rtnl_message_traffic_control_get_parent(message, &tmp->parent);
        if (r < 0) {
                log_link_warning_errno(link, r, "rtnl: received QDisc message without parent, ignoring: %m");
                return 0;
        }

        r = sd_netlink_message_read_string_strdup(message, TCA_KIND, &tmp->tca_kind);
        if (r < 0) {
                log_link_warning_errno(link, r, "rtnl: received QDisc message without kind, ignoring: %m");
                return 0;
        }

        (void) qdisc_get(link, tmp, &qdisc);

        switch (type) {
        case RTM_NEWQDISC:
                if (qdisc) {
                        qdisc_enter_configured(qdisc);
                        log_qdisc_debug(qdisc, link, "Received remembered");
                } else {
                        qdisc_enter_configured(tmp);
                        log_qdisc_debug(tmp, link, "Received new");

                        r = qdisc_add(link, tmp);
                        if (r < 0) {
                                log_link_warning_errno(link, r, "Failed to remember QDisc, ignoring: %m");
                                return 0;
                        }

                        qdisc = TAKE_PTR(tmp);
                }

                break;

        case RTM_DELQDISC:
                if (qdisc) {
                        qdisc_enter_removed(qdisc);
                        if (qdisc->state == 0) {
                                log_qdisc_debug(qdisc, link, "Forgetting");
                                qdisc_free(qdisc);
                        } else
                                log_qdisc_debug(qdisc, link, "Removed");
                } else
                        log_qdisc_debug(tmp, link, "Kernel removed unknown");

                break;

        default:
                assert_not_reached();
        }

        return 1;
}

static int qdisc_section_verify(QDisc *qdisc, bool *has_root, bool *has_clsact) {
        int r;

        assert(qdisc);
        assert(has_root);
        assert(has_clsact);

        if (section_is_invalid(qdisc->section))
                return -EINVAL;

        if (QDISC_VTABLE(qdisc) && QDISC_VTABLE(qdisc)->verify) {
                r = QDISC_VTABLE(qdisc)->verify(qdisc);
                if (r < 0)
                        return r;
        }

        if (qdisc->parent == TC_H_ROOT) {
                if (*has_root)
                        return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
                                                 "%s: More than one root qdisc section is defined. "
                                                 "Ignoring the qdisc section from line %u.",
                                                 qdisc->section->filename, qdisc->section->line);
                *has_root = true;
        } else if (qdisc->parent == TC_H_CLSACT) { /* TC_H_CLSACT == TC_H_INGRESS */
                if (*has_clsact)
                        return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
                                                 "%s: More than one clsact or ingress qdisc section is defined. "
                                                 "Ignoring the qdisc section from line %u.",
                                                 qdisc->section->filename, qdisc->section->line);
                *has_clsact = true;
        }

        return 0;
}

void network_drop_invalid_qdisc(Network *network) {
        bool has_root = false, has_clsact = false;
        QDisc *qdisc;

        assert(network);

        HASHMAP_FOREACH(qdisc, network->qdiscs_by_section)
                if (qdisc_section_verify(qdisc, &has_root, &has_clsact) < 0)
                        qdisc_free(qdisc);
}

int config_parse_qdisc_parent(
                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) {

        _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
        Network *network = ASSERT_PTR(data);
        int r;

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

        r = qdisc_new_static(ltype, network, filename, section_line, &qdisc);
        if (r == -ENOMEM)
                return log_oom();
        if (r < 0) {
                log_syntax(unit, LOG_WARNING, filename, line, r,
                           "More than one kind of queueing discipline, ignoring assignment: %m");
                return 0;
        }

        if (streq(rvalue, "root"))
                qdisc->parent = TC_H_ROOT;
        else if (streq(rvalue, "clsact")) {
                qdisc->parent = TC_H_CLSACT;
                qdisc->handle = TC_H_MAKE(TC_H_CLSACT, 0);
        } else if (streq(rvalue, "ingress")) {
                qdisc->parent = TC_H_INGRESS;
                qdisc->handle = TC_H_MAKE(TC_H_INGRESS, 0);
        } else {
                r = parse_handle(rvalue, &qdisc->parent);
                if (r < 0) {
                        log_syntax(unit, LOG_WARNING, filename, line, r,
                                   "Failed to parse 'Parent=', ignoring assignment: %s",
                                   rvalue);
                        return 0;
                }
        }

        if (STR_IN_SET(rvalue, "clsact", "ingress")) {
                r = free_and_strdup(&qdisc->tca_kind, rvalue);
                if (r < 0)
                        return log_oom();
        } else
                qdisc->tca_kind = mfree(qdisc->tca_kind);

        TAKE_PTR(qdisc);

        return 0;
}

int config_parse_qdisc_handle(
                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) {

        _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
        Network *network = ASSERT_PTR(data);
        uint16_t n;
        int r;

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

        r = qdisc_new_static(ltype, network, filename, section_line, &qdisc);
        if (r == -ENOMEM)
                return log_oom();
        if (r < 0) {
                log_syntax(unit, LOG_WARNING, filename, line, r,
                           "More than one kind of queueing discipline, ignoring assignment: %m");
                return 0;
        }

        if (isempty(rvalue)) {
                qdisc->handle = TC_H_UNSPEC;
                TAKE_PTR(qdisc);
                return 0;
        }

        r = safe_atou16_full(rvalue, 16, &n);
        if (r < 0) {
                log_syntax(unit, LOG_WARNING, filename, line, r,
                           "Failed to parse 'Handle=', ignoring assignment: %s",
                           rvalue);
                return 0;
        }

        qdisc->handle = (uint32_t) n << 16;
        TAKE_PTR(qdisc);

        return 0;
}
