connman: update patches to start before remote-fs-pre.target
[opendreambox.git] / meta-opendreambox / recipes-connectivity / connman / connman / 0002-device-inet-Create-read-only-devices-instead-of-igno.patch
1 From 6f59293860dd9ed9ff4148812d965b076c4b8f12 Mon Sep 17 00:00:00 2001
2 From: Andreas Oberritter <obi@opendreambox.org>
3 Date: Wed, 29 Oct 2014 21:19:25 +0100
4 Subject: [PATCH 2/3] device/inet: Create read-only devices instead of ignoring
5  completely
6
7 Booting an nfsroot with connman requires passing -I eth0 to ignore
8 the interface. This isn't very nice, for at least the following
9 reasons:
10
11 * A User interface based on connman is led to believe that there's no
12   network interface and thus connman seems to be offline when it's not.
13 * The DHCP lease obtained by the kernel won't get renewed.
14 * DNS servers won't get obtained from DHCP, thus requiring a workaround
15   to copy /proc/net/pnp to /etc/resolv.conf and passing -r to connmand.
16
17 Therefore change behaviour to restrict interfaces passed with -I to
18 read-only ioctls.
19
20 Signed-off-by: Andreas Oberritter <obi@opendreambox.org>
21 ---
22  Makefile.am      |   1 +
23  include/device.h |   3 ++
24  src/device.c     |  34 +++++++++++---
25  src/inet.c       | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++-----
26  src/ipconfig.c   |  16 +++++++
27  src/rtnl.c       |  20 +-------
28  6 files changed, 178 insertions(+), 36 deletions(-)
29
30 diff --git a/Makefile.am b/Makefile.am
31 index a574170..47aa7b8 100644
32 --- a/Makefile.am
33 +++ b/Makefile.am
34 @@ -209,6 +209,7 @@ src_connmand_CFLAGS = @DBUS_CFLAGS@ @GLIB_CFLAGS@ @XTABLES_CFLAGS@ \
35                                 -DSTORAGEDIR=\""$(storagedir)\"" \
36                                 -DVPN_STORAGEDIR=\""$(vpn_storagedir)\"" \
37                                 -DCONFIGDIR=\""$(configdir)\"" \
38 +                               -DCONNMAND \
39                                 -I$(builddir)/src
40  
41  EXTRA_DIST = src/genbuiltin src/connman-dbus.conf src/connman-polkit.conf \
42 diff --git a/include/device.h b/include/device.h
43 index 57b925c..3c9615f 100644
44 --- a/include/device.h
45 +++ b/include/device.h
46 @@ -93,6 +93,9 @@ int connman_device_set_string(struct connman_device *device,
47                                         const char *key, const char *value);
48  const char *connman_device_get_string(struct connman_device *device,
49                                                         const char *key);
50 +void connman_device_set_readonly(struct connman_device *device,
51 +                                               bool readonly);
52 +bool connman_device_get_readonly(struct connman_device *device);
53  
54  int connman_device_add_network(struct connman_device *device,
55                                         struct connman_network *network);
56 diff --git a/src/device.c b/src/device.c
57 index c0683ab..301e850 100644
58 --- a/src/device.c
59 +++ b/src/device.c
60 @@ -54,6 +54,7 @@ struct connman_device {
61         bool powered;
62         bool scanning;
63         bool disconnected;
64 +       bool readonly;
65         char *name;
66         char *node;
67         char *address;
68 @@ -782,6 +783,32 @@ bool connman_device_get_disconnected(struct connman_device *device)
69  }
70  
71  /**
72 + * connman_device_set_readonly:
73 + * @device: device structure
74 + * @readonly: read-only state
75 + *
76 + * Change read-only state of device
77 + */
78 +void connman_device_set_readonly(struct connman_device *device,
79 +                                               bool readonly)
80 +{
81 +       DBG("device %p readonly %d", device, readonly);
82 +
83 +       device->readonly = readonly;
84 +}
85 +
86 +/**
87 + * connman_device_get_readonly:
88 + * @device: device structure
89 + *
90 + * Get device read-only state
91 + */
92 +bool connman_device_get_readonly(struct connman_device *device)
93 +{
94 +       return device->readonly;
95 +}
96 +
97 +/**
98   * connman_device_set_string:
99   * @device: device structure
100   * @key: unique identifier
101 @@ -1246,12 +1273,6 @@ struct connman_device *connman_device_create_from_index(int index)
102         if (!devname)
103                 return NULL;
104  
105 -       if (__connman_device_isfiltered(devname)) {
106 -               connman_info("Ignoring interface %s (filtered)", devname);
107 -               g_free(devname);
108 -               return NULL;
109 -       }
110 -
111         type = __connman_rtnl_get_device_type(index);
112  
113         switch (type) {
114 @@ -1305,6 +1326,7 @@ struct connman_device *connman_device_create_from_index(int index)
115         }
116  
117         connman_device_set_string(device, "Address", addr);
118 +       connman_device_set_readonly(device, __connman_device_isfiltered(devname));
119  
120  done:
121         g_free(devname);
122 diff --git a/src/inet.c b/src/inet.c
123 index cd220ff..ac646c9 100644
124 --- a/src/inet.c
125 +++ b/src/inet.c
126 @@ -55,6 +55,21 @@
127         ((struct rtattr *) (((uint8_t*) (nmsg)) +       \
128         NLMSG_ALIGN((nmsg)->nlmsg_len)))
129  
130 +static inline int __connman_inet_check_write_perm(int ifindex)
131 +{
132 +    #if defined(CONNMAND)
133 +       struct connman_device *dev = connman_device_find_by_index(ifindex);
134 +
135 +       if (!dev)
136 +               return -ENODEV;
137 +
138 +       if (connman_device_get_readonly(dev))
139 +               return -EPERM;
140 +    #endif
141 +
142 +       return 0;
143 +}
144 +
145  int __connman_inet_rtnl_addattr_l(struct nlmsghdr *n, size_t max_length,
146                                 int type, const void *data, size_t data_length)
147  {
148 @@ -104,6 +119,11 @@ int __connman_inet_modify_address(int cmd, int flags,
149         if (family != AF_INET && family != AF_INET6)
150                 return -EINVAL;
151  
152 +       if (__connman_inet_check_write_perm(index) < 0) {
153 +               DBG("insufficient permission, ignoring request");
154 +               return 0;
155 +       }
156 +
157         memset(&request, 0, sizeof(request));
158  
159         header = (struct nlmsghdr *)request;
160 @@ -245,6 +265,12 @@ int connman_inet_ifup(int index)
161         struct ifreq ifr;
162         int sk, err;
163  
164 +       err = __connman_inet_check_write_perm(index);
165 +       if (err < 0) {
166 +               DBG("insufficient permission");
167 +               return err;
168 +       }
169 +
170         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
171         if (sk < 0)
172                 return -errno;
173 @@ -288,6 +314,12 @@ int connman_inet_ifdown(int index)
174         struct sockaddr_in *addr;
175         int sk, err;
176  
177 +       err = __connman_inet_check_write_perm(index);
178 +       if (err < 0) {
179 +               DBG("insufficient permission");
180 +               return err;
181 +       }
182 +
183         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
184         if (sk < 0)
185                 return -errno;
186 @@ -454,11 +486,17 @@ int connman_inet_add_network_route(int index, const char *host,
187         struct ifreq ifr;
188         struct rtentry rt;
189         struct sockaddr_in addr;
190 -       int sk, err = 0;
191 +       int sk, err;
192  
193         DBG("index %d host %s gateway %s netmask %s", index,
194                 host, gateway, netmask);
195  
196 +       err = __connman_inet_check_write_perm(index);
197 +       if (err < 0) {
198 +               DBG("insufficient permission");
199 +               return err;
200 +       }
201 +
202         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
203         if (sk < 0) {
204                 err = -errno;
205 @@ -525,10 +563,16 @@ int connman_inet_del_network_route(int index, const char *host)
206         struct ifreq ifr;
207         struct rtentry rt;
208         struct sockaddr_in addr;
209 -       int sk, err = 0;
210 +       int sk, err;
211  
212         DBG("index %d host %s", index, host);
213  
214 +       err = __connman_inet_check_write_perm(index);
215 +       if (err < 0) {
216 +               DBG("insufficient permission");
217 +               return err;
218 +       }
219 +
220         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
221         if (sk < 0) {
222                 err = -errno;
223 @@ -573,13 +617,19 @@ int connman_inet_del_ipv6_network_route(int index, const char *host,
224                                                 unsigned char prefix_len)
225  {
226         struct in6_rtmsg rt;
227 -       int sk, err = 0;
228 +       int sk, err;
229  
230         DBG("index %d host %s", index, host);
231  
232         if (!host)
233                 return -EINVAL;
234  
235 +       err = __connman_inet_check_write_perm(index);
236 +       if (err < 0) {
237 +               DBG("insufficient permission");
238 +               return err;
239 +       }
240 +
241         memset(&rt, 0, sizeof(rt));
242  
243         rt.rtmsg_dst_len = prefix_len;
244 @@ -623,13 +673,19 @@ int connman_inet_add_ipv6_network_route(int index, const char *host,
245                                         unsigned char prefix_len)
246  {
247         struct in6_rtmsg rt;
248 -       int sk, err = 0;
249 +       int sk, err;
250  
251         DBG("index %d host %s gateway %s", index, host, gateway);
252  
253         if (!host)
254                 return -EINVAL;
255  
256 +       err = __connman_inet_check_write_perm(index);
257 +       if (err < 0) {
258 +               DBG("insufficient permission");
259 +               return err;
260 +       }
261 +
262         memset(&rt, 0, sizeof(rt));
263  
264         rt.rtmsg_dst_len = prefix_len;
265 @@ -677,13 +733,19 @@ int connman_inet_add_ipv6_host_route(int index, const char *host,
266  int connman_inet_clear_ipv6_gateway_address(int index, const char *gateway)
267  {
268         struct in6_rtmsg rt;
269 -       int sk, err = 0;
270 +       int sk, err;
271  
272         DBG("index %d gateway %s", index, gateway);
273  
274         if (!gateway)
275                 return -EINVAL;
276  
277 +       err = __connman_inet_check_write_perm(index);
278 +       if (err < 0) {
279 +               DBG("insufficient permission");
280 +               return err;
281 +       }
282 +
283         memset(&rt, 0, sizeof(rt));
284  
285         if (inet_pton(AF_INET6, gateway, &rt.rtmsg_gateway) < 0) {
286 @@ -720,10 +782,16 @@ int connman_inet_set_gateway_interface(int index)
287         struct ifreq ifr;
288         struct rtentry rt;
289         struct sockaddr_in addr;
290 -       int sk, err = 0;
291 +       int sk, err;
292  
293         DBG("index %d", index);
294  
295 +       err = __connman_inet_check_write_perm(index);
296 +       if (err < 0) {
297 +               DBG("insufficient permission");
298 +               return err;
299 +       }
300 +
301         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
302         if (sk < 0) {
303                 err = -errno;
304 @@ -773,10 +841,16 @@ int connman_inet_set_ipv6_gateway_interface(int index)
305         struct rtentry rt;
306         struct sockaddr_in6 addr;
307         const struct in6_addr any = IN6ADDR_ANY_INIT;
308 -       int sk, err = 0;
309 +       int sk, err;
310  
311         DBG("index %d", index);
312  
313 +       err = __connman_inet_check_write_perm(index);
314 +       if (err < 0) {
315 +               DBG("insufficient permission");
316 +               return err;
317 +       }
318 +
319         sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
320         if (sk < 0) {
321                 err = -errno;
322 @@ -825,10 +899,16 @@ int connman_inet_clear_gateway_address(int index, const char *gateway)
323         struct ifreq ifr;
324         struct rtentry rt;
325         struct sockaddr_in addr;
326 -       int sk, err = 0;
327 +       int sk, err;
328  
329         DBG("index %d gateway %s", index, gateway);
330  
331 +       err = __connman_inet_check_write_perm(index);
332 +       if (err < 0) {
333 +               DBG("insufficient permission");
334 +               return err;
335 +       }
336 +
337         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
338         if (sk < 0) {
339                 err = -errno;
340 @@ -882,10 +962,16 @@ int connman_inet_clear_gateway_interface(int index)
341         struct ifreq ifr;
342         struct rtentry rt;
343         struct sockaddr_in addr;
344 -       int sk, err = 0;
345 +       int sk, err;
346  
347         DBG("index %d", index);
348  
349 +       err = __connman_inet_check_write_perm(index);
350 +       if (err < 0) {
351 +               DBG("insufficient permission");
352 +               return err;
353 +       }
354 +
355         sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
356         if (sk < 0) {
357                 err = -errno;
358 @@ -935,10 +1021,16 @@ int connman_inet_clear_ipv6_gateway_interface(int index)
359         struct rtentry rt;
360         struct sockaddr_in6 addr;
361         const struct in6_addr any = IN6ADDR_ANY_INIT;
362 -       int sk, err = 0;
363 +       int sk, err;
364  
365         DBG("index %d", index);
366  
367 +       err = __connman_inet_check_write_perm(index);
368 +       if (err < 0) {
369 +               DBG("insufficient permission");
370 +               return err;
371 +       }
372 +
373         sk = socket(PF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
374         if (sk < 0) {
375                 err = -errno;
376 @@ -1035,11 +1127,17 @@ bool connman_inet_compare_subnet(int index, const char *host)
377  int connman_inet_remove_from_bridge(int index, const char *bridge)
378  {
379         struct ifreq ifr;
380 -       int sk, err = 0;
381 +       int sk, err;
382  
383         if (!bridge)
384                 return -EINVAL;
385  
386 +       err = __connman_inet_check_write_perm(index);
387 +       if (err < 0) {
388 +               DBG("insufficient permission");
389 +               return err;
390 +       }
391 +
392         sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
393         if (sk < 0) {
394                 err = -errno;
395 @@ -1066,11 +1164,17 @@ out:
396  int connman_inet_add_to_bridge(int index, const char *bridge)
397  {
398         struct ifreq ifr;
399 -       int sk, err = 0;
400 +       int sk, err;
401  
402         if (!bridge)
403                 return -EINVAL;
404  
405 +       err = __connman_inet_check_write_perm(index);
406 +       if (err < 0) {
407 +               DBG("insufficient permission");
408 +               return err;
409 +       }
410 +
411         sk = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
412         if (sk < 0) {
413                 err = -errno;
414 @@ -1099,6 +1203,12 @@ int connman_inet_set_mtu(int index, int mtu)
415         struct ifreq ifr;
416         int sk, err;
417  
418 +       err = __connman_inet_check_write_perm(index);
419 +       if (err < 0) {
420 +               DBG("insufficient permission");
421 +               return err;
422 +       }
423 +
424         sk = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
425         if (sk < 0)
426                 return sk;
427 @@ -2812,6 +2922,12 @@ static int iproute_default_modify(int cmd, uint32_t table_id, int ifindex,
428         if (ret <= 0)
429                 return -EINVAL;
430  
431 +       ret = __connman_inet_check_write_perm(ifindex);
432 +       if (ret < 0) {
433 +               DBG("insufficient permission");
434 +               return ret;
435 +       }
436 +
437         memset(&rth, 0, sizeof(rth));
438  
439         rth.req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
440 diff --git a/src/ipconfig.c b/src/ipconfig.c
441 index 2e840a6..a353112 100644
442 --- a/src/ipconfig.c
443 +++ b/src/ipconfig.c
444 @@ -92,6 +92,17 @@ static GHashTable *ipdevice_hash = NULL;
445  static GList *ipconfig_list = NULL;
446  static bool is_ipv6_supported = false;
447  
448 +static int __connman_ipconfig_check_write_perm(const gchar *ifname)
449 +{
450 +       int index = connman_inet_ifindex(ifname);
451 +       struct connman_device *dev = connman_device_find_by_index(index);
452 +
453 +       if (!dev)
454 +               return -ENODEV;
455 +
456 +       return connman_device_get_readonly(dev) ? -EPERM : 0;
457 +}
458 +
459  void __connman_ipconfig_clear_address(struct connman_ipconfig *ipconfig)
460  {
461         if (!ipconfig)
462 @@ -211,6 +222,8 @@ static void set_ipv6_state(gchar *ifname, bool enable)
463  
464         if (!ifname)
465                 path = g_strdup("/proc/sys/net/ipv6/conf/all/disable_ipv6");
466 +       else if (__connman_ipconfig_check_write_perm(ifname) < 0)
467 +               return;
468         else
469                 path = g_strdup_printf(
470                         "/proc/sys/net/ipv6/conf/%s/disable_ipv6", ifname);
471 @@ -274,6 +287,9 @@ static void set_ipv6_privacy(gchar *ifname, int value)
472         if (!ifname)
473                 return;
474  
475 +       if (__connman_ipconfig_check_write_perm(ifname) < 0)
476 +               return;
477 +
478         path = g_strdup_printf("/proc/sys/net/ipv6/conf/%s/use_tempaddr",
479                                                                 ifname);
480  
481 diff --git a/src/rtnl.c b/src/rtnl.c
482 index a46aa28..b5a6dfa 100644
483 --- a/src/rtnl.c
484 +++ b/src/rtnl.c
485 @@ -83,17 +83,6 @@ static void free_interface(gpointer data)
486         g_free(interface);
487  }
488  
489 -static bool ether_blacklisted(const char *name)
490 -{
491 -       if (!name)
492 -               return true;
493 -
494 -       if (__connman_device_isfiltered(name))
495 -               return true;
496 -
497 -       return false;
498 -}
499 -
500  static bool wext_interface(char *ifname)
501  {
502         struct iwreq wrq;
503 @@ -124,13 +113,8 @@ static void read_uevent(struct interface_data *interface)
504  
505         name = connman_inet_ifname(interface->index);
506  
507 -       if (ether_blacklisted(name)) {
508 -               interface->service_type = CONNMAN_SERVICE_TYPE_UNKNOWN;
509 -               interface->device_type = CONNMAN_DEVICE_TYPE_UNKNOWN;
510 -       } else {
511 -               interface->service_type = CONNMAN_SERVICE_TYPE_ETHERNET;
512 -               interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET;
513 -       }
514 +       interface->service_type = CONNMAN_SERVICE_TYPE_ETHERNET;
515 +       interface->device_type = CONNMAN_DEVICE_TYPE_ETHERNET;
516  
517         filename = g_strdup_printf("/sys/class/net/%s/uevent", name);
518  
519 -- 
520 1.9.1
521