linux: consolidate os_ip4_tunnel and os_ip6_tunnel
authorFerry Huberts <ferry.huberts@pelagic.nl>
Wed, 8 Aug 2012 12:25:17 +0000 (14:25 +0200)
committerFerry Huberts <ferry.huberts@pelagic.nl>
Wed, 8 Aug 2012 12:32:14 +0000 (14:32 +0200)
the code was almost the same, so merge the functions

Signed-off-by: Ferry Huberts <ferry.huberts@pelagic.nl>
src/linux/kernel_tunnel.c

index 63cec71..262d7f9 100644 (file)
@@ -111,88 +111,72 @@ void olsr_os_cleanup_iptunnel(const char * dev) {
 }
 
 /**
- * creates an ipip tunnel (for ipv4)
+ * creates an ipip tunnel (for ipv4 or ipv6)
+ *
  * @param name interface name
- * @param target pointer to tunnel target IP, NULL if tunnel should be removed
+ * @param target pointer to tunnel target IP, NULL if tunnel should be removed.
+ * Must be of type 'in_addr_t *' for ipv4 and of type 'struct in6_addr *' for
+ * ipv6
  * @return 0 if an error happened,
  *   if_index for successful created tunnel, 1 for successful deleted tunnel
  */
-static int os_ip4_tunnel(const char *name, in_addr_t *target)
-{
-  struct ifreq ifr;
-  int err;
-  struct ip_tunnel_parm p;
-  char buffer[INET6_ADDRSTRLEN];
-
-  /* only IPIP tunnel if OLSR runs with IPv4 */
-  assert (olsr_cnf->ip_version == AF_INET);
-  memset(&p, 0, sizeof(p));
-  p.iph.version = 4;
-  p.iph.ihl = 5;
-  p.iph.ttl = 64;
-  p.iph.protocol = IPPROTO_IPIP;
-  if (target) {
-    p.iph.daddr = *target;
-  }
-  strncpy(p.name, name, IFNAMSIZ);
-
-  memset(&ifr, 0, sizeof(ifr));
-  strncpy(ifr.ifr_name, target != NULL ? TUNNEL_ENDPOINT_IF : name, IFNAMSIZ);
-  ifr.ifr_ifru.ifru_data = (void *) &p;
-
-  if ((err = ioctl(olsr_cnf->ioctl_s, target != NULL ? SIOCADDTUNNEL : SIOCDELTUNNEL, &ifr))) {
-    olsr_syslog(OLSR_LOG_ERR, "Cannot %s a tunnel %s to %s: %s (%d)\n",
-        target != NULL ? "add" : "remove", name,
-        target != NULL ? inet_ntop(olsr_cnf->ip_version, target, buffer, sizeof(buffer)) : "-",
-        strerror(errno), errno);
-    return 0;
-  }
-  olsr_syslog(OLSR_LOG_INFO, "Tunnel %s %s, to %s",
-      name,
-      target != NULL ? "added" : "removed",
-      target != NULL ? inet_ntop(olsr_cnf->ip_version, target, buffer, sizeof(buffer)) : "-");
-  return target != NULL ? if_nametoindex(name) : 1;
-}
+static int os_ip_tunnel(const char *name, void *target) {
+       struct ifreq ifr;
+       int err;
+       void * p;
+       char buffer[INET6_ADDRSTRLEN];
+       const char * tunName;
+       struct ip_tunnel_parm p4;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+       struct ip6_tnl_parm p6;
+#endif
 
-/**
- * creates an ipip tunnel (for ipv6)
- * @param name interface name
- * @param target pointer to tunnel target IP, NULL if tunnel should be removed
- * @return 0 if an error happened,
- *   if_index for successful created tunnel, 1 for successful deleted tunnel
- */
+       memset(&ifr, 0, sizeof(ifr));
+
+       if (olsr_cnf->ip_version == AF_INET) {
+               p = &p4;
+               tunName = TUNNEL_ENDPOINT_IF;
+
+               memset(&p4, 0, sizeof(p4));
+               p4.iph.version = 4;
+               p4.iph.ihl = 5;
+               p4.iph.ttl = 64;
+               p4.iph.protocol = IPPROTO_IPIP;
+               if (target) {
+                       p4.iph.daddr = *((in_addr_t *) target);
+               }
+               strncpy(p4.name, name, IFNAMSIZ);
+       } else {
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-static int os_ip6_tunnel(const char *name, struct in6_addr *target)
-{
-  struct ifreq ifr;
-  int err;
-  struct ip6_tnl_parm p;
-
-  /* only IP6 tunnel if OLSR runs with IPv6 */
-  assert (olsr_cnf->ip_version == AF_INET6);
-  memset(&p, 0, sizeof(p));
-  p.proto = 0; /* any protocol */
-  if (target) {
-    p.raddr = *target;
-  }
-  strncpy(p.name, name, IFNAMSIZ);
+               p = (void *) &p6;
+               tunName = TUNNEL_ENDPOINT_IF6;
+
+               memset(&p6, 0, sizeof(p6));
+               p6.proto = 0; /* any protocol */
+               if (target) {
+                       p6.raddr = *((struct in6_addr *) target);
+               }
+               strncpy(p6.name, name, IFNAMSIZ);
+#else
+               return 0;
+#endif
+       }
 
-  memset(&ifr, 0, sizeof(ifr));
-  strncpy(ifr.ifr_name, target != NULL ? TUNNEL_ENDPOINT_IF6 : name, IFNAMSIZ);
-  ifr.ifr_ifru.ifru_data = (void *) &p;
+       strncpy(ifr.ifr_name, target != NULL ? tunName : name, IFNAMSIZ);
+       ifr.ifr_ifru.ifru_data = p;
 
-  if ((err = ioctl(olsr_cnf->ioctl_s, target != NULL ? SIOCADDTUNNEL : SIOCDELTUNNEL, &ifr))) {
-    char buffer[INET6_ADDRSTRLEN];
+       if ((err = ioctl(olsr_cnf->ioctl_s, target != NULL ? SIOCADDTUNNEL : SIOCDELTUNNEL, &ifr))) {
+               olsr_syslog(OLSR_LOG_ERR, "Cannot %s tunnel %s to %s: %s (%d)\n", target != NULL ? "add" : "remove", name,
+                               target != NULL ? inet_ntop(olsr_cnf->ip_version, target, buffer, sizeof(buffer)) : "-", strerror(errno),
+                               errno);
+               return 0;
+       }
 
-    olsr_syslog(OLSR_LOG_ERR, "Cannot %s a tunnel %s to %s: %s (%d)\n",
-        target != NULL ? "add" : "remove", name,
-        target != NULL ? inet_ntop(olsr_cnf->ip_version, target, buffer, sizeof(buffer)) : "-",
-        strerror(errno), errno);
-    return 0;
-  }
-  return target != NULL ? if_nametoindex(name) : 1;
+       olsr_syslog(OLSR_LOG_INFO, "Tunnel %s %s, to %s", name, target != NULL ? "added" : "removed",
+                       target != NULL ? inet_ntop(olsr_cnf->ip_version, target, buffer, sizeof(buffer)) : "-");
+
+       return target != NULL ? if_nametoindex(name) : 1;
 }
-#endif
 
 /**
  * Dummy for generating an interface name for an olsr ipip tunnel
@@ -227,17 +211,7 @@ struct olsr_iptunnel_entry *olsr_os_add_ipip_tunnel(union olsr_ip_addr *target,
     memset(name, 0, sizeof(name));
     generate_iptunnel_name(target, name);
 
-    if (olsr_cnf->ip_version == AF_INET) {
-      if_idx = os_ip4_tunnel(name, &target->v4.s_addr);
-    }
-    else {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-      if_idx = os_ip6_tunnel(name, &target->v6);
-#else
-      if_idx = 0;
-#endif
-    }
-
+    if_idx = os_ip_tunnel(name, (olsr_cnf->ip_version == AF_INET) ? (void *) &target->v4.s_addr : (void *) &target->v6);
     if (if_idx == 0) {
       // cannot create tunnel
       olsr_syslog(OLSR_LOG_ERR, "Cannot create tunnel %s\n", name);
@@ -245,14 +219,7 @@ struct olsr_iptunnel_entry *olsr_os_add_ipip_tunnel(union olsr_ip_addr *target,
     }
 
     if (olsr_if_set_state(name, true)) {
-      if (olsr_cnf->ip_version == AF_INET) {
-        os_ip4_tunnel(name, NULL);
-      }
-      else {
-  #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-        os_ip6_tunnel(name, NULL);
-  #endif
-      }
+      os_ip_tunnel(name, NULL);
       return NULL;
     }
 
@@ -291,14 +258,7 @@ static void internal_olsr_os_del_ipip_tunnel(struct olsr_iptunnel_entry *t, bool
   }
 
   olsr_if_set_state(t->if_name, false);
-  if (olsr_cnf->ip_version == AF_INET) {
-    os_ip4_tunnel(t->if_name, NULL);
-  }
-  else {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
-    os_ip6_tunnel(t->if_name, NULL);
-#endif
-  }
+  os_ip_tunnel(t->if_name, NULL);
 
   avl_delete(&tunnel_tree, &t->node);
   if (!cleanup) {