]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/confile_utils.c
network: implement network clearing
[mirror_lxc.git] / src / lxc / confile_utils.c
CommitLineData
0b843d35
CB
1/* liblxcapi
2 *
3 * Copyright © 2017 Christian Brauner <christian.brauner@ubuntu.com>.
4 * Copyright © 2017 Canonical Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
ce2f5ae8
CB
20#include "config.h"
21
0b843d35 22#include <stdio.h>
ce2f5ae8 23#include <stdlib.h>
0b843d35
CB
24#include <string.h>
25
663e9916 26#include "conf.h"
ce2f5ae8
CB
27#include "confile.h"
28#include "confile_utils.h"
29#include "error.h"
663e9916 30#include "log.h"
ce2f5ae8 31#include "list.h"
0b843d35
CB
32#include "utils.h"
33
ce2f5ae8
CB
34lxc_log_define(lxc_confile_utils, lxc);
35
0b843d35
CB
36int parse_idmaps(const char *idmap, char *type, unsigned long *nsid,
37 unsigned long *hostid, unsigned long *range)
38{
39 int ret = -1;
40 unsigned long tmp_hostid, tmp_nsid, tmp_range;
41 char tmp_type;
42 char *window, *slide;
43 char *dup = NULL;
44
45 /* Duplicate string. */
46 dup = strdup(idmap);
47 if (!dup)
48 goto on_error;
49
50 /* A prototypical idmap entry would be: "u 1000 1000000 65536" */
51
52 /* align */
53 slide = window = dup;
54 /* skip whitespace */
55 slide += strspn(slide, " \t\r");
56 if (slide != window && *slide == '\0')
57 goto on_error;
58
59 /* Validate type. */
60 if (*slide != 'u' && *slide != 'g')
61 goto on_error;
62 /* Assign type. */
63 tmp_type = *slide;
64
65 /* move beyond type */
66 slide++;
67 /* align */
68 window = slide;
69 /* Validate that only whitespace follows. */
70 slide += strspn(slide, " \t\r");
71 /* There must be whitespace. */
72 if (slide == window)
73 goto on_error;
74
75 /* Mark beginning of nsuid. */
76 window = slide;
77 /* Validate that non-whitespace follows. */
78 slide += strcspn(slide, " \t\r");
79 /* There must be non-whitespace. */
80 if (slide == window || *slide == '\0')
81 goto on_error;
82 /* Mark end of nsuid. */
83 *slide = '\0';
84
85 /* Parse nsuid. */
86 if (lxc_safe_ulong(window, &tmp_nsid) < 0)
87 goto on_error;
88
89 /* Move beyond \0. */
90 slide++;
91 /* align */
92 window = slide;
93 /* Validate that only whitespace follows. */
94 slide += strspn(slide, " \t\r");
95 /* If there was only one whitespace then we whiped it with our \0 above.
96 * So only ensure that we're not at the end of the string.
97 */
98 if (*slide == '\0')
99 goto on_error;
100
101 /* Mark beginning of hostid. */
102 window = slide;
103 /* Validate that non-whitespace follows. */
104 slide += strcspn(slide, " \t\r");
105 /* There must be non-whitespace. */
106 if (slide == window || *slide == '\0')
107 goto on_error;
108 /* Mark end of nsuid. */
109 *slide = '\0';
110
111 /* Parse hostid. */
112 if (lxc_safe_ulong(window, &tmp_hostid) < 0)
113 goto on_error;
114
115 /* Move beyond \0. */
116 slide++;
117 /* align */
118 window = slide;
119 /* Validate that only whitespace follows. */
120 slide += strspn(slide, " \t\r");
121 /* If there was only one whitespace then we whiped it with our \0 above.
122 * So only ensure that we're not at the end of the string.
123 */
124 if (*slide == '\0')
125 goto on_error;
126
127 /* Mark beginning of range. */
128 window = slide;
129 /* Validate that non-whitespace follows. */
130 slide += strcspn(slide, " \t\r");
131 /* There must be non-whitespace. */
132 if (slide == window)
133 goto on_error;
134
135 /* The range is the last valid entry we expect. So make sure that there
136 * is not trailing garbage and if there is, error out.
137 */
138 if (*(slide + strspn(slide, " \t\r\n")) != '\0')
139 goto on_error;
140 /* Mark end of range. */
141 *slide = '\0';
142
143 /* Parse range. */
144 if (lxc_safe_ulong(window, &tmp_range) < 0)
145 goto on_error;
146
147 *type = tmp_type;
148 *nsid = tmp_nsid;
149 *hostid = tmp_hostid;
150 *range = tmp_range;
151
152 /* Yay, we survived. */
153 ret = 0;
154
155on_error:
156 free(dup);
157
158 return ret;
159}
663e9916
CB
160
161bool lxc_config_value_empty(const char *value)
162{
163 if (value && strlen(value) > 0)
164 return false;
165
166 return true;
167}
ce2f5ae8
CB
168
169struct lxc_netdev *lxc_find_netdev_by_idx(struct lxc_conf *conf,
170 unsigned int idx)
171{
172 struct lxc_netdev *netdev = NULL;
173 struct lxc_list *networks = &conf->network;
174 struct lxc_list *insert = networks;
175
176 /* lookup network */
177 if (lxc_list_empty(networks))
178 return NULL;
179
180 lxc_list_for_each(insert, networks) {
181 netdev = insert->elem;
182 if (netdev->idx >= idx)
183 break;
184 }
185
186 /* network already exists */
187 if (netdev->idx == idx)
188 return netdev;
189
190 return NULL;
191}
192
193/* Takes care of finding the correct netdev struct in the networks list or
194 * allocates a new one if it couldn't be found.
195 */
196struct lxc_netdev *lxc_get_netdev_by_idx(struct lxc_conf *conf,
197 unsigned int idx)
198{
199 struct lxc_list *newlist;
200 struct lxc_netdev *netdev = NULL;
201 struct lxc_list *networks = &conf->network;
202 struct lxc_list *insert = networks;
203
204 /* lookup network */
205 netdev = lxc_find_netdev_by_idx(conf, idx);
206 if (netdev)
207 return netdev;
208
209 /* network does not exist */
210 netdev = malloc(sizeof(*netdev));
211 if (!netdev)
212 return NULL;
213
214 memset(netdev, 0, sizeof(*netdev));
215 lxc_list_init(&netdev->ipv4);
216 lxc_list_init(&netdev->ipv6);
217
218 /* give network a unique index */
219 netdev->idx = idx;
220
221 /* prepare new list */
222 newlist = malloc(sizeof(*newlist));
223 if (!newlist) {
224 free(netdev);
225 return NULL;
226 }
227
228 lxc_list_init(newlist);
229 newlist->elem = netdev;
230
231 /* Insert will now point to the correct position to insert the new
232 * netdev.
233 */
234 lxc_list_add_tail(insert, newlist);
235
236 return netdev;
237}
1ed6ba91
CB
238
239void lxc_log_configured_netdevs(const struct lxc_conf *conf)
240{
241 struct lxc_netdev *netdev;
242 struct lxc_list *it = (struct lxc_list *)&conf->network;;
243
244 if ((conf->loglevel != LXC_LOG_LEVEL_TRACE) &&
245 (lxc_log_get_level() != LXC_LOG_LEVEL_TRACE))
246 return;
247
248 if (lxc_list_empty(it)) {
249 TRACE("container has no networks configured");
250 return;
251 }
252
253 lxc_list_for_each(it, &conf->network) {
254 netdev = it->elem;
255
256 TRACE("index: %d", netdev->idx);
257 switch (netdev->type) {
258 case LXC_NET_VETH:
259 TRACE("type: veth");
260 break;
261 case LXC_NET_MACVLAN:
262 TRACE("type: macvlan");
263 break;
264 case LXC_NET_VLAN:
265 TRACE("type: vlan");
266 break;
267 case LXC_NET_PHYS:
268 TRACE("type: phys");
269 break;
270 case LXC_NET_EMPTY:
271 TRACE("type: empty");
272 break;
273 case LXC_NET_NONE:
274 TRACE("type: none");
275 break;
276 default:
277 ERROR("invalid network type %d", netdev->type);
278 return;
279 }
280
281 TRACE("flags: %s", netdev->flags == IFF_UP ? "up" : "none");
282 if (netdev->link)
283 TRACE("link: %s", netdev->link);
284 if (netdev->name)
285 TRACE("name: %s", netdev->name);
286 if (netdev->hwaddr)
287 TRACE("hwaddr: %s", netdev->hwaddr);
288 if (netdev->mtu)
289 TRACE("mtu: %s", netdev->mtu);
290 if (netdev->upscript)
291 TRACE("upscript: %s", netdev->upscript);
292 if (netdev->downscript)
293 TRACE("downscript: %s", netdev->downscript);
294 }
295}