/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 | } |