chiark / gitweb /
networkctl: remove unused variable
[elogind.git] / src / network / networkd-dhcp6.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright (C) 2014 Intel Corporation. All rights reserved.
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <netinet/ether.h>
23 #include <linux/if.h>
24
25 #include "networkd-link.h"
26 #include "network-internal.h"
27
28 #include "sd-icmp6-nd.h"
29 #include "sd-dhcp6-client.h"
30
31 static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) {
32         Link *link = userdata;
33
34         assert(link);
35         assert(link->network);
36         assert(link->manager);
37
38         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
39                 return;
40
41         switch(event) {
42         case DHCP6_EVENT_STOP:
43         case DHCP6_EVENT_RESEND_EXPIRE:
44         case DHCP6_EVENT_RETRANS_MAX:
45         case DHCP6_EVENT_IP_ACQUIRE:
46         case DHCP6_EVENT_INFORMATION_REQUEST:
47                 log_link_debug(link, "DHCPv6 event %d", event);
48
49                 break;
50
51         default:
52                 if (event < 0)
53                         log_link_warning(link, "DHCPv6 error: %s",
54                                          strerror(-event));
55                 else
56                         log_link_warning(link, "DHCPv6 unknown event: %d",
57                                          event);
58                 return;
59         }
60 }
61
62 static int dhcp6_configure(Link *link, int event) {
63         int r;
64         bool information_request;
65
66         assert_return(link, -EINVAL);
67
68         if (link->dhcp6_client) {
69                 if (event != ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED)
70                         return 0;
71
72                 r = sd_dhcp6_client_get_information_request(link->dhcp6_client,
73                                                         &information_request);
74                 if (r < 0) {
75                         log_link_warning(link, "Could not get DHCPv6 Information request setting");
76                         link->dhcp6_client =
77                                 sd_dhcp6_client_unref(link->dhcp6_client);
78                         return r;
79                 }
80
81                 if (!information_request)
82                         return r;
83
84                 r = sd_dhcp6_client_set_information_request(link->dhcp6_client,
85                                                         false);
86                 if (r < 0) {
87                         log_link_warning(link, "Could not unset DHCPv6 Information request");
88                         link->dhcp6_client =
89                                 sd_dhcp6_client_unref(link->dhcp6_client);
90                         return r;
91                 }
92
93                 r = sd_dhcp6_client_start(link->dhcp6_client);
94                 if (r < 0) {
95                         log_link_warning(link, "Could not restart DHCPv6 after enabling Information request");
96                         link->dhcp6_client =
97                                 sd_dhcp6_client_unref(link->dhcp6_client);
98                         return r;
99                 }
100
101                 return r;
102         }
103
104         r = sd_dhcp6_client_new(&link->dhcp6_client);
105         if (r < 0)
106                 return r;
107
108         r = sd_dhcp6_client_attach_event(link->dhcp6_client, NULL, 0);
109         if (r < 0) {
110                 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
111                 return r;
112         }
113
114         r = sd_dhcp6_client_set_mac(link->dhcp6_client,
115                                     (const uint8_t *) &link->mac,
116                                     sizeof (link->mac), ARPHRD_ETHER);
117         if (r < 0) {
118                 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
119                 return r;
120         }
121
122         r = sd_dhcp6_client_set_index(link->dhcp6_client, link->ifindex);
123         if (r < 0) {
124                 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
125                 return r;
126         }
127
128         r = sd_dhcp6_client_set_callback(link->dhcp6_client, dhcp6_handler,
129                                          link);
130         if (r < 0) {
131                 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
132                 return r;
133         }
134
135         if (event == ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER) {
136                 r = sd_dhcp6_client_set_information_request(link->dhcp6_client,
137                                                         true);
138                 if (r < 0) {
139                         link->dhcp6_client =
140                                 sd_dhcp6_client_unref(link->dhcp6_client);
141                         return r;
142                 }
143         }
144
145         r = sd_dhcp6_client_start(link->dhcp6_client);
146         if (r < 0)
147                 link->dhcp6_client = sd_dhcp6_client_unref(link->dhcp6_client);
148
149         return r;
150 }
151
152 static void icmp6_router_handler(sd_icmp6_nd *nd, int event, void *userdata) {
153         Link *link = userdata;
154
155         assert(link);
156         assert(link->network);
157         assert(link->manager);
158
159         if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER))
160                 return;
161
162         switch(event) {
163         case ICMP6_EVENT_ROUTER_ADVERTISMENT_NONE:
164                 return;
165
166         case ICMP6_EVENT_ROUTER_ADVERTISMENT_TIMEOUT:
167         case ICMP6_EVENT_ROUTER_ADVERTISMENT_OTHER:
168         case ICMP6_EVENT_ROUTER_ADVERTISMENT_MANAGED:
169                 break;
170
171         default:
172                 if (event < 0)
173                         log_link_warning(link, "ICMPv6 error: %s",
174                                          strerror(-event));
175                 else
176                         log_link_warning(link, "ICMPv6 unknown event: %d",
177                                          event);
178
179                 return;
180         }
181
182         dhcp6_configure(link, event);
183 }
184
185 int icmp6_configure(Link *link) {
186         int r;
187
188         assert_return(link, -EINVAL);
189
190         r = sd_icmp6_nd_new(&link->icmp6_router_discovery);
191         if (r < 0)
192                 return r;
193
194         r = sd_icmp6_nd_attach_event(link->icmp6_router_discovery, NULL, 0);
195         if (r < 0)
196                 return r;
197
198         r = sd_icmp6_nd_set_mac(link->icmp6_router_discovery, &link->mac);
199         if (r < 0)
200                 return r;
201
202         r = sd_icmp6_nd_set_index(link->icmp6_router_discovery, link->ifindex);
203         if (r < 0)
204                 return r;
205
206         r = sd_icmp6_nd_set_callback(link->icmp6_router_discovery,
207                                 icmp6_router_handler, link);
208
209         return r;
210 }