static int bootp_process(struct bootphdr *bph, struct net_device *dev) { struct in_device *in_dev; in_addr_t ip_addr; in_addr_t ip_gate; in_addr_t ip_mask; int ret; in_dev = inetdev_get_by_dev(dev); if (in_dev == NULL) { return -EINVAL; } ret = bootp_get_ip(bph, &ip_addr); if (ret) { return ret; } inetdev_set_addr(in_dev, ip_addr); ret = bootp_get_mask(bph, &ip_mask); if (ret == 0) { inetdev_set_mask(in_dev, ip_mask); rt_add_route(in_dev->dev, ip_addr & ip_mask, ip_mask, INADDR_ANY, 0); } ret = bootp_get_gateway(bph, &ip_gate); if (ret == 0) { rt_add_route(in_dev->dev, INADDR_ANY, INADDR_ANY, ip_gate, RTF_GATEWAY); } return 0; }
/** * @brief Extract route information and store them in route table. * * @param local_addr Local network address of this node * @param length Length of address list * @param list Address list with route information */ static void rt_extract_routes(uint16_t local_addr, uint8_t length, uint16_t *list) { DEBUG("call [%u]: rt_extract_routes\n", fk_thread->pid); uint16_t net_id = NETWORK_ADDR_BC(list[0]); /* BC address of source of RREQ */ route_table_entry_t *rte = rt_lookup_route(net_id); /* Should exist (preconfigured) */ if (rte == NULL) { DEBUG("exit [%u]: rt_extract_routes\n", fk_thread->pid); return; /* else exit here */ } int i = 0; while (i < length && list[i] != local_addr) { i++; } if (i == length) { DEBUG("exit [%u]: rt_extract_routes\n", fk_thread->pid); return; } int pos = i; int leftNeighbour = -1; int rightNeighbour = -1; if (pos > 0) { leftNeighbour = list[pos - 1]; } if (pos + 1 != length) { rightNeighbour = list[pos + 1]; } i = 0; while (i < length) { uint16_t next = list[i]; if (local_addr != next) { int distance = pos - i; int router = leftNeighbour; if (distance < 0) { router = rightNeighbour; distance *= -1; } rt_add_route(next, (uint16_t)router, (uint8_t)distance, rte->interface_id); } i++; } DEBUG("exit [%u]: rt_extract_routes\n", fk_thread->pid); }
/** * Add a route to the given prefix into the given node. The outgoing * interface is a link. The weight of the route can be specified as it * can be different from the outgoing link's weight. * * Pre: the outgoing link (next-hop interface) must exist in the node. */ int node_rt_add_route_link(net_node_t * node, ip_pfx_t pfx, net_iface_t * oif, net_addr_t gateway, uint32_t weight, uint8_t type) { rt_info_t * rtinfo; net_iface_t * sub_link; net_error_t result; // If a next-hop has been specified, check that it is reachable // through the given interface. if ((gateway != IP_ADDR_ANY) && (oif != NULL)) { switch (oif->type) { case NET_IFACE_RTR: if (oif->dest.iface->owner->rid != gateway) return ENET_RT_NH_UNREACH; break; case NET_IFACE_PTP: if (!node_has_address(oif->dest.iface->owner, gateway)) return ENET_RT_NH_UNREACH; break; case NET_IFACE_PTMP: sub_link= net_subnet_find_link(oif->dest.subnet, gateway); if ((sub_link == NULL) || (sub_link->addr == oif->addr)) return ENET_RT_NH_UNREACH; break; default: abort(); } } else if ((gateway == IP_ADDR_ANY) && (oif == NULL)) { return ENET_RT_NO_GW_NO_OIF; } // Check if route info already exists (if we add a parallel path) rtinfo= rt_find_exact(node->rt, pfx, type); // Build route info if (rtinfo == NULL) { rtinfo= rt_info_create(pfx, weight, type); result= rt_info_add_entry(rtinfo, oif, gateway); if (result != ESUCCESS) { rt_info_destroy(&rtinfo); return result; } result= rt_add_route(node->rt, pfx, rtinfo); } else result= rt_info_add_entry(rtinfo, oif, gateway); return result; }