Skip to content

Commit

Permalink
eigrp: reimplement passive-interface [default] command
Browse files Browse the repository at this point in the history
Maintain a vector of mappings [if_name -> if_passive].
Otherwise, if topo is not already convereged, configuration
does not apply, since iface is missing from the iface list.

Fixes: #11301
Signed-off-by: Volodymyr Huti <[email protected]>
  • Loading branch information
Volodymyr Huti committed Nov 9, 2023
1 parent a95b83c commit 7010f1f
Show file tree
Hide file tree
Showing 8 changed files with 267 additions and 56 deletions.
52 changes: 47 additions & 5 deletions eigrpd/eigrp_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,23 @@ void eigrp_cli_show_router_id(struct vty *vty, const struct lyd_node *dnode,
vty_out(vty, " eigrp router-id %s\n", router_id);
}

/*
* XPath: /frr-ripd:ripd/instance/passive-default
*/
DEFPY_YANG(
eigrp_passive_default,
eigrp_passive_default_cmd,
"[no] passive-interface default",
NO_STR
"Suppress routing updates on an interface\n"
"default for all interfaces\n")
{
nb_cli_enqueue_change(vty, "./passive-default", NB_OP_MODIFY,
no ? "false" : "true");

return nb_cli_apply_changes(vty, NULL);
}

/*
* XPath: /frr-eigrpd:eigrpd/instance/passive-interface
*/
Expand All @@ -131,12 +148,19 @@ DEFPY_YANG(
"Suppress routing updates on an interface\n"
"Interface to suppress on\n")
{
if (no)
nb_cli_enqueue_change(vty, "./passive-interface",
NB_OP_DESTROY, ifname);
else
bool passive_default =
yang_dnode_get_bool(vty->candidate_config->dnode, "%s%s",
VTY_CURR_XPATH, "/passive-default");

if (passive_default) {
nb_cli_enqueue_change(vty, "./non-passive-interface",
no ? NB_OP_CREATE : NB_OP_DESTROY,
ifname);
} else {
nb_cli_enqueue_change(vty, "./passive-interface",
NB_OP_CREATE, ifname);
no ? NB_OP_DESTROY : NB_OP_CREATE,
ifname);
}

return nb_cli_apply_changes(vty, NULL);
}
Expand All @@ -150,6 +174,15 @@ void eigrp_cli_show_passive_interface(struct vty *vty,
vty_out(vty, " passive-interface %s\n", ifname);
}

void eigrp_cli_show_non_passive_interface(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults)
{
const char *ifname = yang_dnode_get_string(dnode, NULL);

vty_out(vty, "no passive-interface %s\n", ifname);
}

/*
* XPath: /frr-eigrpd:eigrpd/instance/active-time
*/
Expand Down Expand Up @@ -826,6 +859,14 @@ void eigrp_cli_show_keychain(struct vty *vty, const struct lyd_node *dnode,
keychain);
}

void eigrpd_cli_show_passive_default(struct vty *vty, const struct lyd_node *dnode,
bool show_defaults)
{
if (!yang_dnode_get_bool(dnode, NULL))
vty_out(vty, " no");

vty_out(vty, " passive-interface default\n");
}

/*
* CLI installation procedures.
Expand Down Expand Up @@ -865,6 +906,7 @@ eigrp_cli_init(void)
install_element(EIGRP_NODE, &eigrp_router_id_cmd);
install_element(EIGRP_NODE, &no_eigrp_router_id_cmd);
install_element(EIGRP_NODE, &eigrp_passive_interface_cmd);
install_element(EIGRP_NODE, &eigrp_passive_default_cmd);
install_element(EIGRP_NODE, &eigrp_timers_active_cmd);
install_element(EIGRP_NODE, &no_eigrp_timers_active_cmd);
install_element(EIGRP_NODE, &eigrp_variance_cmd);
Expand Down
6 changes: 6 additions & 0 deletions eigrpd/eigrp_cli.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ extern void eigrp_cli_show_authentication(struct vty *vty,
extern void eigrp_cli_show_keychain(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults);
void eigrpd_cli_show_passive_default(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults);
void eigrp_cli_show_non_passive_interface(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults);
extern void eigrp_cli_init(void);

#endif /*EIGRP_CLI_H_ */
110 changes: 109 additions & 1 deletion eigrpd/eigrp_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#include "network.h"
#include "command.h"
#include "stream.h"
#include "log.h"
#include "zlog.h"
#include "keychain.h"
#include "vrf.h"

Expand All @@ -44,6 +44,9 @@
#include "eigrpd/eigrp_metric.h"

DEFINE_MTYPE_STATIC(EIGRPD, EIGRP_IF, "EIGRP interface");
DEFINE_MTYPE_STATIC(EIGRPD, EIGRP_IF_STRING, "EIGRP Interface String");

static void eigrp_passive_interface_apply(struct interface *ifp);

int eigrp_if_new_hook(struct interface *ifp)
{
Expand Down Expand Up @@ -114,6 +117,7 @@ static int eigrp_ifp_create(struct interface *ifp)

ei->params.type = eigrp_default_iftype(ifp);

eigrp_passive_interface_apply(ifp);
eigrp_if_update(ifp);

return 0;
Expand Down Expand Up @@ -154,6 +158,7 @@ static int eigrp_ifp_up(struct interface *ifp)
return 0;
}

eigrp_passive_interface_apply(ifp);
eigrp_if_up(ifp->info);

return 0;
Expand Down Expand Up @@ -368,6 +373,109 @@ bool eigrp_if_is_passive(struct eigrp_interface *ei)
return true;
}


/* Utility function for looking up passive interface settings. */
static int eigrp_passive_nondefault_lookup(struct eigrp *eigrp, const char *ifname)
{
unsigned int i;
char *str;

for (i = 0; i < vector_active(eigrp->passive_nondefault); i++) {
str = vector_slot(eigrp->passive_nondefault, i);
if (str && !strcmp(str, ifname))
return i;
}
return -1;
}

static void eigrp_passive_interface_apply(struct interface *ifp)
{
struct eigrp_interface *ei = ifp->info;
struct eigrp *eigrp;
int ifidx;

if (!ei || !ei->eigrp)
return;

eigrp = ei->eigrp;
ifidx = (eigrp_passive_nondefault_lookup(eigrp, ifp->name));
ei->params.passive_interface = (ifidx < 0) ? eigrp->passive_interface_default
: !eigrp->passive_interface_default;
if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE))
zlog_debug("interface %s: passive = %d", ifp->name,
ei->params.passive_interface);

}

static void eigrp_passive_interface_apply_all(struct eigrp *eigrp)
{
struct interface *ifp;
struct vrf *vrf;

vrf = vrf_lookup_by_id(eigrp->vrf_id);
FOR_ALL_INTERFACES (vrf, ifp)
eigrp_passive_interface_apply(ifp);
}


/* Passive interface. */
int eigrp_passive_nondefault_set(struct eigrp *eigrp, const char *ifname)
{
if (eigrp_passive_nondefault_lookup(eigrp, ifname) >= 0)
/*
* Don't return an error, this can happen after changing
* 'passive-default'.
*/
return NB_OK;

vector_set(eigrp->passive_nondefault,
XSTRDUP(MTYPE_EIGRP_IF_STRING, ifname));

eigrp_passive_interface_apply_all(eigrp);

return NB_OK;
}

int eigrp_passive_nondefault_unset(struct eigrp *eigrp, const char *ifname)
{
int i;
char *str;

i = eigrp_passive_nondefault_lookup(eigrp, ifname);
if (i < 0)
/*
* Don't return an error, this can happen after changing
* 'passive-default'.
*/
return NB_OK;

str = vector_slot(eigrp->passive_nondefault, i);
XFREE(MTYPE_EIGRP_IF_STRING, str);
vector_unset(eigrp->passive_nondefault, i);

eigrp_passive_interface_apply_all(eigrp);

return NB_OK;
}


/* Free all configured eigrp passive-interface settings. */
void eigrp_passive_nondefault_clean(struct eigrp *eigrp)
{
unsigned int i;
char *str;

for (i = 0; i < vector_active(eigrp->passive_nondefault); i++) {
str = vector_slot(eigrp->passive_nondefault, i);
if (str) {
XFREE(MTYPE_EIGRP_IF_STRING, str);
vector_slot(eigrp->passive_nondefault, i) = NULL;
}
}
eigrp_passive_interface_apply_all(eigrp);
}


void eigrp_if_set_multicast(struct eigrp_interface *ei)
{
if (!eigrp_if_is_passive(ei)) {
Expand Down
4 changes: 4 additions & 0 deletions eigrpd/eigrp_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ extern void eigrp_if_free(struct eigrp_interface *, int);
extern int eigrp_if_down(struct eigrp_interface *);
extern void eigrp_if_stream_unset(struct eigrp_interface *);

extern void eigrp_passive_nondefault_clean(struct eigrp *);
extern int eigrp_passive_nondefault_set(struct eigrp *, const char *);
extern int eigrp_passive_nondefault_unset(struct eigrp *, const char *);

extern struct eigrp_interface *eigrp_if_lookup_by_local_addr(struct eigrp *,
struct interface *,
struct in_addr);
Expand Down
Loading

0 comments on commit 7010f1f

Please sign in to comment.