/** * 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; }
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); }