/**
 * Release an olsr ipip tunnel. Tunnel will be deleted
 * if this was the last user
 * @param t pointer to olsr_iptunnel_entry
 */
static void internal_olsr_os_del_ipip_tunnel(struct olsr_iptunnel_entry *t, bool cleanup) {
  if (!cleanup) {
    if (t->usage == 0) {
      return;
    }
    t->usage--;

    if (t->usage > 0) {
      return;
    }
  }

  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
  }

  avl_delete(&tunnel_tree, &t->node);
  if (!cleanup) {
    olsr_cookie_free(tunnel_cookie, t);
  }
}
/**
 * demands an ipip tunnel to a certain target. If no tunnel exists it will be created
 * @param target ip address of the target
 * @param transportV4 true if IPv4 traffic is used, false for IPv6 traffic
 * @return NULL if an error happened, pointer to olsr_iptunnel_entry otherwise
 */
struct olsr_iptunnel_entry *olsr_os_add_ipip_tunnel(union olsr_ip_addr *target, bool transportV4 __attribute__ ((unused))) {
  struct olsr_iptunnel_entry *t;

  assert(olsr_cnf->ip_version == AF_INET6 || transportV4);

  t = (struct olsr_iptunnel_entry *)avl_find(&tunnel_tree, target);
  if (t == NULL) {
    char name[IFNAMSIZ];
    int if_idx;
    struct ipaddr_str buf;

    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 (if_idx == 0) {
      // cannot create tunnel
      olsr_syslog(OLSR_LOG_ERR, "Cannot create tunnel %s\n", name);
      return NULL;
    }

    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
      }
      return NULL;
    }

    /* set originator IP for tunnel */
    olsr_os_ifip(if_idx, &olsr_cnf->main_addr, true);

    t = olsr_cookie_malloc(tunnel_cookie);
    memcpy(&t->target, target, sizeof(*target));
    t->node.key = &t->target;

    strncpy(t->if_name, name, IFNAMSIZ);
    t->if_index = if_idx;

    avl_insert(&tunnel_tree, &t->node, AVL_DUP_NO);
  }

  t->usage++;
  return t;
}
예제 #3
0
int olsr_os_init_iptunnel(const char * dev) {
  tunnel_cookie = olsr_alloc_cookie("iptunnel", OLSR_COOKIE_TYPE_MEMORY);
  olsr_cookie_set_memory_size(tunnel_cookie, sizeof(struct olsr_iptunnel_entry));
  avl_init(&tunnel_tree, avl_comp_default);

  store_iptunnel_state = olsr_if_isup(dev);
  if (store_iptunnel_state) {
    return 0;
  }
  if (olsr_if_set_state(dev, true)) {
    return -1;
  }

  return olsr_os_ifip(if_nametoindex(dev), &olsr_cnf->main_addr, true);
}
void olsr_os_cleanup_iptunnel(void) {
  while (tunnel_tree.count > 0) {
    struct olsr_iptunnel_entry *t;

    /* kill tunnel */
    t = (struct olsr_iptunnel_entry *)avl_walk_first(&tunnel_tree);
    t->usage = 1;

    olsr_os_del_ipip_tunnel(t);
  }
  if (!store_iptunnel_state) {
    olsr_if_set_state(olsr_cnf->ip_version == AF_INET ? DEV_IPV4_TUNNEL : DEV_IPV6_TUNNEL, false);
  }

  olsr_free_cookie(tunnel_cookie);
}
예제 #5
0
void olsr_os_cleanup_iptunnel(const char * dev) {
  while (tunnel_tree.count > 0) {
    struct olsr_iptunnel_entry *t;

    /* kill tunnel */
    t = (struct olsr_iptunnel_entry *)avl_walk_first(&tunnel_tree);
    t->usage = 1;

    olsr_os_del_ipip_tunnel(t);
  }
  if (!store_iptunnel_state) {
    olsr_if_set_state(dev, false);
  }

  olsr_free_cookie(tunnel_cookie);
}
예제 #6
0
/**
 * Release an olsr ipip tunnel. Tunnel will be deleted
 * if this was the last user
 * @param t pointer to olsr_iptunnel_entry
 */
static void internal_olsr_os_del_ipip_tunnel(struct olsr_iptunnel_entry *t, bool cleanup) {
  if (!cleanup) {
    if (t->usage == 0) {
      return;
    }
    t->usage--;

    if (t->usage > 0) {
      return;
    }
  }

  olsr_if_set_state(t->if_name, false);
  os_ip_tunnel(t->if_name, NULL);

  avl_delete(&tunnel_tree, &t->node);
  if (!cleanup) {
    olsr_cookie_free(tunnel_cookie, t);
  }
}