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