summaryrefslogtreecommitdiffstats
path: root/zebra/zebra_nb_state.c
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2020-05-19 02:34:48 +0200
committerRenato Westphal <renato@opensourcerouting.org>2020-05-16 04:47:43 +0200
commitbf6f7f7d54e77dfee82d3fb4c7b497865143a506 (patch)
tree7add4ff1a72a6b9339c065c73693494b8030c386 /zebra/zebra_nb_state.c
parentzebra: add missing return in one get_elem() callback (diff)
downloadfrr-bf6f7f7d54e77dfee82d3fb4c7b497865143a506.tar.xz
frr-bf6f7f7d54e77dfee82d3fb4c7b497865143a506.zip
zebra: implement two missing RIB lookup_entry() callbacks
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
Diffstat (limited to 'zebra/zebra_nb_state.c')
-rw-r--r--zebra/zebra_nb_state.c72
1 files changed, 69 insertions, 3 deletions
diff --git a/zebra/zebra_nb_state.c b/zebra/zebra_nb_state.c
index 6becfcdf6..a09ac8568 100644
--- a/zebra/zebra_nb_state.c
+++ b/zebra/zebra_nb_state.c
@@ -512,8 +512,9 @@ int lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_get_keys(
const void *lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_lookup_entry(
struct nb_cb_lookup_entry_args *args)
{
- /* TODO: implement me. */
- return NULL;
+ struct route_entry *re = (struct route_entry *)args->parent_list_entry;
+
+ return re->nhe;
}
/*
@@ -617,7 +618,72 @@ const void *
lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_lookup_entry(
struct nb_cb_lookup_entry_args *args)
{
- /* TODO: implement me. */
+ struct nhg_hash_entry *nhe;
+ struct nexthop nexthop_lookup = {};
+ struct nexthop *nexthop;
+ const char *nh_type_str;
+
+ nhe = (struct nhg_hash_entry *)args->parent_list_entry;
+ nexthop_lookup.vrf_id = nhe->vrf_id;
+
+ /*
+ * Get nexthop type.
+ * TODO: use yang_str2enum() instead.
+ */
+ nh_type_str = args->keys->key[0];
+ if (strmatch(nh_type_str, "ifindex"))
+ nexthop_lookup.type = NEXTHOP_TYPE_IFINDEX;
+ else if (strmatch(nh_type_str, "ip4"))
+ nexthop_lookup.type = NEXTHOP_TYPE_IPV4;
+ else if (strmatch(nh_type_str, "ip4-ifindex"))
+ nexthop_lookup.type = NEXTHOP_TYPE_IPV4_IFINDEX;
+ else if (strmatch(nh_type_str, "ip6"))
+ nexthop_lookup.type = NEXTHOP_TYPE_IPV6;
+ else if (strmatch(nh_type_str, "ip6-ifindex"))
+ nexthop_lookup.type = NEXTHOP_TYPE_IPV6_IFINDEX;
+ else if (strmatch(nh_type_str, "blackhole"))
+ nexthop_lookup.type = NEXTHOP_TYPE_BLACKHOLE;
+ else
+ /* unexpected */
+ return NULL;
+
+ /* Get nexthop address. */
+ switch (nexthop_lookup.type) {
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ yang_str2ipv4(args->keys->key[1], &nexthop_lookup.gate.ipv4);
+ break;
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ yang_str2ipv6(args->keys->key[1], &nexthop_lookup.gate.ipv6);
+ break;
+ case NEXTHOP_TYPE_IFINDEX:
+ case NEXTHOP_TYPE_BLACKHOLE:
+ break;
+ }
+
+ /* Get nexthop interface. */
+ switch (nexthop_lookup.type) {
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ case NEXTHOP_TYPE_IFINDEX:
+ nexthop_lookup.ifindex =
+ ifname2ifindex(args->keys->key[2], nhe->vrf_id);
+ break;
+ case NEXTHOP_TYPE_IPV4:
+ case NEXTHOP_TYPE_IPV6:
+ case NEXTHOP_TYPE_BLACKHOLE:
+ break;
+ }
+
+ /* Lookup requested nexthop (ignore weight and metric). */
+ for (ALL_NEXTHOPS(nhe->nhg, nexthop)) {
+ nexthop_lookup.weight = nexthop->weight;
+ nexthop_lookup.src = nexthop->src;
+ if (nexthop_same_no_labels(&nexthop_lookup, nexthop))
+ return nexthop;
+ }
+
return NULL;
}