/**
 * 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;
}
Exemplo n.º 2
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);
}