/* Given a destination ip address: * - find interface the packet would be shipped through * - return this interface's ip address as the src ip address */ uint32_t find_srcip(uint32_t dest) { struct sr_instance* sr = sr_get_global_instance(0); router_state* rs = (router_state*)sr->interface_subsystem; iface_entry* iface_struct; char *iface = 0; struct in_addr dst; struct in_addr src; uint32_t srcip; iface = calloc(32, sizeof(char)); dst.s_addr = dest; src.s_addr = 0; lock_if_list_rd(rs); lock_rtable_rd(rs); if(get_next_hop(&src, iface, 32, rs, &dst)) { srcip = 0; } else { iface_struct = get_iface(rs, iface); assert(iface_struct); srcip = iface_struct->ip; } unlock_rtable(rs); unlock_if_list(rs); return srcip; }
clusterer_node_t* get_clusterer_nodes(int cluster_id) { clusterer_node_t *ret_nodes = NULL; node_info_t *node; cluster_info_t *cl; lock_start_read(cl_list_lock); cl = get_cluster_by_id(cluster_id); if (!cl) { LM_ERR("cluster id: %d not found!\n", cluster_id); lock_stop_read(cl_list_lock); return NULL; } for (node = cl->node_list; node; node = node->next) if (get_next_hop(node) > 0) if (add_clusterer_node(&ret_nodes, node) < 0) { lock_stop_read(cl_list_lock); LM_ERR("Unable to add node: %d to the returned list of reachable nodes\n", node->node_id); free_clusterer_nodes(ret_nodes); return NULL; } lock_stop_read(cl_list_lock); return ret_nodes; }
uint32_t napt_set_default_route(fal_ip4_addr_t dst_addr, fal_ip4_addr_t src_addr) { sw_error_t rv; /* search for the next hop (s) */ if (!(get_aclrulemask() & (1 << S17_ACL_LIST_DROUTE))) { if (multi_route_indev && \ (nf_athrs17_hnat_wan_type != NF_S17_WAN_TYPE_PPPOE) && (nf_athrs17_hnat_wan_type != NF_S17_WAN_TYPE_PPPOES0)) { uint32_t next_hop = get_next_hop(dst_addr, src_addr); aos_printk("Next hop: %08x\n", next_hop); if (next_hop != 0) { fal_host_entry_t arp_entry; memset(&arp_entry, 0, sizeof(arp_entry)); arp_entry.ip4_addr = next_hop; arp_entry.flags = FAL_IP_IP4_ADDR; rv = isis_ip_host_get(0, FAL_IP_ENTRY_IPADDR_EN, &arp_entry); if (rv != SW_OK) { printk("%s: isis_ip_host_get error... (non-existed host: %08x?) \n", __func__, next_hop); /* add into the nh_ent */ wan_nh_add((u_int8_t *)&next_hop, (u_int8_t *)NULL, 0); } else { printk("%s %d\n", __FUNCTION__, __LINE__); if (wan_nh_get(next_hop) != -1) droute_add_acl_rules(*(uint32_t *)&lanip, arp_entry.entry_id); else printk("%s %d\n", __FUNCTION__, __LINE__); } } else { aos_printk("no need to set the default route... \n"); set_aclrulemask (S17_ACL_LIST_DROUTE); } } } /* end next hop (s) */ return SW_OK; }
int cl_get_my_index(int cluster_id, str *capability, int *nr_nodes) { int i, j, tmp; int sorted[MAX_NO_NODES]; node_info_t *node; cluster_info_t *cl; struct remote_cap *cap; lock_start_read(cl_list_lock); cl = get_cluster_by_id(cluster_id); if (!cl) { LM_ERR("cluster id: %d not found!\n", cluster_id); lock_stop_read(cl_list_lock); return -1; } *nr_nodes = 0; for (node = cl->node_list; node; node = node->next) if (get_next_hop(node) > 0) { lock_get(node->lock); for (cap = node->capabilities; cap; cap = cap->next) if (!str_strcmp(capability, &cap->name)) break; if (cap && cap->flags & CAP_STATE_OK) sorted[(*nr_nodes)++] = node->node_id; lock_release(node->lock); } lock_stop_read(cl_list_lock); /* sort array of reachable node ids */ for (i = 1; i < *nr_nodes; i++) { tmp = sorted[i]; for (j = i - 1; j >= 0 && sorted[j] > tmp; j = j - 1) sorted[j+1] = sorted[j]; sorted[j+1] = tmp; } for (i = 0; i < *nr_nodes && sorted[i] < current_id; i++) ; (*nr_nodes)++; return i; }
clusterer_node_t *api_get_next_hop(int cluster_id, int node_id) { clusterer_node_t *ret = NULL; node_info_t *dest_node; cluster_info_t *cluster; int rc; lock_start_read(cl_list_lock); cluster = get_cluster_by_id(cluster_id); if (!cluster) { LM_DBG("Cluster id: %d not found!\n", cluster_id); return NULL; } dest_node = get_node_by_id(cluster, node_id); if (!dest_node) { LM_DBG("Node id: %d no found!\n", node_id); return NULL; } rc = get_next_hop(dest_node); if (rc < 0) return NULL; else if (rc == 0) { LM_DBG("No other path to node: %d\n", node_id); return NULL; } lock_get(dest_node->lock); if (add_clusterer_node(&ret, dest_node->next_hop) < 0) { LM_ERR("Failed to allocate next hop\n"); return NULL; } lock_release(dest_node->lock); lock_stop_read(cl_list_lock); return ret; }
static struct mi_root * clusterer_list(struct mi_root *cmd_tree, void *param) { cluster_info_t *cl; node_info_t *n_info; struct mi_root *rpl_tree = NULL; struct mi_node *node = NULL; struct mi_node *node_s = NULL; struct mi_attr* attr; str val; static str str_up = str_init("Up "); static str str_prob = str_init("Probe "); static str str_down = str_init("Down "); static str str_none = str_init("none"); int n_hop; rpl_tree = init_mi_tree(200, MI_OK_S, MI_OK_LEN); if (!rpl_tree) return NULL; rpl_tree->node.flags |= MI_IS_ARRAY; lock_start_read(cl_list_lock); /* iterate through clusters */ for (cl = *cluster_list; cl; cl = cl->next) { val.s = int2str(cl->cluster_id, &val.len); node = add_mi_node_child(&rpl_tree->node, MI_DUP_VALUE|MI_IS_ARRAY, MI_SSTR("Cluster"), val.s, val.len); if (!node) goto error; /* iterate through servers */ for (n_info = cl->node_list; n_info; n_info = n_info->next) { val.s = int2str(n_info->node_id, &val.len); node_s = add_mi_node_child(node, MI_DUP_VALUE, MI_SSTR("Node"), val.s, val.len); if (!node) goto error; val.s = sint2str(n_info->id, &val.len); attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("DB_ID"), val.s, val.len); if (!attr) goto error; attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("URL"), n_info->url.s, n_info->url.len); if (!attr) goto error; lock_get(n_info->lock); val.s = int2str(n_info->flags & NODE_STATE_ENABLED ? 1 : 0, &val.len); attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("Enabled"), val.s, val.len); if (!attr) { lock_release(n_info->lock); goto error; } if (n_info->link_state == LS_UP) val = str_up; else if (n_info->link_state == LS_DOWN) val = str_down; else val = str_prob; attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("Link_state"), val.s, val.len); if (!attr) { lock_release(n_info->lock); goto error; } lock_release(n_info->lock); n_hop = get_next_hop(n_info); if (n_hop <= 0) val = str_none; else val.s = int2str(n_hop, &val.len); attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("Next_hop"), val.s, val.len); if (!attr) goto error; if (n_info->description.s) attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("Description"), n_info->description.s, n_info->description.len); else attr = add_mi_attr(node_s, MI_DUP_VALUE, MI_SSTR("Description"), "none", 4); if (!attr) goto error; } } lock_stop_read(cl_list_lock); return rpl_tree; error: lock_stop_read(cl_list_lock); if (rpl_tree) free_mi_tree(rpl_tree); return NULL; }
static mi_response_t *clusterer_list(const mi_params_t *params, struct mi_handler *async_hdl) { cluster_info_t *cl; node_info_t *n_info; str val; mi_response_t *resp = NULL; mi_item_t *resp_obj; mi_item_t *clusters_arr, *cluster_item, *nodes_arr, *node_item; static str str_up = str_init("Up"); static str str_prob = str_init("Probe"); static str str_down = str_init("Down"); static str str_none = str_init("none"); int n_hop; resp = init_mi_result_object(&resp_obj); if (!resp) return 0; clusters_arr = add_mi_array(resp_obj, MI_SSTR("Clusters")); if (!clusters_arr) { free_mi_response(resp); return 0; } lock_start_read(cl_list_lock); /* iterate through clusters */ for (cl = *cluster_list; cl; cl = cl->next) { cluster_item = add_mi_object(clusters_arr, NULL, 0); if (!cluster_item) goto error; if (add_mi_number(cluster_item, MI_SSTR("cluster_id"), cl->cluster_id) < 0) goto error; nodes_arr = add_mi_array(cluster_item, MI_SSTR("Nodes")); if (!nodes_arr) goto error; /* iterate through nodes */ for (n_info = cl->node_list; n_info; n_info = n_info->next) { node_item = add_mi_object(nodes_arr, NULL, 0); if (!node_item) goto error; if (add_mi_number(node_item, MI_SSTR("node_id"), n_info->node_id) < 0) goto error; if (add_mi_number(node_item, MI_SSTR("db_id"), n_info->id) < 0) goto error; if (add_mi_string(node_item, MI_SSTR("url"), n_info->url.s, n_info->url.len) < 0) goto error; lock_get(n_info->lock); if (n_info->link_state == LS_UP) val = str_up; else if (n_info->link_state == LS_DOWN) val = str_down; else val = str_prob; if (add_mi_string(node_item, MI_SSTR("link_state"), val.s, val.len) < 0) { lock_release(n_info->lock); goto error; } lock_release(n_info->lock); n_hop = get_next_hop(n_info); if (n_hop <= 0) val = str_none; else val.s = int2str(n_hop, &val.len); if (add_mi_string(node_item, MI_SSTR("next_hop"), val.s, val.len) < 0) goto error; if (n_info->description.s) { if (add_mi_string(node_item, MI_SSTR("description"), n_info->description.s, n_info->description.len) < 0) goto error; } else if (add_mi_string(node_item, MI_SSTR("description"), MI_SSTR("none")) < 0) goto error; } } lock_stop_read(cl_list_lock); return resp; error: lock_stop_read(cl_list_lock); if (resp) free_mi_response(resp); return NULL; }