diff --git a/zebra/zebra_nb_config.c b/zebra/zebra_nb_config.c index a6aa72cf48..5b87a18a06 100644 --- a/zebra/zebra_nb_config.c +++ b/zebra/zebra_nb_config.c @@ -30,6 +30,7 @@ #include "zebra/interface.h" #include "zebra/connected.h" #include "zebra/zebra_router.h" +#include "zebra/debug.h" /* * XPath: /frr-zebra:zebra/mcast-rpf-lookup @@ -1222,11 +1223,12 @@ int lib_interface_zebra_bandwidth_destroy(struct nb_cb_destroy_args *args) int lib_vrf_zebra_ribs_rib_create(struct nb_cb_create_args *args) { struct vrf *vrf; - afi_t afi = AFI_IP; - safi_t safi = SAFI_UNICAST; + afi_t afi; + safi_t safi; struct zebra_vrf *zvrf; struct zebra_router_table *zrt; uint32_t table_id; + const char *afi_safi_name; vrf = nb_running_get_entry(args->dnode, NULL, false); zvrf = vrf_info_lookup(vrf->vrf_id); @@ -1234,9 +1236,8 @@ int lib_vrf_zebra_ribs_rib_create(struct nb_cb_create_args *args) if (!table_id) table_id = zvrf->table_id; - /* TODO: once identityref nb wrapper available, parse - * afi-safi-name and feed into the creation of the table - */ + afi_safi_name = yang_dnode_get_string(args->dnode, "./afi-safi-name"); + zebra_afi_safi_identity2value(afi_safi_name, &afi, &safi); zrt = zebra_router_find_zrt(zvrf, table_id, afi, safi); diff --git a/zebra/zebra_nb_state.c b/zebra/zebra_nb_state.c index 0abc48eb46..415c0d3f6d 100644 --- a/zebra/zebra_nb_state.c +++ b/zebra/zebra_nb_state.c @@ -23,6 +23,8 @@ #include "zebra_nb.h" #include "zebra/interface.h" #include "zebra/zebra_router.h" +#include "zebra/debug.h" +#include "printfrr.h" /* * XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/up-count @@ -183,11 +185,11 @@ int lib_vrf_zebra_ribs_rib_get_keys(struct nb_cb_get_keys_args *args) args->keys->num = 2; - snprintf(args->keys->key[0], sizeof(args->keys->key[0]), "%s", - "frr-zebra:ipv4-unicast"); - /* TODO: implement key[0], afi-safi identityref */ - snprintf(args->keys->key[1], sizeof(args->keys->key[1]), "%" PRIu32, - zrt->tableid); + snprintfrr(args->keys->key[0], sizeof(args->keys->key[0]), "%s:%s", + "frr-zebra", + zebra_afi_safi_value2identity(zrt->afi, zrt->safi)); + snprintfrr(args->keys->key[1], sizeof(args->keys->key[1]), "%" PRIu32, + zrt->tableid); return NB_OK; } @@ -197,12 +199,19 @@ lib_vrf_zebra_ribs_rib_lookup_entry(struct nb_cb_lookup_entry_args *args) { struct vrf *vrf = (struct vrf *)args->parent_list_entry; struct zebra_vrf *zvrf; - afi_t afi = AFI_IP; - safi_t safi = SAFI_UNICAST; + afi_t afi; + safi_t safi; + uint32_t table_id = 0; zvrf = zebra_vrf_lookup_by_id(vrf->vrf_id); - return zebra_router_find_zrt(zvrf, zvrf->table_id, afi, safi); + zebra_afi_safi_identity2value(args->keys->key[0], &afi, &safi); + table_id = yang_str2uint32(args->keys->key[1]); + /* table_id 0 assume vrf's table_id. */ + if (!table_id) + table_id = zvrf->table_id; + + return zebra_router_find_zrt(zvrf, table_id, afi, safi); } /* @@ -268,7 +277,13 @@ lib_vrf_zebra_ribs_rib_route_prefix_get_elem(struct nb_cb_get_elem_args *args) const void *lib_vrf_zebra_ribs_rib_route_route_entry_get_next( struct nb_cb_get_next_args *args) { - struct route_entry *re = NULL; + struct route_entry *re = (struct route_entry *)args->list_entry; + struct route_node *rn = (struct route_node *)args->parent_list_entry; + + if (args->list_entry == NULL) + RNODE_FIRST_RE(rn, re); + else + RNODE_NEXT_RE(rn, re); return re; } @@ -276,14 +291,32 @@ const void *lib_vrf_zebra_ribs_rib_route_route_entry_get_next( int lib_vrf_zebra_ribs_rib_route_route_entry_get_keys( struct nb_cb_get_keys_args *args) { - /* TODO: implement me. */ + struct route_entry *re = (struct route_entry *)args->list_entry; + + args->keys->num = 1; + + strlcpy(args->keys->key[0], zebra_route_string(re->type), + sizeof(args->keys->key[0])); + return NB_OK; } const void *lib_vrf_zebra_ribs_rib_route_route_entry_lookup_entry( struct nb_cb_lookup_entry_args *args) { - /* TODO: implement me. */ + struct route_node *rn = (struct route_node *)args->parent_list_entry; + struct route_entry *re = NULL; + int proto_type = 0; + afi_t afi; + + afi = family2afi(rn->p.family); + proto_type = proto_redistnum(afi, args->keys->key[0]); + + RNODE_FOREACH_RE (rn, re) { + if (proto_type == re->type) + return re; + } + return NULL; } @@ -293,8 +326,9 @@ const void *lib_vrf_zebra_ribs_rib_route_route_entry_lookup_entry( struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_protocol_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ - return NULL; + struct route_entry *re = (struct route_entry *)args->list_entry; + + return yang_data_new_enum(args->xpath, re->type); } /* @@ -303,7 +337,11 @@ struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_protocol_get_elem( struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_instance_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ + struct route_entry *re = (struct route_entry *)args->list_entry; + + if (re->instance) + return yang_data_new_uint16(args->xpath, re->instance); + return NULL; } @@ -313,8 +351,9 @@ struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_instance_get_elem( struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_distance_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ - return NULL; + struct route_entry *re = (struct route_entry *)args->list_entry; + + return yang_data_new_uint8(args->xpath, re->distance); } /* @@ -323,8 +362,9 @@ struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_distance_get_elem( struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_metric_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ - return NULL; + struct route_entry *re = (struct route_entry *)args->list_entry; + + return yang_data_new_uint32(args->xpath, re->metric); } /* @@ -333,7 +373,11 @@ struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_metric_get_elem( struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_tag_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ + struct route_entry *re = (struct route_entry *)args->list_entry; + + if (re->tag) + return yang_data_new_uint32(args->xpath, re->tag); + return NULL; } @@ -343,7 +387,11 @@ struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_tag_get_elem( struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_selected_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ + struct route_entry *re = (struct route_entry *)args->list_entry; + + if (CHECK_FLAG(re->flags, ZEBRA_FLAG_SELECTED)) + return yang_data_new_empty(args->xpath); + return NULL; } @@ -353,7 +401,11 @@ struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_selected_get_elem( struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_installed_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ + struct route_entry *re = (struct route_entry *)args->list_entry; + + if (CHECK_FLAG(re->status, ROUTE_ENTRY_INSTALLED)) + return yang_data_new_empty(args->xpath); + return NULL; } @@ -363,7 +415,11 @@ struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_installed_get_elem( struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_failed_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ + struct route_entry *re = (struct route_entry *)args->list_entry; + + if (CHECK_FLAG(re->status, ROUTE_ENTRY_FAILED)) + return yang_data_new_empty(args->xpath); + return NULL; } @@ -373,7 +429,11 @@ struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_failed_get_elem( struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_queued_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ + struct route_entry *re = (struct route_entry *)args->list_entry; + + if (CHECK_FLAG(re->status, ROUTE_ENTRY_QUEUED)) + return yang_data_new_empty(args->xpath); + return NULL; } @@ -385,7 +445,11 @@ struct yang_data * lib_vrf_zebra_ribs_rib_route_route_entry_internal_flags_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ + struct route_entry *re = (struct route_entry *)args->list_entry; + + if (re->flags) + return yang_data_new_int32(args->xpath, re->flags); + return NULL; } @@ -397,7 +461,11 @@ struct yang_data * lib_vrf_zebra_ribs_rib_route_route_entry_internal_status_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ + struct route_entry *re = (struct route_entry *)args->list_entry; + + if (re->status) + return yang_data_new_int32(args->xpath, re->status); + return NULL; } @@ -407,8 +475,9 @@ lib_vrf_zebra_ribs_rib_route_route_entry_internal_status_get_elem( struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_uptime_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ - return NULL; + struct route_entry *re = (struct route_entry *)args->list_entry; + + return yang_data_new_date_and_time(args->xpath, re->uptime); } /* @@ -418,14 +487,25 @@ struct yang_data *lib_vrf_zebra_ribs_rib_route_route_entry_uptime_get_elem( const void *lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_get_next( struct nb_cb_get_next_args *args) { - /* TODO: implement me. */ + struct route_entry *re = (struct route_entry *)args->parent_list_entry; + struct nhg_hash_entry *nhe = (struct nhg_hash_entry *)args->list_entry; + + if (args->list_entry == NULL) { + nhe = re->nhe; + return nhe; + } return NULL; } int lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_get_keys( struct nb_cb_get_keys_args *args) { - /* TODO: implement me. */ + struct nhg_hash_entry *nhe = (struct nhg_hash_entry *)args->list_entry; + + args->keys->num = 1; + snprintfrr(args->keys->key[0], sizeof(args->keys->key[0]), "%" PRIu32, + nhe->id); + return NB_OK; } @@ -444,8 +524,12 @@ struct yang_data * lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_name_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ - return NULL; + struct nhg_hash_entry *nhe = (struct nhg_hash_entry *)args->list_entry; + char name[20] = {'\0'}; + + snprintfrr(name, sizeof(name), "%" PRIu32, nhe->id); + + return yang_data_new_string(args->xpath, name); } /* @@ -456,14 +540,76 @@ const void * lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_get_next( struct nb_cb_get_next_args *args) { - /* TODO: implement me. */ - return NULL; + struct nexthop *nexthop = (struct nexthop *)args->list_entry; + struct nhg_hash_entry *nhe = + (struct nhg_hash_entry *)args->parent_list_entry; + + if (args->list_entry == NULL) + nexthop = nhe->nhg.nexthop; + else + nexthop = nexthop_next(nexthop); + + return nexthop; } int lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_get_keys( struct nb_cb_get_keys_args *args) { - /* TODO: implement me. */ + struct nexthop *nexthop = (struct nexthop *)args->list_entry; + + args->keys->num = 3; + + strlcpy(args->keys->key[0], yang_nexthop_type2str(nexthop->type), + sizeof(args->keys->key[0])); + + switch (nexthop->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + snprintfrr(args->keys->key[1], sizeof(args->keys->key[1]), + "%pI4", &nexthop->gate.ipv4); + if (nexthop->ifindex) + strlcpy(args->keys->key[2], + ifindex2ifname(nexthop->ifindex, + nexthop->vrf_id), + sizeof(args->keys->key[2])); + else + /* no ifindex */ + strlcpy(args->keys->key[2], " ", + sizeof(args->keys->key[2])); + + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + snprintfrr(args->keys->key[1], sizeof(args->keys->key[1]), + "%pI6", &nexthop->gate.ipv6); + + if (nexthop->ifindex) + strlcpy(args->keys->key[2], + ifindex2ifname(nexthop->ifindex, + nexthop->vrf_id), + sizeof(args->keys->key[2])); + else + /* no ifindex */ + strlcpy(args->keys->key[2], " ", + sizeof(args->keys->key[2])); + + break; + case NEXTHOP_TYPE_IFINDEX: + strlcpy(args->keys->key[1], "", sizeof(args->keys->key[1])); + strlcpy(args->keys->key[2], + ifindex2ifname(nexthop->ifindex, nexthop->vrf_id), + sizeof(args->keys->key[2])); + + break; + case NEXTHOP_TYPE_BLACKHOLE: + /* Gateway IP */ + strlcpy(args->keys->key[1], "", sizeof(args->keys->key[1])); + strlcpy(args->keys->key[2], " ", sizeof(args->keys->key[2])); + break; + default: + break; + } + return NB_OK; } @@ -483,7 +629,28 @@ struct yang_data * lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_nh_type_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ + struct nexthop *nexthop = (struct nexthop *)args->list_entry; + + switch (nexthop->type) { + case NEXTHOP_TYPE_IFINDEX: + return yang_data_new_string(args->xpath, "ifindex"); + break; + case NEXTHOP_TYPE_IPV4: + return yang_data_new_string(args->xpath, "ip4"); + break; + case NEXTHOP_TYPE_IPV4_IFINDEX: + return yang_data_new_string(args->xpath, "ip4-ifindex"); + break; + case NEXTHOP_TYPE_IPV6: + return yang_data_new_string(args->xpath, "ip6"); + break; + case NEXTHOP_TYPE_IPV6_IFINDEX: + return yang_data_new_string(args->xpath, "ip6-ifindex"); + break; + default: + break; + } + return NULL; } @@ -495,8 +662,10 @@ struct yang_data * lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_vrf_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ - return NULL; + struct nexthop *nexthop = (struct nexthop *)args->list_entry; + + return yang_data_new_string(args->xpath, + vrf_id_to_name(nexthop->vrf_id)); } /* @@ -507,8 +676,32 @@ struct yang_data * lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_gateway_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ - return NULL; + struct nexthop *nexthop = (struct nexthop *)args->list_entry; + struct ipaddr addr; + + switch (nexthop->type) { + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + addr.ipa_type = IPADDR_V4; + memcpy(&addr.ipaddr_v4, &(nexthop->gate.ipv4), + sizeof(struct in_addr)); + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + addr.ipa_type = IPADDR_V6; + memcpy(&addr.ipaddr_v6, &(nexthop->gate.ipv6), + sizeof(struct in6_addr)); + break; + case NEXTHOP_TYPE_BLACKHOLE: + case NEXTHOP_TYPE_IFINDEX: + /* No addr here */ + return yang_data_new_string(args->xpath, ""); + break; + default: + break; + } + + return yang_data_new_ip(args->xpath, &addr); } /* @@ -519,7 +712,13 @@ struct yang_data * lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_interface_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ + struct nexthop *nexthop = (struct nexthop *)args->list_entry; + + if (nexthop->ifindex) + yang_data_new_string( + args->xpath, + ifindex2ifname(nexthop->ifindex, nexthop->vrf_id)); + return NULL; } @@ -531,8 +730,28 @@ struct yang_data * lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_bh_type_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ - return NULL; + struct nexthop *nexthop = (struct nexthop *)args->list_entry; + const char *type_str = ""; + + if (nexthop->type != NEXTHOP_TYPE_BLACKHOLE) + return NULL; + + switch (nexthop->bh_type) { + case BLACKHOLE_NULL: + type_str = "null"; + break; + case BLACKHOLE_REJECT: + type_str = "reject"; + break; + case BLACKHOLE_ADMINPROHIB: + type_str = "prohibited"; + break; + case BLACKHOLE_UNSPEC: + type_str = "unspec"; + break; + } + + return yang_data_new_string(args->xpath, type_str); } /* @@ -543,7 +762,11 @@ struct yang_data * lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_onlink_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ + struct nexthop *nexthop = (struct nexthop *)args->list_entry; + + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ONLINK)) + return yang_data_new_bool(args->xpath, true); + return NULL; } @@ -630,7 +853,11 @@ struct yang_data * lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_duplicate_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ + struct nexthop *nexthop = (struct nexthop *)args->list_entry; + + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_DUPLICATE)) + return yang_data_new_empty(args->xpath); + return NULL; } @@ -642,7 +869,11 @@ struct yang_data * lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_recursive_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ + struct nexthop *nexthop = (struct nexthop *)args->list_entry; + + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) + return yang_data_new_empty(args->xpath); + return NULL; } @@ -654,7 +885,11 @@ struct yang_data * lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_active_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ + struct nexthop *nexthop = (struct nexthop *)args->list_entry; + + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)) + return yang_data_new_empty(args->xpath); + return NULL; } @@ -666,7 +901,11 @@ struct yang_data * lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_fib_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ + struct nexthop *nexthop = (struct nexthop *)args->list_entry; + + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)) + return yang_data_new_empty(args->xpath); + return NULL; } @@ -678,6 +917,10 @@ struct yang_data * lib_vrf_zebra_ribs_rib_route_route_entry_nexthop_group_frr_nexthops_nexthop_weight_get_elem( struct nb_cb_get_elem_args *args) { - /* TODO: implement me. */ + struct nexthop *nexthop = (struct nexthop *)args->list_entry; + + if (nexthop->weight) + return yang_data_new_uint8(args->xpath, nexthop->weight); + return NULL; }