chiark / gitweb /
bootchart: Ensure that systemd is the init called after using bootchart
[elogind.git] / src / libsystemd-network / sd-dhcp6-lease.c
1 /***
2   This file is part of systemd.
3
4   Copyright (C) 2014 Tom Gundersen
5   Copyright (C) 2014 Intel Corporation. All rights reserved.
6
7   systemd is free software; you can redistribute it and/or modify it
8   under the terms of the GNU Lesser General Public License as published by
9   the Free Software Foundation; either version 2.1 of the License, or
10   (at your option) any later version.
11
12   systemd is distributed in the hope that it will be useful, but
13   WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   Lesser General Public License for more details.
16
17   You should have received a copy of the GNU Lesser General Public License
18   along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include <errno.h>
22
23 #include "util.h"
24
25 #include "dhcp6-lease-internal.h"
26
27 int dhcp6_lease_clear_timers(DHCP6IA *ia) {
28         assert_return(ia, -EINVAL);
29
30         ia->timeout_t1 = sd_event_source_unref(ia->timeout_t1);
31         ia->timeout_t2 = sd_event_source_unref(ia->timeout_t2);
32
33         return 0;
34 }
35
36 int dhcp6_lease_ia_rebind_expire(const DHCP6IA *ia, uint32_t *expire) {
37         DHCP6Address *addr;
38         uint32_t valid = 0, t;
39
40         assert_return(ia, -EINVAL);
41         assert_return(expire, -EINVAL);
42
43         LIST_FOREACH(addresses, addr, ia->addresses) {
44                 t = be32toh(addr->iaaddr.lifetime_valid);
45                 if (valid < t)
46                         valid = t;
47         }
48
49         t = be32toh(ia->lifetime_t2);
50         if (t > valid)
51                 return -EINVAL;
52
53         *expire = valid - t;
54
55         return 0;
56 }
57
58 DHCP6IA *dhcp6_lease_free_ia(DHCP6IA *ia) {
59         DHCP6Address *address;
60
61         if (!ia)
62                 return NULL;
63
64         dhcp6_lease_clear_timers(ia);
65
66         while (ia->addresses) {
67                 address = ia->addresses;
68
69                 LIST_REMOVE(addresses, ia->addresses, address);
70
71                 free(address);
72         }
73
74         return NULL;
75 }
76
77 int dhcp6_lease_set_serverid(sd_dhcp6_lease *lease, const uint8_t *id,
78                              size_t len) {
79         assert_return(lease, -EINVAL);
80         assert_return(id, -EINVAL);
81
82         free(lease->serverid);
83
84         lease->serverid = memdup(id, len);
85         if (!lease->serverid)
86                 return -EINVAL;
87
88         lease->serverid_len = len;
89
90         return 0;
91 }
92
93 int dhcp6_lease_get_serverid(sd_dhcp6_lease *lease, uint8_t **id, size_t *len) {
94         assert_return(lease, -EINVAL);
95         assert_return(id, -EINVAL);
96         assert_return(len, -EINVAL);
97
98         *id = lease->serverid;
99         *len = lease->serverid_len;
100
101         return 0;
102 }
103
104 int dhcp6_lease_set_preference(sd_dhcp6_lease *lease, uint8_t preference) {
105         assert_return(lease, -EINVAL);
106
107         lease->preference = preference;
108
109         return 0;
110 }
111
112 int dhcp6_lease_get_preference(sd_dhcp6_lease *lease, uint8_t *preference) {
113         assert_return(preference, -EINVAL);
114
115         if (!lease)
116                 return -EINVAL;
117
118         *preference = lease->preference;
119
120         return 0;
121 }
122
123 int dhcp6_lease_set_rapid_commit(sd_dhcp6_lease *lease) {
124         assert_return(lease, -EINVAL);
125
126         lease->rapid_commit = true;
127
128         return 0;
129 }
130
131 int dhcp6_lease_get_rapid_commit(sd_dhcp6_lease *lease, bool *rapid_commit) {
132         assert_return(lease, -EINVAL);
133         assert_return(rapid_commit, -EINVAL);
134
135         *rapid_commit = lease->rapid_commit;
136
137         return 0;
138 }
139
140 int dhcp6_lease_get_iaid(sd_dhcp6_lease *lease, be32_t *iaid) {
141         assert_return(lease, -EINVAL);
142         assert_return(iaid, -EINVAL);
143
144         *iaid = lease->ia.id;
145
146         return 0;
147 }
148
149 int sd_dhcp6_lease_get_address(sd_dhcp6_lease *lease, struct in6_addr *addr,
150                                uint32_t *lifetime_preferred,
151                                uint32_t *lifetime_valid) {
152         assert_return(lease, -EINVAL);
153         assert_return(addr, -EINVAL);
154         assert_return(lifetime_preferred, -EINVAL);
155         assert_return(lifetime_valid, -EINVAL);
156
157         if (!lease->addr_iter)
158                 return -ENOMSG;
159
160         memcpy(addr, &lease->addr_iter->iaaddr.address,
161                 sizeof(struct in6_addr));
162         *lifetime_preferred =
163                 be32toh(lease->addr_iter->iaaddr.lifetime_preferred);
164         *lifetime_valid = be32toh(lease->addr_iter->iaaddr.lifetime_valid);
165
166         lease->addr_iter = lease->addr_iter->addresses_next;
167
168         return 0;
169 }
170
171 void sd_dhcp6_lease_reset_address_iter(sd_dhcp6_lease *lease) {
172         if (lease)
173                 lease->addr_iter = lease->ia.addresses;
174 }
175
176 sd_dhcp6_lease *sd_dhcp6_lease_ref(sd_dhcp6_lease *lease) {
177         if (lease)
178                 assert_se(REFCNT_INC(lease->n_ref) >= 2);
179
180         return lease;
181 }
182
183 sd_dhcp6_lease *sd_dhcp6_lease_unref(sd_dhcp6_lease *lease) {
184         if (lease && REFCNT_DEC(lease->n_ref) == 0) {
185                 free(lease->serverid);
186                 dhcp6_lease_free_ia(&lease->ia);
187
188                 free(lease);
189         }
190
191         return NULL;
192 }
193
194 int dhcp6_lease_new(sd_dhcp6_lease **ret) {
195         sd_dhcp6_lease *lease;
196
197         lease = new0(sd_dhcp6_lease, 1);
198         if (!lease)
199                 return -ENOMEM;
200
201         lease->n_ref = REFCNT_INIT;
202
203         LIST_HEAD_INIT(lease->ia.addresses);
204
205         *ret = lease;
206         return 0;
207 }