#include "zebra_nb.h"
#include "zebra/interface.h"
#include "zebra/connected.h"
+#include "zebra/zebra_router.h"
/*
* XPath: /frr-zebra:zebra/mcast-rpf-lookup
*/
int lib_vrf_ribs_rib_create(struct nb_cb_create_args *args)
{
+ struct vrf *vrf;
+ afi_t afi = AFI_IP;
+ safi_t safi = SAFI_UNICAST;
+ struct zebra_vrf *zvrf;
+ struct zebra_router_table *zrt;
+ uint32_t table_id;
+
+ vrf = nb_running_get_entry(args->dnode, NULL, false);
+ zvrf = vrf_info_lookup(vrf->vrf_id);
+ table_id = yang_dnode_get_uint32(args->dnode, "./table-id");
+ 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
+ */
+
+ zrt = zebra_router_find_zrt(zvrf, table_id, afi, safi);
+
switch (args->event) {
case NB_EV_VALIDATE:
+ if (!zrt) {
+ zlog_debug("%s: vrf %s table is not found.", __func__,
+ vrf->name);
+ return NB_ERR_VALIDATION;
+ }
+ break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
+ break;
case NB_EV_APPLY:
- /* TODO: implement me. */
+
+ nb_running_set_entry(args->dnode, zrt);
+
break;
}
int lib_vrf_ribs_rib_destroy(struct nb_cb_destroy_args *args)
{
- switch (args->event) {
- case NB_EV_VALIDATE:
- case NB_EV_PREPARE:
- case NB_EV_ABORT:
- case NB_EV_APPLY:
- /* TODO: implement me. */
- break;
- }
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ nb_running_unset_entry(args->dnode);
return NB_OK;
}
#include "libfrr.h"
#include "zebra_nb.h"
#include "zebra/interface.h"
+#include "zebra/zebra_router.h"
/*
* XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/up-count
const void *lib_vrf_ribs_rib_get_next(struct nb_cb_get_next_args *args)
{
- /* TODO: implement me. */
- return NULL;
+ struct vrf *vrf = (struct vrf *)parent_list_entry;
+ struct zebra_router_table *zrt =
+ (struct zebra_router_table *)list_entry;
+
+ struct zebra_vrf *zvrf;
+ afi_t afi;
+ safi_t safi;
+
+ zvrf = zebra_vrf_lookup_by_id(vrf->vrf_id);
+
+ if (list_entry == NULL) {
+ afi = AFI_IP;
+ safi = SAFI_UNICAST;
+
+ zrt = zebra_router_find_zrt(zvrf, zvrf->table_id, afi, safi);
+ if (zrt == NULL)
+ return NULL;
+ } else {
+ zrt = RB_NEXT(zebra_router_table_head, zrt);
+ /* vrf_id/ns_id do not match, only walk for the given VRF */
+ while (zrt && zrt->ns_id != zvrf->zns->ns_id)
+ zrt = RB_NEXT(zebra_router_table_head, zrt);
+ }
+
+ return zrt;
}
int lib_vrf_ribs_rib_get_keys(struct nb_cb_get_keys_args *args)
{
- /* TODO: implement me. */
+ const struct zebra_router_table *zrt = list_entry;
+
+ keys->num = 2;
+
+ snprintf(keys->key[0], sizeof(keys->key[0]), "%s",
+ "frr-zebra:ipv4-unicast");
+ /* TODO: implement key[0], afi-safi identityref */
+ snprintf(keys->key[1], sizeof(keys->key[1]), "%" PRIu32, zrt->tableid);
+
return NB_OK;
}
const void *lib_vrf_ribs_rib_lookup_entry(struct nb_cb_lookup_entry_args *args)
{
- /* TODO: implement me. */
- return NULL;
+ struct vrf *vrf = (struct vrf *)parent_list_entry;
+ struct zebra_vrf *zvrf;
+ afi_t afi = AFI_IP;
+ safi_t safi = SAFI_UNICAST;
+
+ zvrf = zebra_vrf_lookup_by_id(vrf->vrf_id);
+
+ return zebra_router_find_zrt(zvrf, zvrf->table_id, afi, safi);
}
/*
*/
const void *lib_vrf_ribs_rib_route_get_next(struct nb_cb_get_next_args *args)
{
- /* TODO: implement me. */
- return NULL;
+ const struct zebra_router_table *zrt = parent_list_entry;
+ const struct route_node *rn = list_entry;
+
+ if (list_entry == NULL)
+ rn = route_top(zrt->table);
+ else
+ rn = srcdest_route_next((struct route_node *)rn);
+
+ return rn;
}
int lib_vrf_ribs_rib_route_get_keys(struct nb_cb_get_keys_args *args)
{
- /* TODO: implement me. */
+ const struct route_node *rn = list_entry;
+ char dst_buf[PREFIX_STRLEN];
+ const struct prefix *dst_p;
+
+ srcdest_rnode_prefixes(rn, &dst_p, NULL);
+ keys->num = 1;
+ strlcpy(keys->key[0], prefix2str(dst_p, dst_buf, sizeof(dst_p)),
+ sizeof(keys->key[0]));
+
return NB_OK;
}
const void *
lib_vrf_ribs_rib_route_lookup_entry(struct nb_cb_lookup_entry_args *args)
{
- /* TODO: implement me. */
- return NULL;
+ const struct zebra_router_table *zrt = parent_list_entry;
+ struct prefix p;
+ struct route_node *rn;
+
+ yang_str2prefix(keys->key[0], &p);
+
+ rn = route_node_lookup(zrt->table, &p);
+
+ if (!rn)
+ return NULL;
+
+ route_unlock_node(rn);
+
+ return rn;
}
/*
struct yang_data *
lib_vrf_ribs_rib_route_prefix_get_elem(struct nb_cb_get_elem_args *args)
{
- /* TODO: implement me. */
- return NULL;
+ const struct route_node *rn = list_entry;
+
+ return yang_data_new_prefix(xpath, &rn->p);
}
/*
const void *
lib_vrf_ribs_rib_route_route_entry_get_next(struct nb_cb_get_next_args *args)
{
- /* TODO: implement me. */
- return NULL;
+ struct route_entry *re = NULL;
+
+ return re;
}
int lib_vrf_ribs_rib_route_route_entry_get_keys(
return (e1->safi - e2->safi);
}
+struct zebra_router_table *zebra_router_find_zrt(struct zebra_vrf *zvrf,
+ uint32_t tableid, afi_t afi,
+ safi_t safi)
+{
+ struct zebra_router_table finder;
+ struct zebra_router_table *zrt;
+
+ memset(&finder, 0, sizeof(finder));
+ finder.afi = afi;
+ finder.safi = safi;
+ finder.tableid = tableid;
+ finder.ns_id = zvrf->zns->ns_id;
+ zrt = RB_FIND(zebra_router_table_head, &zrouter.tables, &finder);
+
+ return zrt;
+}
struct route_table *zebra_router_find_table(struct zebra_vrf *zvrf,
uint32_t tableid, afi_t afi,