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

#include <netinet/in.h>
#include <linux/if.h>

#include "alloc-util.h"
#include "dns-domain.h"
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "network-internal.h"
#include "networkd-link.h"
#include "networkd-manager-bus.h"
#include "networkd-manager.h"
#include "networkd-network.h"
#include "networkd-state-file.h"
#include "ordered-set.h"
#include "set.h"
#include "strv.h"
#include "tmpfile-util.h"

static int ordered_set_put_dns_server(OrderedSet **s, int ifindex, struct in_addr_full *dns) {
        const char *p;
        int r;

        assert(s);
        assert(dns);

        if (dns->ifindex != 0 && dns->ifindex != ifindex)
                return 0;

        p = in_addr_full_to_string(dns);
        if (!p)
                return 0;

        r = ordered_set_put_strdup(s, p);
        if (r == -EEXIST)
                return 0;

        return r;
}

static int ordered_set_put_dns_servers(OrderedSet **s, int ifindex, struct in_addr_full **dns, unsigned n) {
        int r, c = 0;

        assert(s);
        assert(dns || n == 0);

        for (unsigned i = 0; i < n; i++) {
                r = ordered_set_put_dns_server(s, ifindex, dns[i]);
                if (r < 0)
                        return r;

                c += r;
        }

        return c;
}

static int ordered_set_put_in4_addr(OrderedSet **s, const struct in_addr *address) {
        _cleanup_free_ char *p = NULL;
        int r;

        assert(s);
        assert(address);

        r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p);
        if (r < 0)
                return r;

        r = ordered_set_ensure_allocated(s, &string_hash_ops_free);
        if (r < 0)
                return r;

        r = ordered_set_consume(*s, TAKE_PTR(p));
        if (r == -EEXIST)
                return 0;

        return r;
}

static int ordered_set_put_in4_addrv(
                OrderedSet **s,
                const struct in_addr *addresses,
                size_t n,
                bool (*predicate)(const struct in_addr *addr)) {

        int r, c = 0;

        assert(s);
        assert(n == 0 || addresses);

        for (size_t i = 0; i < n; i++) {
                if (predicate && !predicate(&addresses[i]))
                        continue;
                r = ordered_set_put_in4_addr(s, addresses+i);
                if (r < 0)
                        return r;

                c += r;
        }

        return c;
}

int manager_save(Manager *m) {
        _cleanup_ordered_set_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *search_domains = NULL, *route_domains = NULL;
        const char *operstate_str, *carrier_state_str, *address_state_str, *ipv4_address_state_str, *ipv6_address_state_str, *online_state_str;
        LinkOperationalState operstate = LINK_OPERSTATE_OFF;
        LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF;
        LinkAddressState ipv4_address_state = LINK_ADDRESS_STATE_OFF, ipv6_address_state = LINK_ADDRESS_STATE_OFF,
                address_state = LINK_ADDRESS_STATE_OFF;
        LinkOnlineState online_state;
        size_t links_offline = 0, links_online = 0;
        _cleanup_(unlink_and_freep) char *temp_path = NULL;
        _cleanup_strv_free_ char **p = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        Link *link;
        int r;

        assert(m);

        if (isempty(m->state_file))
                return 0; /* Do not update state file when running in test mode. */

        HASHMAP_FOREACH(link, m->links_by_index) {
                const struct in_addr *addresses;

                if (link->flags & IFF_LOOPBACK)
                        continue;

                operstate = MAX(operstate, link->operstate);
                carrier_state = MAX(carrier_state, link->carrier_state);
                address_state = MAX(address_state, link->address_state);
                ipv4_address_state = MAX(ipv4_address_state, link->ipv4_address_state);
                ipv6_address_state = MAX(ipv6_address_state, link->ipv6_address_state);

                if (!link->network)
                        continue;

                if (link->network->required_for_online) {
                        if (link->online_state == LINK_ONLINE_STATE_OFFLINE)
                                links_offline++;
                        else if (link->online_state == LINK_ONLINE_STATE_ONLINE)
                                links_online++;
                }

                /* First add the static configured entries */
                if (link->n_dns != UINT_MAX)
                        r = ordered_set_put_dns_servers(&dns, link->ifindex, link->dns, link->n_dns);
                else
                        r = ordered_set_put_dns_servers(&dns, link->ifindex, link->network->dns, link->network->n_dns);
                if (r < 0)
                        return r;

                r = ordered_set_put_strdupv(&ntp, link->ntp ?: link->network->ntp);
                if (r < 0)
                        return r;

                r = ordered_set_put_string_set(&search_domains, link->search_domains ?: link->network->search_domains);
                if (r < 0)
                        return r;

                r = ordered_set_put_string_set(&route_domains, link->route_domains ?: link->network->route_domains);
                if (r < 0)
                        return r;

                if (!link->dhcp_lease)
                        continue;

                /* Secondly, add the entries acquired via DHCP */
                if (link->network->dhcp_use_dns) {
                        r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses);
                        if (r > 0) {
                                r = ordered_set_put_in4_addrv(&dns, addresses, r, in4_addr_is_non_local);
                                if (r < 0)
                                        return r;
                        } else if (r < 0 && r != -ENODATA)
                                return r;
                }

                if (link->network->dhcp_use_ntp) {
                        r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses);
                        if (r > 0) {
                                r = ordered_set_put_in4_addrv(&ntp, addresses, r, in4_addr_is_non_local);
                                if (r < 0)
                                        return r;
                        } else if (r < 0 && r != -ENODATA)
                                return r;
                }

                if (link->network->dhcp_use_sip) {
                        r = sd_dhcp_lease_get_sip(link->dhcp_lease, &addresses);
                        if (r > 0) {
                                r = ordered_set_put_in4_addrv(&sip, addresses, r, in4_addr_is_non_local);
                                if (r < 0)
                                        return r;
                        } else if (r < 0 && r != -ENODATA)
                                return r;
                }

                if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) {
                        OrderedSet **target_domains;
                        const char *domainname;
                        char **domains = NULL;

                        target_domains = link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES ? &search_domains : &route_domains;
                        r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname);
                        if (r >= 0) {
                                r = ordered_set_put_strdup(target_domains, domainname);
                                if (r < 0)
                                        return r;
                        } else if (r != -ENODATA)
                                return r;

                        r = sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains);
                        if (r >= 0) {
                                r = ordered_set_put_strdupv(target_domains, domains);
                                if (r < 0)
                                        return r;
                        } else if (r != -ENODATA)
                                return r;
                }
        }

        if (carrier_state >= LINK_CARRIER_STATE_ENSLAVED)
                carrier_state = LINK_CARRIER_STATE_CARRIER;

        online_state = links_online > 0 ?
                (links_offline > 0 ? LINK_ONLINE_STATE_PARTIAL : LINK_ONLINE_STATE_ONLINE) :
                (links_offline > 0 ? LINK_ONLINE_STATE_OFFLINE : _LINK_ONLINE_STATE_INVALID);

        operstate_str = link_operstate_to_string(operstate);
        assert(operstate_str);

        carrier_state_str = link_carrier_state_to_string(carrier_state);
        assert(carrier_state_str);

        address_state_str = link_address_state_to_string(address_state);
        assert(address_state_str);

        ipv4_address_state_str = link_address_state_to_string(ipv4_address_state);
        assert(ipv4_address_state_str);

        ipv6_address_state_str = link_address_state_to_string(ipv6_address_state);
        assert(ipv6_address_state_str);

        r = fopen_temporary(m->state_file, &f, &temp_path);
        if (r < 0)
                return r;

        (void) fchmod(fileno(f), 0644);

        fprintf(f,
                "# This is private data. Do not parse.\n"
                "OPER_STATE=%s\n"
                "CARRIER_STATE=%s\n"
                "ADDRESS_STATE=%s\n"
                "IPV4_ADDRESS_STATE=%s\n"
                "IPV6_ADDRESS_STATE=%s\n",
                operstate_str, carrier_state_str, address_state_str, ipv4_address_state_str, ipv6_address_state_str);

        online_state_str = link_online_state_to_string(online_state);
        if (online_state_str)
                fprintf(f, "ONLINE_STATE=%s\n", online_state_str);

        ordered_set_print(f, "DNS=", dns);
        ordered_set_print(f, "NTP=", ntp);
        ordered_set_print(f, "SIP=", sip);
        ordered_set_print(f, "DOMAINS=", search_domains);
        ordered_set_print(f, "ROUTE_DOMAINS=", route_domains);

        r = fflush_and_check(f);
        if (r < 0)
                return r;

        r = conservative_rename(temp_path, m->state_file);
        if (r < 0)
                return r;

        temp_path = mfree(temp_path);

        if (m->operational_state != operstate) {
                m->operational_state = operstate;
                if (strv_extend(&p, "OperationalState") < 0)
                        log_oom();
        }

        if (m->carrier_state != carrier_state) {
                m->carrier_state = carrier_state;
                if (strv_extend(&p, "CarrierState") < 0)
                        log_oom();
        }

        if (m->address_state != address_state) {
                m->address_state = address_state;
                if (strv_extend(&p, "AddressState") < 0)
                        log_oom();
        }

        if (m->ipv4_address_state != ipv4_address_state) {
                m->ipv4_address_state = ipv4_address_state;
                if (strv_extend(&p, "IPv4AddressState") < 0)
                        log_oom();
        }

        if (m->ipv6_address_state != ipv6_address_state) {
                m->ipv6_address_state = ipv6_address_state;
                if (strv_extend(&p, "IPv6AddressState") < 0)
                        log_oom();
        }

        if (m->online_state != online_state) {
                m->online_state = online_state;
                if (strv_extend(&p, "OnlineState") < 0)
                        log_oom();
        }

        if (p) {
                r = manager_send_changed_strv(m, p);
                if (r < 0)
                        log_warning_errno(r, "Could not emit changed properties, ignoring: %m");
        }

        m->dirty = false;

        return 0;
}

static void print_link_hashmap(FILE *f, const char *prefix, Hashmap* h) {
        bool space = false;
        Link *link;

        assert(f);
        assert(prefix);

        if (hashmap_isempty(h))
                return;

        fputs(prefix, f);
        HASHMAP_FOREACH(link, h) {
                if (space)
                        fputc(' ', f);

                fprintf(f, "%i", link->ifindex);
                space = true;
        }

        fputc('\n', f);
}

static void link_save_dns(Link *link, FILE *f, struct in_addr_full **dns, unsigned n_dns, bool *space) {
        bool _space = false;

        if (!space)
                space = &_space;

        for (unsigned j = 0; j < n_dns; j++) {
                const char *str;

                if (dns[j]->ifindex != 0 && dns[j]->ifindex != link->ifindex)
                        continue;

                str = in_addr_full_to_string(dns[j]);
                if (!str)
                        continue;

                if (*space)
                        fputc(' ', f);
                fputs(str, f);
                *space = true;
        }
}

static void serialize_addresses(
                FILE *f,
                const char *lvalue,
                bool *space,
                char **addresses,
                sd_dhcp_lease *lease,
                bool conditional,
                sd_dhcp_lease_server_type_t what,
                sd_dhcp6_lease *lease6,
                bool conditional6,
                int (*lease6_get_addr)(sd_dhcp6_lease*, const struct in6_addr**),
                int (*lease6_get_fqdn)(sd_dhcp6_lease*, char ***)) {

        bool _space = false;
        int r;

        if (!space)
                space = &_space;

        if (lvalue)
                fprintf(f, "%s=", lvalue);
        fputstrv(f, addresses, NULL, space);

        if (lease && conditional) {
                const struct in_addr *lease_addresses;

                r = sd_dhcp_lease_get_servers(lease, what, &lease_addresses);
                if (r > 0)
                        serialize_in_addrs(f, lease_addresses, r, space, in4_addr_is_non_local);
        }

        if (lease6 && conditional6 && lease6_get_addr) {
                const struct in6_addr *in6_addrs;

                r = lease6_get_addr(lease6, &in6_addrs);
                if (r > 0)
                        serialize_in6_addrs(f, in6_addrs, r, space);
        }

        if (lease6 && conditional6 && lease6_get_fqdn) {
                char **in6_hosts;

                r = lease6_get_fqdn(lease6, &in6_hosts);
                if (r > 0)
                        fputstrv(f, in6_hosts, NULL, space);
        }

        if (lvalue)
                fputc('\n', f);
}

static void link_save_domains(Link *link, FILE *f, OrderedSet *static_domains, DHCPUseDomains use_domains) {
        bool space = false;
        const char *p;

        assert(link);
        assert(link->network);
        assert(f);

        ORDERED_SET_FOREACH(p, static_domains)
                fputs_with_space(f, p, NULL, &space);

        if (use_domains == DHCP_USE_DOMAINS_NO)
                return;

        if (link->dhcp_lease && link->network->dhcp_use_domains == use_domains) {
                const char *domainname;
                char **domains;

                if (sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname) >= 0)
                        fputs_with_space(f, domainname, NULL, &space);
                if (sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains) >= 0)
                        fputstrv(f, domains, NULL, &space);
        }

        if (link->dhcp6_lease && link->network->dhcp6_use_domains == use_domains) {
                char **domains;

                if (sd_dhcp6_lease_get_domains(link->dhcp6_lease, &domains) >= 0)
                        fputstrv(f, domains, NULL, &space);
        }

        if (link->network->ipv6_accept_ra_use_domains == use_domains) {
                NDiscDNSSL *dd;

                SET_FOREACH(dd, link->ndisc_dnssl)
                        fputs_with_space(f, NDISC_DNSSL_DOMAIN(dd), NULL, &space);
        }
}

int link_save(Link *link) {
        const char *admin_state, *oper_state, *carrier_state, *address_state, *ipv4_address_state, *ipv6_address_state;
        _cleanup_(unlink_and_freep) char *temp_path = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        int r;

        assert(link);
        assert(link->manager);

        if (isempty(link->state_file))
                return 0; /* Do not update state files when running in test mode. */

        if (link->state == LINK_STATE_LINGER)
                return 0;

        link_lldp_save(link);

        admin_state = link_state_to_string(link->state);
        assert(admin_state);

        oper_state = link_operstate_to_string(link->operstate);
        assert(oper_state);

        carrier_state = link_carrier_state_to_string(link->carrier_state);
        assert(carrier_state);

        address_state = link_address_state_to_string(link->address_state);
        assert(address_state);

        ipv4_address_state = link_address_state_to_string(link->ipv4_address_state);
        assert(ipv4_address_state);

        ipv6_address_state = link_address_state_to_string(link->ipv6_address_state);
        assert(ipv6_address_state);

        r = fopen_temporary(link->state_file, &f, &temp_path);
        if (r < 0)
                return r;

        (void) fchmod(fileno(f), 0644);

        fprintf(f,
                "# This is private data. Do not parse.\n"
                "ADMIN_STATE=%s\n"
                "OPER_STATE=%s\n"
                "CARRIER_STATE=%s\n"
                "ADDRESS_STATE=%s\n"
                "IPV4_ADDRESS_STATE=%s\n"
                "IPV6_ADDRESS_STATE=%s\n",
                admin_state, oper_state, carrier_state, address_state, ipv4_address_state, ipv6_address_state);

        if (link->network) {
                const char *online_state;
                bool space = false;

                online_state = link_online_state_to_string(link->online_state);
                if (online_state)
                        fprintf(f, "ONLINE_STATE=%s\n", online_state);

                fprintf(f, "REQUIRED_FOR_ONLINE=%s\n",
                        yes_no(link->network->required_for_online));

                LinkOperationalStateRange st = link->network->required_operstate_for_online;
                fprintf(f, "REQUIRED_OPER_STATE_FOR_ONLINE=%s%s%s\n",
                        strempty(link_operstate_to_string(st.min)),
                        st.max != LINK_OPERSTATE_RANGE_DEFAULT.max ? ":" : "",
                        st.max != LINK_OPERSTATE_RANGE_DEFAULT.max ? strempty(link_operstate_to_string(st.max)) : "");

                fprintf(f, "REQUIRED_FAMILY_FOR_ONLINE=%s\n",
                        link_required_address_family_to_string(link->network->required_family_for_online));

                fprintf(f, "ACTIVATION_POLICY=%s\n",
                        activation_policy_to_string(link->network->activation_policy));

                fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);

                fputs("NETWORK_FILE_DROPINS=\"", f);
                STRV_FOREACH(d, link->network->dropins) {
                        _cleanup_free_ char *escaped = NULL;

                        escaped = xescape(*d, ":");
                        if (!escaped)
                                return -ENOMEM;

                        fputs_with_space(f, escaped, ":", &space);
                }
                fputs("\"\n", f);

                /************************************************************/

                fputs("DNS=", f);
                if (link->n_dns != UINT_MAX)
                        link_save_dns(link, f, link->dns, link->n_dns, NULL);
                else {
                        space = false;
                        link_save_dns(link, f, link->network->dns, link->network->n_dns, &space);

                        serialize_addresses(f, NULL, &space,
                                            NULL,
                                            link->dhcp_lease,
                                            link->network->dhcp_use_dns,
                                            SD_DHCP_LEASE_DNS,
                                            link->dhcp6_lease,
                                            link->network->dhcp6_use_dns,
                                            sd_dhcp6_lease_get_dns,
                                            NULL);

                        if (link->network->ipv6_accept_ra_use_dns) {
                                NDiscRDNSS *dd;

                                SET_FOREACH(dd, link->ndisc_rdnss)
                                        serialize_in6_addrs(f, &dd->address, 1, &space);
                        }
                }

                fputc('\n', f);

                /************************************************************/

                if (link->ntp) {
                        fputs("NTP=", f);
                        fputstrv(f, link->ntp, NULL, NULL);
                        fputc('\n', f);
                } else
                        serialize_addresses(f, "NTP", NULL,
                                            link->network->ntp,
                                            link->dhcp_lease,
                                            link->network->dhcp_use_ntp,
                                            SD_DHCP_LEASE_NTP,
                                            link->dhcp6_lease,
                                            link->network->dhcp6_use_ntp,
                                            sd_dhcp6_lease_get_ntp_addrs,
                                            sd_dhcp6_lease_get_ntp_fqdn);

                serialize_addresses(f, "SIP", NULL,
                                    NULL,
                                    link->dhcp_lease,
                                    link->network->dhcp_use_sip,
                                    SD_DHCP_LEASE_SIP,
                                    NULL, false, NULL, NULL);

                /************************************************************/

                fputs("DOMAINS=", f);
                if (link->search_domains)
                        link_save_domains(link, f, link->search_domains, DHCP_USE_DOMAINS_NO);
                else
                        link_save_domains(link, f, link->network->search_domains, DHCP_USE_DOMAINS_YES);
                fputc('\n', f);

                /************************************************************/

                fputs("ROUTE_DOMAINS=", f);
                if (link->route_domains)
                        link_save_domains(link, f, link->route_domains, DHCP_USE_DOMAINS_NO);
                else
                        link_save_domains(link, f, link->network->route_domains, DHCP_USE_DOMAINS_ROUTE);
                fputc('\n', f);

                /************************************************************/

                fprintf(f, "LLMNR=%s\n",
                        resolve_support_to_string(link->llmnr >= 0 ? link->llmnr : link->network->llmnr));

                /************************************************************/

                fprintf(f, "MDNS=%s\n",
                        resolve_support_to_string(link->mdns >= 0 ? link->mdns : link->network->mdns));

                /************************************************************/

                int dns_default_route =
                        link->dns_default_route >= 0 ? link->dns_default_route :
                        link->network->dns_default_route;
                if (dns_default_route >= 0)
                        fprintf(f, "DNS_DEFAULT_ROUTE=%s\n", yes_no(dns_default_route));

                /************************************************************/

                DnsOverTlsMode dns_over_tls_mode =
                        link->dns_over_tls_mode != _DNS_OVER_TLS_MODE_INVALID ? link->dns_over_tls_mode :
                        link->network->dns_over_tls_mode;
                if (dns_over_tls_mode != _DNS_OVER_TLS_MODE_INVALID)
                        fprintf(f, "DNS_OVER_TLS=%s\n", dns_over_tls_mode_to_string(dns_over_tls_mode));

                /************************************************************/

                DnssecMode dnssec_mode =
                        link->dnssec_mode != _DNSSEC_MODE_INVALID ? link->dnssec_mode :
                        link->network->dnssec_mode;
                if (dnssec_mode != _DNSSEC_MODE_INVALID)
                        fprintf(f, "DNSSEC=%s\n", dnssec_mode_to_string(dnssec_mode));

                /************************************************************/

                Set *nta_anchors = link->dnssec_negative_trust_anchors;
                if (set_isempty(nta_anchors))
                        nta_anchors = link->network->dnssec_negative_trust_anchors;

                if (!set_isempty(nta_anchors)) {
                        const char *n;

                        fputs("DNSSEC_NTA=", f);
                        space = false;
                        SET_FOREACH(n, nta_anchors)
                                fputs_with_space(f, n, NULL, &space);
                        fputc('\n', f);
                }
        }

        print_link_hashmap(f, "CARRIER_BOUND_TO=", link->bound_to_links);
        print_link_hashmap(f, "CARRIER_BOUND_BY=", link->bound_by_links);

        if (link->dhcp_lease) {
                r = dhcp_lease_save(link->dhcp_lease, link->lease_file);
                if (r < 0)
                        return r;

                fprintf(f,
                        "DHCP_LEASE=%s\n",
                        link->lease_file);
        } else
                (void) unlink(link->lease_file);

        r = link_serialize_dhcp6_client(link, f);
        if (r < 0)
                return r;

        r = fflush_and_check(f);
        if (r < 0)
                return r;

        r = conservative_rename(temp_path, link->state_file);
        if (r < 0)
                return r;

        temp_path = mfree(temp_path);

        return 0;
}

void link_dirty(Link *link) {
        int r;

        assert(link);
        assert(link->manager);

        /* The serialized state in /run is no longer up-to-date. */

        /* Also mark manager dirty as link is dirty */
        link->manager->dirty = true;

        r = set_ensure_put(&link->manager->dirty_links, NULL, link);
        if (r <= 0)
                /* Ignore allocation errors and don't take another ref if the link was already dirty */
                return;
        link_ref(link);
}

void link_clean(Link *link) {
        assert(link);
        assert(link->manager);

        /* The serialized state in /run is up-to-date */

        link_unref(set_remove(link->manager->dirty_links, link));
}

int link_save_and_clean(Link *link) {
        int r;

        r = link_save(link);
        if (r < 0)
                return r;

        link_clean(link);
        return 0;
}
