source: rtems-libbsd/rtemsbsd/rtems/rtems-bsd-rc-conf-net.c @ bd09f9f

5-freebsd-12
Last change on this file since bd09f9f was bd09f9f, checked in by Sebastian Huber <sebastian.huber@…>, on May 3, 2018 at 6:18:24 AM

rc_conf: Do not create directories used by dhcpcd

The dhcpcd will create the directories on its own.

  • Property mode set to 100644
File size: 20.0 KB
Line 
1/*
2 * Copyright (c) 2016 Chris Johns <chrisj@rtems.org>.  All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26/*
27 * Handle the networking directives found in rc.conf.
28 *  - ifconfig_*
29 *  - cloned_interfaces
30 *  - autobridge_interfaces
31 *  - autobridge_bridge*
32 *  - defaultrouter
33 */
34
35#define _GNU_SOURCE
36
37#include <sys/param.h>
38#include <sys/types.h>
39#include <sys/queue.h>
40#include <sys/kernel.h>
41#include <sysexits.h>
42
43#include <ifaddrs.h>
44#include <arpa/inet.h>
45#include <net/if.h>
46#include <net/route.h>
47#include <netinet/in.h>
48#include <sys/socket.h>
49
50#include <errno.h>
51#include <stddef.h>
52#include <stdio.h>
53#include <stdlib.h>
54#include <string.h>
55#include <unistd.h>
56
57#include <rtems.h>
58#include <rtems/chain.h>
59
60#include <machine/rtems-bsd-commands.h>
61#include <machine/rtems-bsd-rc-conf-services.h>
62
63#include <rtems/rtems-routes.h>
64
65/*
66 * Default defaultroute_delay is 30seconds.
67 */
68static int defaultroute_delay_secs = 30;
69
70/*
71 * Show a result.
72 */
73static void
74show_result(const char* label, int r)
75{
76  if (r < 0)
77    fprintf(stderr, "error: %s: %s\n", label, strerror(errno));
78}
79
80/*
81 * cloned_interfaces
82 *
83 * eg cloned_interfaces="vlan0 bridge0 tap1 tap2"
84 *
85 * See 'man rc.conf(5)' on FreeBSD.
86 */
87static int
88cloned_interfaces(rtems_bsd_rc_conf* rc_conf, rtems_bsd_rc_conf_argc_argv* aa)
89{
90  int arg;
91  int r = 0;
92
93  r = rtems_bsd_rc_conf_find(rc_conf, "cloned_interfaces", aa);
94  if (r < 0) {
95    if (errno == ENOENT)
96      r = 0;
97    return r;
98  }
99
100  for (arg = 1; arg < aa->argc; ++arg) {
101    const char* ifconfg_args[] = {
102      "ifconfig", aa->argv[arg], "create", NULL
103    };
104    rtems_bsd_rc_conf_print_cmd(rc_conf, "cloning_interfaces", 3, ifconfg_args);
105    rtems_bsd_command_ifconfig(3, (char**) ifconfg_args);
106  }
107
108  return 0;
109}
110
111/*
112 * create_args_'interface'
113 *
114 * eg create_args_myvlan="vlan 102"
115 *
116 * See 'man rc.conf(5)' on FreeBSD.
117 */
118typedef struct {
119  rtems_chain_node node;
120  const char*      label;
121  int              argc;
122  const char**     argv;
123} create_args_item;
124
125static RTEMS_CHAIN_DEFINE_EMPTY(create_args_items);
126
127static int
128load_create_args(rtems_bsd_rc_conf* rc_conf, rtems_bsd_rc_conf_argc_argv* aa)
129{
130  int r = 0;
131
132  r = rtems_bsd_rc_conf_find(rc_conf, "create_args_.*", aa);
133
134  while (r == 0) {
135    rtems_chain_node* node;
136    const char*       label;
137    create_args_item* item;
138    int               arg;
139
140    rtems_bsd_rc_conf_print_cmd(rc_conf, "create_args_", aa->argc, aa->argv);
141
142    label = aa->argv[0] + strlen("create_args_");
143
144    node = rtems_chain_first(&create_args_items);
145
146    while (!rtems_chain_is_tail(&create_args_items, node)) {
147      item = (create_args_item*) node;
148      if (strcasecmp(item->label, label) == 0) {
149        fprintf(stderr, "error: %s:%d: duplicate create args entry: %s\n",
150                rtems_bsd_rc_conf_name(rc_conf),
151                rtems_bsd_rc_conf_line(rc_conf),
152                aa->argv[0]);
153        errno = EEXIST;
154        return -1;
155      }
156      node = rtems_chain_next(node);
157    }
158
159    item = calloc(1, sizeof(*item));
160    if (item == NULL) {
161      errno = ENOMEM;
162      fprintf(stderr, "error: %s:%d: %s\n",
163              rtems_bsd_rc_conf_name(rc_conf),
164              rtems_bsd_rc_conf_line(rc_conf),
165              strerror(errno));
166      return -1;
167    }
168
169    item->argc = aa->argc;
170
171    item->label = strdup(label);
172    if (item->label == NULL) {
173      free(item);
174      errno = ENOMEM;
175      fprintf(stderr, "error: %s:%d: %s\n",
176              rtems_bsd_rc_conf_name(rc_conf),
177              rtems_bsd_rc_conf_line(rc_conf),
178              strerror(errno));
179      return -1;
180    }
181
182    item->argv = calloc(aa->argc + 1, sizeof(char*));
183    if (item->argv == NULL) {
184      free((void*) item->label);
185      free(item);
186      errno = ENOMEM;
187      fprintf(stderr, "error: %s:%d: %s\n",
188              rtems_bsd_rc_conf_name(rc_conf),
189              rtems_bsd_rc_conf_line(rc_conf),
190              strerror(errno));
191      return -1;
192    }
193
194    for (arg = 0; arg < aa->argc; ++arg) {
195      item->argv[arg] = strdup(aa->argv[0]);
196      if (item->argv[arg] == NULL) {
197        int a;
198        for (a = 0; a < arg; ++a)
199          free((void*) item->argv[a]);
200        free(item->argv);
201        free((void*) item->label);
202        free(item);
203        errno = ENOMEM;
204        fprintf(stderr, "error: %s:%d: %s\n",
205                rtems_bsd_rc_conf_name(rc_conf),
206                rtems_bsd_rc_conf_line(rc_conf),
207                strerror(errno));
208        return -1;
209      }
210    }
211
212    rtems_chain_append(&create_args_items, &item->node);
213
214    r = rtems_bsd_rc_conf_find_next(rc_conf, aa);
215  }
216
217  /*
218   * ignore not found.
219   */
220  if (r < 0 && errno == ENOENT)
221    r = 0;
222
223  return 0;
224}
225
226/*
227 * ifconfig_show
228
229 */
230static int
231ifconfig_show(const char* ifname)
232{
233  const char const* ifconfig_show[] = { "ifconfig", ifname, NULL };
234  return rtems_bsd_command_ifconfig(2, (char**) ifconfig_show);
235}
236
237/*
238 * ifconfig_'interface'
239 *
240 * eg ifconfig_em0="inet 10.10.5.33 netmask 255.255.255.0"
241 *    ifconfig_em0_alias0="ether 10:22:33:44:55:66"
242 *    ifconfig_em0_alias1="inet 10.1.1.111 netmask 0xffffffff"
243 *
244 * See 'man rc.conf(5)' on FreeBSD.
245 */
246static int
247ifconfig_(rtems_bsd_rc_conf* rc_conf,
248          const char*        ifname,
249          int                argc,
250          const char**       argv,
251          int                opt_argc,
252          const char**       opt_argv,
253          bool               add_up)
254{
255  const char**      args;
256  int               arg;
257  int               ifconfig_argc = 0;
258  int               r;
259
260  for (arg = 1; arg < argc; ++arg) {
261    if (strcasecmp(argv[arg], "NOAUTO") == 0)
262      return 0;
263  }
264
265  args = calloc(argc + opt_argc + 3, sizeof(char*));
266  if (args == NULL) {
267    errno = ENOMEM;
268    return -1;
269  }
270
271  args[ifconfig_argc++] = "ifconfig";
272  args[ifconfig_argc++] = ifname;
273
274  for (arg = 1; arg < argc; ++arg) {
275    if (strcasecmp("DHCP",     argv[arg]) == 0 ||
276        strcasecmp("SYNCDHCP", argv[arg]) == 0 ||
277        strcasecmp("UP",       argv[arg]) == 0) {
278      add_up = false;
279    }
280    else {
281      args[ifconfig_argc++] = argv[arg];
282    }
283  }
284
285  if (opt_argv != NULL) {
286    for (arg = 0; arg < opt_argc; ++arg) {
287      args[ifconfig_argc++] = opt_argv[arg];
288    }
289  }
290
291  if (add_up)
292    args[ifconfig_argc++] = "up";
293
294  rtems_bsd_rc_conf_print_cmd(rc_conf, "ifconfig", ifconfig_argc, args);
295
296  r = rtems_bsd_command_ifconfig(ifconfig_argc, (char**) args);
297
298  free(args);
299
300  if (r != EX_OK) {
301    errno = ECANCELED;
302    return -1;
303  }
304
305  return r;
306}
307
308/*
309 * hostname
310 *
311 * eg hostname="myhost"
312 *
313 * See 'man rc.conf(5)' on FreeBSD.
314 */
315static int
316hostname(rtems_bsd_rc_conf* rc_conf, rtems_bsd_rc_conf_argc_argv* aa)
317{
318  const char**      argv;
319  int               r;
320  const char const* default_argv[] = { "hostname", "Amnesiac", NULL };
321
322  r = rtems_bsd_rc_conf_find(rc_conf, "hostname", aa);
323  if (r < 0 && errno != ENOENT)
324    return -1;
325
326  if (r < 0 || (r == 0 && aa->argc != 2)) {
327    argv = default_argv;
328  }
329  else {
330    argv = aa->argv;
331  }
332
333  fprintf(stdout, "Setting hostname: %s.\n", argv[1]);
334
335  return sethostname(argv[1], strlen(argv[1]));
336}
337
338/*
339 * defaultrouter
340 *
341 * eg defaultrouter="1.2.3.4"
342 *
343 * See 'man rc.conf(5)' on FreeBSD.
344 */
345static int
346defaultrouter(rtems_bsd_rc_conf* rc_conf, rtems_bsd_rc_conf_argc_argv* aa, bool dhcp)
347{
348  int r;
349
350  if (dhcp) {
351    char* end = NULL;
352    int   delay = 30;
353
354    /*
355     * See if a delay is specified else use default to 30 seconds. Wait for a
356     * valid default route.
357     */
358    r = rtems_bsd_rc_conf_find(rc_conf, "defaultroute_delay", aa);
359    if (r == 0 && aa->argc == 2) {
360      delay = (int) strtol(aa->argv[1], &end, 10);
361      if (*end != '\0') {
362        fprintf(stderr, "error: defaultroute_delay: invalid delay value\n");
363        delay = 30;
364      }
365    }
366
367    printf("Waiting %ds for default route interface: ", delay);
368    fflush(stdout);
369
370    while (delay > 0) {
371      struct sockaddr_in sin;
372      struct sockaddr*   rti_info[RTAX_MAX];
373
374      --delay;
375
376      memset(&sin, 0, sizeof(sin));
377      memset(&rti_info[0], 0, sizeof(rti_info));
378      sin.sin_family = AF_INET;
379      inet_pton(AF_INET, "0.0.0.0", &sin.sin_addr);
380
381      r = rtems_get_route(&sin, rti_info);
382      if (r == 0 && rti_info[RTAX_GATEWAY] != NULL) {
383        break;
384      }
385      else if (r < 0 && errno != ESRCH) {
386        fprintf(stderr,
387                "error: get routes %d: %d %s\n", r, errno, strerror(errno));
388      }
389
390      sleep(1);
391    }
392
393    /*
394     * We should print the interface but I cannot see how to get the interface
395     * with the default route without a lot of code.
396     */
397    if (delay > 0) {
398      printf("found.\n");
399      return 0;
400    }
401
402    printf("\nerror: no default route found, try defaultrouter\n");
403  }
404
405  r = rtems_bsd_rc_conf_find(rc_conf, "defaultrouter", aa);
406  if (r < 0 && errno != ENOENT)
407    return -1;
408
409  if (r == 0) {
410    if (aa->argc > 2) {
411      errno = EINVAL;
412      return -1;
413    }
414
415    if (strcasecmp(aa->argv[1], "NO") != 0) {
416      const char* args[] = { "route", "add", "default", aa->argv[1], NULL };
417
418      rtems_bsd_rc_conf_print_cmd(rc_conf, "defaultrouter", 4, args);
419
420      r = rtems_bsd_command_route(4, (char**) args);
421      if (r != EX_OK) {
422        errno = ECANCELED;
423        return -1;
424      }
425    }
426  }
427
428  return 0;
429}
430
431static int
432list_interfaces(const char* msg, struct ifaddrs* ifap)
433{
434  struct ifaddrs* ifa;
435
436  fprintf(stdout, msg);
437
438  /*
439   * Always have lo0 first.
440   */
441
442  for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
443    if (strcasecmp("lo0", ifa->ifa_name) == 0) {
444      fprintf(stdout, "%s ", ifa->ifa_name);
445      break;
446    }
447  }
448
449  for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
450    if (strcasecmp("lo0", ifa->ifa_name) != 0) {
451      fprintf(stdout, "%s ", ifa->ifa_name);
452    }
453  }
454
455  fprintf(stdout, "\b.\n");
456
457  return 0;
458}
459
460static int
461show_interfaces(struct ifaddrs* ifap)
462{
463  struct ifaddrs* ifa;
464
465  for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
466    ifconfig_show(ifa->ifa_name);
467  }
468
469  return 0;
470}
471
472static int
473dhcp_check(rtems_bsd_rc_conf_argc_argv* aa)
474{
475  int arg;
476  for (arg = 0; arg < aa->argc; ++arg) {
477    if (strcasestr(aa->argv[1], "DHCP") != NULL ||
478        strcasestr(aa->argv[1], "SYNCDHCP") != NULL)
479      return true;
480  }
481  return false;
482}
483
484static int
485setup_lo0(rtems_bsd_rc_conf* rc_conf, struct ifaddrs* ifap)
486{
487  struct ifaddrs* ifa;
488
489  for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
490    if (strcasecmp("lo0", ifa->ifa_name) == 0) {
491      const char* lo0_argv[] = {
492        "ifconfig_lo0", "inet", "127.0.0.1", "netmask", "255.0.0.0", NULL
493      };
494      show_result("lo0",
495                  ifconfig_(rc_conf, "lo0",
496                            5, lo0_argv,
497                            0, NULL,
498                            true));
499      return 0;
500    }
501  }
502
503  fprintf(stderr, "warning: no loopback interface found\n");
504
505  return -1;
506}
507
508static int
509setup_interfaces(rtems_bsd_rc_conf*           rc_conf,
510                 rtems_bsd_rc_conf_argc_argv* aa,
511                 struct ifaddrs*              ifap,
512                 bool*                        dhcp)
513{
514  struct ifaddrs* ifa;
515  int             r;
516
517  for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
518    if (strcasecmp("lo0", ifa->ifa_name) != 0) {
519      char iface[64];
520      snprintf(iface, sizeof(iface), "ifconfig_%s", ifa->ifa_name);
521      r = rtems_bsd_rc_conf_find(rc_conf, iface, aa);
522      if (r == 0) {
523        if (dhcp_check(aa)) {
524          *dhcp = true;
525        }
526        /*
527         * A DHCP ifconfig can have other options we need to set on the
528         * interface.
529         */
530        show_result(iface, ifconfig_(rc_conf, ifa->ifa_name,
531                                     aa->argc, aa->argv,
532                                     0, NULL,
533                                     true));
534      }
535      snprintf(iface, sizeof(iface), "ifconfig_%s_alias[0-9]+", ifa->ifa_name);
536      if (r == 0) {
537        r = rtems_bsd_rc_conf_find(rc_conf, iface, aa);
538        while (r == 0) {
539          const char* alias_argv[] = { "alias", NULL };
540          show_result(iface,
541                      ifconfig_(rc_conf, ifa->ifa_name,
542                                aa->argc, aa->argv,
543                                1, alias_argv,
544                                false));
545          r = rtems_bsd_rc_conf_find_next(rc_conf, aa);
546        }
547      }
548    }
549  }
550
551  return 0;
552}
553
554static int
555setup_vlans(rtems_bsd_rc_conf*           rc_conf,
556            rtems_bsd_rc_conf_argc_argv* aa,
557            struct ifaddrs*              ifap,
558            bool*                        dhcp)
559{
560  rtems_bsd_rc_conf_argc_argv* vaa;
561  struct ifaddrs*              ifa;
562
563  vaa = rtems_bsd_rc_conf_argc_argv_create();
564  if (vaa == NULL)
565    return -1;
566
567  show_result("create_args", load_create_args(rc_conf, aa));
568
569  for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
570    if (strcasecmp("lo0", ifa->ifa_name) != 0) {
571      char expr[128];
572      int  r;
573      /*
574       * Look for vlans_'iface'="101 102 103"
575       */
576      snprintf(expr, sizeof(expr), "vlans_%s", ifa->ifa_name);
577      r = rtems_bsd_rc_conf_find(rc_conf, expr, aa);
578      if (r == 0) {
579        int arg;
580        for (arg = 1; arg < aa->argc; ++arg) {
581          char vlan_name[64];
582          const char* vlan_create[] = {
583            "ifconfig", vlan_name, "create", NULL
584          };
585          /*
586           * Create the VLAN name as 'iface'.'vlan'.
587           */
588          snprintf(vlan_name, sizeof(vlan_name),
589                   "%s.%s", ifa->ifa_name, aa->argv[arg]);
590          rtems_bsd_rc_conf_print_cmd(rc_conf, "vlan", 3, vlan_create);
591          r = rtems_bsd_command_ifconfig(3, (char**) vlan_create);
592          if (r == 0) {
593            /*
594             * Look for ifconfig_'iface'_'vlan'="..."
595             */
596            snprintf(expr, sizeof(expr),
597                     "ifconfig_%s_%s", ifa->ifa_name, aa->argv[arg]);
598            r = rtems_bsd_rc_conf_find(rc_conf, expr, vaa);
599            if (r == 0) {
600              if (dhcp_check(vaa)) {
601                *dhcp = true;
602              }
603              else {
604                show_result(vlan_name,
605                            ifconfig_(rc_conf, vlan_name,
606                                      vaa->argc, vaa->argv,
607                                      0, NULL,
608                                      true));
609              }
610            }
611          }
612        }
613      }
614    }
615  }
616
617  rtems_bsd_rc_conf_argc_argv_destroy(vaa);
618
619  return 0;
620}
621
622/*
623 * The rc_conf struct cannot be passed to a thread as a pointer. It can only be
624 * used in the rc.conf worker thread. As a result the values needed to print a
625 * verbose message to aid debugging need to have local copies made and passed
626 * to the dhcpcd worker. The dhcpcd worker should run for ever. Clean up the
627 * memory if it exits.
628 */
629typedef struct dhcpcd_data {
630  rtems_bsd_rc_conf_argc_argv* argc_argv;
631  bool                         verbose;
632  const char*                  name;
633} dhcpcd_data;
634
635static void
636dhcpcd_worker(rtems_task_argument arg)
637{
638  dhcpcd_data*  dd = (dhcpcd_data*) arg;
639  int           argc;
640  const char**  argv;
641  const char*   dhcpcd_argv[] = { "dhcpcd", NULL };
642  int           r;
643
644  if (dd->argc_argv->argc > 0) {
645    argc = dd->argc_argv->argc;
646    argv = dd->argc_argv->argv;
647  }
648  else {
649    argc = 1;
650    argv = dhcpcd_argv;
651  }
652
653  if (dd->verbose) {
654    fprintf(stdout, "rc.conf: %s: dhcpcd ", dd->name);
655    for (r = 1; r < argc; ++r)
656      fprintf(stdout, "%s ", argv[r]);
657    fprintf(stdout, "\n");
658  }
659
660  r = rtems_bsd_command_dhcpcd(argc, argv);
661  if (r != EX_OK)
662    fprintf(stderr, "error: dhcpcd: stopped\n");
663
664  free(dd->name);
665  rtems_bsd_rc_conf_argc_argv_destroy(dd->argc_argv);
666  free(dd);
667
668  rtems_task_delete(RTEMS_SELF);
669}
670
671static int
672run_dhcp(rtems_bsd_rc_conf* rc_conf, rtems_bsd_rc_conf_argc_argv* aa)
673{
674  dhcpcd_data*        dd;
675  rtems_status_code   sc;
676  rtems_id            id;
677  rtems_task_priority priority = RTEMS_MAXIMUM_PRIORITY - 1;
678  char*               end = NULL;
679  int                 r;
680
681  /*
682   * These are passed to the worker and cleaned up there if it ever exits. Do
683   * not destroy here unless an error before the thread runs.
684   */
685  dd = calloc(1, sizeof(*dd));
686  if (dd == NULL) {
687    fprintf(stderr, "error: dhcpcd data: no memory\n");
688    errno = ENOMEM;
689    return -1;
690  }
691
692  dd->name = strdup(rtems_bsd_rc_conf_name(rc_conf));
693  if (dd == NULL) {
694    free(dd);
695    fprintf(stderr, "error: dhcpcd data: no memory\n");
696    errno = ENOMEM;
697    return -1;
698  }
699
700  dd->argc_argv = rtems_bsd_rc_conf_argc_argv_create();
701  if (dd->argc_argv == NULL) {
702    free(dd->name);
703    free(dd);
704    errno = ENOMEM;
705    return -1;
706  }
707
708  dd->verbose = rtems_bsd_rc_conf_verbose(rc_conf);
709
710  r = rtems_bsd_rc_conf_find(rc_conf, "dhcpcd_priority", dd->argc_argv);
711  if (r == 0) {
712    if (dd->argc_argv->argc == 2) {
713      priority = strtoul(dd->argc_argv->argv[1], &end, 10);
714      if (priority == 0 || *end != '\0')
715        priority = RTEMS_MAXIMUM_PRIORITY - 1;
716    }
717  }
718
719  rtems_bsd_rc_conf_find(rc_conf, "dhcpcd_options", dd->argc_argv);
720
721  sc = rtems_task_create(rtems_build_name('D', 'H', 'C', 'P'),
722                         priority,
723                         2 * RTEMS_MINIMUM_STACK_SIZE,
724                         RTEMS_DEFAULT_MODES,
725                         RTEMS_FLOATING_POINT,
726                         &id);
727  if (sc == RTEMS_SUCCESSFUL)
728    sc = rtems_task_start(id, dhcpcd_worker, (rtems_task_argument) dd);
729  if (sc != RTEMS_SUCCESSFUL) {
730    fprintf(stderr,
731            "error: dhcpcd: thread create/start: %s\n", rtems_status_text(sc));
732    rtems_bsd_rc_conf_argc_argv_destroy(dd->argc_argv);
733    free(dd->name);
734    free(dd);
735    errno = EIO;
736    return -1;
737  }
738
739  /*
740   * Let it run before moving on.
741   */
742  sleep(1);
743
744  return 0;
745}
746
747static int
748interfaces(rtems_bsd_rc_conf* rc_conf, rtems_bsd_rc_conf_argc_argv* aa)
749{
750  struct ifaddrs* ifap;
751  bool            dhcp = false;
752
753  if (getifaddrs(&ifap) != 0) {
754    fprintf(stderr, "error: interfaces: getifaddrs: %s\n", strerror(errno));
755    return -1;
756  }
757
758  list_interfaces("Starting network: ", ifap);
759  show_result("cloned_interfaces", cloned_interfaces(rc_conf, aa));
760  show_result("lo0", setup_lo0(rc_conf, ifap));
761  show_result("ifaces", setup_interfaces(rc_conf, aa, ifap, &dhcp));
762  show_result("vlans", setup_vlans(rc_conf, aa, ifap, &dhcp));
763  show_interfaces(ifap);
764
765  if (dhcp)
766    show_result("dhcp", run_dhcp(rc_conf, aa));
767  show_result("defaultrouter", defaultrouter(rc_conf, aa, dhcp));
768
769  free(ifap);
770
771  return 0;
772}
773
774static int
775network_service(rtems_bsd_rc_conf* rc_conf)
776{
777  rtems_bsd_rc_conf_argc_argv* aa;
778  int                          r;
779
780  aa = rtems_bsd_rc_conf_argc_argv_create();
781  if (aa == NULL)
782    return -1;
783
784  show_result("hostname", hostname(rc_conf, aa));
785
786  r = interfaces(rc_conf, aa);
787  if (r < 0) {
788    rtems_bsd_rc_conf_argc_argv_destroy(aa);
789    return -1;
790  }
791
792  rtems_bsd_rc_conf_argc_argv_destroy(aa);
793
794  return 0;
795}
796
797void
798rc_conf_net_init(void* arg)
799{
800  int r;
801  r = rtems_bsd_rc_conf_service_add("network",
802                                    "after:first;",
803                                    network_service);
804  if (r < 0)
805    fprintf(stderr,
806            "error: network service add failed: %s\n", strerror(errno));
807}
Note: See TracBrowser for help on using the repository browser.