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

55-freebsd-126-freebsd-12
Last change on this file since dd35ec5 was 0237319, checked in by Sebastian Huber <sebastian.huber@…>, on 05/23/17 at 11:18:31

Update due to Newlib 2017-06-07 changes

The following files are now provided by Newlib:

  • arpa/inet.h
  • net/if.h
  • netinet/in.h
  • netinet/tcp.h
  • sys/socket.h
  • sys/uio.h
  • sys/un.h

The <sys/param.h> and <sys/cpuset.h> are now compatible enough to be
used directly.

Update #2833.

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