Changeset 573b1982 in rtems-libbsd


Ignore:
Timestamp:
Jun 29, 2016, 11:19:52 PM (3 years ago)
Author:
Chris Johns <chrisj@…>
Branches:
afaeccc05a556f6aa25ba044a7e49d6aa634a59e, freebsd-9.3, master
Children:
dc5b267
Parents:
912b685
Message:

Add DHCP support to rc.conf.

Files:
3 edited

Legend:

Unmodified
Added
Removed
  • rtemsbsd/rtems/rtems-bsd-rc-conf-net.c

    r912b685 r573b1982  
    4040
    4141#include <ifaddrs.h>
     42#include <net/if.h>
     43#include <net/route.h>
     44#include <netinet/in.h>
     45#include <sys/socket.h>
    4246
    4347#include <errno.h>
     
    4549#include <stdio.h>
    4650#include <stdlib.h>
     51#include <sys/stat.h>
    4752#include <unistd.h>
    4853
     
    5257#include <machine/rtems-bsd-commands.h>
    5358#include <machine/rtems-bsd-rc-conf-services.h>
     59
     60#include <rtems/rtems-routes.h>
    5461
    5562/*
     
    336343}
    337344
    338 /*
    339  * defaultroute_delay
    340  *
    341  * eg defaultroute=120
    342  *
    343  * See 'man rc.conf(5)' on FreeBSD.
    344  */
    345 static int
    346 defaultroute_delay(rtems_bsd_rc_conf* rc_conf,
    347                    int                argc,
    348                    const char**       argv)
    349 {
    350   int   value;
    351   char* end = NULL;
    352 
    353   if (argc != 2) {
    354     errno = EINVAL;
    355     return -1;
    356   }
    357 
    358   value = strtol(argv[1], &end, 10);
    359 
    360   if (end == NULL) {
    361       const char* args[] = {
    362         "defaultrouter_delay", argv[1], NULL
    363     };
    364 
    365     rtems_bsd_rc_conf_print_cmd(rc_conf, "defaultrouter", 2, args);
    366 
    367     defaultroute_delay_secs = value;
    368   }
    369   else {
    370     errno = EINVAL;
    371     return -1;
    372   }
    373 
    374   return 0;
    375 }
    376 
    377345static int
    378346show_interfaces(const char* msg, struct ifaddrs* ifap)
     
    381349
    382350  fprintf(stdout, msg);
     351
     352  /*
     353   * Always have lo0 first.
     354   */
    383355
    384356  for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
     
    401373
    402374static int
     375dhcp_check(rtems_bsd_rc_conf_argc_argv* aa)
     376{
     377  if (aa->argc == 2 &&
     378      (strcasecmp("DHCP",     aa->argv[1]) == 0 ||
     379       strcasecmp("SYNCDHCP", aa->argv[1]) == 0))
     380    return true;
     381  return false;
     382}
     383
     384static int
    403385setup_lo0(rtems_bsd_rc_conf* rc_conf, struct ifaddrs* ifap)
    404386{
    405387  struct ifaddrs* ifa;
     388
    406389  for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
    407390    if (strcasecmp("lo0", ifa->ifa_name) == 0) {
     
    413396    }
    414397  }
     398
    415399  fprintf(stderr, "warning: no loopback interface found\n");
     400
    416401  return -1;
    417402}
     
    420405setup_interfaces(rtems_bsd_rc_conf*           rc_conf,
    421406                 rtems_bsd_rc_conf_argc_argv* aa,
    422                  struct ifaddrs*              ifap)
     407                 struct ifaddrs*              ifap,
     408                 bool*                        dhcp)
    423409{
    424410  struct ifaddrs* ifa;
     411  int             r;
     412
    425413  for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
    426414    if (strcasecmp("lo0", ifa->ifa_name) != 0) {
    427415      char iface[64];
    428       int  r;
    429416      snprintf(iface, sizeof(iface), "ifconfig_%s", ifa->ifa_name);
    430417      r = rtems_bsd_rc_conf_find(rc_conf, iface, aa);
    431418      if (r == 0) {
    432         show_result(iface, ifconfig_(rc_conf, ifa->ifa_name, aa->argc, aa->argv));
     419        if (dhcp_check(aa)) {
     420          *dhcp = true;
     421        }
     422        else {
     423          show_result(iface, ifconfig_(rc_conf, ifa->ifa_name, aa->argc, aa->argv));
     424        }
    433425      }
    434426    }
    435427  }
     428
    436429  return 0;
    437430}
     
    440433setup_vlans(rtems_bsd_rc_conf*           rc_conf,
    441434            rtems_bsd_rc_conf_argc_argv* aa,
    442             struct ifaddrs*              ifap)
     435            struct ifaddrs*              ifap,
     436            bool*                        dhcp)
    443437{
    444438  rtems_bsd_rc_conf_argc_argv* vaa;
     
    482476            r = rtems_bsd_rc_conf_find(rc_conf, expr, vaa);
    483477            if (r == 0) {
    484               show_result(vlan_name, ifconfig_(rc_conf, vlan_name,
    485                                                vaa->argc, vaa->argv));
     478              if (dhcp_check(vaa)) {
     479                *dhcp = true;
     480              }
     481              else {
     482                show_result(vlan_name, ifconfig_(rc_conf, vlan_name,
     483                                                 vaa->argc, vaa->argv));
     484              }
    486485            }
    487486          }
     
    496495}
    497496
     497/*
     498 * The rc_conf struct cannot be passed to a thread as a pointer. It can only be
     499 * used in the rc.conf worker thread. As a result the values need to print a
     500 * verbose message to aid debugging needs to have local oopies made and passed
     501 * to the dhcpcd worker. The dhcpcd worker runs for ever.
     502 */
     503typedef struct dhcpcd_data {
     504  rtems_bsd_rc_conf_argc_argv* argc_argv;
     505  bool                         verbose;
     506  const char*                  name;
     507} dhcpcd_data;
     508
     509static void
     510dhcpcd_worker(rtems_task_argument arg)
     511{
     512  dhcpcd_data*  dd = (dhcpcd_data*) arg;
     513  int           argc;
     514  const char**  argv;
     515  const char*   dhcpcd_argv[] = { "dhcpcd", NULL };
     516  struct stat   sb;
     517  int           r;
     518
     519  r = stat("/var", &sb);
     520  if (r < 0) {
     521    mkdir("/var", S_IRWXU | S_IRWXG | S_IRWXO);
     522  }
     523
     524  r = stat("/var/db", &sb);
     525  if (r < 0) {
     526    mkdir("/var/db", S_IRWXU | S_IRWXG | S_IRWXO);
     527  }
     528
     529  if (dd->argc_argv->argc > 0) {
     530    argc = dd->argc_argv->argc;
     531    argv = dd->argc_argv->argv;
     532  }
     533  else {
     534    argc = 1;
     535    argv = dhcpcd_argv;
     536  }
     537
     538  if (dd->verbose) {
     539    fprintf(stdout, "rc.conf: %s: dhcpcd ", dd->name);
     540    for (r = 1; r < argc; ++r)
     541      fprintf(stdout, "%s ", argv[r]);
     542    fprintf(stdout, "\n");
     543  }
     544
     545  r = rtems_bsd_command_dhcpcd(argc, argv);
     546  if (r != EX_OK)
     547    fprintf(stderr, "error: dhcpcd: stopped\n");
     548
     549  free(dd->name);
     550  rtems_bsd_rc_conf_argc_argv_destroy(dd->argc_argv);
     551  free(dd);
     552
     553  rtems_task_delete(RTEMS_SELF);
     554}
     555
     556static int
     557run_dhcp(rtems_bsd_rc_conf* rc_conf, rtems_bsd_rc_conf_argc_argv* aa)
     558{
     559  dhcpcd_data*        dd;
     560  rtems_status_code   sc;
     561  rtems_id            id;
     562  rtems_task_priority priority = RTEMS_MAXIMUM_PRIORITY - 1;
     563  char*               end = NULL;
     564  int                 delay = 30;
     565  int                 r;
     566
     567  /*
     568   * These are passed to the worker and cleaned up there if it ever exits. Do
     569   * not destroy here unless an error before the thread runs.
     570   */
     571  dd = calloc(1, sizeof(*dd));
     572  if (dd == NULL) {
     573    fprintf(stderr, "error: dhcpcd data: no memory\n");
     574    errno = ENOMEM;
     575    return -1;
     576  }
     577
     578  dd->name = strdup(rtems_bsd_rc_conf_name(rc_conf));
     579  if (dd == NULL) {
     580    free(dd);
     581    fprintf(stderr, "error: dhcpcd data: no memory\n");
     582    errno = ENOMEM;
     583    return -1;
     584  }
     585
     586  dd->argc_argv = rtems_bsd_rc_conf_argc_argv_create();
     587  if (dd->argc_argv == NULL) {
     588    free(dd->name);
     589    free(dd);
     590    errno = ENOMEM;
     591    return -1;
     592  }
     593
     594  dd->verbose = rtems_bsd_rc_conf_verbose(rc_conf);
     595
     596  r = rtems_bsd_rc_conf_find(rc_conf, "dhcpcd_priority", dd->argc_argv);
     597  if (r == 0) {
     598    if (dd->argc_argv->argc == 2) {
     599      priority = strtoul(dd->argc_argv->argv[1], &end, 10);
     600      if (priority == 0 || *end != '\0')
     601        priority = RTEMS_MAXIMUM_PRIORITY - 1;
     602    }
     603  }
     604
     605  rtems_bsd_rc_conf_find(rc_conf, "dhcpcd_options", dd->argc_argv);
     606
     607  sc = rtems_task_create(rtems_build_name('D', 'H', 'C', 'P'),
     608                         priority,
     609                         2 * RTEMS_MINIMUM_STACK_SIZE,
     610                         RTEMS_DEFAULT_MODES,
     611                         RTEMS_FLOATING_POINT,
     612                         &id);
     613  if (sc == RTEMS_SUCCESSFUL)
     614    sc = rtems_task_start(id, dhcpcd_worker, (rtems_task_argument) dd);
     615  if (sc != RTEMS_SUCCESSFUL) {
     616    fprintf(stderr,
     617            "error: dhcpcd: thread create/start: %s\n", rtems_status_text(sc));
     618    rtems_bsd_rc_conf_argc_argv_destroy(dd->argc_argv);
     619    free(dd->name);
     620    free(dd);
     621    errno = EIO;
     622    return -1;
     623  }
     624
     625  /*
     626   * See if a delay is specified else use default to 30 seconds. Wait for a
     627   * valid default route.
     628   */
     629  r = rtems_bsd_rc_conf_find(rc_conf, "defaultroute_delay", aa);
     630  if (r == 0 && aa->argc == 2) {
     631    delay = (int) strtol(aa->argv[1], &end, 10);
     632    if (*end != '\0') {
     633      fprintf(stderr, "error: defaultroute_delay: invalid delay value\n");
     634      delay = 30;
     635    }
     636  }
     637
     638  printf("Waiting %ds for default route interface: ", delay);
     639  fflush(stdout);
     640
     641  while (delay > 0) {
     642    struct sockaddr_in sin;
     643    struct sockaddr*   rti_info[RTAX_MAX];
     644
     645    --delay;
     646
     647    memset(&sin, 0, sizeof(sin));
     648    sin.sin_family = AF_INET;
     649    inet_pton(AF_INET, "0.0.0.0.", &sin.sin_addr);
     650
     651    r = rtems_get_route(&sin, rti_info);
     652    if (r == 0 && rti_info[RTAX_GATEWAY] != NULL) {
     653      break;
     654    }
     655    else if (r < 0 && errno != ESRCH) {
     656      fprintf(stderr,
     657              "error: get routes %d: %d %s\n", r, errno, strerror(errno));
     658    }
     659
     660    sleep(1);
     661  }
     662
     663  /*
     664   * We should print the interface but I cannot see how to get the interface
     665   * with the default route without a lot of code.
     666   */
     667  if (delay > 0)
     668    printf("found.\n");
     669  else
     670    printf("\nerror: no default route found\n");
     671
     672  return 0;
     673}
     674
    498675static int
    499676interfaces(rtems_bsd_rc_conf* rc_conf, rtems_bsd_rc_conf_argc_argv* aa)
    500677{
    501678  struct ifaddrs* ifap;
     679  bool            dhcp = false;
    502680
    503681  if (getifaddrs(&ifap) != 0) {
     
    509687  show_result("cloned_interfaces", cloned_interfaces(rc_conf, aa));
    510688  show_result("lo0", setup_lo0(rc_conf, ifap));
    511   show_result("ifaces", setup_interfaces(rc_conf, aa, ifap));
    512   show_result("vlans", setup_vlans(rc_conf, aa, ifap));
     689  show_result("ifaces", setup_interfaces(rc_conf, aa, ifap, &dhcp));
     690  show_result("vlans", setup_vlans(rc_conf, aa, ifap, &dhcp));
     691  show_result("defaultrouter", defaultrouter(rc_conf, aa));
     692  if (dhcp)
     693    show_result("dhcp", run_dhcp(rc_conf, aa));
    513694
    514695  free(ifap);
     
    534715    return -1;
    535716  }
    536 
    537   show_result("defaultrouter", defaultrouter(rc_conf, aa));
    538717
    539718  rtems_bsd_rc_conf_argc_argv_destroy(aa);
     
    550729                                    network_service);
    551730  if (r < 0)
    552     fprintf(stderr, "error: network service add failed: %s\n", strerror(errno));
    553 }
     731    fprintf(stderr,
     732            "error: network service add failed: %s\n", strerror(errno));
     733}
  • rtemsbsd/rtems/rtems-bsd-rc-conf.c

    r912b685 r573b1982  
    3838#include <regex.h>
    3939
     40#include <syslog.h>
     41
    4042#include <rtems.h>
    4143#include <rtems/chain.h>
     
    109111    aa->argv = NULL;
    110112    aa->command = NULL;
     113    aa->argc = 0;
    111114  }
    112115}
     
    422425    regfree(&rege);
    423426  }
     427
     428  argc_argv_clean(argc_argv);
    424429
    425430  errno = ENOENT;
     
    670675}
    671676
    672 static rtems_task rc_conf_worker(rtems_task_argument task_argument)
     677static void
     678rc_conf_syslog(rtems_bsd_rc_conf* rc_conf)
     679{
     680  rtems_bsd_rc_conf_argc_argv* aa;
     681  int                          r = 0;
     682  aa = rtems_bsd_rc_conf_argc_argv_create();
     683  if (aa != NULL) {
     684    r = rtems_bsd_rc_conf_find(rc_conf, "syslog_priority", aa);
     685    if (r == 0) {
     686      if (aa->argc == 2) {
     687        r = rtems_bsd_setlogpriority(aa->argv[1]);
     688        if (r < 0)
     689          fprintf(stderr,
     690                  "error: syslog: invalid priority: %s\n", aa->argv[1]);
     691      }
     692      else {
     693        fprintf(stderr, "error: syslog: invalid priority\n");
     694      }
     695    }
     696    rtems_bsd_rc_conf_argc_argv_destroy(aa);
     697  }
     698}
     699
     700static rtems_task
     701rc_conf_worker(rtems_task_argument task_argument)
    673702{
    674703  rtems_bsd_rc_conf* rc_conf = (rtems_bsd_rc_conf*) task_argument;
    675   rtems_chain_node* node = rtems_chain_first(&services);
    676   int               r = 0;
    677   int               error;
     704  rtems_chain_node*  node = rtems_chain_first(&services);
     705  int                r = 0;
     706  int                error;
     707
     708  /*
     709   * Check for a syslog priority before any services are run.
     710   */
     711  rc_conf_syslog(rc_conf);
    678712
    679713  if (rc_conf->verbose)
     
    687721    rr = srv->entry(rc_conf);
    688722    if (rr < 0) {
    689       fprintf(stderr, "error: bsd service: %s: %s\n", srv->name, strerror(errno));
     723      fprintf(stderr,
     724              "error: bsd service: %s: %s\n", srv->name, strerror(errno));
    690725      if (r == 0) {
    691726        r = rr;
  • testsuite/rcconf02/test_main.c

    r912b685 r573b1982  
    2424 */
    2525
     26/*
     27 * Tests:
     28 *
     29 * 1. rc.conf processing
     30 *  1.1  syslog_priority
     31 *  1.2  create_args_*
     32 *  1.3  hostname
     33 *  1.4  ifconfig_<iface>
     34 *  1.5  vlans_<iface>
     35 *  1.6  ifconfig_<iface>.<vlan>
     36 *  1.7  defaultrouter
     37 *  1.8  defaultroute_delay
     38 *  1.9  ftp_enable
     39 *  1.10 ftp_options
     40 *  1.11 dhcpcd_priority
     41 *  1.12 dhcpcd_options
     42 *
     43 * 2. dhcpcd (via vlan, should timeout unless VLAN is present)
     44 *
     45 * 3. get route, the defaultrouter sets a default route and the vlan DHCP
     46 *    interface requires the default route be probed and found.
     47 *
     48 * 4. ftpd
     49 */
     50
    2651#include <rtems/bsd/sys/param.h>
    2752
     
    4570#include <rtems/shell.h>
    4671
     72#if DEFINE_FOR_TESTING
    4773#define RCCONF02_HAS_SHELL
     74#endif
    4875
    4976#define TEST_NAME "LIBBSD RC.CONF 2"
    5077
    5178#define IFACE_IPV4(iface) \
    52   "ifconfig_" # iface " inet " NET_CFG_SELF_IP " netmask " NET_CFG_NETMASK "\n"
     79  "ifconfig_" # iface "=\"inet " NET_CFG_SELF_IP " netmask " NET_CFG_NETMASK "\"\n"
     80
    5381
    5482#define RC_CONF_IFACES \
     
    6290#define IFACE_VLAN(iface) \
    6391  "vlans_" # iface "=\"101 102\"\n" \
    64   "ifconfig_" # iface "_101=\"inet 192.0.101.1/24\n" \
    65   "ifconfig_" # iface "_102=\"inet 192.0.102.1/24\n"
     92  "ifconfig_" # iface "_101=\"inet 192.0.101.1/24\"\n" \
     93  "ifconfig_" # iface "_102=\"DHCP\"\n"
    6694
    6795#define RC_CONF_VLANS \
     
    73101  IFACE_VLAN(re0)
    74102
    75 static const char* rc_conf_text =                       \
    76   "#\n"                                                 \
    77   "# Tests rc.conf. Add every NIC\n"                    \
    78   "#\n"                                                 \
    79   "hostname=\"rctest\"\n"                               \
    80   "\n"                                                  \
    81   "create_args_myvlan=\"vlan 102\"\n"                   \
    82   "create_args_yourvlan=\"vlan 202\"\n"                 \
    83   "\n"                                                  \
    84   RC_CONF_IFACES                                        \
    85   "\n"                                                  \
    86   RC_CONF_VLANS                                         \
    87   "\n"                                                  \
    88   "defaultrouter=\"" NET_CFG_GATEWAY_IP "\"\n"          \
    89   "\n"                                                  \
    90   "ftpd_enable=\"YES\"\n"                               \
     103static const char* rc_conf_text =                          \
     104  "#\n"                                                    \
     105  "# Tests rc.conf. Add every NIC\n"                       \
     106  "#\n"                                                    \
     107  "\n"                                                     \
     108  "syslog_priority=\"debug\"\n"                            \
     109  "\n"                                                     \
     110  "hostname=\"rctest\"\n"                                  \
     111  "\n"                                                     \
     112  "create_args_myvlan=\"vlan 102\"\n"                      \
     113  "create_args_yourvlan=\"vlan 202\"\n"                    \
     114  "\n"                                                     \
     115  RC_CONF_IFACES                                           \
     116  "\n"                                                     \
     117  RC_CONF_VLANS                                            \
     118  "\n"                                                     \
     119  "defaultrouter=\"" NET_CFG_GATEWAY_IP "\"\n"             \
     120  "defaultroute_delay=\"5\"\n"                             \
     121  "\n"                                                     \
     122  "dhcpcd_options=\"-h foobar\"\n"                         \
     123  "\n"                                                     \
     124  "ftpd_enable=\"YES\"\n"                                  \
    91125  "ftpd_options=\"-v -p 21 -C 10 -P 150 -L -I 10 -R /\"\n" \
    92126  "n";
     
    130164    NULL
    131165    );
     166#else
     167  printf("RCCONF02 sleeping for 10s\n");
     168  sleep(10);
    132169#endif /* RCCONF02_HAS_SHELL */
    133170
Note: See TracChangeset for help on using the changeset viewer.