/** *Add a gatewayentry to the HNA set * *@param addr the address of the gateway * *@return the created entry */ struct hna_entry * olsr_add_hna_entry(const union olsr_ip_addr *addr) { struct hna_entry *new_entry; uint32_t hash; new_entry = olsr_cookie_malloc(hna_entry_mem_cookie); /* Fill struct */ new_entry->A_gateway_addr = *addr; /* Link nets */ new_entry->networks.next = &new_entry->networks; new_entry->networks.prev = &new_entry->networks; /* queue */ hash = olsr_ip_hashing(addr); hna_set[hash].next->prev = new_entry; new_entry->next = hna_set[hash].next; hna_set[hash].next = new_entry; new_entry->prev = &hna_set[hash]; return new_entry; }
/** * Alloc and key a new rt_path. */ static struct rt_path * olsr_alloc_rt_path(struct tc_entry *tc, struct olsr_ip_prefix *prefix, uint8_t origin) { struct rt_path *rtp = olsr_cookie_malloc(rtp_mem_cookie); if (!rtp) { return NULL; } memset(rtp, 0, sizeof(*rtp)); rtp->rtp_dst = *prefix; /* set key and backpointer prior to tree insertion */ rtp->rtp_prefix_tree_node.key = &rtp->rtp_dst; /* insert to the tc prefix tree */ avl_insert(&tc->prefix_tree, &rtp->rtp_prefix_tree_node, AVL_DUP_NO); olsr_lock_tc_entry(tc); /* backlink to the owning tc entry */ rtp->rtp_tc = tc; /* store the origin of the route */ rtp->rtp_origin = origin; return rtp; }
/** * 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; }
/** * Add a new tc_entry to the tc tree * * @param adr (last)adr address of the entry * @return a pointer to the created entry */ static struct tc_entry * olsr_add_tc_entry(union olsr_ip_addr *adr) { #ifdef DEBUG struct ipaddr_str buf; #endif /* DEBUG */ struct tc_entry *tc; /* * Safety net against loss of the last main IP address. */ if (ipequal(&olsr_cnf->main_addr, &all_zero)) { return NULL; } #ifdef DEBUG OLSR_PRINTF(1, "TC: add entry %s\n", olsr_ip_to_string(&buf, adr)); #endif /* DEBUG */ tc = olsr_cookie_malloc(tc_mem_cookie); if (!tc) { return NULL; } /* Fill entry */ tc->addr = *adr; tc->vertex_node.key = &tc->addr; /* * Insert into the global tc tree. */ avl_insert(&tc_tree, &tc->vertex_node, AVL_DUP_NO); olsr_lock_tc_entry(tc); /* * Initialize subtrees for edges and prefixes. */ avl_init(&tc->edge_tree, avl_comp_default); avl_init(&tc->prefix_tree, avl_comp_prefix_default); /* * Add a rt_path for ourselves. */ olsr_insert_routing_table(adr, olsr_cnf->maxplen, adr, OLSR_RT_ORIGIN_INT); return tc; }
/** * Start a new timer. * * @param relative time expressed in milliseconds * @param jitter expressed in percent * @param timer callback function * @param context for the callback function * @return a pointer to the created entry */ struct timer_entry * olsr_start_timer(unsigned int rel_time, uint8_t jitter_pct, bool periodical, timer_cb_func cb_func, void *context, struct olsr_cookie_info *ci) { struct timer_entry *timer; if (ci == NULL) { ci = def_timer_ci; } assert(cb_func); timer = olsr_cookie_malloc(timer_mem_cookie); /* * Compute random numbers only once. */ if (!timer->timer_random) { timer->timer_random = random(); } /* Fill entry */ timer->timer_clock = calc_jitter(rel_time, jitter_pct, timer->timer_random); timer->timer_cb = cb_func; timer->timer_cb_context = context; timer->timer_jitter_pct = jitter_pct; timer->timer_flags = OLSR_TIMER_RUNNING; /* The cookie is used for debugging to traceback the originator */ timer->timer_cookie = ci; olsr_cookie_usage_incr(ci->ci_id); /* Singleshot or periodical timer ? */ timer->timer_period = periodical ? rel_time : 0; /* * Now insert in the respective timer_wheel slot. */ list_add_before(&timer_wheel[timer->timer_clock & TIMER_WHEEL_MASK], &timer->timer_list); OLSR_PRINTF(7, "TIMER: start %s timer %p firing in %s, ctx %p\n", ci->ci_name, timer, olsr_clock_string(timer->timer_clock), context); return timer; }
/** * Adds a network entry to a HNA gateway. * * @param hna_gw the gateway entry to add the network to * @param net the network address to add * @param prefixlen the prefix length * * @return the newly created entry */ struct hna_net * olsr_add_hna_net(struct hna_entry *hna_gw, const union olsr_ip_addr *net, uint8_t prefixlen) { /* Add the net */ struct hna_net *new_net = olsr_cookie_malloc(hna_net_mem_cookie); /* Fill struct */ memset(new_net, 0, sizeof(struct hna_net)); new_net->hna_prefix.prefix = *net; new_net->hna_prefix.prefix_len= prefixlen; /* Set backpointer */ new_net->hna_gw = hna_gw; /* Queue */ hna_gw->networks.next->prev = new_net; new_net->next = hna_gw->networks.next; hna_gw->networks.next = new_net; new_net->prev = &hna_gw->networks; return new_net; }
/** * Alloc and key a new rt_entry. */ static struct rt_entry * olsr_alloc_rt_entry(struct olsr_ip_prefix *prefix) { struct rt_entry *rt = olsr_cookie_malloc(rt_mem_cookie); if (!rt) { return NULL; } memset(rt, 0, sizeof(*rt)); /* Mark this entry as fresh (see process_routes.c:512) */ rt->rt_nexthop.iif_index = -1; /* set key and backpointer prior to tree insertion */ rt->rt_dst = *prefix; rt->rt_tree_node.key = &rt->rt_dst; avl_insert(&routingtree, &rt->rt_tree_node, AVL_DUP_NO); /* init the originator subtree */ avl_init(&rt->rt_path_tree, avl_comp_default); return rt; }