[olsr-dev] Patch: for (some Qs about exending the dyn_gw plugin)

Andreas Tønnesen (spam-protected)
Mon Nov 29 21:19:59 CET 2004


Hi Jens,

This looks cool, but there seems to me there is one major problem. There 
is no protection of the access to the hna set from the thread. This 
critical section should be protected in some way or it might lead to a 
race condition. One could register a scheduled event(running in olsrds 
thread) that updates routes based on information shared with the ping 
thread, or one could go by it some other way. In any case it must be 
solved. There might be a low probability for the race condition to 
occure, but for a daemon "low probability" just isn't good enough :-)

- Andreas

Jens Nachtigall wrote:
>>Just submit the patch when you feel like the plugin is working in a
>>satisfactionary way.
> 
> 
> Please see the attachment. If no key    "Ping" is given in the config, 
> then it works as now (except that it is done in its  own thread). If 
> "Ping" is given, then pings are done to do a gw safety check.
> 
> Also, a "Interval" can be given in the config to e.g. only test (and 
> ping) every X given secs.
> 
> This way the plugin can be used by its 2 main groups 
> (wildcatwireless.net and the freifunk-firmware [and others]).
> 
> I'll send a patch with comments for the olsrd.conf.default and the 
> dyn_gw.readme tomorrow or so.
> 
> Jens
> 
> 
> ------------------------------------------------------------------------
> 
> Index: Makefile
> ===================================================================
> RCS file: /cvsroot/olsrd/olsrd-current/lib/dyn_gw/Makefile,v
> retrieving revision 1.6
> diff -u -r1.6 Makefile
> --- Makefile	19 Nov 2004 12:35:28 -0000	1.6
> +++ Makefile	29 Nov 2004 19:34:02 -0000
> @@ -10,8 +10,8 @@
>  LIBDIR ?= $(INSTALL_PREFIX)/usr/lib
>  # -fPIC creates position independent code
>  MYFLAGS ?= -Wall -fPIC -g # Uncomment -g for debugging
> -LIBS ?= -lc -lm
> -CFLAGS ?= -g -O2
> +LIBS ?= -lpthread -lc -lm
> +CFLAGS ?= -Wall -Wmissing-prototypes -Wstrict-prototypes -g -O2
>  
>  #Sourcefiles
>  #add yours here
> Index: src/olsrd_dyn_gw.c
> ===================================================================
> RCS file: /cvsroot/olsrd/olsrd-current/lib/dyn_gw/src/olsrd_dyn_gw.c,v
> retrieving revision 1.6
> diff -u -r1.6 olsrd_dyn_gw.c
> --- src/olsrd_dyn_gw.c	7 Nov 2004 10:57:54 -0000	1.6
> +++ src/olsrd_dyn_gw.c	29 Nov 2004 19:34:02 -0000
> @@ -1,6 +1,6 @@
>  /*
>   * OLSR plugin
> - * Copyright (C) 2004 Andreas Tønnesen ((spam-protected))
> + * Copyright (C) 2004 Andreas Tnnesen ((spam-protected))
>   *
>   * This file is part of the olsrd dynamic gateway detection.
>   *
> @@ -35,9 +35,54 @@
>  #include <linux/in_route.h>
>  #include <unistd.h>
>  #include <errno.h>
> +#include <pthread.h>
> +#include <time.h>
> +
>  
>  static int has_inet_gateway;
>  
> +/* set default interval, in case none is given in the config file */
> +int interval = 5;
> +
> +/* list to store the Ping IP addresses given in the config file */
> +struct ping_list {
> +  char *ping_address;
> +  struct ping_list *next;
> +};
> +struct ping_list *the_ping_list = NULL;
> +
> +int
> +register_olsr_param(char *key, char *value)
> +{
> +  /* foo_addr is only used for call to inet_aton */ 
> +  struct in_addr *foo_addr;
> +  int retval = -1;
> + 
> +  if (!strcmp(key, "Interval")) {
> +    if (sscanf(value, "%d", &interval) == 1) {
> +      retval = 1;
> +    }
> +  }
> +  if (!strcmp(key, "Ping")) {
> +    /* if value contains a valid IPaddr, then add it to the list */
> +    if (inet_aton(strdup(value), foo_addr)) {
> +      the_ping_list = add_to_ping_list(value, the_ping_list);
> +      retval = 1;
> +    }
> +  }
> +  return retval;
> +}
> +
> +/* add the valid IPs to the head of the list */
> +struct ping_list *
> +add_to_ping_list(char *ping_address, struct ping_list *the_ping_list)
> +{
> +  struct ping_list *new = (struct ping_list *) malloc(sizeof(struct ping_list));
> +  new->ping_address = strdup(ping_address);
> +  new->next = the_ping_list;
> +  return new;
> +}    
> +
>  /**
>   *Do initialization here
>   *
> @@ -47,6 +92,8 @@
>  int
>  olsr_plugin_init()
>  {
> +  pthread_t ping_thread;
> +  
>    gw_net.v4 = INET_NET;
>    gw_netmask.v4 = INET_PREFIX;
>  
> @@ -58,9 +105,10 @@
>        olsr_printf(1, "HNA Internet gateway deleted\n");
>      }
>  
> -  /* Register the GW check */
> -  olsr_register_scheduler_event(&olsr_event, NULL, 5, 4, NULL);
> -
> +  pthread_create(&ping_thread, NULL, olsr_event, NULL);
> +  /*      
> +  olsr_register_scheduler_event(olsr_event, NULL, interval, 4, NULL);
> +  */
>    return 1;
>  }
>  
> @@ -95,39 +143,42 @@
>  
>  
>  /**
> - *Scheduled event
> + * the threaded function which happens within an endless loop,
> + * reiterated every "Interval" sec (as given in the config or 
> + * the default value)
>   */
> -void
> +void *
>  olsr_event(void *foo)
>  {
> -  int res;
> +  for(;;) {
> +    struct timespec remainder_spec;
> +    /* the time to wait in "Interval" sec (see connfig), default=5sec */
> +    struct timespec sleeptime_spec  = {(time_t) interval, 0L };
>  
> -  res = check_gw(&gw_net, &gw_netmask);
> +    int res;
> +    
> +    /* check for table entry and if Ping IPs are given also do pings */
> +    res = check_gw(&gw_net, &gw_netmask);
>  
> -  if((res == 1) && (has_inet_gateway == 0))
> -    {
> +    if((res == 1) && (has_inet_gateway == 0)) {
>        olsr_printf(1, "Adding OLSR local HNA entry for Internet\n");
>        add_local_hna4_entry(&gw_net, &gw_netmask);
>        has_inet_gateway = 1;
> +    } else {
> +      if((res == 0) && (has_inet_gateway == 1)) {
> +        /* Remove all local Inet HNA entries */
> +        while(remove_local_hna4_entry(&gw_net, &gw_netmask)) {
> +          olsr_printf(1, "Removing OLSR local HNA entry for Internet\n");
> +        }
> +        has_inet_gateway = 0;
> +      }
>      }
> -  else
> -    {
> -      if((res == 0) && (has_inet_gateway == 1))
> -	{
> -	  /* Remove all local Inet HNA entries */
> -	  while(remove_local_hna4_entry(&gw_net, &gw_netmask))
> -	    {
> -	      olsr_printf(1, "Removing OLSR local HNA entry for Internet\n");
> -	    }
> -	  has_inet_gateway = 0;
> -	}
> -    }
> -
> +    while(nanosleep(&sleeptime_spec, &remainder_spec) < 0)
> +      sleeptime_spec = remainder_spec;
> +  }
>  }
>  
>  
> -
> -
>  int
>  check_gw(union olsr_ip_addr *net, union hna_netmask *mask)
>  {
> @@ -179,8 +230,17 @@
>  	   (netmask == mask->v4) && 
>  	   (dest_addr == net->v4))
>  	  {
> -	    olsr_printf(1, "INTERNET GATEWAY VIA %s detected.\n", iface);
> -	    retval = 1;
> +      /* don't ping, if there was no "Ping" IP addr in the config file */
> +      if (the_ping_list != NULL) {  
> +        /*validate the found inet gw by pinging*/ 
> +        if (ping_is_possible()) {
> +          olsr_printf(1, "INTERNET GATEWAY (ping is possible) VIA %s detected in routing table.\n", iface);
> +          retval=1;      
> +        }
> +      } else {
> +        olsr_printf(1, "INTERNET GATEWAY VIA %s detected in routing table.\n", iface);
> +        retval=1;      
> +      }
>  	  }
>  
>      }
> @@ -195,9 +255,23 @@
>      return retval;
>  }
>  
> -
> -
> -
> +int
> +ping_is_possible() 
> +{
> +  struct ping_list *list;
> +  for (list = the_ping_list; list != NULL; list = list->next) {
> +    char ping_command[50] = "ping -c 1 -q ";
> +    strcat(ping_command, list->ping_address);
> +    olsr_printf(1, "\nDo ping on %s ...\n", list->ping_address);
> +    if (system(ping_command) == 0) {
> +      olsr_printf(1, "...OK\n\n");
> +      return 1;      
> +    } else {
> +      olsr_printf(1, "...FAILED\n\n");
> +    }
> +  }
> +  return 0;
> +}
>  
>  
>  
> Index: src/olsrd_dyn_gw.h
> ===================================================================
> RCS file: /cvsroot/olsrd/olsrd-current/lib/dyn_gw/src/olsrd_dyn_gw.h,v
> retrieving revision 1.6
> diff -u -r1.6 olsrd_dyn_gw.h
> --- src/olsrd_dyn_gw.h	7 Nov 2004 10:57:55 -0000	1.6
> +++ src/olsrd_dyn_gw.h	29 Nov 2004 19:34:02 -0000
> @@ -42,14 +42,23 @@
>  
>  /* Timeout function to register with the sceduler */
>  void
> -olsr_timeout();
> +olsr_timeout(void);
>  
>  
>  /* Event function to register with the sceduler */
> -void
> +void *
>  olsr_event(void *foo);
>  
>  int
>  check_gw(union olsr_ip_addr *, union hna_netmask *);
>  
> +int
> +ping_is_possible(void);
> +
> +struct ping_list *
> +add_to_ping_list(char *, struct ping_list *);
> +
> +
> +
> +
>  #endif
> Index: src/olsrd_plugin.c
> ===================================================================
> RCS file: /cvsroot/olsrd/olsrd-current/lib/dyn_gw/src/olsrd_plugin.c,v
> retrieving revision 1.8
> diff -u -r1.8 olsrd_plugin.c
> --- src/olsrd_plugin.c	6 Nov 2004 12:23:46 -0000	1.8
> +++ src/olsrd_plugin.c	29 Nov 2004 19:34:03 -0000
> @@ -1,6 +1,6 @@
>  /*
>   * OLSR plugin
> - * Copyright (C) 2004 Andreas Tønnesen ((spam-protected))
> + * Copyright (C) 2004 Andreas Tnnesen ((spam-protected))
>   *
>   * This file is part of the olsrd dynamic gateway detection.
>   *
> @@ -103,13 +103,6 @@
>  }
>  
>  
> -int
> -register_olsr_param(char *key, char *value)
> -{
> -  //if(!strcmp(key, "Ip6Net"
> -  return 1;
> -}
> -
>  
>  /**
>   *Register needed functions and pointers
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> olsr-dev mailing list
> (spam-protected)
> https://www.olsr.org/mailman/listinfo/olsr-dev

-- 
Andreas Tønnesen
http://www.olsr.org



More information about the Olsr-dev mailing list