return (FIB_FORW_CHAIN_TYPE_UNICAST_IP6);
case FIB_PROTOCOL_MPLS:
if (MPLS_EOS == fib_entry->fe_prefix.fp_eos)
- /*
- * If the entry being asked is a eos-MPLS label entry,
- * then use the payload-protocol field, that we stashed there
- * for just this purpose
- */
- return (fib_forw_chain_type_from_dpo_proto(
- fib_entry->fe_prefix.fp_payload_proto));
+ return (FIB_FORW_CHAIN_TYPE_MPLS_EOS);
else
return (FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS);
}
fib_entry_src_t *src;
fib_node_index_t fei;
fib_source_t source;
- u32 n_covered;
int level;
fei = va_arg (*args, fib_node_index_t);
}
}));
- n_covered = fib_entry_cover_get_size(fib_entry);
- if (n_covered > 0) {
- s = format(s, "\n tracking %d covered: ", n_covered);
- s = fib_entry_cover_list_format(fib_entry, s);
- }
- s = fib_ae_import_format(fib_entry, s);
- s = fib_ae_export_format(fib_entry, s);
-
s = format (s, "\n forwarding: ");
}
else
fib_entry_delegate_type_t fdt;
fib_entry_delegate_t *fed;
- FOR_EACH_DELEGATE_CHAIN(fib_entry, fdt, fed,
+ s = format (s, " Delegates:\n");
+ FOR_EACH_DELEGATE(fib_entry, fdt, fed,
{
- s = format(s, " %U-chain\n %U",
- format_fib_forw_chain_type,
- fib_entry_delegate_type_to_chain_type(fdt),
- format_dpo_id, &fed->fd_dpo, 2);
- s = format(s, "\n");
+ s = format(s, " %U\n", format_fib_entry_deletegate, fed);
});
}
}
if (level >= FIB_ENTRY_FORMAT_DETAIL2)
{
- s = format(s, "\nchildren:");
+ s = format(s, " Children:");
s = fib_node_children_format(fib_entry->fe_node.fn_children, s);
}
ASSERT(0 == vec_len(fib_entry->fe_delegates));
vec_free(fib_entry->fe_delegates);
+ vec_free(fib_entry->fe_srcs);
pool_put(fib_entry_pool, fib_entry);
}
return (fib_path_list_contribute_urpf(fib_entry->fe_parent, urpf));
}
+/*
+ * If the client is request a chain for multicast forwarding then swap
+ * the chain type to one that can provide such transport.
+ */
+static fib_forward_chain_type_t
+fib_entry_chain_type_mcast_to_ucast (fib_forward_chain_type_t fct)
+{
+ switch (fct)
+ {
+ case FIB_FORW_CHAIN_TYPE_MCAST_IP4:
+ case FIB_FORW_CHAIN_TYPE_MCAST_IP6:
+ /*
+ * we can only transport IP multicast packets if there is an
+ * LSP.
+ */
+ fct = FIB_FORW_CHAIN_TYPE_MPLS_EOS;
+ break;
+ case FIB_FORW_CHAIN_TYPE_MPLS_EOS:
+ case FIB_FORW_CHAIN_TYPE_UNICAST_IP4:
+ case FIB_FORW_CHAIN_TYPE_UNICAST_IP6:
+ case FIB_FORW_CHAIN_TYPE_MPLS_NON_EOS:
+ case FIB_FORW_CHAIN_TYPE_ETHERNET:
+ case FIB_FORW_CHAIN_TYPE_NSH:
+ break;
+ }
+
+ return (fct);
+}
+
/*
* fib_entry_contribute_forwarding
*
fib_entry = fib_entry_get(fib_entry_index);
+ /*
+ * mfib children ask for mcast chains. fix these to the appropriate ucast types.
+ */
+ fct = fib_entry_chain_type_mcast_to_ucast(fct);
+
if (fct == fib_entry_get_default_chain_type(fib_entry))
{
dpo_copy(dpo, &fib_entry->fe_lb);
dpo_copy(dpo, &fed->fd_dpo);
}
+ /*
+ * don't allow the special index indicating replicate.vs.load-balance
+ * to escape to the clients
+ */
+ dpo->dpoi_index &= ~MPLS_IS_REPLICATE;
}
const dpo_id_t *
return (fib_entry);
}
-static void
+static fib_entry_t*
fib_entry_post_flag_update_actions (fib_entry_t *fib_entry,
fib_source_t source,
fib_entry_flag_t old_flags)
{
+ fib_node_index_t fei;
+
+ /*
+ * save the index so we can recover from pool reallocs
+ */
+ fei = fib_entry_get_index(fib_entry);
+
/*
* handle changes to attached export for import entries
*/
* no change. nothing to do.
*/
+ /*
+ * reload the entry address post possible pool realloc
+ */
+ fib_entry = fib_entry_get(fei);
+
/*
* handle changes to attached export for export entries
*/
// FIXME
}
// else FIXME
+
+ return (fib_entry);
}
static void
fib_source_t source,
fib_entry_flag_t old_flags)
{
- fib_entry_post_flag_update_actions(fib_entry, source, old_flags);
+ fib_entry = fib_entry_post_flag_update_actions(fib_entry,
+ source,
+ old_flags);
fib_entry_src_action_installed(fib_entry, source);
}
/*
* no more sources left. this entry is toast.
*/
+ fib_entry = fib_entry_post_flag_update_actions(fib_entry,
+ source,
+ bflags);
fib_entry_src_action_uninstall(fib_entry);
- fib_entry_post_flag_update_actions(fib_entry, source, bflags);
return (FIB_ENTRY_SRC_FLAG_NONE);
}
/*
* no more sources left. this entry is toast.
*/
+ fib_entry = fib_entry_post_flag_update_actions(fib_entry,
+ source,
+ bflags);
fib_entry_src_action_uninstall(fib_entry);
- fib_entry_post_flag_update_actions(fib_entry, source, bflags);
return (FIB_ENTRY_SRC_FLAG_NONE);
}
return (fib_entry_src_get_source(bsrc));
}
+/**
+ * Return !0 is the entry is reoslved, i.e. will return a valid forwarding
+ * chain
+ */
+int
+fib_entry_is_resolved (fib_node_index_t fib_entry_index)
+{
+ fib_entry_delegate_t *fed;
+ fib_entry_t *fib_entry;
+
+ fib_entry = fib_entry_get(fib_entry_index);
+
+ fed = fib_entry_delegate_get(fib_entry, FIB_ENTRY_DELEGATE_BFD);
+
+ if (NULL == fed)
+ {
+ /*
+ * no BFD tracking - resolved
+ */
+ return (!0);
+ }
+ else
+ {
+ /*
+ * defer to the state of the BFD tracking
+ */
+ return (FIB_BFD_STATE_UP == fed->fd_bfd_state);
+ }
+}
+
+void
+fib_entry_set_flow_hash_config (fib_node_index_t fib_entry_index,
+ flow_hash_config_t hash_config)
+{
+ fib_entry_t *fib_entry;
+
+ fib_entry = fib_entry_get(fib_entry_index);
+
+ /*
+ * pass the hash-config on to the load-balance object where it is cached.
+ * we can ignore LBs in the delegate chains, since they will not be of the
+ * correct protocol type (i.e. they are not IP)
+ * There's no way, nor need, to change the hash config for MPLS.
+ */
+ if (dpo_id_is_valid(&fib_entry->fe_lb))
+ {
+ load_balance_t *lb;
+
+ ASSERT(DPO_LOAD_BALANCE == fib_entry->fe_lb.dpoi_type);
+
+ lb = load_balance_get(fib_entry->fe_lb.dpoi_index);
+
+ /*
+ * atomic update for packets in flight
+ */
+ lb->lb_hash_config = hash_config;
+ }
+}
+
static int
fib_ip4_address_compare (const ip4_address_t * a1,
const ip4_address_t * a2)
fib_entry_t *fib_entry;
fib_entry = fib_entry_get(fib_entry_index);
- fib_path_list_walk(fib_entry->fe_parent, fib_path_encode, api_rpaths);
+ if (FIB_NODE_INDEX_INVALID != fib_entry->fe_parent)
+ {
+ fib_path_list_walk(fib_entry->fe_parent, fib_path_encode, api_rpaths);
+ }
}
void