Coverage Report

Created: 2025-06-24 06:40

/src/systemd/src/network/netdev/netdev-util.c
Line
Count
Source (jump to first uncovered line)
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3
#include "netdev-util.h"
4
#include "networkd-address.h"
5
#include "networkd-link.h"
6
#include "set.h"
7
#include "string-table.h"
8
9
static const char * const netdev_local_address_type_table[_NETDEV_LOCAL_ADDRESS_TYPE_MAX] = {
10
        [NETDEV_LOCAL_ADDRESS_IPV4LL] = "ipv4_link_local",
11
        [NETDEV_LOCAL_ADDRESS_IPV6LL] = "ipv6_link_local",
12
        [NETDEV_LOCAL_ADDRESS_DHCP4]  = "dhcp4",
13
        [NETDEV_LOCAL_ADDRESS_DHCP6]  = "dhcp6",
14
        [NETDEV_LOCAL_ADDRESS_SLAAC]  = "slaac",
15
};
16
17
DEFINE_STRING_TABLE_LOOKUP(netdev_local_address_type, NetDevLocalAddressType);
18
19
int link_get_local_address(
20
                Link *link,
21
                NetDevLocalAddressType type,
22
                int family,
23
                int *ret_family,
24
0
                union in_addr_union *ret_address) {
25
26
0
        Address *a;
27
28
0
        assert(link);
29
30
0
        switch (type) {
31
0
        case NETDEV_LOCAL_ADDRESS_IPV4LL:
32
0
                assert(IN_SET(family, AF_UNSPEC, AF_INET));
33
0
                family = AF_INET;
34
0
                break;
35
0
        case NETDEV_LOCAL_ADDRESS_IPV6LL:
36
0
                assert(IN_SET(family, AF_UNSPEC, AF_INET6));
37
0
                family = AF_INET6;
38
0
                break;
39
0
        case NETDEV_LOCAL_ADDRESS_DHCP4:
40
0
                assert(IN_SET(family, AF_UNSPEC, AF_INET));
41
0
                family = AF_INET;
42
0
                break;
43
0
        case NETDEV_LOCAL_ADDRESS_DHCP6:
44
0
                assert(IN_SET(family, AF_UNSPEC, AF_INET6));
45
0
                family = AF_INET6;
46
0
                break;
47
0
        case NETDEV_LOCAL_ADDRESS_SLAAC:
48
0
                assert(IN_SET(family, AF_UNSPEC, AF_INET6));
49
0
                family = AF_INET6;
50
0
                break;
51
0
        default:
52
0
                assert_not_reached();
53
0
        }
54
55
0
        if (!link_is_ready_to_configure(link, /* allow_unmanaged = */ false))
56
0
                return -EBUSY;
57
58
0
        SET_FOREACH(a, link->addresses) {
59
0
                if (!address_is_ready(a))
60
0
                        continue;
61
62
0
                if (a->family != family)
63
0
                        continue;
64
65
0
                if (in_addr_is_set(a->family, &a->in_addr_peer))
66
0
                        continue;
67
68
0
                switch (type) {
69
0
                case NETDEV_LOCAL_ADDRESS_IPV4LL:
70
0
                        if (a->source != NETWORK_CONFIG_SOURCE_IPV4LL)
71
0
                                continue;
72
0
                        break;
73
0
                case NETDEV_LOCAL_ADDRESS_IPV6LL:
74
0
                        if (!in6_addr_is_link_local(&a->in_addr.in6))
75
0
                                continue;
76
0
                        break;
77
0
                case NETDEV_LOCAL_ADDRESS_DHCP4:
78
0
                        if (a->source != NETWORK_CONFIG_SOURCE_DHCP4)
79
0
                                continue;
80
0
                        break;
81
0
                case NETDEV_LOCAL_ADDRESS_DHCP6:
82
0
                        if (a->source != NETWORK_CONFIG_SOURCE_DHCP6)
83
0
                                continue;
84
0
                        break;
85
0
                case NETDEV_LOCAL_ADDRESS_SLAAC:
86
0
                        if (a->source != NETWORK_CONFIG_SOURCE_NDISC)
87
0
                                continue;
88
0
                        break;
89
0
                default:
90
0
                        assert_not_reached();
91
0
                }
92
93
0
                if (ret_family)
94
0
                        *ret_family = a->family;
95
0
                if (ret_address)
96
0
                        *ret_address = a->in_addr;
97
0
                return 1;
98
0
        }
99
100
0
        return -ENXIO;
101
0
}