diff options
Diffstat (limited to 'zebra')
| -rw-r--r-- | zebra/ChangeLog | 12 | ||||
| -rw-r--r-- | zebra/Makefile.am | 8 | ||||
| -rw-r--r-- | zebra/ioctl_null.c | 34 | ||||
| -rw-r--r-- | zebra/kernel_null.c | 25 | ||||
| -rw-r--r-- | zebra/misc_null.c | 4 | ||||
| -rw-r--r-- | zebra/redistribute_null.c | 26 | ||||
| -rw-r--r-- | zebra/test_main.c | 337 | ||||
| -rw-r--r-- | zebra/zebra_rib.c | 7 | 
8 files changed, 453 insertions, 0 deletions
diff --git a/zebra/ChangeLog b/zebra/ChangeLog index 36e717d9..2e9328da 100644 --- a/zebra/ChangeLog +++ b/zebra/ChangeLog @@ -1,3 +1,15 @@ +2006-07-27 Paul Jakma <paul.jakma@sun.com> + +	* {ioctl,kernel}_null.c: Dummy/Null kernel method implementations, +	  useful for testing zebra code that calls such methods. +	* {redistribute,misc}_null.c: Dummy/Null methods, as above. But +	  for zclient, and for various misc functions. +	* test_main.c: Test harness for zebra, currently just to test the +	  RIB. +	* Makefile.am: Build testzebra using above. +	* zebra_rib.c: Add a global for the workqueue hold time, useful +	  for testing. +  2006-07-27 Rumen Svobodnikov <rumen@telecoms.bg>  	* connected.c: (connected_up_ipv4) interface connected routes always diff --git a/zebra/Makefile.am b/zebra/Makefile.am index 751f606f..7527562a 100644 --- a/zebra/Makefile.am +++ b/zebra/Makefile.am @@ -21,17 +21,25 @@ otherobj = $(ioctl_method) $(ipforward) $(if_method) $(if_proc) \  sbin_PROGRAMS = zebra +noinst_PROGRAMS = testzebra +  zebra_SOURCES = \  	zserv.c main.c interface.c connected.c zebra_rib.c \  	redistribute.c debug.c rtadv.c zebra_snmp.c zebra_vty.c \  	irdp_main.c irdp_interface.c irdp_packet.c router-id.c +testzebra_SOURCES = test_main.c zebra_rib.c interface.c connected.c debug.c \ +	zebra_vty.c \ +	kernel_null.c  redistribute_null.c ioctl_null.c misc_null.c +  noinst_HEADERS = \  	connected.h ioctl.h rib.h rt.h zserv.h redistribute.h debug.h rtadv.h \  	interface.h ipforward.h irdp.h router-id.h kernel_socket.h  zebra_LDADD = $(otherobj) $(LIBCAP) $(LIB_IPV6) ../lib/libzebra.la +testzebra_LDADD = $(LIBCAP) $(LIB_IPV6) ../lib/libzebra.la +  zebra_DEPENDENCIES = $(otherobj)  EXTRA_DIST = if_ioctl.c if_ioctl_solaris.c if_netlink.c if_proc.c \ diff --git a/zebra/ioctl_null.c b/zebra/ioctl_null.c new file mode 100644 index 00000000..d1f3db08 --- /dev/null +++ b/zebra/ioctl_null.c @@ -0,0 +1,34 @@ +#include <zebra.h> + +#include "zebra/rib.h" +#include "zebra/rt.h" +#include "zebra/ioctl.h" + +void ifreq_set_name (struct ifreq *a, struct interface *b) { return; } + +int if_set_prefix (struct interface *a, struct connected *b) { return 0; } +#pragma weak if_unset_prefix = if_set_prefix +#pragma weak if_prefix_add_ipv6 = if_set_prefix +#pragma weak if_prefix_delete_ipv6 = if_set_prefix + +int if_ioctl (u_long a, caddr_t b) { return 0; } + +int if_set_flags (struct interface *a, uint64_t b) { return 0; } +#pragma weak if_unset_flags = if_set_flags + +void if_get_flags (struct interface *a) { return; } +#pragma weak if_get_metric = if_get_flags +#pragma weak if_get_mtu = if_get_flags + +#ifdef SOLARIS_IPV6 +#pragma weak if_ioctl_ipv6 = if_ioctl +struct connected *if_lookup_linklocal(struct interface *a) { return 0; } + +#define AF_IOCTL(af, request, buffer) \ +        ((af) == AF_INET? if_ioctl(request, buffer) : \ +                          if_ioctl_ipv6(request, buffer)) +#else /* SOLARIS_IPV6 */ + +#define AF_IOCTL(af, request, buffer)  if_ioctl(request, buffer) + +#endif /* SOLARIS_IPV6 */ diff --git a/zebra/kernel_null.c b/zebra/kernel_null.c new file mode 100644 index 00000000..a84f4371 --- /dev/null +++ b/zebra/kernel_null.c @@ -0,0 +1,25 @@ +/* NULL kernel methods for testing. */ + +#include <zebra.h> + +#include "zebra/zserv.h" +#include "zebra/rt.h" +#include "zebra/redistribute.h" + +int kernel_add_ipv4 (struct prefix *a, struct rib *b) { return 0; } +#pragma weak kernel_delete_ipv4 = kernel_add_ipv4 +int kernel_add_ipv6 (struct prefix *a, struct rib *b) { return 0; } +#pragma weak kernel_delete_ipv6 = kernel_add_ipv6 +int kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate, +                            unsigned int index, int flags, int table) +{ return 0; } + +int kernel_add_route (struct prefix_ipv4 *a, struct in_addr *b, int c, int d) +{ return 0; } + +int kernel_address_add_ipv4 (struct interface *a, struct connected *b) +{ return 0; } +#pragma weak kernel_address_delete_ipv4 = kernel_address_add_ipv4 + +void kernel_init (void) { return; } +#pragma weak route_read = kernel_init diff --git a/zebra/misc_null.c b/zebra/misc_null.c new file mode 100644 index 00000000..8063c90d --- /dev/null +++ b/zebra/misc_null.c @@ -0,0 +1,4 @@ + +void ifstat_update_proc (void) { return; } +#pragma weak rtadv_config_write = ifstat_update_proc +#pragma weak irdp_config_write = ifstat_update_proc diff --git a/zebra/redistribute_null.c b/zebra/redistribute_null.c new file mode 100644 index 00000000..e57a73b9 --- /dev/null +++ b/zebra/redistribute_null.c @@ -0,0 +1,26 @@ +#include <zebra.h> +#include "zebra/rib.h" +#include "zebra/zserv.h" + +#include "zebra/redistribute.h" + +void zebra_redistribute_add (int a, struct zserv *b, int c) +{ return; } +#pragma weak zebra_redistribute_delete = zebra_redistribute_add +#pragma weak zebra_redistribute_default_add = zebra_redistribute_add +#pragma weak zebra_redistribute_default_delete = zebra_redistribute_add + +void redistribute_add (struct prefix *a, struct rib *b) +{ return; } +#pragma weak redistribute_delete = redistribute_add + +void zebra_interface_up_update (struct interface *a) +{ return; } +#pragma weak zebra_interface_down_update = zebra_interface_up_update +#pragma weak zebra_interface_add_update = zebra_interface_up_update +#pragma weak zebra_interface_delete_update = zebra_interface_up_update + +void zebra_interface_address_add_update (struct interface *a, +					 	struct connected *b) +{ return; } +#pragma weak zebra_interface_address_delete_update = zebra_interface_address_add_update diff --git a/zebra/test_main.c b/zebra/test_main.c new file mode 100644 index 00000000..59cec462 --- /dev/null +++ b/zebra/test_main.c @@ -0,0 +1,337 @@ +/* main routine. + * Copyright (C) 1997, 98 Kunihiro Ishiguro + * + * GNU Zebra is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * GNU Zebra is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Zebra; see the file COPYING.  If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA.   + */ + +#include <zebra.h> + +#include <lib/version.h> +#include "getopt.h" +#include "command.h" +#include "thread.h" +#include "filter.h" +#include "memory.h" +#include "prefix.h" +#include "log.h" +#include "privs.h" +#include "sigevent.h" + +#include "zebra/rib.h" +#include "zebra/zserv.h" +#include "zebra/debug.h" +#include "zebra/router-id.h" +#include "zebra/interface.h" + +/* Zebra instance */ +struct zebra_t zebrad = +{ +  .rtm_table_default = 0, +}; + +/* process id. */ +pid_t old_pid; +pid_t pid; + +/* zebra_rib's workqueue hold time. Private export for use by test code only */ +extern int rib_process_hold_time; + +/* Pacify zclient.o in libzebra, which expects this variable. */ +struct thread_master *master; + +/* Command line options. */ +struct option longopts[] =  +{ +  { "batch",       no_argument,       NULL, 'b'}, +  { "daemon",      no_argument,       NULL, 'd'}, +  { "log_mode",    no_argument,       NULL, 'l'}, +  { "config_file", required_argument, NULL, 'f'}, +  { "help",        no_argument,       NULL, 'h'}, +  { "vty_addr",    required_argument, NULL, 'A'}, +  { "vty_port",    required_argument, NULL, 'P'}, +  { "version",     no_argument,       NULL, 'v'}, +  { "rib_hold",	   required_argument, NULL, 'r'}, +  { 0 } +}; + +zebra_capabilities_t _caps_p [] =  +{ +  ZCAP_NET_ADMIN, +  ZCAP_SYS_ADMIN, +  ZCAP_NET_RAW, +}; + +/* Default configuration file path. */ +char config_default[] = SYSCONFDIR DEFAULT_CONFIG_FILE; + +/* Process ID saved for use by init system */ +const char *pid_file = PATH_ZEBRA_PID; + +/* Help information display. */ +static void +usage (char *progname, int status) +{ +  if (status != 0) +    fprintf (stderr, "Try `%s --help' for more information.\n", progname); +  else +    {     +      printf ("Usage : %s [OPTION...]\n\n"\ +	      "Daemon which manages kernel routing table management and "\ +	      "redistribution between different routing protocols.\n\n"\ +	      "-b, --batch        Runs in batch mode\n"\ +	      "-d, --daemon       Runs in daemon mode\n"\ +	      "-f, --config_file  Set configuration file name\n"\ +	      "-l, --log_mode     Set verbose log mode flag\n"\ +	      "-A, --vty_addr     Set vty's bind address\n"\ +	      "-P, --vty_port     Set vty's port number\n"\ +	      "-r, --rib_hold	  Set rib-queue hold time\n"\ +              "-v, --version      Print program version\n"\ +	      "-h, --help         Display this help and exit\n"\ +	      "\n"\ +	      "Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS); +    } + +  exit (status); +} + +static unsigned int test_ifindex = 0; + +/* testrib commands */ +DEFUN (test_interface_state, +       test_interface_state_cmd, +       "state (up|down)", +       "configure interface\n" +       "up\n" +       "down\n") +{ +  struct interface *ifp; +  if (argc < 1) +    return CMD_WARNING; +   +  ifp = vty->index; +  if (ifp->ifindex == IFINDEX_INTERNAL) +    { +      ifp->ifindex = ++test_ifindex; +      ifp->mtu = 1500; +      ifp->flags = IFF_BROADCAST|IFF_MULTICAST; +    } +   +  switch (argv[0][0]) +    { +      case 'u': +        SET_FLAG (ifp->flags, IFF_UP); +        if_add_update (ifp); +        printf ("up\n"); +        break; +      case 'd': +        UNSET_FLAG (ifp->flags, IFF_UP); +        if_delete_update (ifp); +        printf ("down\n"); +        break; +      default: +        return CMD_WARNING; +    } +  return CMD_SUCCESS; +} + +static void +test_cmd_init (void) +{ +  install_element (INTERFACE_NODE, &test_interface_state_cmd); +} + +/* SIGHUP handler. */ +static void  +sighup (void) +{ +  zlog_info ("SIGHUP received"); + +  /* Reload of config file. */ +  ; +} + +/* SIGINT handler. */ +static void +sigint (void) +{ +  zlog_notice ("Terminating on signal"); + +  exit (0); +} + +/* SIGUSR1 handler. */ +static void +sigusr1 (void) +{ +  zlog_rotate (NULL); +} + +struct quagga_signal_t zebra_signals[] = +{ +  {  +    .signal = SIGHUP,  +    .handler = &sighup, +  }, +  { +    .signal = SIGUSR1, +    .handler = &sigusr1, +  }, +  { +    .signal = SIGINT, +    .handler = &sigint, +  }, +  { +    .signal = SIGTERM, +    .handler = &sigint, +  }, +}; + +/* Main startup routine. */ +int +main (int argc, char **argv) +{ +  char *p; +  char *vty_addr = NULL; +  int vty_port = 0; +  int batch_mode = 0; +  int daemon_mode = 0; +  char *config_file = NULL; +  char *progname; +  struct thread thread; + +  /* Set umask before anything for security */ +  umask (0027); + +  /* preserve my name */ +  progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]); + +  zlog_default = openzlog (progname, ZLOG_ZEBRA, +			   LOG_CONS|LOG_NDELAY|LOG_PID, LOG_DAEMON); + +  while (1)  +    { +      int opt; +   +      opt = getopt_long (argc, argv, "bdlf:hA:P:r:v", longopts, 0); + +      if (opt == EOF) +	break; + +      switch (opt)  +	{ +	case 0: +	  break; +	case 'b': +	  batch_mode = 1; +	case 'd': +	  daemon_mode = 1; +	  break; +	case 'l': +	  /* log_mode = 1; */ +	  break; +	case 'f': +	  config_file = optarg; +	  break; +	case 'A': +	  vty_addr = optarg; +	  break; +	case 'P': +	  /* Deal with atoi() returning 0 on failure, and zebra not +	     listening on zebra port... */ +	  if (strcmp(optarg, "0") == 0)  +	    { +	      vty_port = 0; +	      break; +	    }  +	  vty_port = atoi (optarg); +	  break; +	case 'r': +	  rib_process_hold_time = atoi(optarg); +	  break; +	case 'v': +	  print_version (progname); +	  exit (0); +	  break; +	case 'h': +	  usage (progname, 0); +	  break; +	default: +	  usage (progname, 1); +	  break; +	} +    } +   +  /* port and conf file mandatory */ +  if (!vty_port || !config_file) +    usage (progname, 1); +   +  /* Make master thread emulator. */ +  zebrad.master = thread_master_create (); + +  /* Vty related initialize. */ +  signal_init (zebrad.master, Q_SIGC(zebra_signals), zebra_signals); +  cmd_init (1); +  vty_init (zebrad.master); +  memory_init (); +  if_init(); +  zebra_debug_init (); +  zebra_if_init (); +  test_cmd_init (); + +  /* Zebra related initialize. */ +  rib_init (); +  access_list_init (); + +  /* Make kernel routing socket. */ +  kernel_init (); +  route_read (); +  zebra_vty_init(); + +  /* Sort VTY commands. */ +  sort_node (); + +  /* Configuration file read*/ +  vty_read_config (config_file, config_default); + +  /* Clean up rib. */ +  rib_weed_tables (); + +  /* Exit when zebra is working in batch mode. */ +  if (batch_mode) +    exit (0); + +  /* Needed for BSD routing socket. */ +  old_pid = getpid (); + +  /* Daemonize. */ +  if (daemon_mode) +    daemon (0, 0); + +  /* Needed for BSD routing socket. */ +  pid = getpid (); + +  /* Make vty server socket. */ +  vty_serv_sock (vty_addr, vty_port, "/tmp/test_zebra"); + +  /* Print banner. */ +  zlog_notice ("Zebra %s starting: vty@%d", QUAGGA_VERSION, vty_port); + +  while (thread_fetch (zebrad.master, &thread)) +    thread_call (&thread); + +  /* Not reached... */ +  return 0; +} diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 665e5673..7373c6d8 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -42,6 +42,12 @@  /* Default rtm_table for all clients */  extern struct zebra_t zebrad; +/* Hold time for RIB process, should be very minimal. + * it is useful to able to set it otherwise for testing, hence exported + * as global here for test-rig code. + */ +int rib_process_hold_time = 10; +  /* Each route type's string and default distance value. */  struct  {   @@ -1120,6 +1126,7 @@ rib_queue_init (struct zebra_t *zebra)    zebra->ribq->spec.del_item_data = &rib_queue_qnode_del;    /* XXX: TODO: These should be runtime configurable via vty */    zebra->ribq->spec.max_retries = 3; +  zebra->ribq->spec.hold = rib_process_hold_time;    return;  }  | 
