Skip to content

Commit

Permalink
lib: vrf northbound callbacks
Browse files Browse the repository at this point in the history
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
  • Loading branch information
chiragshah6 committed Mar 18, 2020
1 parent 84b5d31 commit e9740b4
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 17 deletions.
196 changes: 196 additions & 0 deletions lib/vrf.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "privs.h"
#include "nexthop_group.h"
#include "lib_errors.h"
#include "northbound.h"

/* default VRF ID value used when VRF backend is not NETNS */
#define VRF_DEFAULT_INTERNAL 0
Expand Down Expand Up @@ -1010,3 +1011,198 @@ vrf_id_t vrf_generate_id(void)

return ++vrf_id_local;
}

/* ------- Northbound callbacks ------- */

/*
* XPath: /frr-vrf:lib/vrf
*/
static int lib_vrf_create(enum nb_event event, const struct lyd_node *dnode,
union nb_resource *resource)
{
const char *vrfname;
struct vrf *vrfp;

vrfname = yang_dnode_get_string(dnode, "./name");

if (event != NB_EV_APPLY)
return NB_OK;

vrfp = vrf_get(VRF_UNKNOWN, vrfname);

nb_running_set_entry(dnode, vrfp);
#if 0
switch (event) {
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
case NB_EV_APPLY:
/* TODO: implement me. */
break;
}
#endif

return NB_OK;
}

static int lib_vrf_destroy(enum nb_event event, const struct lyd_node *dnode)
{
struct vrf *vrfp;


switch (event) {
case NB_EV_VALIDATE:
vrfp = nb_running_get_entry(dnode, NULL, true);
if (CHECK_FLAG(vrfp->status, VRF_ACTIVE)) {
zlog_debug("%s Only inactive VRFs can be deleted",
__func__);
return NB_ERR_VALIDATION;
}
break;
case NB_EV_PREPARE:
case NB_EV_ABORT:
break;
case NB_EV_APPLY:
vrfp = nb_running_unset_entry(dnode);
/* Clear configured flag and invoke delete. */
UNSET_FLAG(vrfp->status, VRF_CONFIGURED);
vrf_delete(vrfp);
break;
}

return NB_OK;
}

static const void *lib_vrf_get_next(const void *parent_list_entry,
const void *list_entry)
{
struct vrf *vrfp = (struct vrf *)list_entry;

if (list_entry == NULL) {
vrfp = RB_MIN(vrf_name_head, &vrfs_by_name);
} else {
vrfp = RB_NEXT(vrf_name_head, vrfp);
}

return vrfp;
}

static int lib_vrf_get_keys(const void *list_entry, struct yang_list_keys *keys)
{
struct vrf *vrfp = (struct vrf *)list_entry;

keys->num = 1;
strlcpy(keys->key[0], vrfp->name, sizeof(keys->key[0]));

return NB_OK;
}

static const void *lib_vrf_lookup_entry(const void *parent_list_entry,
const struct yang_list_keys *keys)
{
const char *vrfname = keys->key[0];

struct vrf *vrf = vrf_lookup_by_name(vrfname);

return vrf;
}

/*
* XPath: /frr-vrf:lib/vrf/id
*/
static struct yang_data *lib_vrf_state_id_get_elem(const char *xpath,
const void *list_entry)
{
struct vrf *vrfp = (struct vrf *)list_entry;

return yang_data_new_uint32(xpath, vrfp->vrf_id);
}

/*
* XPath: /frr-vrf:lib/vrf/active
*/
static struct yang_data *lib_vrf_state_active_get_elem(const char *xpath,
const void *list_entry)
{
struct vrf *vrfp = (struct vrf *)list_entry;

if (vrfp->status == VRF_ACTIVE)
return yang_data_new_bool(
xpath, vrfp->status == VRF_ACTIVE ? true : false);

return NULL;
}

/*
* XPath: /frr-vrf:lib/vrf/netns/name
*/
static int lib_vrf_netns_name_modify(enum nb_event event,
const struct lyd_node *dnode,
union nb_resource *resource)
{
switch (event) {
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
case NB_EV_APPLY:
/* TODO: implement me. */
break;
}

return NB_OK;
}

static int lib_vrf_netns_name_destroy(enum nb_event event,
const struct lyd_node *dnode)
{
switch (event) {
case NB_EV_VALIDATE:
case NB_EV_PREPARE:
case NB_EV_ABORT:
case NB_EV_APPLY:
/* TODO: implement me. */
break;
}

return NB_OK;
}

/* clang-format off */
const struct frr_yang_module_info frr_vrf_info = {
.name = "frr-vrf",
.nodes = {
{
.xpath = "/frr-vrf:lib/vrf",
.cbs = {
.create = lib_vrf_create,
.destroy = lib_vrf_destroy,
.get_next = lib_vrf_get_next,
.get_keys = lib_vrf_get_keys,
.lookup_entry = lib_vrf_lookup_entry,
}
},
{
.xpath = "/frr-vrf:lib/vrf/netns/name",
.cbs = {
.modify = lib_vrf_netns_name_modify,
.destroy = lib_vrf_netns_name_destroy,
}
},
{
.xpath = "/frr-vrf:lib/vrf/state/id",
.cbs = {
.get_elem = lib_vrf_state_id_get_elem,
}
},
{
.xpath = "/frr-vrf:lib/vrf/state/active",
.cbs = {
.get_elem = lib_vrf_state_active_get_elem,
}
},
{
.xpath = NULL,
},
}
};

2 changes: 2 additions & 0 deletions lib/vrf.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,8 @@ extern int vrf_enable(struct vrf *vrf);
extern void vrf_delete(struct vrf *vrf);
extern vrf_id_t vrf_generate_id(void);

extern const struct frr_yang_module_info frr_vrf_info;

#ifdef __cplusplus
}
#endif
Expand Down
1 change: 1 addition & 0 deletions lib/yang.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ static const char *yang_module_imp_clb(const char *mod_name,

static const char *const frr_native_modules[] = {
"frr-interface",
"frr-vrf",
"frr-ripd",
"frr-ripngd",
"frr-isisd",
Expand Down
41 changes: 24 additions & 17 deletions yang/frr-vrf.yang
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ module frr-vrf {
namespace "http://frrouting.org/yang/vrf";
prefix frr-vrf;

import ietf-yang-types {
prefix yang;
}

organization
"Free Range Routing";
contact
Expand Down Expand Up @@ -36,29 +40,32 @@ module frr-vrf {
"VRF name.";
}

leaf id {
type uint32 {
range "0..4294967295";
container netns {
/* FIXME: libyang support is required */
/* if-feature "netns"; */
leaf name {
type string;
description
"Namespace name.";
}
config false;
description
"VRF Id.";
}

leaf active {
type boolean;
default "false";
container state {
config false;
description
"VRF active in kernel.";
}
leaf id {
type uint32 {
range "0..4294967295";
}
description
"VRF Id.";
}

container netns {
if-feature "netns";
leaf name {
type string;
leaf active {
type boolean;
default "false";
config false;
description
"Namespace name.";
"VRF active in kernel.";
}
}
}
Expand Down

0 comments on commit e9740b4

Please sign in to comment.