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

#include "sd-netlink.h"

#include "format-util.h"
#include "memory-util.h"
#include "netlink-internal.h"
#include "netlink-util.h"
#include "parse-util.h"
#include "strv.h"

int rtnl_set_link_name(sd_netlink **rtnl, int ifindex, const char *name) {
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
        _cleanup_strv_free_ char **alternative_names = NULL;
        char old_name[IF_NAMESIZE + 1] = {};
        int r;

        assert(rtnl);
        assert(ifindex > 0);
        assert(name);

        if (!ifname_valid(name))
                return -EINVAL;

        r = rtnl_get_link_alternative_names(rtnl, ifindex, &alternative_names);
        if (r < 0)
                log_debug_errno(r, "Failed to get alternative names on network interface %i, ignoring: %m",
                                ifindex);

        if (strv_contains(alternative_names, name)) {
                r = rtnl_delete_link_alternative_names(rtnl, ifindex, STRV_MAKE(name));
                if (r < 0)
                        return log_debug_errno(r, "Failed to remove '%s' from alternative names on network interface %i: %m",
                                               name, ifindex);

                format_ifname(ifindex, old_name);
        }

        r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex);
        if (r < 0)
                return r;

        r = sd_netlink_message_append_string(message, IFLA_IFNAME, name);
        if (r < 0)
                return r;

        r = sd_netlink_call(*rtnl, message, 0, NULL);
        if (r < 0)
                return r;

        if (!isempty(old_name)) {
                r = rtnl_set_link_alternative_names(rtnl, ifindex, STRV_MAKE(old_name));
                if (r < 0)
                        log_debug_errno(r, "Failed to set '%s' as an alternative name on network interface %i, ignoring: %m",
                                        old_name, ifindex);
        }

        return 0;
}

int rtnl_set_link_properties(
                sd_netlink **rtnl,
                int ifindex,
                const char *alias,
                const struct ether_addr *mac,
                uint32_t txqueues,
                uint32_t rxqueues,
                uint32_t txqueuelen,
                uint32_t mtu,
                uint32_t gso_max_size,
                size_t gso_max_segments) {
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
        int r;

        assert(rtnl);
        assert(ifindex > 0);

        if (!alias && !mac && txqueues == 0 && rxqueues == 0 && txqueuelen == UINT32_MAX && mtu == 0 &&
            gso_max_size == 0 && gso_max_segments == 0)
                return 0;

        if (!*rtnl) {
                r = sd_netlink_open(rtnl);
                if (r < 0)
                        return r;
        }

        r = sd_rtnl_message_new_link(*rtnl, &message, RTM_SETLINK, ifindex);
        if (r < 0)
                return r;

        if (alias) {
                r = sd_netlink_message_append_string(message, IFLA_IFALIAS, alias);
                if (r < 0)
                        return r;
        }

        if (mac) {
                r = sd_netlink_message_append_ether_addr(message, IFLA_ADDRESS, mac);
                if (r < 0)
                        return r;
        }

        if (txqueues > 0) {
                r = sd_netlink_message_append_u32(message, IFLA_NUM_TX_QUEUES, txqueues);
                if (r < 0)
                        return r;
        }

        if (rxqueues > 0) {
                r = sd_netlink_message_append_u32(message, IFLA_NUM_RX_QUEUES, rxqueues);
                if (r < 0)
                        return r;
        }

        if (txqueuelen < UINT32_MAX) {
                r = sd_netlink_message_append_u32(message, IFLA_TXQLEN, txqueuelen);
                if (r < 0)
                        return r;
        }

        if (mtu != 0) {
                r = sd_netlink_message_append_u32(message, IFLA_MTU, mtu);
                if (r < 0)
                        return r;
        }

        if (gso_max_size > 0) {
                r = sd_netlink_message_append_u32(message, IFLA_GSO_MAX_SIZE, gso_max_size);
                if (r < 0)
                        return r;
        }

        if (gso_max_segments > 0) {
                r = sd_netlink_message_append_u32(message, IFLA_GSO_MAX_SEGS, gso_max_segments);
                if (r < 0)
                        return r;
        }

        r = sd_netlink_call(*rtnl, message, 0, NULL);
        if (r < 0)
                return r;

        return 0;
}

int rtnl_get_link_alternative_names(sd_netlink **rtnl, int ifindex, char ***ret) {
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL;
        _cleanup_strv_free_ char **names = NULL;
        int r;

        assert(rtnl);
        assert(ifindex > 0);
        assert(ret);

        if (!*rtnl) {
                r = sd_netlink_open(rtnl);
                if (r < 0)
                        return r;
        }

        r = sd_rtnl_message_new_link(*rtnl, &message, RTM_GETLINK, ifindex);
        if (r < 0)
                return r;

        r = sd_netlink_call(*rtnl, message, 0, &reply);
        if (r < 0)
                return r;

        r = sd_netlink_message_read_strv(reply, IFLA_PROP_LIST, IFLA_ALT_IFNAME, &names);
        if (r < 0 && r != -ENODATA)
                return r;

        *ret = TAKE_PTR(names);

        return 0;
}

static int rtnl_update_link_alternative_names(sd_netlink **rtnl, uint16_t nlmsg_type, int ifindex, char * const *alternative_names) {
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
        int r;

        assert(rtnl);
        assert(ifindex > 0);
        assert(IN_SET(nlmsg_type, RTM_NEWLINKPROP, RTM_DELLINKPROP));

        if (strv_isempty(alternative_names))
                return 0;

        if (!*rtnl) {
                r = sd_netlink_open(rtnl);
                if (r < 0)
                        return r;
        }

        r = sd_rtnl_message_new_link(*rtnl, &message, nlmsg_type, ifindex);
        if (r < 0)
                return r;

        r = sd_netlink_message_open_container(message, IFLA_PROP_LIST);
        if (r < 0)
                return r;

        r = sd_netlink_message_append_strv(message, IFLA_ALT_IFNAME, alternative_names);
        if (r < 0)
                return r;

        r = sd_netlink_message_close_container(message);
        if (r < 0)
                return r;

        r = sd_netlink_call(*rtnl, message, 0, NULL);
        if (r < 0)
                return r;

        return 0;
}

int rtnl_set_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names) {
        return rtnl_update_link_alternative_names(rtnl, RTM_NEWLINKPROP, ifindex, alternative_names);
}

int rtnl_delete_link_alternative_names(sd_netlink **rtnl, int ifindex, char * const *alternative_names) {
        return rtnl_update_link_alternative_names(rtnl, RTM_DELLINKPROP, ifindex, alternative_names);
}

int rtnl_set_link_alternative_names_by_ifname(sd_netlink **rtnl, const char *ifname, char * const *alternative_names) {
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL;
        int r;

        assert(rtnl);
        assert(ifname);

        if (strv_isempty(alternative_names))
                return 0;

        if (!*rtnl) {
                r = sd_netlink_open(rtnl);
                if (r < 0)
                        return r;
        }

        r = sd_rtnl_message_new_link(*rtnl, &message, RTM_NEWLINKPROP, 0);
        if (r < 0)
                return r;

        r = sd_netlink_message_append_string(message, IFLA_IFNAME, ifname);
        if (r < 0)
                return r;

        r = sd_netlink_message_open_container(message, IFLA_PROP_LIST);
        if (r < 0)
                return r;

        r = sd_netlink_message_append_strv(message, IFLA_ALT_IFNAME, alternative_names);
        if (r < 0)
                return r;

        r = sd_netlink_message_close_container(message);
        if (r < 0)
                return r;

        r = sd_netlink_call(*rtnl, message, 0, NULL);
        if (r < 0)
                return r;

        return 0;
}

int rtnl_resolve_link_alternative_name(sd_netlink **rtnl, const char *name, char **ret) {
        _cleanup_(sd_netlink_unrefp) sd_netlink *our_rtnl = NULL;
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL;
        int r, ifindex;

        assert(name);

        /* This returns ifindex and the main interface name. */

        if (!ifname_valid_full(name, IFNAME_VALID_ALTERNATIVE))
                return -EINVAL;

        if (!rtnl)
                rtnl = &our_rtnl;
        if (!*rtnl) {
                r = sd_netlink_open(rtnl);
                if (r < 0)
                        return r;
        }

        r = sd_rtnl_message_new_link(*rtnl, &message, RTM_GETLINK, 0);
        if (r < 0)
                return r;

        r = sd_netlink_message_append_string(message, IFLA_ALT_IFNAME, name);
        if (r < 0)
                return r;

        r = sd_netlink_call(*rtnl, message, 0, &reply);
        if (r == -EINVAL)
                return -ENODEV; /* The device doesn't exist */
        if (r < 0)
                return r;

        r = sd_rtnl_message_link_get_ifindex(reply, &ifindex);
        if (r < 0)
                return r;
        assert(ifindex > 0);

        if (ret) {
                r = sd_netlink_message_read_string_strdup(message, IFLA_IFNAME, ret);
                if (r < 0)
                        return r;
        }

        return ifindex;
}

int rtnl_resolve_ifname(sd_netlink **rtnl, const char *name) {
        int r;

        /* Like if_nametoindex, but resolves "alternative names" too. */

        assert(name);

        r = if_nametoindex(name);
        if (r > 0)
                return r;

        return rtnl_resolve_link_alternative_name(rtnl, name, NULL);
}

int rtnl_resolve_interface(sd_netlink **rtnl, const char *name) {
        int r;

        /* Like rtnl_resolve_ifname, but resolves interface numbers too. */

        assert(name);

        r = parse_ifindex(name);
        if (r > 0)
                return r;
        assert(r < 0);

        return rtnl_resolve_ifname(rtnl, name);
}

int rtnl_resolve_interface_or_warn(sd_netlink **rtnl, const char *name) {
        int r;

        r = rtnl_resolve_interface(rtnl, name);
        if (r < 0)
                return log_error_errno(r, "Failed to resolve interface \"%s\": %m", name);
        return r;
}

int rtnl_get_link_info(sd_netlink **rtnl, int ifindex, unsigned short *ret_iftype, unsigned *ret_flags) {
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *message = NULL, *reply = NULL;
        unsigned short iftype;
        unsigned flags;
        int r;

        assert(rtnl);
        assert(ifindex > 0);

        if (!ret_iftype && !ret_flags)
                return 0;

        if (!*rtnl) {
                r = sd_netlink_open(rtnl);
                if (r < 0)
                        return r;
        }

        r = sd_rtnl_message_new_link(*rtnl, &message, RTM_GETLINK, ifindex);
        if (r < 0)
                return r;

        r = sd_netlink_call(*rtnl, message, 0, &reply);
        if (r == -EINVAL)
                return -ENODEV; /* The device does not exist */
        if (r < 0)
                return r;

        if (ret_iftype) {
                r = sd_rtnl_message_link_get_type(reply, &iftype);
                if (r < 0)
                        return r;
        }

        if (ret_flags) {
                r = sd_rtnl_message_link_get_flags(reply, &flags);
                if (r < 0)
                        return r;
        }

        if (ret_iftype)
                *ret_iftype = iftype;
        if (ret_flags)
                *ret_flags = flags;
        return 0;
}

int rtnl_message_new_synthetic_error(sd_netlink *rtnl, int error, uint32_t serial, sd_netlink_message **ret) {
        struct nlmsgerr *err;
        int r;

        assert(error <= 0);

        r = message_new(rtnl, ret, NLMSG_ERROR);
        if (r < 0)
                return r;

        rtnl_message_seal(*ret);
        (*ret)->hdr->nlmsg_seq = serial;

        err = NLMSG_DATA((*ret)->hdr);
        err->error = error;

        return 0;
}

int rtnl_log_parse_error(int r) {
        return log_error_errno(r, "Failed to parse netlink message: %m");
}

int rtnl_log_create_error(int r) {
        return log_error_errno(r, "Failed to create netlink message: %m");
}

void rtattr_append_attribute_internal(struct rtattr *rta, unsigned short type, const void *data, size_t data_length) {
        size_t padding_length;
        uint8_t *padding;

        assert(rta);
        assert(!data || data_length > 0);

        /* fill in the attribute */
        rta->rta_type = type;
        rta->rta_len = RTA_LENGTH(data_length);
        if (data)
                /* we don't deal with the case where the user lies about the type
                 * and gives us too little data (so don't do that)
                 */
                padding = mempcpy(RTA_DATA(rta), data, data_length);

        else
                /* if no data was passed, make sure we still initialize the padding
                   note that we can have data_length > 0 (used by some containers) */
                padding = RTA_DATA(rta);

        /* make sure also the padding at the end of the message is initialized */
        padding_length = (uint8_t *) rta + RTA_SPACE(data_length) - padding;
        memzero(padding, padding_length);
}

int rtattr_append_attribute(struct rtattr **rta, unsigned short type, const void *data, size_t data_length) {
        struct rtattr *new_rta, *sub_rta;
        size_t message_length;

        assert(rta);
        assert(!data || data_length > 0);

        /* get the new message size (with padding at the end) */
        message_length = RTA_ALIGN(rta ? (*rta)->rta_len : 0) + RTA_SPACE(data_length);

        /* buffer should be smaller than both one page or 8K to be accepted by the kernel */
        if (message_length > MIN(page_size(), 8192UL))
                return -ENOBUFS;

        /* realloc to fit the new attribute */
        new_rta = realloc(*rta, message_length);
        if (!new_rta)
                return -ENOMEM;
        *rta = new_rta;

        /* get pointer to the attribute we are about to add */
        sub_rta = (struct rtattr *) ((uint8_t *) *rta + RTA_ALIGN((*rta)->rta_len));

        rtattr_append_attribute_internal(sub_rta, type, data, data_length);

        /* update rta_len */
        (*rta)->rta_len = message_length;

        return 0;
}

MultipathRoute *multipath_route_free(MultipathRoute *m) {
        if (!m)
                return NULL;

        free(m->ifname);

        return mfree(m);
}

int multipath_route_dup(const MultipathRoute *m, MultipathRoute **ret) {
        _cleanup_(multipath_route_freep) MultipathRoute *n = NULL;
        _cleanup_free_ char *ifname = NULL;

        assert(m);
        assert(ret);

        if (m->ifname) {
                ifname = strdup(m->ifname);
                if (!ifname)
                        return -ENOMEM;
        }

        n = new(MultipathRoute, 1);
        if (!n)
                return -ENOMEM;

        *n = (MultipathRoute) {
                .gateway = m->gateway,
                .weight = m->weight,
                .ifindex = m->ifindex,
                .ifname = TAKE_PTR(ifname),
        };

        *ret = TAKE_PTR(n);

        return 0;
}

int rtattr_read_nexthop(const struct rtnexthop *rtnh, size_t size, int family, OrderedSet **ret) {
        _cleanup_ordered_set_free_free_ OrderedSet *set = NULL;
        int r;

        assert(rtnh);
        assert(IN_SET(family, AF_INET, AF_INET6));

        if (size < sizeof(struct rtnexthop))
                return -EBADMSG;

        for (; size >= sizeof(struct rtnexthop); ) {
                _cleanup_(multipath_route_freep) MultipathRoute *m = NULL;

                if (NLMSG_ALIGN(rtnh->rtnh_len) > size)
                        return -EBADMSG;

                if (rtnh->rtnh_len < sizeof(struct rtnexthop))
                        return -EBADMSG;

                m = new(MultipathRoute, 1);
                if (!m)
                        return -ENOMEM;

                *m = (MultipathRoute) {
                        .ifindex = rtnh->rtnh_ifindex,
                        .weight = rtnh->rtnh_hops,
                };

                if (rtnh->rtnh_len > sizeof(struct rtnexthop)) {
                        size_t len = rtnh->rtnh_len - sizeof(struct rtnexthop);

                        for (struct rtattr *attr = RTNH_DATA(rtnh); RTA_OK(attr, len); attr = RTA_NEXT(attr, len)) {
                                if (attr->rta_type == RTA_GATEWAY) {
                                        if (attr->rta_len != RTA_LENGTH(FAMILY_ADDRESS_SIZE(family)))
                                                return -EBADMSG;

                                        m->gateway.family = family;
                                        memcpy(&m->gateway.address, RTA_DATA(attr), FAMILY_ADDRESS_SIZE(family));
                                        break;
                                } else if (attr->rta_type == RTA_VIA) {
                                        uint16_t gw_family;

                                        if (family != AF_INET)
                                                return -EINVAL;

                                        if (attr->rta_len < RTA_LENGTH(sizeof(uint16_t)))
                                                return -EBADMSG;

                                        gw_family = *(uint16_t *) RTA_DATA(attr);

                                        if (gw_family != AF_INET6)
                                                return -EBADMSG;

                                        if (attr->rta_len != RTA_LENGTH(FAMILY_ADDRESS_SIZE(gw_family) + sizeof(gw_family)))
                                                return -EBADMSG;

                                        memcpy(&m->gateway, RTA_DATA(attr), FAMILY_ADDRESS_SIZE(gw_family) + sizeof(gw_family));
                                        break;
                                }
                        }
                }

                r = ordered_set_ensure_put(&set, NULL, m);
                if (r < 0)
                        return r;

                TAKE_PTR(m);

                size -= NLMSG_ALIGN(rtnh->rtnh_len);
                rtnh = RTNH_NEXT(rtnh);
        }

        if (ret)
                *ret = TAKE_PTR(set);
        return 0;
}
