📄 ip_cmn_rte_table.ex.c
字号:
ip_cmn_rte_table_entry_redistribute (route_table, route_entry, redist_type, removed_proto);
/* It is possible that because of this new entry, some */
/* of the unresolved default/static routes have now */
/* become resolved. Check for this. */
ip_cmn_rte_table_unresolved_routes_check (route_table, addr_family, route_entry);
FRET (OPC_COMPCODE_SUCCESS);
}
void
Inet_Cmn_Rte_Table_Clear (IpT_Cmn_Rte_Table* route_table, InetT_Addr_Family addr_family)
{
OmsT_Ptree* ptree_ptr = OPC_NIL;
/* Clear out the whole ptree at once using oms_ptree_clear function */
/* oms_ptree_clear takes care of Lists (next_hop_list, backup_list) */
/* We need to destroy Hash Table (IpT_Cmn_Rte_Dest_Src_Table_Handle)*/
FIN (Inet_Cmn_Rte_Table_Clear (IpT_Cmn_Rte_Table*, InetT_Addr_Family));
/* Get a pointer to the IPv4 (InetC_Addr_Family_v4)/ IPv6(InetC_Addr_Family_v6) ptree */
ptree_ptr = route_table->ptree_ptr_array [addr_family];
if (ptree_ptr == OPC_NIL)
FOUT;
oms_ptree_clear (ptree_ptr, ip_cmn_rte_table_entry_free_proc, route_table);
/* Destroy the hash table, but do not destroy the values in it */
prg_string_hash_table_free_proc (route_table->dest_src_table, ip_cmn_rte_table_dest_src_tbl_entry_free);
/* Set table pointer as OPC_NIL */
route_table->dest_src_table = OPC_NIL;
FOUT;
}
static IpT_Cmn_Rte_Table_Entry*
ip_cmn_rte_default_route_add (IpT_Cmn_Rte_Table* cmn_rte_table,
void* src_obj_ptr, InetT_Address next_hop, IpT_Port_Info port_info,
int metric, IpT_Rte_Proc_Id proto, int admin_distance)
{
IpT_Cmn_Rte_Table_Entry * new_route_entry;
IpT_Cmn_Rte_Table_Entry * route_to_next_hop = OPC_NIL;
IpT_Cmn_Rte_Table_Entry * old_best_default_route;
IpT_Dest_Prefix default_dest_prefix;
/** Add a 0/0 route to the route table. The route could **/
/** be inserted by a dynamic routing protocol or it **/
/** could be a static entry. **/
/** If this is a valid route the new route entry will be**/
/** returned. **/
FIN (ip_cmn_rte_default_route_add (cmn_rte_table, addr_family, src_obj_ptr, ...));
/* Create a route table entry structure. */
default_dest_prefix = ip_cmn_rte_table_dest_prefix_create
(InetI_Default_v4_Addr, inet_smask_from_length_create (0));
new_route_entry = ip_cmn_rte_table_entry_create (default_dest_prefix,
proto, admin_distance, src_obj_ptr);
/* Since this is a 0/0 route, it is a candidate default */
/* Flag the route appropritely. */
ip_cmn_rte_table_entry_cand_default_flag_set (new_route_entry);
/* Make the first entry in the "next_hop" list for the new entry */
ip_cmn_rte_next_hop_add (new_route_entry, next_hop, metric, &port_info);
/* Print trace information. */
#ifndef OPD_NO_DEBUG
if (op_prg_odb_ltrace_active ("ip_cmn_rte_table"))
{
char dest_str [INETC_ADDR_STR_LEN];
char src_proto_str [64];
char nh_str [INETC_ADDR_STR_LEN];
char trace_msg [256];
ip_cmn_rte_table_dest_prefix_print (dest_str, default_dest_prefix);
ip_cmn_rte_proto_name_print (src_proto_str, proto);
inet_address_print (nh_str, next_hop);
/* And now the full message. */
sprintf (trace_msg,
"Dest |%s|, Next Hop |%s|, O/P Intf. |%d|, Metric |%d| and Src. Proto. |%s|.",
dest_str, nh_str, ip_rte_intf_tbl_index_from_port_info_get (route_table->iprmd_ptr, port_info),
metric, src_proto_str);
op_prg_odb_print_major ("Adding the following route to the Common IP Routing Table:", OPC_NIL);
op_prg_odb_print_minor (trace_msg, OPC_NIL);
}
#endif
/* First check if the next hop is reachable. */
/* Note that a default route cannot be used to resolve */
/* the next hop. Do not perform this check for Null0 */
/* routes. */
if ((!inet_address_equal (InetI_Null0_Next_Hop_Addr, next_hop)) &&
(!inet_address_equal (INETC_ADDRESS_INVALID, next_hop)) &&
((OPC_COMPCODE_FAILURE == inet_cmn_rte_table_lookup (cmn_rte_table,
next_hop, OPC_NIL, OPC_NIL, OPC_NIL, &route_to_next_hop)) ||
(ip_cmn_rte_table_entry_is_default (route_to_next_hop))))
{
/* Next hop is not reachable. Add the entry to the */
/* list of unresolved default routes. */
ip_cmn_rte_default_route_list_add (cmn_rte_table,
cmn_rte_table->unresolved_default_routes, &new_route_entry);
#ifndef OPD_NO_DEBUG
if (op_prg_odb_ltrace_active ("ip_cmn_rte_table"))
{
op_prg_odb_print_minor ("The next hop is not reachable.",
"Adding the route to the list of unresolved default routes", OPC_NIL);
}
#endif
/* We need to return NIL since the next hop is not */
/* reachable. */
FRET (OPC_NIL);
}
/* If we used another route to resolve the next hop, */
/* flag it. */
if (OPC_NIL != route_to_next_hop)
{
ip_cmn_rte_table_entry_default_flag_set (route_to_next_hop);
}
/* Next hop is reachable. Add the entry to the list of */
/* resolved default routes. If there is an existing */
/* entry from the same protocol, a new next hop will be */
/* added to that entry. */
ip_cmn_rte_default_route_list_add (cmn_rte_table,
cmn_rte_table->resolved_default_routes, &new_route_entry);
/* Cache the existing best default route. */
old_best_default_route = cmn_rte_table->best_default_route;
/* The new route might replace the gateway of last */
/* resort. Call the function that will check if this */
/* is true. */
ip_cmn_rte_gateway_of_last_resort_update (cmn_rte_table);
#ifndef OPD_NO_DEBUG
if (op_prg_odb_ltrace_active ("ip_cmn_rte_table"))
{
op_prg_odb_print_minor ("Updating the gateway of last resort...",
"The new gateway of last resort is:", OPC_NIL);
ip_cmn_rte_table_entry_print (cmn_rte_table->gateway_of_last_resort);
}
#endif
/* Update statistics for this route table. */
op_stat_write (cmn_rte_table->update_stathandle [IpC_Rte_Table_Any_Update], 1.0);
if (oms_routing_convergence_status_check (cmn_rte_table->convg_handle) == OmsC_Convergence_Reached)
{
char dest_str [INETC_ADDR_STR_LEN];
char src_proto_str [16];
char convergence_reason [256];
ip_cmn_rte_table_dest_prefix_print (dest_str, new_route_entry->dest_prefix);
ip_cmn_rte_proto_name_print (src_proto_str, proto);
sprintf(convergence_reason,
"Updated %s route to destination %s", src_proto_str, dest_str);
ip_cmn_rte_table_last_update_time_set (cmn_rte_table, convergence_reason);
}
else
{
ip_cmn_rte_table_last_update_time_set (cmn_rte_table, OPC_NIL);
}
/* Check if the best default route was set. */
if (OPC_NIL == old_best_default_route)
{
/* The new entry would have become the BDR. Send*/
/* an ADD redistribution interrupt. */
ip_cmn_rte_table_entry_redistribute (cmn_rte_table, new_route_entry,
IPC_REDIST_TYPE_ADD, IpC_Dyn_Rte_Invalid);
}
/* There was an existing BDR. Did we add a NH to */
/* this route. */
else if (new_route_entry == old_best_default_route)
{
/* We just added a Next hop to the BDR. Send an */
/* UPDATE redistribution interrupt. */
ip_cmn_rte_table_entry_redistribute (cmn_rte_table, new_route_entry,
IPC_REDIST_TYPE_UPDATE, IpC_Dyn_Rte_Invalid);
}
/* The entry that changed was not the original BDR */
/* If the new entry has become the BDR, send an */
/* update interrupt. */
else if (new_route_entry == cmn_rte_table->best_default_route)
{
/* The BDR is now a different route, send an */
/* update interrupt. */
ip_cmn_rte_table_entry_redistribute (cmn_rte_table, new_route_entry,
IPC_REDIST_TYPE_UPDATE, old_best_default_route->route_src_proto);
}
/*
else
{
The new route did not become the BDR.
No need to send any redistribution interrupts.
}
*/
/* Return the newly created entry. */
FRET (new_route_entry);
}
static Compcode
ip_cmn_rte_default_route_delete (IpT_Cmn_Rte_Table* cmn_rte_table,
IpT_Rte_Proc_Id proto, int* admin_dist_ptr)
{
IpT_Cmn_Rte_Table_Entry* default_route_ptr;
int index;
/** A dynamic routing protocol is withdrawing a 0/0 **/
/** route from the common route table. **/
FIN (ip_cmn_rte_default_route_delete (cmn_rte_table, proto));
/* Print trace information. */
#ifndef OPD_NO_DEBUG
if (op_prg_odb_ltrace_active ("ip_cmn_rte_table"))
{
char trace_msg [256];
char src_proto_str [64];
ip_cmn_rte_proto_name_print (src_proto_str, proto);
/* And now the full message. */
sprintf (trace_msg, "Deleting the default route inserted by \"%s\".", src_proto_str);
op_prg_odb_print_major (trace_msg, OPC_NIL);
}
#endif
/* Search for a default route inserted by the specified */
/* protocol in the list of resolved default routes. */
if (OPC_NIL != ip_cmn_rte_default_route_list_find
(cmn_rte_table->resolved_default_routes, proto, &index))
{
/* We have found a matching entry. */
#ifndef OPD_NO_DEBUG
if (op_prg_odb_ltrace_active ("ip_cmn_rte_table"))
{
op_prg_odb_print_minor ("Found a matching entry in the list of resolved default routes.", OPC_NIL);
}
#endif
/* Remove the entry from the list. */
default_route_ptr = (IpT_Cmn_Rte_Table_Entry*)
op_prg_list_remove (cmn_rte_table->resolved_default_routes, index);
/* If this is the current best default route, pick a*/
/* new one. */
if (cmn_rte_table->best_default_route == default_route_ptr)
{
/* Update statistics for this route table. */
op_stat_write (cmn_rte_table->update_stathandle [IpC_Rte_Table_Any_Update], 1.0);
if (oms_routing_convergence_status_check (cmn_rte_table->convg_handle) == OmsC_Convergence_Reached)
{
char dest_str [INETC_ADDR_STR_LEN];
char src_proto_str [16];
char convergence_reason [256];
ip_cmn_rte_table_dest_prefix_print (dest_str, default_route_ptr->dest_prefix);
ip_cmn_rte_proto_name_print (src_proto_str, proto);
sprintf(convergence_reason,
"Updated %s route to destination %s", src_proto_str, dest_str);
ip_cmn_rte_table_last_update_time_set (cmn_rte_table, convergence_reason);
}
else
{
ip_cmn_rte_table_last_update_time_set (cmn_rte_table, OPC_NIL);
}
/* Update the gateway of last resort. */
ip_cmn_rte_gateway_of_last_resort_update (cmn_rte_table);
/* If the current best default route is unset, */
/* send a WITHDRAW redistribution interrupt. */
if (OPC_NIL == cmn_rte_table->best_default_route)
{
ip_cmn_rte_table_entry_redistribute (cmn_rte_table, default_route_ptr,
IPC_REDIST_TYPE_WITHDRAW, proto);
}
else
{
/* We now have a different BDR. Send an */
/* UPDATE redistribution interrupt. */
ip_cmn_rte_table_entry_redistribute (cmn_rte_table, cmn_rte_table->best_default_route,
IPC_REDIST_TYPE_UPDATE, proto);
}
}
/* Fill in the admin distance if it is requested */
if (OPC_NIL != admin_dist_ptr)
{
*admin_dist_ptr = default_route_ptr->admin_distance;
}
/* Free the memory allocated to the route. */
ip_cmn_rte_table_entry_free (default_route_ptr, cmn_rte_table);
/* Return SUCCESS to indicate a matching entry was */
/* found. */
FRET (OPC_COMPCODE_SUCCESS);
}
/* We did not find a match in the list of resolved */
/* default routes. Try the list of unresolved default */
/* routes. */
if (OPC_NIL != ip_cmn_rte_default_route_list_find
(cmn_rte_table->unresolved_default_routes, proto, &index))
{
/* We have found a matching entry. */
#ifndef OPD_NO_DEBUG
if (op_prg_odb_ltrace_active ("ip_cmn_rte_table"))
{
op_prg_odb_print_minor ("Found a matching entry in the list of unresolved default routes.", OPC_NIL);
}
#endif
/* Remove the entry from the list. */
default_route_ptr = (IpT_Cmn_Rte_Table_Entry*) op_prg_list_remove
(cmn_rte_table->unresolved_default_routes, index);
/* Fill in the admin distance if it is requested */
if (OPC_NIL != admin_dist_ptr)
{
*admin_dist_ptr = default_route_ptr->admin_distance;
}
/* Free the memory allocated to the route. */
ip_cmn_rte_table_entry_free (default_route_ptr, cmn_rte_table);
/* Return SUCCESS to indicate a matching entry was */
/* found. */
FRET (OPC_COMPCODE_SUCCESS);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -