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: FRRouting#11301
Signed-off-by: Volodymyr Huti <[email protected]>
  • Loading branch information
Volodymyr Huti committed Mar 20, 2024
1 parent 8968b3f commit d92757c
Show file tree
Hide file tree
Showing 8 changed files with 276 additions and 60 deletions.
55 changes: 49 additions & 6 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-eigrpd:eigrpd/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,14 +148,22 @@ DEFPY_YANG(
"Suppress routing updates on an interface\n"
"Interface to suppress on\n")
{
bool passive_default = yang_dnode_get_bool(vty->candidate_config->dnode,
"%s%s", VTY_CURR_XPATH,
"/passive-default");
char xpath[XPATH_MAXLEN];

snprintf(xpath, sizeof(xpath), "./passive-interface[.='%s']", ifname);

if (no)
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
else
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
if (passive_default) {
snprintf(xpath, sizeof(xpath),
"./non-passive-interface[.='%s']", ifname);
nb_cli_enqueue_change(vty, xpath,
no ? NB_OP_CREATE : NB_OP_DESTROY, NULL);
} else {
snprintf(xpath, sizeof(xpath),
"./passive-interface[.='%s']", ifname);
nb_cli_enqueue_change(vty, xpath,
no ? NB_OP_DESTROY : NB_OP_CREATE, NULL);
}

return nb_cli_apply_changes(vty, NULL);
}
Expand All @@ -152,6 +177,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 @@ -945,6 +979,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 @@ -984,6 +1026,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_ */
111 changes: 110 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(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,110 @@ 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 = 1; i < vector_active(eigrp->passive_nondefault); i++) {
str = vector_slot(eigrp->passive_nondefault, i);
if (str && strmatch(str, ifname))
return i;
}
return 0;
}

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 = 1; 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
10 changes: 7 additions & 3 deletions eigrpd/eigrp_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,13 @@ 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 struct eigrp_interface *eigrp_if_lookup_by_local_addr(struct eigrp *,
struct interface *,
struct in_addr);
extern void eigrp_passive_nondefault_clean(struct eigrp *);
extern int eigrp_passive_nondefault_set(struct eigrp *eigrp, const char *ifname);
extern int eigrp_passive_nondefault_unset(struct eigrp *eigrp, const char *ifname);

extern struct eigrp_interface *eigrp_if_lookup_by_local_addr(struct eigrp *eigrp,
struct interface *ifp,
struct in_addr address);
extern struct eigrp_interface *eigrp_if_lookup_by_name(struct eigrp *,
const char *);

Expand Down
Loading

0 comments on commit d92757c

Please sign in to comment.