mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 09:20:25 +00:00
zebra: add northbound support for zebra interface
Signed-off-by: Chirag Shah <chirag@cumulusnetworks.com>
This commit is contained in:
parent
83ed00f1df
commit
09268680bb
@ -500,7 +500,7 @@ void if_flags_update(struct interface *ifp, uint64_t newflags)
|
|||||||
|
|
||||||
/* Wake up configured address if it is not in current kernel
|
/* Wake up configured address if it is not in current kernel
|
||||||
address. */
|
address. */
|
||||||
static void if_addr_wakeup(struct interface *ifp)
|
void if_addr_wakeup(struct interface *ifp)
|
||||||
{
|
{
|
||||||
struct listnode *node, *nnode;
|
struct listnode *node, *nnode;
|
||||||
struct connected *ifc;
|
struct connected *ifc;
|
||||||
@ -1881,6 +1881,24 @@ DEFUN (show_interface_desc_vrf_all,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int if_multicast_set(struct interface *ifp)
|
||||||
|
{
|
||||||
|
struct zebra_if *if_data;
|
||||||
|
|
||||||
|
if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
|
||||||
|
if (if_set_flags(ifp, IFF_MULTICAST) < 0) {
|
||||||
|
zlog_debug("Can't set multicast flag on interface %s",
|
||||||
|
ifp->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if_refresh(ifp);
|
||||||
|
}
|
||||||
|
if_data = ifp->info;
|
||||||
|
if_data->multicast = IF_ZEBRA_MULTICAST_ON;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
DEFUN (multicast,
|
DEFUN (multicast,
|
||||||
multicast_cmd,
|
multicast_cmd,
|
||||||
"multicast",
|
"multicast",
|
||||||
@ -1904,6 +1922,24 @@ DEFUN (multicast,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int if_multicast_unset(struct interface *ifp)
|
||||||
|
{
|
||||||
|
struct zebra_if *if_data;
|
||||||
|
|
||||||
|
if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
|
||||||
|
if (if_unset_flags(ifp, IFF_MULTICAST) < 0) {
|
||||||
|
zlog_debug("Can't unset multicast flag on interface %s",
|
||||||
|
ifp->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if_refresh(ifp);
|
||||||
|
}
|
||||||
|
if_data = ifp->info;
|
||||||
|
if_data->multicast = IF_ZEBRA_MULTICAST_OFF;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
DEFUN (no_multicast,
|
DEFUN (no_multicast,
|
||||||
no_multicast_cmd,
|
no_multicast_cmd,
|
||||||
"no multicast",
|
"no multicast",
|
||||||
@ -1928,23 +1964,35 @@ DEFUN (no_multicast,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFUN (linkdetect,
|
int if_linkdetect(struct interface *ifp, bool detect)
|
||||||
linkdetect_cmd,
|
|
||||||
"link-detect",
|
|
||||||
"Enable link detection on interface\n")
|
|
||||||
{
|
{
|
||||||
VTY_DECLVAR_CONTEXT(interface, ifp);
|
|
||||||
int if_was_operative;
|
int if_was_operative;
|
||||||
|
|
||||||
if_was_operative = if_is_no_ptm_operative(ifp);
|
if_was_operative = if_is_no_ptm_operative(ifp);
|
||||||
SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
|
if (detect) {
|
||||||
|
SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
|
||||||
|
|
||||||
/* When linkdetection is enabled, if might come down */
|
/* When linkdetection is enabled, if might come down */
|
||||||
if (!if_is_no_ptm_operative(ifp) && if_was_operative)
|
if (!if_is_no_ptm_operative(ifp) && if_was_operative)
|
||||||
if_down(ifp);
|
if_down(ifp);
|
||||||
|
} else {
|
||||||
|
UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
|
||||||
|
|
||||||
|
/* Interface may come up after disabling link detection */
|
||||||
|
if (if_is_operative(ifp) && !if_was_operative)
|
||||||
|
if_up(ifp);
|
||||||
|
}
|
||||||
/* FIXME: Will defer status change forwarding if interface
|
/* FIXME: Will defer status change forwarding if interface
|
||||||
does not come down! */
|
does not come down! */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUN(linkdetect, linkdetect_cmd, "link-detect",
|
||||||
|
"Enable link detection on interface\n")
|
||||||
|
{
|
||||||
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
||||||
|
|
||||||
|
if_linkdetect(ifp, true);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -1957,20 +2005,31 @@ DEFUN (no_linkdetect,
|
|||||||
"Disable link detection on interface\n")
|
"Disable link detection on interface\n")
|
||||||
{
|
{
|
||||||
VTY_DECLVAR_CONTEXT(interface, ifp);
|
VTY_DECLVAR_CONTEXT(interface, ifp);
|
||||||
int if_was_operative;
|
|
||||||
|
|
||||||
if_was_operative = if_is_no_ptm_operative(ifp);
|
if_linkdetect(ifp, false);
|
||||||
UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
|
|
||||||
|
|
||||||
/* Interface may come up after disabling link detection */
|
|
||||||
if (if_is_operative(ifp) && !if_was_operative)
|
|
||||||
if_up(ifp);
|
|
||||||
|
|
||||||
/* FIXME: see linkdetect_cmd */
|
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int if_shutdown(struct interface *ifp)
|
||||||
|
{
|
||||||
|
struct zebra_if *if_data;
|
||||||
|
|
||||||
|
if (ifp->ifindex != IFINDEX_INTERNAL) {
|
||||||
|
/* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */
|
||||||
|
rtadv_stop_ra(ifp);
|
||||||
|
if (if_unset_flags(ifp, IFF_UP) < 0) {
|
||||||
|
zlog_debug("Can't shutdown interface %s", ifp->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if_refresh(ifp);
|
||||||
|
}
|
||||||
|
if_data = ifp->info;
|
||||||
|
if_data->shutdown = IF_ZEBRA_SHUTDOWN_ON;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
DEFUN (shutdown_if,
|
DEFUN (shutdown_if,
|
||||||
shutdown_if_cmd,
|
shutdown_if_cmd,
|
||||||
"shutdown",
|
"shutdown",
|
||||||
@ -1996,6 +2055,30 @@ DEFUN (shutdown_if,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int if_no_shutdown(struct interface *ifp)
|
||||||
|
{
|
||||||
|
struct zebra_if *if_data;
|
||||||
|
|
||||||
|
if (ifp->ifindex != IFINDEX_INTERNAL) {
|
||||||
|
if (if_set_flags(ifp, IFF_UP | IFF_RUNNING) < 0) {
|
||||||
|
zlog_debug("Can't up interface %s", ifp->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if_refresh(ifp);
|
||||||
|
|
||||||
|
/* Some addresses (in particular, IPv6 addresses on Linux) get
|
||||||
|
* removed when the interface goes down. They need to be
|
||||||
|
* readded.
|
||||||
|
*/
|
||||||
|
if_addr_wakeup(ifp);
|
||||||
|
}
|
||||||
|
|
||||||
|
if_data = ifp->info;
|
||||||
|
if_data->shutdown = IF_ZEBRA_SHUTDOWN_OFF;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
DEFUN (no_shutdown_if,
|
DEFUN (no_shutdown_if,
|
||||||
no_shutdown_if_cmd,
|
no_shutdown_if_cmd,
|
||||||
"no shutdown",
|
"no shutdown",
|
||||||
@ -2748,6 +2831,79 @@ DEFUN (no_link_params_use_bw,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int if_ip_address_install(struct interface *ifp, struct prefix *prefix,
|
||||||
|
const char *label, struct prefix *pp)
|
||||||
|
{
|
||||||
|
struct zebra_if *if_data;
|
||||||
|
struct prefix_ipv4 lp;
|
||||||
|
struct prefix_ipv4 *p;
|
||||||
|
struct connected *ifc;
|
||||||
|
enum zebra_dplane_result dplane_res;
|
||||||
|
|
||||||
|
if_data = ifp->info;
|
||||||
|
|
||||||
|
lp.family = prefix->family;
|
||||||
|
lp.prefix = prefix->u.prefix4;
|
||||||
|
lp.prefixlen = prefix->prefixlen;
|
||||||
|
apply_mask_ipv4(&lp);
|
||||||
|
|
||||||
|
ifc = connected_check_ptp(ifp, &lp, pp ? pp : NULL);
|
||||||
|
if (!ifc) {
|
||||||
|
ifc = connected_new();
|
||||||
|
ifc->ifp = ifp;
|
||||||
|
|
||||||
|
/* Address. */
|
||||||
|
p = prefix_ipv4_new();
|
||||||
|
*p = lp;
|
||||||
|
ifc->address = (struct prefix *)p;
|
||||||
|
|
||||||
|
if (pp) {
|
||||||
|
SET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
|
||||||
|
p = prefix_ipv4_new();
|
||||||
|
*p = *(struct prefix_ipv4 *)pp;
|
||||||
|
ifc->destination = (struct prefix *)p;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Label. */
|
||||||
|
if (label)
|
||||||
|
ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
|
||||||
|
|
||||||
|
/* Add to linked list. */
|
||||||
|
listnode_add(ifp->connected, ifc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This address is configured from zebra. */
|
||||||
|
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
|
||||||
|
SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
|
||||||
|
|
||||||
|
/* In case of this route need to install kernel. */
|
||||||
|
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
|
||||||
|
&& CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)
|
||||||
|
&& !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) {
|
||||||
|
/* Some system need to up the interface to set IP address. */
|
||||||
|
if (!if_is_up(ifp)) {
|
||||||
|
if_set_flags(ifp, IFF_UP | IFF_RUNNING);
|
||||||
|
if_refresh(ifp);
|
||||||
|
}
|
||||||
|
|
||||||
|
dplane_res = dplane_intf_addr_set(ifp, ifc);
|
||||||
|
if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
|
||||||
|
zlog_debug(
|
||||||
|
"dplane can't set interface IP address: %s.\n",
|
||||||
|
dplane_res2str(dplane_res));
|
||||||
|
return NB_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
|
||||||
|
/* The address will be advertised to zebra clients when the
|
||||||
|
* notification
|
||||||
|
* from the kernel has been received.
|
||||||
|
* It will also be added to the subnet chain list, then. */
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ip_address_install(struct vty *vty, struct interface *ifp,
|
static int ip_address_install(struct vty *vty, struct interface *ifp,
|
||||||
const char *addr_str, const char *peer_str,
|
const char *addr_str, const char *peer_str,
|
||||||
const char *label)
|
const char *label)
|
||||||
@ -2842,6 +2998,51 @@ static int ip_address_install(struct vty *vty, struct interface *ifp,
|
|||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int if_ip_address_uinstall(struct interface *ifp, struct prefix *prefix)
|
||||||
|
{
|
||||||
|
struct connected *ifc = NULL;
|
||||||
|
enum zebra_dplane_result dplane_res;
|
||||||
|
|
||||||
|
if (prefix->family == AF_INET) {
|
||||||
|
/* Check current interface address. */
|
||||||
|
ifc = connected_check_ptp(ifp, prefix, NULL);
|
||||||
|
if (!ifc) {
|
||||||
|
zlog_debug("interface %s Can't find address\n",
|
||||||
|
ifp->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (prefix->family == AF_INET6) {
|
||||||
|
/* Check current interface address. */
|
||||||
|
ifc = connected_check(ifp, prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ifc) {
|
||||||
|
zlog_debug("interface %s Can't find address\n", ifp->name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
UNSET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
|
||||||
|
|
||||||
|
/* This is not real address or interface is not active. */
|
||||||
|
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
|
||||||
|
|| !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
|
||||||
|
listnode_delete(ifp->connected, ifc);
|
||||||
|
connected_free(&ifc);
|
||||||
|
return CMD_WARNING_CONFIG_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is real route. */
|
||||||
|
dplane_res = dplane_intf_addr_unset(ifp, ifc);
|
||||||
|
if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
|
||||||
|
zlog_debug("Can't unset interface IP address: %s.\n",
|
||||||
|
dplane_res2str(dplane_res));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ip_address_uninstall(struct vty *vty, struct interface *ifp,
|
static int ip_address_uninstall(struct vty *vty, struct interface *ifp,
|
||||||
const char *addr_str, const char *peer_str,
|
const char *addr_str, const char *peer_str,
|
||||||
const char *label)
|
const char *label)
|
||||||
@ -2995,6 +3196,71 @@ DEFUN (no_ip_address_label,
|
|||||||
}
|
}
|
||||||
#endif /* HAVE_NETLINK */
|
#endif /* HAVE_NETLINK */
|
||||||
|
|
||||||
|
int if_ipv6_address_install(struct interface *ifp, struct prefix *prefix,
|
||||||
|
const char *label)
|
||||||
|
{
|
||||||
|
struct zebra_if *if_data;
|
||||||
|
struct prefix_ipv6 cp;
|
||||||
|
struct connected *ifc;
|
||||||
|
struct prefix_ipv6 *p;
|
||||||
|
enum zebra_dplane_result dplane_res;
|
||||||
|
|
||||||
|
if_data = ifp->info;
|
||||||
|
|
||||||
|
cp.family = prefix->family;
|
||||||
|
cp.prefixlen = prefix->prefixlen;
|
||||||
|
cp.prefix = prefix->u.prefix6;
|
||||||
|
apply_mask_ipv6(&cp);
|
||||||
|
|
||||||
|
ifc = connected_check(ifp, (struct prefix *)&cp);
|
||||||
|
if (!ifc) {
|
||||||
|
ifc = connected_new();
|
||||||
|
ifc->ifp = ifp;
|
||||||
|
|
||||||
|
/* Address. */
|
||||||
|
p = prefix_ipv6_new();
|
||||||
|
*p = cp;
|
||||||
|
ifc->address = (struct prefix *)p;
|
||||||
|
|
||||||
|
/* Label. */
|
||||||
|
if (label)
|
||||||
|
ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
|
||||||
|
|
||||||
|
/* Add to linked list. */
|
||||||
|
listnode_add(ifp->connected, ifc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This address is configured from zebra. */
|
||||||
|
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED))
|
||||||
|
SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
|
||||||
|
|
||||||
|
/* In case of this route need to install kernel. */
|
||||||
|
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
|
||||||
|
&& CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)
|
||||||
|
&& !(if_data && if_data->shutdown == IF_ZEBRA_SHUTDOWN_ON)) {
|
||||||
|
/* Some system need to up the interface to set IP address. */
|
||||||
|
if (!if_is_up(ifp)) {
|
||||||
|
if_set_flags(ifp, IFF_UP | IFF_RUNNING);
|
||||||
|
if_refresh(ifp);
|
||||||
|
}
|
||||||
|
|
||||||
|
dplane_res = dplane_intf_addr_set(ifp, ifc);
|
||||||
|
if (dplane_res == ZEBRA_DPLANE_REQUEST_FAILURE) {
|
||||||
|
zlog_debug(
|
||||||
|
"dplane can't set interface IP address: %s.\n",
|
||||||
|
dplane_res2str(dplane_res));
|
||||||
|
return NB_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
|
||||||
|
/* The address will be advertised to zebra clients when the
|
||||||
|
* notification
|
||||||
|
* from the kernel has been received. */
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int ipv6_address_install(struct vty *vty, struct interface *ifp,
|
static int ipv6_address_install(struct vty *vty, struct interface *ifp,
|
||||||
const char *addr_str, const char *peer_str,
|
const char *addr_str, const char *peer_str,
|
||||||
const char *label)
|
const char *label)
|
||||||
|
@ -440,6 +440,17 @@ extern void zebra_if_update_link(struct interface *ifp, ifindex_t link_ifindex,
|
|||||||
ns_id_t ns_id);
|
ns_id_t ns_id);
|
||||||
extern void zebra_if_update_all_links(void);
|
extern void zebra_if_update_all_links(void);
|
||||||
extern void zebra_if_set_protodown(struct interface *ifp, bool down);
|
extern void zebra_if_set_protodown(struct interface *ifp, bool down);
|
||||||
|
extern int if_ip_address_install(struct interface *ifp, struct prefix *prefix,
|
||||||
|
const char *label, struct prefix *pp);
|
||||||
|
extern int if_ipv6_address_install(struct interface *ifp, struct prefix *prefix,
|
||||||
|
const char *label);
|
||||||
|
extern int if_ip_address_uinstall(struct interface *ifp, struct prefix *prefix);
|
||||||
|
extern int if_shutdown(struct interface *ifp);
|
||||||
|
extern int if_no_shutdown(struct interface *ifp);
|
||||||
|
extern int if_multicast_set(struct interface *ifp);
|
||||||
|
extern int if_multicast_unset(struct interface *ifp);
|
||||||
|
extern int if_linkdetect(struct interface *ifp, bool detect);
|
||||||
|
extern void if_addr_wakeup(struct interface *ifp);
|
||||||
|
|
||||||
/* Nexthop group connected functions */
|
/* Nexthop group connected functions */
|
||||||
extern void if_nhg_dependents_add(struct interface *ifp,
|
extern void if_nhg_dependents_add(struct interface *ifp,
|
||||||
|
@ -24,9 +24,11 @@
|
|||||||
#include "libfrr.h"
|
#include "libfrr.h"
|
||||||
#include "lib/command.h"
|
#include "lib/command.h"
|
||||||
#include "lib/routemap.h"
|
#include "lib/routemap.h"
|
||||||
|
|
||||||
#include "zebra/zebra_nb.h"
|
#include "zebra/zebra_nb.h"
|
||||||
#include "zebra/rib.h"
|
#include "zebra/rib.h"
|
||||||
|
#include "zebra_nb.h"
|
||||||
|
#include "zebra/interface.h"
|
||||||
|
#include "zebra/connected.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XPath: /frr-zebra:zebra/mcast-rpf-lookup
|
* XPath: /frr-zebra:zebra/mcast-rpf-lookup
|
||||||
@ -1013,12 +1015,38 @@ int lib_interface_zebra_ip_addrs_create(enum nb_event event,
|
|||||||
const struct lyd_node *dnode,
|
const struct lyd_node *dnode,
|
||||||
union nb_resource *resource)
|
union nb_resource *resource)
|
||||||
{
|
{
|
||||||
|
struct interface *ifp;
|
||||||
|
struct prefix prefix;
|
||||||
|
char buf[PREFIX_STRLEN] = {0};
|
||||||
|
|
||||||
|
ifp = nb_running_get_entry(dnode, NULL, true);
|
||||||
|
// addr_family = yang_dnode_get_enum(dnode, "./address-family");
|
||||||
|
yang_dnode_get_prefix(&prefix, dnode, "./ip-prefix");
|
||||||
|
apply_mask(&prefix);
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case NB_EV_VALIDATE:
|
case NB_EV_VALIDATE:
|
||||||
|
if (prefix.family == AF_INET
|
||||||
|
&& ipv4_martian(&prefix.u.prefix4)) {
|
||||||
|
zlog_debug("invalid address %s",
|
||||||
|
prefix2str(&prefix, buf, sizeof(buf)));
|
||||||
|
return NB_ERR_VALIDATION;
|
||||||
|
} else if (prefix.family == AF_INET6
|
||||||
|
&& ipv6_martian(&prefix.u.prefix6)) {
|
||||||
|
zlog_debug("invalid address %s",
|
||||||
|
prefix2str(&prefix, buf, sizeof(buf)));
|
||||||
|
return NB_ERR_VALIDATION;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case NB_EV_PREPARE:
|
case NB_EV_PREPARE:
|
||||||
case NB_EV_ABORT:
|
case NB_EV_ABORT:
|
||||||
|
break;
|
||||||
case NB_EV_APPLY:
|
case NB_EV_APPLY:
|
||||||
/* TODO: implement me. */
|
if (prefix.family == AF_INET)
|
||||||
|
if_ip_address_install(ifp, &prefix, NULL, NULL);
|
||||||
|
else if (prefix.family == AF_INET6)
|
||||||
|
if_ipv6_address_install(ifp, &prefix, NULL);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1028,12 +1056,54 @@ int lib_interface_zebra_ip_addrs_create(enum nb_event event,
|
|||||||
int lib_interface_zebra_ip_addrs_destroy(enum nb_event event,
|
int lib_interface_zebra_ip_addrs_destroy(enum nb_event event,
|
||||||
const struct lyd_node *dnode)
|
const struct lyd_node *dnode)
|
||||||
{
|
{
|
||||||
|
struct interface *ifp;
|
||||||
|
struct prefix prefix;
|
||||||
|
struct connected *ifc;
|
||||||
|
|
||||||
|
ifp = nb_running_get_entry(dnode, NULL, true);
|
||||||
|
yang_dnode_get_prefix(&prefix, dnode, "./ip-prefix");
|
||||||
|
apply_mask(&prefix);
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case NB_EV_VALIDATE:
|
case NB_EV_VALIDATE:
|
||||||
|
if (prefix.family == AF_INET) {
|
||||||
|
/* Check current interface address. */
|
||||||
|
ifc = connected_check_ptp(ifp, &prefix, NULL);
|
||||||
|
if (!ifc) {
|
||||||
|
zlog_debug("interface %s Can't find address\n",
|
||||||
|
ifp->name);
|
||||||
|
return NB_ERR_VALIDATION;
|
||||||
|
}
|
||||||
|
} else if (prefix.family == AF_INET6) {
|
||||||
|
/* Check current interface address. */
|
||||||
|
ifc = connected_check(ifp, &prefix);
|
||||||
|
if (!ifc) {
|
||||||
|
zlog_debug("interface can't find address %s",
|
||||||
|
ifp->name);
|
||||||
|
return NB_ERR_VALIDATION;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
return NB_ERR_VALIDATION;
|
||||||
|
|
||||||
|
/* This is not configured address. */
|
||||||
|
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) {
|
||||||
|
zlog_debug("interface %s not configured", ifp->name);
|
||||||
|
return NB_ERR_VALIDATION;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is not real address or interface is not active. */
|
||||||
|
if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_QUEUED)
|
||||||
|
|| !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) {
|
||||||
|
listnode_delete(ifp->connected, ifc);
|
||||||
|
connected_free(&ifc);
|
||||||
|
return NB_ERR_VALIDATION;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case NB_EV_PREPARE:
|
case NB_EV_PREPARE:
|
||||||
case NB_EV_ABORT:
|
case NB_EV_ABORT:
|
||||||
|
break;
|
||||||
case NB_EV_APPLY:
|
case NB_EV_APPLY:
|
||||||
/* TODO: implement me. */
|
if_ip_address_uinstall(ifp, &prefix);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1115,14 +1185,14 @@ int lib_interface_zebra_multicast_modify(enum nb_event event,
|
|||||||
const struct lyd_node *dnode,
|
const struct lyd_node *dnode,
|
||||||
union nb_resource *resource)
|
union nb_resource *resource)
|
||||||
{
|
{
|
||||||
switch (event) {
|
if (event != NB_EV_APPLY)
|
||||||
case NB_EV_VALIDATE:
|
return NB_OK;
|
||||||
case NB_EV_PREPARE:
|
|
||||||
case NB_EV_ABORT:
|
struct interface *ifp;
|
||||||
case NB_EV_APPLY:
|
|
||||||
/* TODO: implement me. */
|
ifp = nb_running_get_entry(dnode, NULL, true);
|
||||||
break;
|
|
||||||
}
|
if_multicast_set(ifp);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
@ -1130,14 +1200,14 @@ int lib_interface_zebra_multicast_modify(enum nb_event event,
|
|||||||
int lib_interface_zebra_multicast_destroy(enum nb_event event,
|
int lib_interface_zebra_multicast_destroy(enum nb_event event,
|
||||||
const struct lyd_node *dnode)
|
const struct lyd_node *dnode)
|
||||||
{
|
{
|
||||||
switch (event) {
|
if (event != NB_EV_APPLY)
|
||||||
case NB_EV_VALIDATE:
|
return NB_OK;
|
||||||
case NB_EV_PREPARE:
|
|
||||||
case NB_EV_ABORT:
|
struct interface *ifp;
|
||||||
case NB_EV_APPLY:
|
|
||||||
/* TODO: implement me. */
|
ifp = nb_running_get_entry(dnode, NULL, true);
|
||||||
break;
|
|
||||||
}
|
if_multicast_unset(ifp);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
@ -1149,14 +1219,16 @@ int lib_interface_zebra_link_detect_modify(enum nb_event event,
|
|||||||
const struct lyd_node *dnode,
|
const struct lyd_node *dnode,
|
||||||
union nb_resource *resource)
|
union nb_resource *resource)
|
||||||
{
|
{
|
||||||
switch (event) {
|
if (event != NB_EV_APPLY)
|
||||||
case NB_EV_VALIDATE:
|
return NB_OK;
|
||||||
case NB_EV_PREPARE:
|
|
||||||
case NB_EV_ABORT:
|
struct interface *ifp;
|
||||||
case NB_EV_APPLY:
|
bool link_detect;
|
||||||
/* TODO: implement me. */
|
|
||||||
break;
|
ifp = nb_running_get_entry(dnode, NULL, true);
|
||||||
}
|
link_detect = yang_dnode_get_bool(dnode, "./link-detect");
|
||||||
|
|
||||||
|
if_linkdetect(ifp, link_detect);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
@ -1164,14 +1236,16 @@ int lib_interface_zebra_link_detect_modify(enum nb_event event,
|
|||||||
int lib_interface_zebra_link_detect_destroy(enum nb_event event,
|
int lib_interface_zebra_link_detect_destroy(enum nb_event event,
|
||||||
const struct lyd_node *dnode)
|
const struct lyd_node *dnode)
|
||||||
{
|
{
|
||||||
switch (event) {
|
if (event != NB_EV_APPLY)
|
||||||
case NB_EV_VALIDATE:
|
return NB_OK;
|
||||||
case NB_EV_PREPARE:
|
|
||||||
case NB_EV_ABORT:
|
struct interface *ifp;
|
||||||
case NB_EV_APPLY:
|
bool link_detect;
|
||||||
/* TODO: implement me. */
|
|
||||||
break;
|
ifp = nb_running_get_entry(dnode, NULL, true);
|
||||||
}
|
link_detect = yang_dnode_get_bool(dnode, "./link-detect");
|
||||||
|
|
||||||
|
if_linkdetect(ifp, link_detect);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
@ -1183,14 +1257,11 @@ int lib_interface_zebra_shutdown_modify(enum nb_event event,
|
|||||||
const struct lyd_node *dnode,
|
const struct lyd_node *dnode,
|
||||||
union nb_resource *resource)
|
union nb_resource *resource)
|
||||||
{
|
{
|
||||||
switch (event) {
|
struct interface *ifp;
|
||||||
case NB_EV_VALIDATE:
|
|
||||||
case NB_EV_PREPARE:
|
ifp = nb_running_get_entry(dnode, NULL, true);
|
||||||
case NB_EV_ABORT:
|
|
||||||
case NB_EV_APPLY:
|
if_shutdown(ifp);
|
||||||
/* TODO: implement me. */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
@ -1198,14 +1269,11 @@ int lib_interface_zebra_shutdown_modify(enum nb_event event,
|
|||||||
int lib_interface_zebra_shutdown_destroy(enum nb_event event,
|
int lib_interface_zebra_shutdown_destroy(enum nb_event event,
|
||||||
const struct lyd_node *dnode)
|
const struct lyd_node *dnode)
|
||||||
{
|
{
|
||||||
switch (event) {
|
struct interface *ifp;
|
||||||
case NB_EV_VALIDATE:
|
|
||||||
case NB_EV_PREPARE:
|
ifp = nb_running_get_entry(dnode, NULL, true);
|
||||||
case NB_EV_ABORT:
|
|
||||||
case NB_EV_APPLY:
|
if_no_shutdown(ifp);
|
||||||
/* TODO: implement me. */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
@ -1217,14 +1285,20 @@ int lib_interface_zebra_bandwidth_modify(enum nb_event event,
|
|||||||
const struct lyd_node *dnode,
|
const struct lyd_node *dnode,
|
||||||
union nb_resource *resource)
|
union nb_resource *resource)
|
||||||
{
|
{
|
||||||
switch (event) {
|
if (event != NB_EV_APPLY)
|
||||||
case NB_EV_VALIDATE:
|
return NB_OK;
|
||||||
case NB_EV_PREPARE:
|
|
||||||
case NB_EV_ABORT:
|
struct interface *ifp;
|
||||||
case NB_EV_APPLY:
|
uint32_t bandwidth;
|
||||||
/* TODO: implement me. */
|
|
||||||
break;
|
ifp = nb_running_get_entry(dnode, NULL, true);
|
||||||
}
|
bandwidth = yang_dnode_get_uint32(dnode, "./bandwidth");
|
||||||
|
|
||||||
|
ifp->bandwidth = bandwidth;
|
||||||
|
|
||||||
|
/* force protocols to recalculate routes due to cost change */
|
||||||
|
if (if_is_operative(ifp))
|
||||||
|
zebra_interface_up_update(ifp);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
@ -1232,14 +1306,18 @@ int lib_interface_zebra_bandwidth_modify(enum nb_event event,
|
|||||||
int lib_interface_zebra_bandwidth_destroy(enum nb_event event,
|
int lib_interface_zebra_bandwidth_destroy(enum nb_event event,
|
||||||
const struct lyd_node *dnode)
|
const struct lyd_node *dnode)
|
||||||
{
|
{
|
||||||
switch (event) {
|
if (event != NB_EV_APPLY)
|
||||||
case NB_EV_VALIDATE:
|
return NB_OK;
|
||||||
case NB_EV_PREPARE:
|
|
||||||
case NB_EV_ABORT:
|
struct interface *ifp;
|
||||||
case NB_EV_APPLY:
|
|
||||||
/* TODO: implement me. */
|
ifp = nb_running_get_entry(dnode, NULL, true);
|
||||||
break;
|
|
||||||
}
|
ifp->bandwidth = 0;
|
||||||
|
|
||||||
|
/* force protocols to recalculate routes due to cost change */
|
||||||
|
if (if_is_operative(ifp))
|
||||||
|
zebra_interface_up_update(ifp);
|
||||||
|
|
||||||
return NB_OK;
|
return NB_OK;
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "northbound.h"
|
#include "northbound.h"
|
||||||
#include "libfrr.h"
|
#include "libfrr.h"
|
||||||
#include "zebra_nb.h"
|
#include "zebra_nb.h"
|
||||||
|
#include "zebra/interface.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/up-count
|
* XPath: /frr-interface:lib/interface/frr-zebra:zebra/state/up-count
|
||||||
@ -29,8 +30,12 @@ struct yang_data *
|
|||||||
lib_interface_zebra_state_up_count_get_elem(const char *xpath,
|
lib_interface_zebra_state_up_count_get_elem(const char *xpath,
|
||||||
const void *list_entry)
|
const void *list_entry)
|
||||||
{
|
{
|
||||||
/* TODO: implement me. */
|
const struct interface *ifp = list_entry;
|
||||||
return NULL;
|
struct zebra_if *zebra_if;
|
||||||
|
|
||||||
|
zebra_if = ifp->info;
|
||||||
|
|
||||||
|
return yang_data_new_uint16(xpath, zebra_if->up_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -40,8 +45,12 @@ struct yang_data *
|
|||||||
lib_interface_zebra_state_down_count_get_elem(const char *xpath,
|
lib_interface_zebra_state_down_count_get_elem(const char *xpath,
|
||||||
const void *list_entry)
|
const void *list_entry)
|
||||||
{
|
{
|
||||||
/* TODO: implement me. */
|
const struct interface *ifp = list_entry;
|
||||||
return NULL;
|
struct zebra_if *zebra_if;
|
||||||
|
|
||||||
|
zebra_if = ifp->info;
|
||||||
|
|
||||||
|
return yang_data_new_uint16(xpath, zebra_if->down_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -73,8 +82,17 @@ struct yang_data *
|
|||||||
lib_interface_zebra_state_vlan_id_get_elem(const char *xpath,
|
lib_interface_zebra_state_vlan_id_get_elem(const char *xpath,
|
||||||
const void *list_entry)
|
const void *list_entry)
|
||||||
{
|
{
|
||||||
/* TODO: implement me. */
|
const struct interface *ifp = list_entry;
|
||||||
return NULL;
|
struct zebra_if *zebra_if;
|
||||||
|
struct zebra_l2info_vlan *vlan_info;
|
||||||
|
|
||||||
|
if (!IS_ZEBRA_IF_VLAN(ifp))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
zebra_if = ifp->info;
|
||||||
|
vlan_info = &zebra_if->l2info.vl;
|
||||||
|
|
||||||
|
return yang_data_new_uint16(xpath, vlan_info->vid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -84,8 +102,17 @@ struct yang_data *
|
|||||||
lib_interface_zebra_state_vni_id_get_elem(const char *xpath,
|
lib_interface_zebra_state_vni_id_get_elem(const char *xpath,
|
||||||
const void *list_entry)
|
const void *list_entry)
|
||||||
{
|
{
|
||||||
/* TODO: implement me. */
|
const struct interface *ifp = list_entry;
|
||||||
return NULL;
|
struct zebra_if *zebra_if;
|
||||||
|
struct zebra_l2info_vxlan *vxlan_info;
|
||||||
|
|
||||||
|
if (!IS_ZEBRA_IF_VXLAN(ifp))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
zebra_if = ifp->info;
|
||||||
|
vxlan_info = &zebra_if->l2info.vxl;
|
||||||
|
|
||||||
|
return yang_data_new_uint32(xpath, vxlan_info->vni);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -95,8 +122,17 @@ struct yang_data *
|
|||||||
lib_interface_zebra_state_remote_vtep_get_elem(const char *xpath,
|
lib_interface_zebra_state_remote_vtep_get_elem(const char *xpath,
|
||||||
const void *list_entry)
|
const void *list_entry)
|
||||||
{
|
{
|
||||||
/* TODO: implement me. */
|
const struct interface *ifp = list_entry;
|
||||||
return NULL;
|
struct zebra_if *zebra_if;
|
||||||
|
struct zebra_l2info_vxlan *vxlan_info;
|
||||||
|
|
||||||
|
if (!IS_ZEBRA_IF_VXLAN(ifp))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
zebra_if = ifp->info;
|
||||||
|
vxlan_info = &zebra_if->l2info.vxl;
|
||||||
|
|
||||||
|
return yang_data_new_ipv4(xpath, &vxlan_info->vtep_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -106,8 +142,17 @@ struct yang_data *
|
|||||||
lib_interface_zebra_state_mcast_group_get_elem(const char *xpath,
|
lib_interface_zebra_state_mcast_group_get_elem(const char *xpath,
|
||||||
const void *list_entry)
|
const void *list_entry)
|
||||||
{
|
{
|
||||||
/* TODO: implement me. */
|
const struct interface *ifp = list_entry;
|
||||||
return NULL;
|
struct zebra_if *zebra_if;
|
||||||
|
struct zebra_l2info_vxlan *vxlan_info;
|
||||||
|
|
||||||
|
if (!IS_ZEBRA_IF_VXLAN(ifp))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
zebra_if = ifp->info;
|
||||||
|
vxlan_info = &zebra_if->l2info.vxl;
|
||||||
|
|
||||||
|
return yang_data_new_ipv4(xpath, &vxlan_info->mcast_grp);
|
||||||
}
|
}
|
||||||
|
|
||||||
const void *lib_vrf_ribs_rib_get_next(const void *parent_list_entry,
|
const void *lib_vrf_ribs_rib_get_next(const void *parent_list_entry,
|
||||||
|
Loading…
Reference in New Issue
Block a user