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

#include <net/if_arp.h>

#include "sd-netlink.h"

#include "netlink-util.h"
#include "networkd-manager.h"
#include "networkd-wiphy.h"
#include "parse-util.h"
#include "wifi-util.h"
#include "wlan.h"

static void wlan_done(NetDev *netdev) {
        WLan *w;

        assert(netdev);

        w = WLAN(netdev);

        assert(w);

        w->wiphy_name = mfree(w->wiphy_name);
}

static void wlan_init(NetDev *netdev) {
        WLan *w;

        assert(netdev);

        w = WLAN(netdev);

        assert(w);

        w->wiphy_index = UINT32_MAX;
        w->wds = -1;
}

static int wlan_get_wiphy(NetDev *netdev, Wiphy **ret) {
        WLan *w;

        assert(netdev);

        w = WLAN(netdev);

        assert(w);

        if (w->wiphy_name)
                return wiphy_get_by_name(netdev->manager, w->wiphy_name, ret);

        return wiphy_get_by_index(netdev->manager, w->wiphy_index, ret);
}

static int wlan_is_ready_to_create(NetDev *netdev, Link *link) {
        return wlan_get_wiphy(netdev, NULL) >= 0;
}

static int wlan_fill_message(NetDev *netdev, sd_netlink_message *m) {
        Wiphy *wiphy;
        WLan *w;
        int r;

        assert(netdev);
        assert(m);

        w = WLAN(netdev);

        assert(w);

        r = wlan_get_wiphy(netdev, &wiphy);
        if (r < 0)
                return r;

        r = sd_netlink_message_append_u32(m, NL80211_ATTR_WIPHY, wiphy->index);
        if (r < 0)
                return r;

        r = sd_netlink_message_append_string(m, NL80211_ATTR_IFNAME, netdev->ifname);
        if (r < 0)
                return r;

        r = sd_netlink_message_append_u32(m, NL80211_ATTR_IFTYPE, w->iftype);
        if (r < 0)
                return r;

        if (!hw_addr_is_null(&netdev->hw_addr) && netdev->hw_addr.length == ETH_ALEN) {
                r = sd_netlink_message_append_ether_addr(m, NL80211_ATTR_MAC, &netdev->hw_addr.ether);
                if (r < 0)
                        return r;
        }

        if (w->wds >= 0) {
                r = sd_netlink_message_append_u8(m, NL80211_ATTR_4ADDR, w->wds);
                if (r < 0)
                        return r;
        }

        return 0;
}

static int wlan_create_handler(sd_netlink *genl, sd_netlink_message *m, NetDev *netdev) {
        int r;

        assert(netdev);
        assert(netdev->state != _NETDEV_STATE_INVALID);

        r = sd_netlink_message_get_errno(m);
        if (IN_SET(r, -EEXIST, -ENFILE))
                /* Unlike the other netdevs, the kernel may return -ENFILE. See dev_alloc_name(). */
                log_netdev_info(netdev, "WLAN interface exists, using existing without changing its parameters.");
        else if (r < 0) {
                log_netdev_warning_errno(netdev, r, "WLAN interface could not be created: %m");
                netdev_enter_failed(netdev);

                return 1;
        }

        log_netdev_debug(netdev, "WLAN interface is created.");
        return 1;
}

static int wlan_create(NetDev *netdev) {
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
        int r;

        assert(netdev);
        assert(netdev->manager);
        assert(netdev->manager->genl);

        r = sd_genl_message_new(netdev->manager->genl, NL80211_GENL_NAME, NL80211_CMD_NEW_INTERFACE, &m);
        if (r < 0)
                return log_netdev_warning_errno(netdev, r, "Failed to allocate netlink message: %m");

        r = wlan_fill_message(netdev, m);
        if (r < 0)
                return log_netdev_warning_errno(netdev, r, "Failed to fill netlink message: %m");

        r = netlink_call_async(netdev->manager->genl, NULL, m, wlan_create_handler,
                               netdev_destroy_callback, netdev);
        if (r < 0)
                return log_netdev_warning_errno(netdev, r, "Failed to send netlink message: %m");

        netdev_ref(netdev);
        return 0;
}

static int wlan_verify(NetDev *netdev, const char *filename) {
        WLan *w;

        assert(netdev);
        assert(filename);

        w = WLAN(netdev);

        assert(w);

        if (w->iftype == NL80211_IFTYPE_UNSPECIFIED)
                return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
                                                "%s: WLAN interface type is not specified, ignoring.",
                                                filename);

        if (w->wiphy_index == UINT32_MAX && isempty(w->wiphy_name))
                return log_netdev_warning_errno(netdev, SYNTHETIC_ERRNO(EINVAL),
                                                "%s: physical WLAN device is not specified, ignoring.",
                                                filename);

        return 0;
}

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

        WLan *w = ASSERT_PTR(userdata);
        int r;

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

        if (isempty(rvalue)) {
                w->wiphy_name = mfree(w->wiphy_name);
                w->wiphy_index = UINT32_MAX;
                return 0;
        }

        r = safe_atou32(rvalue, &w->wiphy_index);
        if (r >= 0) {
                w->wiphy_name = mfree(w->wiphy_name);
                return 0;
        }

        r = free_and_strdup_warn(&w->wiphy_name, rvalue);
        if (r < 0)
                return r;

        w->wiphy_index = UINT32_MAX;
        return 0;
}

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

        enum nl80211_iftype t, *iftype = ASSERT_PTR(data);

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

        if (isempty(rvalue)) {
                *iftype = NL80211_IFTYPE_UNSPECIFIED;
                return 0;
        }

        t = nl80211_iftype_from_string(rvalue);
        /* We reuse the kernel provided enum which does not contain negative value. So, the cast
         * below is mandatory. Otherwise, the check below always passes. */
        if ((int) t < 0) {
                log_syntax(unit, LOG_WARNING, filename, line, t,
                           "Failed to parse wlan interface type, ignoring assignment: %s",
                           rvalue);
                return 0;
        }

        *iftype = t;
        return 0;
}

const NetDevVTable wlan_vtable = {
        .object_size = sizeof(WLan),
        .init = wlan_init,
        .done = wlan_done,
        .sections = NETDEV_COMMON_SECTIONS "WLAN\0",
        .is_ready_to_create = wlan_is_ready_to_create,
        .create = wlan_create,
        .create_type = NETDEV_CREATE_INDEPENDENT,
        .config_verify = wlan_verify,
        .iftype = ARPHRD_ETHER,
        .generate_mac = true,
        .skip_netdev_kind_check = true,
};
