mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-11 16:39:33 +00:00
Merge pull request #4797 from opensourcerouting/eigrpd-vrf
eigrpd: vrf support
This commit is contained in:
commit
996c5b515b
@ -65,15 +65,16 @@ Certain signals have special meanings to *eigrpd*.
|
||||
EIGRP Configuration
|
||||
===================
|
||||
|
||||
.. index:: router eigrp (1-65535)
|
||||
.. clicmd:: router eigrp (1-65535)
|
||||
.. index:: router eigrp (1-65535) [vrf NAME]
|
||||
.. clicmd:: router eigrp (1-65535) [vrf NAME]
|
||||
|
||||
The `router eigrp` command is necessary to enable EIGRP. To disable EIGRP,
|
||||
use the `no router eigrp (1-65535)` command. EIGRP must be enabled before
|
||||
carrying out any of the EIGRP commands.
|
||||
carrying out any of the EIGRP commands. Specify vrf NAME if you want
|
||||
eigrp to work within the specified vrf.
|
||||
|
||||
.. index:: no router eigrp (1-65535)
|
||||
.. clicmd:: no router eigrp (1-65535)
|
||||
.. index:: no router eigrp (1-65535) [vrf NAME]
|
||||
.. clicmd:: no router eigrp (1-65535) [vrf NAME]
|
||||
|
||||
Disable EIGRP.
|
||||
|
||||
@ -189,8 +190,8 @@ How to Announce EIGRP route
|
||||
Show EIGRP Information
|
||||
======================
|
||||
|
||||
.. index:: show ip eigrp topology
|
||||
.. clicmd:: show ip eigrp topology
|
||||
.. index:: show ip eigrp [vrf NAME] topology
|
||||
.. clicmd:: show ip eigrp [vrf NAME] topology
|
||||
|
||||
Display current EIGRP status.
|
||||
|
||||
@ -207,6 +208,17 @@ Show EIGRP Information
|
||||
P 10.0.2.0/24, 1 successors, FD is 256256, serno: 0
|
||||
via Connected, enp0s3
|
||||
|
||||
.. index:: show ip eigrp [vrf NAME] interface
|
||||
.. clicmd:: show ip eigrp [vrf NAME] interface
|
||||
|
||||
Display the list of interfaces associated with a particular eigrp
|
||||
instance.
|
||||
|
||||
..index:: show ip eigrp [vrf NAME] neighbor
|
||||
..clicmd:: show ip eigrp [vrf NAME] neighbor
|
||||
|
||||
Display the list of neighbors that have been established within
|
||||
a particular eigrp instance.
|
||||
|
||||
EIGRP Debug Commands
|
||||
====================
|
||||
|
@ -40,17 +40,18 @@
|
||||
DEFPY_NOSH(
|
||||
router_eigrp,
|
||||
router_eigrp_cmd,
|
||||
"router eigrp (1-65535)$as",
|
||||
"router eigrp (1-65535)$as [vrf NAME]",
|
||||
ROUTER_STR
|
||||
EIGRP_STR
|
||||
AS_STR)
|
||||
AS_STR
|
||||
VRF_CMD_HELP_STR)
|
||||
{
|
||||
char xpath[XPATH_MAXLEN];
|
||||
int rv;
|
||||
|
||||
snprintf(xpath, sizeof(xpath),
|
||||
"/frr-eigrpd:eigrpd/instance[asn='%s'][vrf='']",
|
||||
as_str);
|
||||
"/frr-eigrpd:eigrpd/instance[asn='%s'][vrf='%s']",
|
||||
as_str, vrf ? vrf : VRF_DEFAULT_NAME);
|
||||
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
|
||||
rv = nb_cli_apply_changes(vty, NULL);
|
||||
@ -60,20 +61,21 @@ DEFPY_NOSH(
|
||||
return rv;
|
||||
}
|
||||
|
||||
DEFPY_NOSH(
|
||||
DEFPY(
|
||||
no_router_eigrp,
|
||||
no_router_eigrp_cmd,
|
||||
"no router eigrp (1-65535)$as",
|
||||
"no router eigrp (1-65535)$as [vrf NAME]",
|
||||
NO_STR
|
||||
ROUTER_STR
|
||||
EIGRP_STR
|
||||
AS_STR)
|
||||
AS_STR
|
||||
VRF_CMD_HELP_STR)
|
||||
{
|
||||
char xpath[XPATH_MAXLEN];
|
||||
|
||||
snprintf(xpath, sizeof(xpath),
|
||||
"/frr-eigrpd:eigrpd/instance[asn='%s'][vrf='']",
|
||||
as_str);
|
||||
"/frr-eigrpd:eigrpd/instance[asn='%s'][vrf='%s']",
|
||||
as_str, vrf ? vrf : VRF_DEFAULT_NAME);
|
||||
|
||||
nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
@ -83,8 +85,12 @@ void eigrp_cli_show_header(struct vty *vty, struct lyd_node *dnode,
|
||||
bool show_defaults)
|
||||
{
|
||||
const char *asn = yang_dnode_get_string(dnode, "./asn");
|
||||
const char *vrf = yang_dnode_get_string(dnode, "./vrf");
|
||||
|
||||
vty_out(vty, "router eigrp %s\n", asn);
|
||||
vty_out(vty, "router eigrp %s", asn);
|
||||
if (strcmp(vrf, VRF_DEFAULT_NAME))
|
||||
vty_out(vty, " vrf %s", vrf);
|
||||
vty_out(vty, "\n");
|
||||
}
|
||||
|
||||
void eigrp_cli_show_end_header(struct vty *vty, struct lyd_node *dnode)
|
||||
|
@ -65,17 +65,15 @@
|
||||
void eigrp_distribute_update(struct distribute_ctx *ctx,
|
||||
struct distribute *dist)
|
||||
{
|
||||
struct eigrp *e = eigrp_lookup(ctx->vrf->vrf_id);
|
||||
struct interface *ifp;
|
||||
struct eigrp_interface *ei = NULL;
|
||||
struct access_list *alist;
|
||||
struct prefix_list *plist;
|
||||
// struct route_map *routemap;
|
||||
struct eigrp *e;
|
||||
|
||||
/* if no interface address is present, set list to eigrp process struct
|
||||
*/
|
||||
e = eigrp_lookup();
|
||||
assert(e != NULL);
|
||||
|
||||
/* Check if distribute-list was set for process or interface */
|
||||
if (!dist->ifname) {
|
||||
@ -174,7 +172,7 @@ void eigrp_distribute_update(struct distribute_ctx *ctx,
|
||||
return;
|
||||
}
|
||||
|
||||
ifp = if_lookup_by_name(dist->ifname, VRF_DEFAULT);
|
||||
ifp = if_lookup_by_name(dist->ifname, e->vrf_id);
|
||||
if (ifp == NULL)
|
||||
return;
|
||||
|
||||
@ -288,7 +286,7 @@ void eigrp_distribute_update_interface(struct interface *ifp)
|
||||
struct distribute *dist;
|
||||
struct eigrp *eigrp;
|
||||
|
||||
eigrp = eigrp_lookup();
|
||||
eigrp = eigrp_lookup(ifp->vrf_id);
|
||||
if (!eigrp)
|
||||
return;
|
||||
dist = distribute_lookup(eigrp->distribute_ctx, ifp->name);
|
||||
@ -302,11 +300,13 @@ void eigrp_distribute_update_interface(struct interface *ifp)
|
||||
*/
|
||||
void eigrp_distribute_update_all(struct prefix_list *notused)
|
||||
{
|
||||
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
|
||||
struct vrf *vrf;
|
||||
struct interface *ifp;
|
||||
|
||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
||||
FOR_ALL_INTERFACES (vrf, ifp)
|
||||
eigrp_distribute_update_interface(ifp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -35,10 +35,10 @@
|
||||
|
||||
extern void eigrp_distribute_update(struct distribute_ctx *ctx,
|
||||
struct distribute *dist);
|
||||
extern void eigrp_distribute_update_interface(struct interface *);
|
||||
extern void eigrp_distribute_update_all(struct prefix_list *);
|
||||
extern void eigrp_distribute_update_all_wrapper(struct access_list *);
|
||||
extern int eigrp_distribute_timer_process(struct thread *);
|
||||
extern int eigrp_distribute_timer_interface(struct thread *);
|
||||
extern void eigrp_distribute_update_interface(struct interface *ifp);
|
||||
extern void eigrp_distribute_update_all(struct prefix_list *plist);
|
||||
extern void eigrp_distribute_update_all_wrapper(struct access_list *alist);
|
||||
extern int eigrp_distribute_timer_process(struct thread *thread);
|
||||
extern int eigrp_distribute_timer_interface(struct thread *thread);
|
||||
|
||||
#endif /* EIGRPD_EIGRP_FILTER_H_ */
|
||||
|
@ -445,7 +445,7 @@ int eigrp_fsm_event_nq_fcn(struct eigrp_fsm_action_message *msg)
|
||||
prefix->rdistance = prefix->distance = prefix->fdistance = ne->distance;
|
||||
prefix->reported_metric = ne->total_metric;
|
||||
|
||||
if (eigrp_nbr_count_get()) {
|
||||
if (eigrp_nbr_count_get(eigrp)) {
|
||||
prefix->req_action |= EIGRP_FSM_NEED_QUERY;
|
||||
listnode_add(eigrp->topology_changes_internalIPV4, prefix);
|
||||
} else {
|
||||
@ -471,7 +471,7 @@ int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg)
|
||||
prefix->state = EIGRP_FSM_STATE_ACTIVE_3;
|
||||
prefix->rdistance = prefix->distance = prefix->fdistance = ne->distance;
|
||||
prefix->reported_metric = ne->total_metric;
|
||||
if (eigrp_nbr_count_get()) {
|
||||
if (eigrp_nbr_count_get(eigrp)) {
|
||||
prefix->req_action |= EIGRP_FSM_NEED_QUERY;
|
||||
listnode_add(eigrp->topology_changes_internalIPV4, prefix);
|
||||
} else {
|
||||
@ -486,7 +486,7 @@ int eigrp_fsm_event_q_fcn(struct eigrp_fsm_action_message *msg)
|
||||
|
||||
int eigrp_fsm_event_keep_state(struct eigrp_fsm_action_message *msg)
|
||||
{
|
||||
struct eigrp *eigrp;
|
||||
struct eigrp *eigrp = msg->eigrp;
|
||||
struct eigrp_prefix_entry *prefix = msg->prefix;
|
||||
struct eigrp_nexthop_entry *ne = listnode_head(prefix->entries);
|
||||
|
||||
@ -499,13 +499,11 @@ int eigrp_fsm_event_keep_state(struct eigrp_fsm_action_message *msg)
|
||||
if (msg->packet_type == EIGRP_OPC_QUERY)
|
||||
eigrp_send_reply(msg->adv_router, prefix);
|
||||
prefix->req_action |= EIGRP_FSM_NEED_UPDATE;
|
||||
eigrp = eigrp_lookup();
|
||||
assert(eigrp);
|
||||
listnode_add(eigrp->topology_changes_internalIPV4,
|
||||
prefix);
|
||||
}
|
||||
eigrp_topology_update_node_flags(prefix);
|
||||
eigrp_update_routing_table(prefix);
|
||||
eigrp_topology_update_node_flags(eigrp, prefix);
|
||||
eigrp_update_routing_table(eigrp, prefix);
|
||||
}
|
||||
|
||||
if (msg->packet_type == EIGRP_OPC_QUERY)
|
||||
@ -536,9 +534,10 @@ int eigrp_fsm_event_lr(struct eigrp_fsm_action_message *msg)
|
||||
prefix->state = EIGRP_FSM_STATE_PASSIVE;
|
||||
prefix->req_action |= EIGRP_FSM_NEED_UPDATE;
|
||||
listnode_add(eigrp->topology_changes_internalIPV4, prefix);
|
||||
eigrp_topology_update_node_flags(prefix);
|
||||
eigrp_update_routing_table(prefix);
|
||||
eigrp_update_topology_table_prefix(eigrp->topology_table, prefix);
|
||||
eigrp_topology_update_node_flags(eigrp, prefix);
|
||||
eigrp_update_routing_table(eigrp, prefix);
|
||||
eigrp_update_topology_table_prefix(eigrp, eigrp->topology_table,
|
||||
prefix);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -588,9 +587,10 @@ int eigrp_fsm_event_lr_fcs(struct eigrp_fsm_action_message *msg)
|
||||
}
|
||||
prefix->req_action |= EIGRP_FSM_NEED_UPDATE;
|
||||
listnode_add(eigrp->topology_changes_internalIPV4, prefix);
|
||||
eigrp_topology_update_node_flags(prefix);
|
||||
eigrp_update_routing_table(prefix);
|
||||
eigrp_update_topology_table_prefix(eigrp->topology_table, prefix);
|
||||
eigrp_topology_update_node_flags(eigrp, prefix);
|
||||
eigrp_update_routing_table(eigrp, prefix);
|
||||
eigrp_update_topology_table_prefix(eigrp, eigrp->topology_table,
|
||||
prefix);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -612,7 +612,7 @@ int eigrp_fsm_event_lr_fcn(struct eigrp_fsm_action_message *msg)
|
||||
prefix->rdistance = prefix->distance = best_successor->distance;
|
||||
prefix->reported_metric = best_successor->total_metric;
|
||||
|
||||
if (eigrp_nbr_count_get()) {
|
||||
if (eigrp_nbr_count_get(eigrp)) {
|
||||
prefix->req_action |= EIGRP_FSM_NEED_QUERY;
|
||||
listnode_add(eigrp->topology_changes_internalIPV4, prefix);
|
||||
} else {
|
||||
|
@ -147,7 +147,7 @@ eigrp_hello_parameter_decode(struct eigrp_neighbor *nbr,
|
||||
zlog_info("Neighbor %s (%s) is pending: new adjacency",
|
||||
inet_ntoa(nbr->src),
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex,
|
||||
VRF_DEFAULT));
|
||||
eigrp->vrf_id));
|
||||
|
||||
/* Expedited hello sent */
|
||||
eigrp_hello_send(nbr->ei, EIGRP_HELLO_NORMAL, NULL);
|
||||
@ -167,7 +167,7 @@ eigrp_hello_parameter_decode(struct eigrp_neighbor *nbr,
|
||||
"Neighbor %s (%s) is down: Interface PEER-TERMINATION received",
|
||||
inet_ntoa(nbr->src),
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex,
|
||||
VRF_DEFAULT));
|
||||
eigrp->vrf_id));
|
||||
eigrp_nbr_delete(nbr);
|
||||
return NULL;
|
||||
} else {
|
||||
@ -175,7 +175,7 @@ eigrp_hello_parameter_decode(struct eigrp_neighbor *nbr,
|
||||
"Neighbor %s (%s) going down: Kvalue mismatch",
|
||||
inet_ntoa(nbr->src),
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex,
|
||||
VRF_DEFAULT));
|
||||
eigrp->vrf_id));
|
||||
eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_DOWN);
|
||||
}
|
||||
}
|
||||
@ -245,6 +245,7 @@ static void eigrp_sw_version_decode(struct eigrp_neighbor *nbr,
|
||||
static void eigrp_peer_termination_decode(struct eigrp_neighbor *nbr,
|
||||
struct eigrp_tlv_hdr_type *tlv)
|
||||
{
|
||||
struct eigrp *eigrp = nbr->ei->eigrp;
|
||||
struct TLV_Peer_Termination_type *param =
|
||||
(struct TLV_Peer_Termination_type *)tlv;
|
||||
|
||||
@ -254,7 +255,7 @@ static void eigrp_peer_termination_decode(struct eigrp_neighbor *nbr,
|
||||
if (my_ip == received_ip) {
|
||||
zlog_info("Neighbor %s (%s) is down: Peer Termination received",
|
||||
inet_ntoa(nbr->src),
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT));
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id));
|
||||
/* set neighbor to DOWN */
|
||||
nbr->state = EIGRP_NEIGHBOR_DOWN;
|
||||
/* delete neighbor */
|
||||
@ -330,7 +331,7 @@ void eigrp_hello_receive(struct eigrp *eigrp, struct ip *iph,
|
||||
|
||||
if (IS_DEBUG_EIGRP_PACKET(eigrph->opcode - 1, RECV))
|
||||
zlog_debug("Processing Hello size[%u] int(%s) nbr(%s)", size,
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT),
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id),
|
||||
inet_ntoa(nbr->src));
|
||||
|
||||
size -= EIGRP_HEADER_LEN;
|
||||
@ -484,21 +485,15 @@ static uint16_t eigrp_tidlist_encode(struct stream *s)
|
||||
* Part of conditional receive process
|
||||
*
|
||||
*/
|
||||
static uint16_t eigrp_sequence_encode(struct stream *s)
|
||||
static uint16_t eigrp_sequence_encode(struct eigrp *eigrp, struct stream *s)
|
||||
{
|
||||
uint16_t length = EIGRP_TLV_SEQ_BASE_LEN;
|
||||
struct eigrp *eigrp;
|
||||
struct eigrp_interface *ei;
|
||||
struct listnode *node, *node2, *nnode2;
|
||||
struct eigrp_neighbor *nbr;
|
||||
size_t backup_end, size_end;
|
||||
int found;
|
||||
|
||||
eigrp = eigrp_lookup();
|
||||
if (eigrp == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// add in the parameters TLV
|
||||
backup_end = stream_get_endp(s);
|
||||
stream_putw(s, EIGRP_TLV_SEQ);
|
||||
@ -541,15 +536,10 @@ static uint16_t eigrp_sequence_encode(struct stream *s)
|
||||
* Part of conditional receive process
|
||||
*
|
||||
*/
|
||||
static uint16_t eigrp_next_sequence_encode(struct stream *s)
|
||||
static uint16_t eigrp_next_sequence_encode(struct eigrp *eigrp,
|
||||
struct stream *s)
|
||||
{
|
||||
uint16_t length = EIGRP_NEXT_SEQUENCE_TLV_SIZE;
|
||||
struct eigrp *eigrp;
|
||||
|
||||
eigrp = eigrp_lookup();
|
||||
if (eigrp == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// add in the parameters TLV
|
||||
stream_putw(s, EIGRP_TLV_NEXT_MCAST_SEQ);
|
||||
@ -659,8 +649,8 @@ static struct eigrp_packet *eigrp_hello_encode(struct eigrp_interface *ei,
|
||||
length += eigrp_sw_version_encode(ep->s);
|
||||
|
||||
if (flags & EIGRP_HELLO_ADD_SEQUENCE) {
|
||||
length += eigrp_sequence_encode(ep->s);
|
||||
length += eigrp_next_sequence_encode(ep->s);
|
||||
length += eigrp_sequence_encode(ei->eigrp, ep->s);
|
||||
length += eigrp_next_sequence_encode(ei->eigrp, ep->s);
|
||||
}
|
||||
|
||||
// add in the TID list if doing multi-topology
|
||||
|
@ -206,7 +206,7 @@ int eigrp_if_up(struct eigrp_interface *ei)
|
||||
eigrp_prefix_entry_add(eigrp->topology_table, pe);
|
||||
listnode_add(eigrp->topology_changes_internalIPV4, pe);
|
||||
|
||||
eigrp_nexthop_entry_add(pe, ne);
|
||||
eigrp_nexthop_entry_add(eigrp, pe, ne);
|
||||
|
||||
for (ALL_LIST_ELEMENTS(eigrp->eiflist, node, nnode, ei2)) {
|
||||
eigrp_update_send(ei2);
|
||||
@ -218,7 +218,7 @@ int eigrp_if_up(struct eigrp_interface *ei)
|
||||
struct eigrp_fsm_action_message msg;
|
||||
|
||||
ne->prefix = pe;
|
||||
eigrp_nexthop_entry_add(pe, ne);
|
||||
eigrp_nexthop_entry_add(eigrp, pe, ne);
|
||||
|
||||
msg.packet_type = EIGRP_OPC_UPDATE;
|
||||
msg.eigrp = eigrp;
|
||||
@ -329,10 +329,7 @@ void eigrp_if_free(struct eigrp_interface *ei, int source)
|
||||
{
|
||||
struct prefix dest_addr;
|
||||
struct eigrp_prefix_entry *pe;
|
||||
struct eigrp *eigrp = eigrp_lookup();
|
||||
|
||||
if (!eigrp)
|
||||
return;
|
||||
struct eigrp *eigrp = ei->eigrp;
|
||||
|
||||
if (source == INTERFACE_DOWN_BY_VTY) {
|
||||
THREAD_OFF(ei->t_hello);
|
||||
@ -344,7 +341,7 @@ void eigrp_if_free(struct eigrp_interface *ei, int source)
|
||||
pe = eigrp_topology_table_lookup_ipv4(eigrp->topology_table,
|
||||
&dest_addr);
|
||||
if (pe)
|
||||
eigrp_prefix_entry_delete(eigrp->topology_table, pe);
|
||||
eigrp_prefix_entry_delete(eigrp, eigrp->topology_table, pe);
|
||||
|
||||
eigrp_if_down(ei);
|
||||
|
||||
|
@ -65,6 +65,7 @@
|
||||
#include "eigrpd/eigrp_snmp.h"
|
||||
#include "eigrpd/eigrp_filter.h"
|
||||
#include "eigrpd/eigrp_errors.h"
|
||||
#include "eigrpd/eigrp_vrf.h"
|
||||
//#include "eigrpd/eigrp_routemap.h"
|
||||
|
||||
/* eigprd privileges */
|
||||
@ -182,6 +183,7 @@ int main(int argc, char **argv, char **envp)
|
||||
master = eigrp_om->master;
|
||||
|
||||
eigrp_error_init();
|
||||
eigrp_vrf_init();
|
||||
vrf_init(NULL, NULL, NULL, NULL, NULL);
|
||||
|
||||
/*EIGRPd init*/
|
||||
|
@ -194,13 +194,12 @@ void eigrp_nbr_delete(struct eigrp_neighbor *nbr)
|
||||
|
||||
int holddown_timer_expired(struct thread *thread)
|
||||
{
|
||||
struct eigrp_neighbor *nbr;
|
||||
|
||||
nbr = THREAD_ARG(thread);
|
||||
struct eigrp_neighbor *nbr = THREAD_ARG(thread);
|
||||
struct eigrp *eigrp = nbr->ei->eigrp;
|
||||
|
||||
zlog_info("Neighbor %s (%s) is down: holding time expired",
|
||||
inet_ntoa(nbr->src),
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT));
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id));
|
||||
nbr->state = EIGRP_NEIGHBOR_DOWN;
|
||||
eigrp_nbr_delete(nbr);
|
||||
|
||||
@ -297,19 +296,13 @@ void eigrp_nbr_state_update(struct eigrp_neighbor *nbr)
|
||||
}
|
||||
}
|
||||
|
||||
int eigrp_nbr_count_get(void)
|
||||
int eigrp_nbr_count_get(struct eigrp *eigrp)
|
||||
{
|
||||
struct eigrp_interface *iface;
|
||||
struct listnode *node, *node2, *nnode2;
|
||||
struct eigrp_neighbor *nbr;
|
||||
struct eigrp *eigrp = eigrp_lookup();
|
||||
uint32_t counter;
|
||||
|
||||
if (eigrp == NULL) {
|
||||
zlog_debug("EIGRP Routing Process not enabled");
|
||||
return 0;
|
||||
}
|
||||
|
||||
counter = 0;
|
||||
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, iface)) {
|
||||
for (ALL_LIST_ELEMENTS(iface->nbrs, node2, nnode2, nbr)) {
|
||||
@ -335,20 +328,16 @@ int eigrp_nbr_count_get(void)
|
||||
*/
|
||||
void eigrp_nbr_hard_restart(struct eigrp_neighbor *nbr, struct vty *vty)
|
||||
{
|
||||
if (nbr == NULL) {
|
||||
flog_err(EC_EIGRP_CONFIG,
|
||||
"Nbr Hard restart: Neighbor not specified.");
|
||||
return;
|
||||
}
|
||||
struct eigrp *eigrp = nbr->ei->eigrp;
|
||||
|
||||
zlog_debug("Neighbor %s (%s) is down: manually cleared",
|
||||
inet_ntoa(nbr->src),
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT));
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id));
|
||||
if (vty != NULL) {
|
||||
vty_time_print(vty, 0);
|
||||
vty_out(vty, "Neighbor %s (%s) is down: manually cleared\n",
|
||||
inet_ntoa(nbr->src),
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT));
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id));
|
||||
}
|
||||
|
||||
/* send Hello with Peer Termination TLV */
|
||||
|
@ -33,24 +33,25 @@
|
||||
#define _ZEBRA_EIGRP_NEIGHBOR_H
|
||||
|
||||
/* Prototypes */
|
||||
extern struct eigrp_neighbor *eigrp_nbr_get(struct eigrp_interface *,
|
||||
struct eigrp_header *, struct ip *);
|
||||
extern struct eigrp_neighbor *eigrp_nbr_new(struct eigrp_interface *);
|
||||
extern void eigrp_nbr_delete(struct eigrp_neighbor *);
|
||||
extern struct eigrp_neighbor *eigrp_nbr_get(struct eigrp_interface *ei,
|
||||
struct eigrp_header *,
|
||||
struct ip *addr);
|
||||
extern struct eigrp_neighbor *eigrp_nbr_new(struct eigrp_interface *ei);
|
||||
extern void eigrp_nbr_delete(struct eigrp_neighbor *neigh);
|
||||
|
||||
extern int holddown_timer_expired(struct thread *);
|
||||
extern int holddown_timer_expired(struct thread *thread);
|
||||
|
||||
extern int eigrp_neighborship_check(struct eigrp_neighbor *,
|
||||
struct TLV_Parameter_Type *);
|
||||
extern void eigrp_nbr_state_update(struct eigrp_neighbor *);
|
||||
extern void eigrp_nbr_state_set(struct eigrp_neighbor *, uint8_t state);
|
||||
extern uint8_t eigrp_nbr_state_get(struct eigrp_neighbor *);
|
||||
extern int eigrp_nbr_count_get(void);
|
||||
extern const char *eigrp_nbr_state_str(struct eigrp_neighbor *);
|
||||
extern struct eigrp_neighbor *eigrp_nbr_lookup_by_addr(struct eigrp_interface *,
|
||||
struct in_addr *);
|
||||
extern struct eigrp_neighbor *eigrp_nbr_lookup_by_addr_process(struct eigrp *,
|
||||
struct in_addr);
|
||||
extern int eigrp_neighborship_check(struct eigrp_neighbor *neigh,
|
||||
struct TLV_Parameter_Type *tlv);
|
||||
extern void eigrp_nbr_state_update(struct eigrp_neighbor *neigh);
|
||||
extern void eigrp_nbr_state_set(struct eigrp_neighbor *neigh, uint8_t state);
|
||||
extern uint8_t eigrp_nbr_state_get(struct eigrp_neighbor *neigh);
|
||||
extern int eigrp_nbr_count_get(struct eigrp *eigrp);
|
||||
extern const char *eigrp_nbr_state_str(struct eigrp_neighbor *neigh);
|
||||
extern struct eigrp_neighbor *
|
||||
eigrp_nbr_lookup_by_addr(struct eigrp_interface *ei, struct in_addr *addr);
|
||||
extern struct eigrp_neighbor *
|
||||
eigrp_nbr_lookup_by_addr_process(struct eigrp *eigrp, struct in_addr addr);
|
||||
extern void eigrp_nbr_hard_restart(struct eigrp_neighbor *nbr, struct vty *vty);
|
||||
|
||||
extern int eigrp_nbr_split_horizon_check(struct eigrp_nexthop_entry *ne,
|
||||
|
@ -53,7 +53,7 @@ static int eigrp_network_match_iface(const struct prefix *connected_prefix,
|
||||
static void eigrp_network_run_interface(struct eigrp *, struct prefix *,
|
||||
struct interface *);
|
||||
|
||||
int eigrp_sock_init(void)
|
||||
int eigrp_sock_init(struct vrf *vrf)
|
||||
{
|
||||
int eigrp_sock;
|
||||
int ret;
|
||||
@ -62,7 +62,9 @@ int eigrp_sock_init(void)
|
||||
#endif
|
||||
|
||||
frr_elevate_privs(&eigrpd_privs) {
|
||||
eigrp_sock = socket(AF_INET, SOCK_RAW, IPPROTO_EIGRPIGP);
|
||||
eigrp_sock = vrf_socket(
|
||||
AF_INET, SOCK_RAW, IPPROTO_EIGRPIGP, vrf->vrf_id,
|
||||
vrf->vrf_id != VRF_DEFAULT ? vrf->name : NULL);
|
||||
if (eigrp_sock < 0) {
|
||||
zlog_err("eigrp_read_sock_init: socket: %s",
|
||||
safe_strerror(errno));
|
||||
@ -209,7 +211,7 @@ int eigrp_if_drop_allspfrouters(struct eigrp *top, struct prefix *p,
|
||||
|
||||
int eigrp_network_set(struct eigrp *eigrp, struct prefix *p)
|
||||
{
|
||||
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
|
||||
struct vrf *vrf = vrf_lookup_by_id(eigrp->vrf_id);
|
||||
struct route_node *rn;
|
||||
struct interface *ifp;
|
||||
|
||||
@ -283,13 +285,16 @@ void eigrp_if_update(struct interface *ifp)
|
||||
{
|
||||
struct listnode *node, *nnode;
|
||||
struct route_node *rn;
|
||||
struct eigrp *eigrp;
|
||||
struct eigrp *eigrp = eigrp_lookup(ifp->vrf_id);
|
||||
|
||||
/*
|
||||
* In the event there are multiple eigrp autonymnous systems running,
|
||||
* we need to check eac one and add the interface as approperate
|
||||
*/
|
||||
for (ALL_LIST_ELEMENTS(eigrp_om->eigrp, node, nnode, eigrp)) {
|
||||
if (ifp->vrf_id != eigrp->vrf_id)
|
||||
continue;
|
||||
|
||||
/* EIGRP must be on and Router-ID must be configured. */
|
||||
if (eigrp->router_id.s_addr == 0)
|
||||
continue;
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
/* Prototypes */
|
||||
|
||||
extern int eigrp_sock_init(void);
|
||||
extern int eigrp_sock_init(struct vrf *vrf);
|
||||
extern int eigrp_if_ipmulticast(struct eigrp *, struct prefix *, unsigned int);
|
||||
extern int eigrp_network_set(struct eigrp *eigrp, struct prefix *p);
|
||||
extern int eigrp_network_unset(struct eigrp *eigrp, struct prefix *p);
|
||||
|
@ -79,13 +79,18 @@ static int eigrpd_instance_create(enum nb_event event,
|
||||
union nb_resource *resource)
|
||||
{
|
||||
struct eigrp *eigrp;
|
||||
const char *vrf;
|
||||
vrf_id_t vrfid;
|
||||
|
||||
switch (event) {
|
||||
case NB_EV_VALIDATE:
|
||||
/* NOTHING */
|
||||
break;
|
||||
case NB_EV_PREPARE:
|
||||
eigrp = eigrp_get(yang_dnode_get_string(dnode, "./asn"));
|
||||
vrf = yang_dnode_get_string(dnode, "./vrf");
|
||||
vrfid = vrf_name_to_id(vrf);
|
||||
|
||||
eigrp = eigrp_get(yang_dnode_get_uint16(dnode, "./asn"), vrfid);
|
||||
resource->ptr = eigrp;
|
||||
break;
|
||||
case NB_EV_ABORT:
|
||||
@ -745,14 +750,17 @@ static int eigrpd_instance_redistribute_create(enum nb_event event,
|
||||
union nb_resource *resource)
|
||||
{
|
||||
struct eigrp_metrics metrics;
|
||||
const char *vrfname;
|
||||
struct eigrp *eigrp;
|
||||
uint32_t proto;
|
||||
vrf_id_t vrfid;
|
||||
|
||||
switch (event) {
|
||||
case NB_EV_VALIDATE:
|
||||
proto = yang_dnode_get_enum(dnode, "./protocol");
|
||||
if (vrf_bitmap_check(zclient->redist[AFI_IP][proto],
|
||||
VRF_DEFAULT))
|
||||
vrfname = yang_dnode_get_string(dnode, "../vrf");
|
||||
vrfid = vrf_name_to_id(vrfname);
|
||||
if (vrf_bitmap_check(zclient->redist[AFI_IP][proto], vrfid))
|
||||
return NB_ERR_INCONSISTENCY;
|
||||
break;
|
||||
case NB_EV_PREPARE:
|
||||
@ -1181,7 +1189,8 @@ static int lib_interface_eigrp_instance_create(enum nb_event event,
|
||||
break;
|
||||
}
|
||||
|
||||
eigrp = eigrp_get(yang_dnode_get_string(dnode, "./asn"));
|
||||
eigrp = eigrp_get(yang_dnode_get_uint16(dnode, "./asn"),
|
||||
ifp->vrf_id);
|
||||
eif = eigrp_interface_lookup(eigrp, ifp->name);
|
||||
if (eif == NULL)
|
||||
return NB_ERR_INCONSISTENCY;
|
||||
@ -1192,7 +1201,8 @@ static int lib_interface_eigrp_instance_create(enum nb_event event,
|
||||
break;
|
||||
case NB_EV_APPLY:
|
||||
ifp = nb_running_get_entry(dnode, NULL, true);
|
||||
eigrp = eigrp_get(yang_dnode_get_string(dnode, "./asn"));
|
||||
eigrp = eigrp_get(yang_dnode_get_uint16(dnode, "./asn"),
|
||||
ifp->vrf_id);
|
||||
eif = eigrp_interface_lookup(eigrp, ifp->name);
|
||||
if (eif == NULL)
|
||||
return NB_ERR_INCONSISTENCY;
|
||||
|
@ -77,11 +77,13 @@ const struct message eigrp_packet_type_str[] = {
|
||||
static unsigned char zeropad[16] = {0};
|
||||
|
||||
/* Forward function reference*/
|
||||
static struct stream *eigrp_recv_packet(int, struct interface **,
|
||||
struct stream *);
|
||||
static int eigrp_verify_header(struct stream *, struct eigrp_interface *,
|
||||
struct ip *, struct eigrp_header *);
|
||||
static int eigrp_check_network_mask(struct eigrp_interface *, struct in_addr);
|
||||
static struct stream *eigrp_recv_packet(struct eigrp *eigrp, int fd,
|
||||
struct interface **ifp,
|
||||
struct stream *s);
|
||||
static int eigrp_verify_header(struct stream *s, struct eigrp_interface *ei,
|
||||
struct ip *addr, struct eigrp_header *header);
|
||||
static int eigrp_check_network_mask(struct eigrp_interface *ei,
|
||||
struct in_addr mask);
|
||||
|
||||
static int eigrp_retrans_count_exceeded(struct eigrp_packet *ep,
|
||||
struct eigrp_neighbor *nbr)
|
||||
@ -495,7 +497,7 @@ int eigrp_read(struct thread *thread)
|
||||
thread_add_read(master, eigrp_read, eigrp, eigrp->fd, &eigrp->t_read);
|
||||
|
||||
stream_reset(eigrp->ibuf);
|
||||
if (!(ibuf = eigrp_recv_packet(eigrp->fd, &ifp, eigrp->ibuf))) {
|
||||
if (!(ibuf = eigrp_recv_packet(eigrp, eigrp->fd, &ifp, eigrp->ibuf))) {
|
||||
/* This raw packet is known to be at least as big as its IP
|
||||
* header. */
|
||||
return -1;
|
||||
@ -525,7 +527,7 @@ int eigrp_read(struct thread *thread)
|
||||
ifindex
|
||||
retrieval but do not. */
|
||||
c = if_lookup_address((void *)&iph->ip_src, AF_INET,
|
||||
VRF_DEFAULT);
|
||||
eigrp->vrf_id);
|
||||
|
||||
if (c == NULL)
|
||||
return 0;
|
||||
@ -706,7 +708,8 @@ int eigrp_read(struct thread *thread)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct stream *eigrp_recv_packet(int fd, struct interface **ifp,
|
||||
static struct stream *eigrp_recv_packet(struct eigrp *eigrp,
|
||||
int fd, struct interface **ifp,
|
||||
struct stream *ibuf)
|
||||
{
|
||||
int ret;
|
||||
@ -774,7 +777,7 @@ static struct stream *eigrp_recv_packet(int fd, struct interface **ifp,
|
||||
|
||||
ifindex = getsockopt_ifindex(AF_INET, &msgh);
|
||||
|
||||
*ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
|
||||
*ifp = if_lookup_by_index(ifindex, eigrp->vrf_id);
|
||||
|
||||
if (ret != ip_len) {
|
||||
zlog_warn(
|
||||
|
@ -69,6 +69,8 @@ struct eigrp_metrics {
|
||||
};
|
||||
|
||||
struct eigrp {
|
||||
vrf_id_t vrf_id;
|
||||
|
||||
uint16_t AS; /* Autonomous system number */
|
||||
uint16_t vrid; /* Virtual Router ID */
|
||||
uint8_t k_values[6]; /*Array for K values configuration*/
|
||||
@ -85,7 +87,7 @@ struct eigrp {
|
||||
struct list *eiflist; /* eigrp interfaces */
|
||||
uint8_t passive_interface_default; /* passive-interface default */
|
||||
|
||||
unsigned int fd;
|
||||
int fd;
|
||||
unsigned int maxsndbuflen;
|
||||
|
||||
uint32_t sequence_number; /*Global EIGRP sequence number*/
|
||||
|
@ -117,9 +117,9 @@ struct eigrp_nexthop_entry *eigrp_nexthop_entry_new(void)
|
||||
/*
|
||||
* Freeing topology table list
|
||||
*/
|
||||
void eigrp_topology_free(struct route_table *table)
|
||||
void eigrp_topology_free(struct eigrp *eigrp, struct route_table *table)
|
||||
{
|
||||
eigrp_topology_delete_all(table);
|
||||
eigrp_topology_delete_all(eigrp, table);
|
||||
route_table_finish(table);
|
||||
}
|
||||
|
||||
@ -150,7 +150,8 @@ void eigrp_prefix_entry_add(struct route_table *topology,
|
||||
/*
|
||||
* Adding topology entry to topology node
|
||||
*/
|
||||
void eigrp_nexthop_entry_add(struct eigrp_prefix_entry *node,
|
||||
void eigrp_nexthop_entry_add(struct eigrp *eigrp,
|
||||
struct eigrp_prefix_entry *node,
|
||||
struct eigrp_nexthop_entry *entry)
|
||||
{
|
||||
struct list *l = list_new();
|
||||
@ -161,7 +162,8 @@ void eigrp_nexthop_entry_add(struct eigrp_prefix_entry *node,
|
||||
listnode_add_sort(node->entries, entry);
|
||||
entry->prefix = node;
|
||||
|
||||
eigrp_zebra_route_add(node->destination, l, node->fdistance);
|
||||
eigrp_zebra_route_add(eigrp, node->destination,
|
||||
l, node->fdistance);
|
||||
}
|
||||
|
||||
list_delete(&l);
|
||||
@ -170,10 +172,9 @@ void eigrp_nexthop_entry_add(struct eigrp_prefix_entry *node,
|
||||
/*
|
||||
* Deleting topology node from topology table
|
||||
*/
|
||||
void eigrp_prefix_entry_delete(struct route_table *table,
|
||||
void eigrp_prefix_entry_delete(struct eigrp *eigrp, struct route_table *table,
|
||||
struct eigrp_prefix_entry *pe)
|
||||
{
|
||||
struct eigrp *eigrp = eigrp_lookup();
|
||||
struct eigrp_nexthop_entry *ne;
|
||||
struct listnode *node, *nnode;
|
||||
struct route_node *rn;
|
||||
@ -192,10 +193,10 @@ void eigrp_prefix_entry_delete(struct route_table *table,
|
||||
listnode_delete(eigrp->topology_changes_internalIPV4, pe);
|
||||
|
||||
for (ALL_LIST_ELEMENTS(pe->entries, node, nnode, ne))
|
||||
eigrp_nexthop_entry_delete(pe, ne);
|
||||
eigrp_nexthop_entry_delete(eigrp, pe, ne);
|
||||
list_delete(&pe->entries);
|
||||
list_delete(&pe->rij);
|
||||
eigrp_zebra_route_delete(pe->destination);
|
||||
eigrp_zebra_route_delete(eigrp, pe->destination);
|
||||
prefix_free(pe->destination);
|
||||
|
||||
rn->info = NULL;
|
||||
@ -207,12 +208,13 @@ void eigrp_prefix_entry_delete(struct route_table *table,
|
||||
/*
|
||||
* Deleting topology entry from topology node
|
||||
*/
|
||||
void eigrp_nexthop_entry_delete(struct eigrp_prefix_entry *node,
|
||||
void eigrp_nexthop_entry_delete(struct eigrp *eigrp,
|
||||
struct eigrp_prefix_entry *node,
|
||||
struct eigrp_nexthop_entry *entry)
|
||||
{
|
||||
if (listnode_lookup(node->entries, entry) != NULL) {
|
||||
listnode_delete(node->entries, entry);
|
||||
eigrp_zebra_route_delete(node->destination);
|
||||
eigrp_zebra_route_delete(eigrp, node->destination);
|
||||
XFREE(MTYPE_EIGRP_NEXTHOP_ENTRY, entry);
|
||||
}
|
||||
}
|
||||
@ -220,7 +222,8 @@ void eigrp_nexthop_entry_delete(struct eigrp_prefix_entry *node,
|
||||
/*
|
||||
* Deleting all nodes from topology table
|
||||
*/
|
||||
void eigrp_topology_delete_all(struct route_table *topology)
|
||||
void eigrp_topology_delete_all(struct eigrp *eigrp,
|
||||
struct route_table *topology)
|
||||
{
|
||||
struct route_node *rn;
|
||||
struct eigrp_prefix_entry *pe;
|
||||
@ -231,7 +234,7 @@ void eigrp_topology_delete_all(struct route_table *topology)
|
||||
if (!pe)
|
||||
continue;
|
||||
|
||||
eigrp_prefix_entry_delete(topology, pe);
|
||||
eigrp_prefix_entry_delete(eigrp, topology, pe);
|
||||
}
|
||||
}
|
||||
|
||||
@ -426,17 +429,15 @@ void eigrp_topology_update_all_node_flags(struct eigrp *eigrp)
|
||||
if (!pe)
|
||||
continue;
|
||||
|
||||
eigrp_topology_update_node_flags(pe);
|
||||
eigrp_topology_update_node_flags(eigrp, pe);
|
||||
}
|
||||
}
|
||||
|
||||
void eigrp_topology_update_node_flags(struct eigrp_prefix_entry *dest)
|
||||
void eigrp_topology_update_node_flags(struct eigrp *eigrp,
|
||||
struct eigrp_prefix_entry *dest)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct eigrp_nexthop_entry *entry;
|
||||
struct eigrp *eigrp = eigrp_lookup();
|
||||
|
||||
assert(eigrp);
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(dest->entries, node, entry)) {
|
||||
if (entry->reported_distance < dest->fdistance) {
|
||||
@ -464,27 +465,24 @@ void eigrp_topology_update_node_flags(struct eigrp_prefix_entry *dest)
|
||||
}
|
||||
}
|
||||
|
||||
void eigrp_update_routing_table(struct eigrp_prefix_entry *prefix)
|
||||
void eigrp_update_routing_table(struct eigrp *eigrp,
|
||||
struct eigrp_prefix_entry *prefix)
|
||||
{
|
||||
struct eigrp *eigrp = eigrp_lookup();
|
||||
struct list *successors;
|
||||
struct listnode *node;
|
||||
struct eigrp_nexthop_entry *entry;
|
||||
|
||||
if (!eigrp)
|
||||
return;
|
||||
|
||||
successors = eigrp_topology_get_successor_max(prefix, eigrp->max_paths);
|
||||
|
||||
if (successors) {
|
||||
eigrp_zebra_route_add(prefix->destination, successors,
|
||||
eigrp_zebra_route_add(eigrp, prefix->destination, successors,
|
||||
prefix->fdistance);
|
||||
for (ALL_LIST_ELEMENTS_RO(successors, node, entry))
|
||||
entry->flags |= EIGRP_NEXTHOP_ENTRY_INTABLE_FLAG;
|
||||
|
||||
list_delete(&successors);
|
||||
} else {
|
||||
eigrp_zebra_route_delete(prefix->destination);
|
||||
eigrp_zebra_route_delete(eigrp, prefix->destination);
|
||||
for (ALL_LIST_ELEMENTS_RO(prefix->entries, node, entry))
|
||||
entry->flags &= ~EIGRP_NEXTHOP_ENTRY_INTABLE_FLAG;
|
||||
}
|
||||
@ -525,7 +523,8 @@ void eigrp_topology_neighbor_down(struct eigrp *eigrp,
|
||||
eigrp_update_send_all(eigrp, nbr->ei);
|
||||
}
|
||||
|
||||
void eigrp_update_topology_table_prefix(struct route_table *table,
|
||||
void eigrp_update_topology_table_prefix(struct eigrp *eigrp,
|
||||
struct route_table *table,
|
||||
struct eigrp_prefix_entry *prefix)
|
||||
{
|
||||
struct listnode *node1, *node2;
|
||||
@ -533,11 +532,11 @@ void eigrp_update_topology_table_prefix(struct route_table *table,
|
||||
struct eigrp_nexthop_entry *entry;
|
||||
for (ALL_LIST_ELEMENTS(prefix->entries, node1, node2, entry)) {
|
||||
if (entry->distance == EIGRP_MAX_METRIC) {
|
||||
eigrp_nexthop_entry_delete(prefix, entry);
|
||||
eigrp_nexthop_entry_delete(eigrp, prefix, entry);
|
||||
}
|
||||
}
|
||||
if (prefix->distance == EIGRP_MAX_METRIC
|
||||
&& prefix->nt != EIGRP_TOPOLOGY_TYPE_CONNECTED) {
|
||||
eigrp_prefix_entry_delete(table, prefix);
|
||||
eigrp_prefix_entry_delete(eigrp, table, prefix);
|
||||
}
|
||||
}
|
||||
|
@ -37,34 +37,41 @@ extern struct route_table *eigrp_topology_new(void);
|
||||
extern void eigrp_topology_init(struct route_table *table);
|
||||
extern struct eigrp_prefix_entry *eigrp_prefix_entry_new(void);
|
||||
extern struct eigrp_nexthop_entry *eigrp_nexthop_entry_new(void);
|
||||
extern void eigrp_topology_free(struct route_table *table);
|
||||
extern void eigrp_topology_free(struct eigrp *eigrp, struct route_table *table);
|
||||
extern void eigrp_prefix_entry_add(struct route_table *table,
|
||||
struct eigrp_prefix_entry *pe);
|
||||
extern void eigrp_nexthop_entry_add(struct eigrp_prefix_entry *,
|
||||
struct eigrp_nexthop_entry *);
|
||||
extern void eigrp_prefix_entry_delete(struct route_table *table,
|
||||
extern void eigrp_nexthop_entry_add(struct eigrp *eigrp,
|
||||
struct eigrp_prefix_entry *pe,
|
||||
struct eigrp_nexthop_entry *ne);
|
||||
extern void eigrp_prefix_entry_delete(struct eigrp *eigrp,
|
||||
struct route_table *table,
|
||||
struct eigrp_prefix_entry *pe);
|
||||
extern void eigrp_nexthop_entry_delete(struct eigrp_prefix_entry *,
|
||||
struct eigrp_nexthop_entry *);
|
||||
extern void eigrp_topology_delete_all(struct route_table *table);
|
||||
extern void eigrp_nexthop_entry_delete(struct eigrp *eigrp,
|
||||
struct eigrp_prefix_entry *pe,
|
||||
struct eigrp_nexthop_entry *ne);
|
||||
extern void eigrp_topology_delete_all(struct eigrp *eigrp,
|
||||
struct route_table *table);
|
||||
extern struct eigrp_prefix_entry *
|
||||
eigrp_topology_table_lookup_ipv4(struct route_table *table, struct prefix *p);
|
||||
extern struct list *eigrp_topology_get_successor(struct eigrp_prefix_entry *);
|
||||
extern struct list *eigrp_topology_get_successor(struct eigrp_prefix_entry *pe);
|
||||
extern struct list *
|
||||
eigrp_topology_get_successor_max(struct eigrp_prefix_entry *pe,
|
||||
unsigned int maxpaths);
|
||||
extern struct eigrp_nexthop_entry *
|
||||
eigrp_prefix_entry_lookup(struct list *, struct eigrp_neighbor *);
|
||||
extern struct list *eigrp_neighbor_prefixes_lookup(struct eigrp *,
|
||||
struct eigrp_neighbor *);
|
||||
extern void eigrp_topology_update_all_node_flags(struct eigrp *);
|
||||
extern void eigrp_topology_update_node_flags(struct eigrp_prefix_entry *);
|
||||
eigrp_prefix_entry_lookup(struct list *entries, struct eigrp_neighbor *neigh);
|
||||
extern struct list *eigrp_neighbor_prefixes_lookup(struct eigrp *eigrp,
|
||||
struct eigrp_neighbor *n);
|
||||
extern void eigrp_topology_update_all_node_flags(struct eigrp *eigrp);
|
||||
extern void eigrp_topology_update_node_flags(struct eigrp *eigrp,
|
||||
struct eigrp_prefix_entry *pe);
|
||||
extern enum metric_change
|
||||
eigrp_topology_update_distance(struct eigrp_fsm_action_message *);
|
||||
extern void eigrp_update_routing_table(struct eigrp_prefix_entry *);
|
||||
extern void eigrp_topology_neighbor_down(struct eigrp *,
|
||||
struct eigrp_neighbor *);
|
||||
extern void eigrp_update_topology_table_prefix(struct route_table *table,
|
||||
eigrp_topology_update_distance(struct eigrp_fsm_action_message *msg);
|
||||
extern void eigrp_update_routing_table(struct eigrp *eigrp,
|
||||
struct eigrp_prefix_entry *pe);
|
||||
extern void eigrp_topology_neighbor_down(struct eigrp *eigrp,
|
||||
struct eigrp_neighbor *neigh);
|
||||
extern void eigrp_update_topology_table_prefix(struct eigrp *eigrp,
|
||||
struct route_table *table,
|
||||
struct eigrp_prefix_entry *pe);
|
||||
|
||||
#endif
|
||||
|
@ -211,7 +211,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
|
||||
zlog_debug(
|
||||
"Processing Update size[%u] int(%s) nbr(%s) seq [%u] flags [%0x]",
|
||||
size,
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT),
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id),
|
||||
inet_ntoa(nbr->src), nbr->recv_sequence_number, flags);
|
||||
|
||||
|
||||
@ -221,7 +221,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
|
||||
|
||||
zlog_info("Neighbor %s (%s) is resync: peer graceful-restart",
|
||||
inet_ntoa(nbr->src),
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT));
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id));
|
||||
|
||||
/* get all prefixes from neighbor from topology table */
|
||||
nbr_prefixes = eigrp_neighbor_prefixes_lookup(eigrp, nbr);
|
||||
@ -233,7 +233,7 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
|
||||
|
||||
zlog_info("Neighbor %s (%s) is resync: peer graceful-restart",
|
||||
inet_ntoa(nbr->src),
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex, VRF_DEFAULT));
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id));
|
||||
|
||||
/* get all prefixes from neighbor from topology table */
|
||||
nbr_prefixes = eigrp_neighbor_prefixes_lookup(eigrp, nbr);
|
||||
@ -282,12 +282,12 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
|
||||
zlog_info("Neighbor %s (%s) is down: peer restarted",
|
||||
inet_ntoa(nbr->src),
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex,
|
||||
VRF_DEFAULT));
|
||||
eigrp->vrf_id));
|
||||
eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_PENDING);
|
||||
zlog_info("Neighbor %s (%s) is pending: new adjacency",
|
||||
inet_ntoa(nbr->src),
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex,
|
||||
VRF_DEFAULT));
|
||||
eigrp->vrf_id));
|
||||
eigrp_update_send_init(nbr);
|
||||
}
|
||||
}
|
||||
@ -366,11 +366,11 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
|
||||
|
||||
eigrp_prefix_entry_add(eigrp->topology_table,
|
||||
pe);
|
||||
eigrp_nexthop_entry_add(pe, ne);
|
||||
eigrp_nexthop_entry_add(eigrp, pe, ne);
|
||||
pe->distance = pe->fdistance = pe->rdistance =
|
||||
ne->distance;
|
||||
pe->reported_metric = ne->total_metric;
|
||||
eigrp_topology_update_node_flags(pe);
|
||||
eigrp_topology_update_node_flags(eigrp, pe);
|
||||
|
||||
pe->req_action |= EIGRP_FSM_NEED_UPDATE;
|
||||
listnode_add(
|
||||
@ -965,19 +965,20 @@ void eigrp_update_send_GR(struct eigrp_neighbor *nbr, enum GR_type gr_type,
|
||||
zlog_info(
|
||||
"Neighbor %s (%s) is resync: route configuration changed",
|
||||
inet_ntoa(nbr->src),
|
||||
ifindex2ifname(ei->ifp->ifindex, VRF_DEFAULT));
|
||||
ifindex2ifname(ei->ifp->ifindex, eigrp->vrf_id));
|
||||
} else if (gr_type == EIGRP_GR_MANUAL) {
|
||||
/* Graceful restart was called manually */
|
||||
zlog_info("Neighbor %s (%s) is resync: manually cleared",
|
||||
inet_ntoa(nbr->src),
|
||||
ifindex2ifname(ei->ifp->ifindex, VRF_DEFAULT));
|
||||
ifindex2ifname(ei->ifp->ifindex, eigrp->vrf_id));
|
||||
|
||||
if (vty != NULL) {
|
||||
vty_time_print(vty, 0);
|
||||
vty_out(vty,
|
||||
"Neighbor %s (%s) is resync: manually cleared\n",
|
||||
inet_ntoa(nbr->src),
|
||||
ifindex2ifname(ei->ifp->ifindex, VRF_DEFAULT));
|
||||
ifindex2ifname(ei->ifp->ifindex,
|
||||
eigrp->vrf_id));
|
||||
}
|
||||
}
|
||||
|
||||
|
50
eigrpd/eigrp_vrf.c
Normal file
50
eigrpd/eigrp_vrf.c
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* eigrp - vrf code
|
||||
* Copyright (C) 2019 Cumulus Networks, Inc.
|
||||
* Donald Sharp
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; see the file COPYING; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <zebra.h>
|
||||
|
||||
#include "vrf.h"
|
||||
|
||||
#include "eigrpd/eigrp_vrf.h"
|
||||
|
||||
static int eigrp_vrf_new(struct vrf *vrf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eigrp_vrf_enable(struct vrf *vrf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eigrp_vrf_disable(struct vrf *vrf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int eigrp_vrf_delete(struct vrf *vrf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void eigrp_vrf_init(void)
|
||||
{
|
||||
vrf_init(eigrp_vrf_new, eigrp_vrf_enable,
|
||||
eigrp_vrf_disable, eigrp_vrf_delete, NULL);
|
||||
}
|
23
eigrpd/eigrp_vrf.h
Normal file
23
eigrpd/eigrp_vrf.h
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* eigrp - vrf code
|
||||
* Copyright (C) 2019 Cumulus Networks, Inc.
|
||||
* Donald Sharp
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; see the file COPYING; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef __EIGRP_VRF_H__
|
||||
|
||||
extern void eigrp_vrf_init(void);
|
||||
#endif
|
@ -83,12 +83,31 @@ static void eigrp_vty_display_prefix_entry(struct vty *vty,
|
||||
}
|
||||
}
|
||||
|
||||
static struct eigrp *eigrp_vty_get_eigrp(struct vty *vty, const char *vrf_name)
|
||||
{
|
||||
struct vrf *vrf;
|
||||
|
||||
if (vrf_name)
|
||||
vrf = vrf_lookup_by_name(vrf_name);
|
||||
else
|
||||
vrf = vrf_lookup_by_id(VRF_DEFAULT);
|
||||
|
||||
if (!vrf) {
|
||||
vty_out(vty, "VRF %s specified does not exist",
|
||||
vrf_name ? vrf_name : VRF_DEFAULT_NAME);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return eigrp_lookup(vrf->vrf_id);
|
||||
}
|
||||
|
||||
DEFPY (show_ip_eigrp_topology_all,
|
||||
show_ip_eigrp_topology_all_cmd,
|
||||
"show ip eigrp topology [all-links$all]",
|
||||
"show ip eigrp [vrf NAME] topology [all-links$all]",
|
||||
SHOW_STR
|
||||
IP_STR
|
||||
"IP-EIGRP show commands\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"IP-EIGRP topology\n"
|
||||
"Show all links in topology table\n")
|
||||
{
|
||||
@ -96,7 +115,7 @@ DEFPY (show_ip_eigrp_topology_all,
|
||||
struct eigrp_prefix_entry *tn;
|
||||
struct route_node *rn;
|
||||
|
||||
eigrp = eigrp_lookup();
|
||||
eigrp = eigrp_vty_get_eigrp(vty, vrf);
|
||||
if (eigrp == NULL) {
|
||||
vty_out(vty, " EIGRP Routing Process not enabled\n");
|
||||
return CMD_SUCCESS;
|
||||
@ -119,10 +138,11 @@ DEFPY (show_ip_eigrp_topology_all,
|
||||
|
||||
DEFPY (show_ip_eigrp_topology,
|
||||
show_ip_eigrp_topology_cmd,
|
||||
"show ip eigrp topology <A.B.C.D$address|A.B.C.D/M$prefix>",
|
||||
"show ip eigrp [vrf NAME] topology <A.B.C.D$address|A.B.C.D/M$prefix>",
|
||||
SHOW_STR
|
||||
IP_STR
|
||||
"IP-EIGRP show commands\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"IP-EIGRP topology\n"
|
||||
"For a specific address\n"
|
||||
"For a specific prefix\n")
|
||||
@ -132,7 +152,7 @@ DEFPY (show_ip_eigrp_topology,
|
||||
struct route_node *rn;
|
||||
struct prefix cmp;
|
||||
|
||||
eigrp = eigrp_lookup();
|
||||
eigrp = eigrp_vty_get_eigrp(vty, vrf);
|
||||
if (eigrp == NULL) {
|
||||
vty_out(vty, " EIGRP Routing Process not enabled\n");
|
||||
return CMD_SUCCESS;
|
||||
@ -167,12 +187,13 @@ DEFPY (show_ip_eigrp_topology,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_ip_eigrp_interfaces,
|
||||
DEFPY (show_ip_eigrp_interfaces,
|
||||
show_ip_eigrp_interfaces_cmd,
|
||||
"show ip eigrp interfaces [IFNAME] [detail]",
|
||||
"show ip eigrp [vrf NAME] interfaces [IFNAME] [detail]$detail",
|
||||
SHOW_STR
|
||||
IP_STR
|
||||
"IP-EIGRP show commands\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"IP-EIGRP interfaces\n"
|
||||
"Interface name to look at\n"
|
||||
"Detailed information\n")
|
||||
@ -180,22 +201,13 @@ DEFUN (show_ip_eigrp_interfaces,
|
||||
struct eigrp_interface *ei;
|
||||
struct eigrp *eigrp;
|
||||
struct listnode *node;
|
||||
int idx = 0;
|
||||
bool detail = false;
|
||||
const char *ifname = NULL;
|
||||
|
||||
eigrp = eigrp_lookup();
|
||||
eigrp = eigrp_vty_get_eigrp(vty, vrf);
|
||||
if (eigrp == NULL) {
|
||||
vty_out(vty, "EIGRP Routing Process not enabled\n");
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
if (argv_find(argv, argc, "IFNAME", &idx))
|
||||
ifname = argv[idx]->arg;
|
||||
|
||||
if (argv_find(argv, argc, "detail", &idx))
|
||||
detail = true;
|
||||
|
||||
if (!ifname)
|
||||
show_ip_eigrp_interface_header(vty, eigrp);
|
||||
|
||||
@ -210,12 +222,13 @@ DEFUN (show_ip_eigrp_interfaces,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (show_ip_eigrp_neighbors,
|
||||
DEFPY (show_ip_eigrp_neighbors,
|
||||
show_ip_eigrp_neighbors_cmd,
|
||||
"show ip eigrp neighbors [IFNAME] [detail]",
|
||||
"show ip eigrp [vrf NAME] neighbors [IFNAME] [detail]$detail",
|
||||
SHOW_STR
|
||||
IP_STR
|
||||
"IP-EIGRP show commands\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"IP-EIGRP neighbors\n"
|
||||
"Interface to show on\n"
|
||||
"Detailed Information\n")
|
||||
@ -224,21 +237,13 @@ DEFUN (show_ip_eigrp_neighbors,
|
||||
struct eigrp_interface *ei;
|
||||
struct listnode *node, *node2, *nnode2;
|
||||
struct eigrp_neighbor *nbr;
|
||||
bool detail = false;
|
||||
int idx = 0;
|
||||
const char *ifname = NULL;
|
||||
|
||||
eigrp = eigrp_lookup();
|
||||
eigrp = eigrp_vty_get_eigrp(vty, vrf);
|
||||
if (eigrp == NULL) {
|
||||
vty_out(vty, " EIGRP Routing Process not enabled\n");
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
if (argv_find(argv, argc, "IFNAME", &idx))
|
||||
ifname = argv[idx]->arg;
|
||||
|
||||
detail = (argv_find(argv, argc, "detail", &idx));
|
||||
|
||||
show_ip_eigrp_neighbor_header(vty, eigrp);
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(eigrp->eiflist, node, ei)) {
|
||||
@ -246,7 +251,7 @@ DEFUN (show_ip_eigrp_neighbors,
|
||||
for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
|
||||
if (detail || (nbr->state == EIGRP_NEIGHBOR_UP))
|
||||
show_ip_eigrp_neighbor_sub(vty, nbr,
|
||||
detail);
|
||||
!!detail);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -257,12 +262,13 @@ DEFUN (show_ip_eigrp_neighbors,
|
||||
/*
|
||||
* Execute hard restart for all neighbors
|
||||
*/
|
||||
DEFUN (clear_ip_eigrp_neighbors,
|
||||
DEFPY (clear_ip_eigrp_neighbors,
|
||||
clear_ip_eigrp_neighbors_cmd,
|
||||
"clear ip eigrp neighbors",
|
||||
"clear ip eigrp [vrf NAME] neighbors",
|
||||
CLEAR_STR
|
||||
IP_STR
|
||||
"Clear IP-EIGRP\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Clear IP-EIGRP neighbors\n")
|
||||
{
|
||||
struct eigrp *eigrp;
|
||||
@ -271,7 +277,7 @@ DEFUN (clear_ip_eigrp_neighbors,
|
||||
struct eigrp_neighbor *nbr;
|
||||
|
||||
/* Check if eigrp process is enabled */
|
||||
eigrp = eigrp_lookup();
|
||||
eigrp = eigrp_vty_get_eigrp(vty, vrf);
|
||||
if (eigrp == NULL) {
|
||||
vty_out(vty, " EIGRP Routing Process not enabled\n");
|
||||
return CMD_SUCCESS;
|
||||
@ -289,13 +295,13 @@ DEFUN (clear_ip_eigrp_neighbors,
|
||||
"Neighbor %s (%s) is down: manually cleared",
|
||||
inet_ntoa(nbr->src),
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex,
|
||||
VRF_DEFAULT));
|
||||
eigrp->vrf_id));
|
||||
vty_time_print(vty, 0);
|
||||
vty_out(vty,
|
||||
"Neighbor %s (%s) is down: manually cleared\n",
|
||||
inet_ntoa(nbr->src),
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex,
|
||||
VRF_DEFAULT));
|
||||
eigrp->vrf_id));
|
||||
|
||||
/* set neighbor to DOWN */
|
||||
nbr->state = EIGRP_NEIGHBOR_DOWN;
|
||||
@ -311,12 +317,13 @@ DEFUN (clear_ip_eigrp_neighbors,
|
||||
/*
|
||||
* Execute hard restart for all neighbors on interface
|
||||
*/
|
||||
DEFUN (clear_ip_eigrp_neighbors_int,
|
||||
DEFPY (clear_ip_eigrp_neighbors_int,
|
||||
clear_ip_eigrp_neighbors_int_cmd,
|
||||
"clear ip eigrp neighbors IFNAME",
|
||||
"clear ip eigrp [vrf NAME] neighbors IFNAME",
|
||||
CLEAR_STR
|
||||
IP_STR
|
||||
"Clear IP-EIGRP\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Clear IP-EIGRP neighbors\n"
|
||||
"Interface's name\n")
|
||||
{
|
||||
@ -324,20 +331,18 @@ DEFUN (clear_ip_eigrp_neighbors_int,
|
||||
struct eigrp_interface *ei;
|
||||
struct listnode *node2, *nnode2;
|
||||
struct eigrp_neighbor *nbr;
|
||||
int idx = 0;
|
||||
|
||||
/* Check if eigrp process is enabled */
|
||||
eigrp = eigrp_lookup();
|
||||
eigrp = eigrp_vty_get_eigrp(vty, vrf);
|
||||
if (eigrp == NULL) {
|
||||
vty_out(vty, " EIGRP Routing Process not enabled\n");
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* lookup interface by specified name */
|
||||
argv_find(argv, argc, "IFNAME", &idx);
|
||||
ei = eigrp_if_lookup_by_name(eigrp, argv[idx]->arg);
|
||||
ei = eigrp_if_lookup_by_name(eigrp, ifname);
|
||||
if (ei == NULL) {
|
||||
vty_out(vty, " Interface (%s) doesn't exist\n", argv[idx]->arg);
|
||||
vty_out(vty, " Interface (%s) doesn't exist\n", ifname);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
@ -350,13 +355,13 @@ DEFUN (clear_ip_eigrp_neighbors_int,
|
||||
zlog_debug("Neighbor %s (%s) is down: manually cleared",
|
||||
inet_ntoa(nbr->src),
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex,
|
||||
VRF_DEFAULT));
|
||||
eigrp->vrf_id));
|
||||
vty_time_print(vty, 0);
|
||||
vty_out(vty,
|
||||
"Neighbor %s (%s) is down: manually cleared\n",
|
||||
inet_ntoa(nbr->src),
|
||||
ifindex2ifname(nbr->ei->ifp->ifindex,
|
||||
VRF_DEFAULT));
|
||||
eigrp->vrf_id));
|
||||
|
||||
/* set neighbor to DOWN */
|
||||
nbr->state = EIGRP_NEIGHBOR_DOWN;
|
||||
@ -371,26 +376,21 @@ DEFUN (clear_ip_eigrp_neighbors_int,
|
||||
/*
|
||||
* Execute hard restart for neighbor specified by IP
|
||||
*/
|
||||
DEFUN (clear_ip_eigrp_neighbors_IP,
|
||||
DEFPY (clear_ip_eigrp_neighbors_IP,
|
||||
clear_ip_eigrp_neighbors_IP_cmd,
|
||||
"clear ip eigrp neighbors A.B.C.D",
|
||||
"clear ip eigrp [vrf NAME] neighbors A.B.C.D$nbr_addr",
|
||||
CLEAR_STR
|
||||
IP_STR
|
||||
"Clear IP-EIGRP\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Clear IP-EIGRP neighbors\n"
|
||||
"IP-EIGRP neighbor address\n")
|
||||
{
|
||||
struct eigrp *eigrp;
|
||||
struct eigrp_neighbor *nbr;
|
||||
struct in_addr nbr_addr;
|
||||
|
||||
if (!inet_aton(argv[4]->arg, &nbr_addr)) {
|
||||
vty_out(vty, "Unable to parse %s", argv[4]->arg);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* Check if eigrp process is enabled */
|
||||
eigrp = eigrp_lookup();
|
||||
eigrp = eigrp_vty_get_eigrp(vty, vrf);
|
||||
if (eigrp == NULL) {
|
||||
vty_out(vty, " EIGRP Routing Process not enabled\n");
|
||||
return CMD_SUCCESS;
|
||||
@ -414,19 +414,20 @@ DEFUN (clear_ip_eigrp_neighbors_IP,
|
||||
/*
|
||||
* Execute graceful restart for all neighbors
|
||||
*/
|
||||
DEFUN (clear_ip_eigrp_neighbors_soft,
|
||||
DEFPY (clear_ip_eigrp_neighbors_soft,
|
||||
clear_ip_eigrp_neighbors_soft_cmd,
|
||||
"clear ip eigrp neighbors soft",
|
||||
"clear ip eigrp [vrf NAME] neighbors soft",
|
||||
CLEAR_STR
|
||||
IP_STR
|
||||
"Clear IP-EIGRP\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Clear IP-EIGRP neighbors\n"
|
||||
"Resync with peers without adjacency reset\n")
|
||||
{
|
||||
struct eigrp *eigrp;
|
||||
|
||||
/* Check if eigrp process is enabled */
|
||||
eigrp = eigrp_lookup();
|
||||
eigrp = eigrp_vty_get_eigrp(vty, vrf);
|
||||
if (eigrp == NULL) {
|
||||
vty_out(vty, " EIGRP Routing Process not enabled\n");
|
||||
return CMD_SUCCESS;
|
||||
@ -441,12 +442,13 @@ DEFUN (clear_ip_eigrp_neighbors_soft,
|
||||
/*
|
||||
* Execute graceful restart for all neighbors on interface
|
||||
*/
|
||||
DEFUN (clear_ip_eigrp_neighbors_int_soft,
|
||||
DEFPY (clear_ip_eigrp_neighbors_int_soft,
|
||||
clear_ip_eigrp_neighbors_int_soft_cmd,
|
||||
"clear ip eigrp neighbors IFNAME soft",
|
||||
"clear ip eigrp [vrf NAME] neighbors IFNAME soft",
|
||||
CLEAR_STR
|
||||
IP_STR
|
||||
"Clear IP-EIGRP\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Clear IP-EIGRP neighbors\n"
|
||||
"Interface's name\n"
|
||||
"Resync with peer without adjacency reset\n")
|
||||
@ -455,14 +457,14 @@ DEFUN (clear_ip_eigrp_neighbors_int_soft,
|
||||
struct eigrp_interface *ei;
|
||||
|
||||
/* Check if eigrp process is enabled */
|
||||
eigrp = eigrp_lookup();
|
||||
eigrp = eigrp_vty_get_eigrp(vty, vrf);
|
||||
if (eigrp == NULL) {
|
||||
vty_out(vty, " EIGRP Routing Process not enabled\n");
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* lookup interface by specified name */
|
||||
ei = eigrp_if_lookup_by_name(eigrp, argv[4]->arg);
|
||||
ei = eigrp_if_lookup_by_name(eigrp, ifname);
|
||||
if (ei == NULL) {
|
||||
vty_out(vty, " Interface (%s) doesn't exist\n", argv[4]->arg);
|
||||
return CMD_WARNING;
|
||||
@ -476,27 +478,23 @@ DEFUN (clear_ip_eigrp_neighbors_int_soft,
|
||||
/*
|
||||
* Execute graceful restart for neighbor specified by IP
|
||||
*/
|
||||
DEFUN (clear_ip_eigrp_neighbors_IP_soft,
|
||||
DEFPY (clear_ip_eigrp_neighbors_IP_soft,
|
||||
clear_ip_eigrp_neighbors_IP_soft_cmd,
|
||||
"clear ip eigrp neighbors A.B.C.D soft",
|
||||
"clear ip eigrp [vrf NAME] neighbors A.B.C.D$nbr_addr soft",
|
||||
CLEAR_STR
|
||||
IP_STR
|
||||
"Clear IP-EIGRP\n"
|
||||
VRF_CMD_HELP_STR
|
||||
"Clear IP-EIGRP neighbors\n"
|
||||
"IP-EIGRP neighbor address\n"
|
||||
"Resync with peer without adjacency reset\n")
|
||||
{
|
||||
struct eigrp *eigrp;
|
||||
struct eigrp_neighbor *nbr;
|
||||
struct in_addr nbr_addr;
|
||||
|
||||
if (!inet_aton(argv[4]->arg, &nbr_addr)) {
|
||||
vty_out(vty, "Unable to parse: %s", argv[4]->arg);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* Check if eigrp process is enabled */
|
||||
eigrp = eigrp_lookup();
|
||||
eigrp = eigrp_vty_get_eigrp(vty, vrf);
|
||||
if (eigrp == NULL) {
|
||||
vty_out(vty, " EIGRP Routing Process not enabled\n");
|
||||
return CMD_SUCCESS;
|
||||
|
@ -59,7 +59,8 @@ static int eigrp_interface_address_add(ZAPI_CALLBACK_ARGS);
|
||||
static int eigrp_interface_address_delete(ZAPI_CALLBACK_ARGS);
|
||||
static int eigrp_interface_state_up(ZAPI_CALLBACK_ARGS);
|
||||
static int eigrp_interface_state_down(ZAPI_CALLBACK_ARGS);
|
||||
static struct interface *zebra_interface_if_lookup(struct stream *);
|
||||
static struct interface *zebra_interface_if_lookup(struct stream *,
|
||||
vrf_id_t vrf_id);
|
||||
|
||||
static int eigrp_zebra_read_route(ZAPI_CALLBACK_ARGS);
|
||||
|
||||
@ -79,7 +80,7 @@ static int eigrp_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
|
||||
|
||||
router_id_zebra = router_id.u.prefix4;
|
||||
|
||||
eigrp = eigrp_lookup();
|
||||
eigrp = eigrp_lookup(vrf_id);
|
||||
|
||||
if (eigrp != NULL)
|
||||
eigrp_router_id_update(eigrp);
|
||||
@ -137,7 +138,7 @@ static int eigrp_zebra_read_route(ZAPI_CALLBACK_ARGS)
|
||||
if (IPV4_NET127(ntohl(api.prefix.u.prefix4.s_addr)))
|
||||
return 0;
|
||||
|
||||
eigrp = eigrp_lookup();
|
||||
eigrp = eigrp_lookup(vrf_id);
|
||||
if (eigrp == NULL)
|
||||
return 0;
|
||||
|
||||
@ -257,7 +258,7 @@ static int eigrp_interface_state_up(ZAPI_CALLBACK_ARGS)
|
||||
{
|
||||
struct interface *ifp;
|
||||
|
||||
ifp = zebra_interface_if_lookup(zclient->ibuf);
|
||||
ifp = zebra_interface_if_lookup(zclient->ibuf, vrf_id);
|
||||
|
||||
if (ifp == NULL)
|
||||
return 0;
|
||||
@ -328,7 +329,8 @@ static int eigrp_interface_state_down(ZAPI_CALLBACK_ARGS)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct interface *zebra_interface_if_lookup(struct stream *s)
|
||||
static struct interface *zebra_interface_if_lookup(struct stream *s,
|
||||
vrf_id_t vrf_id)
|
||||
{
|
||||
char ifname_tmp[INTERFACE_NAMSIZ];
|
||||
|
||||
@ -336,11 +338,11 @@ static struct interface *zebra_interface_if_lookup(struct stream *s)
|
||||
stream_get(ifname_tmp, s, INTERFACE_NAMSIZ);
|
||||
|
||||
/* And look it up. */
|
||||
return if_lookup_by_name(ifname_tmp, VRF_DEFAULT);
|
||||
return if_lookup_by_name(ifname_tmp, vrf_id);
|
||||
}
|
||||
|
||||
void eigrp_zebra_route_add(struct prefix *p, struct list *successors,
|
||||
uint32_t distance)
|
||||
void eigrp_zebra_route_add(struct eigrp *eigrp, struct prefix *p,
|
||||
struct list *successors, uint32_t distance)
|
||||
{
|
||||
struct zapi_route api;
|
||||
struct zapi_nexthop *api_nh;
|
||||
@ -352,7 +354,7 @@ void eigrp_zebra_route_add(struct prefix *p, struct list *successors,
|
||||
return;
|
||||
|
||||
memset(&api, 0, sizeof(api));
|
||||
api.vrf_id = VRF_DEFAULT;
|
||||
api.vrf_id = eigrp->vrf_id;
|
||||
api.type = ZEBRA_ROUTE_EIGRP;
|
||||
api.safi = SAFI_UNICAST;
|
||||
api.metric = distance;
|
||||
@ -366,7 +368,7 @@ void eigrp_zebra_route_add(struct prefix *p, struct list *successors,
|
||||
if (count >= MULTIPATH_NUM)
|
||||
break;
|
||||
api_nh = &api.nexthops[count];
|
||||
api_nh->vrf_id = VRF_DEFAULT;
|
||||
api_nh->vrf_id = eigrp->vrf_id;
|
||||
if (te->adv_router->src.s_addr) {
|
||||
api_nh->gate.ipv4 = te->adv_router->src;
|
||||
api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
|
||||
@ -388,7 +390,7 @@ void eigrp_zebra_route_add(struct prefix *p, struct list *successors,
|
||||
zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
|
||||
}
|
||||
|
||||
void eigrp_zebra_route_delete(struct prefix *p)
|
||||
void eigrp_zebra_route_delete(struct eigrp *eigrp, struct prefix *p)
|
||||
{
|
||||
struct zapi_route api;
|
||||
|
||||
@ -396,7 +398,7 @@ void eigrp_zebra_route_delete(struct prefix *p)
|
||||
return;
|
||||
|
||||
memset(&api, 0, sizeof(api));
|
||||
api.vrf_id = VRF_DEFAULT;
|
||||
api.vrf_id = eigrp->vrf_id;
|
||||
api.type = ZEBRA_ROUTE_EIGRP;
|
||||
api.safi = SAFI_UNICAST;
|
||||
memcpy(&api.prefix, p, sizeof(*p));
|
||||
@ -411,20 +413,20 @@ void eigrp_zebra_route_delete(struct prefix *p)
|
||||
return;
|
||||
}
|
||||
|
||||
int eigrp_is_type_redistributed(int type)
|
||||
static int eigrp_is_type_redistributed(int type, vrf_id_t vrf_id)
|
||||
{
|
||||
return ((DEFAULT_ROUTE_TYPE(type))
|
||||
? vrf_bitmap_check(zclient->default_information[AFI_IP],
|
||||
VRF_DEFAULT)
|
||||
vrf_id)
|
||||
: vrf_bitmap_check(zclient->redist[AFI_IP][type],
|
||||
VRF_DEFAULT));
|
||||
vrf_id));
|
||||
}
|
||||
|
||||
int eigrp_redistribute_set(struct eigrp *eigrp, int type,
|
||||
struct eigrp_metrics metric)
|
||||
{
|
||||
|
||||
if (eigrp_is_type_redistributed(type)) {
|
||||
if (eigrp_is_type_redistributed(type, eigrp->vrf_id)) {
|
||||
if (eigrp_metrics_is_same(metric, eigrp->dmetric[type])) {
|
||||
eigrp->dmetric[type] = metric;
|
||||
}
|
||||
@ -443,7 +445,7 @@ int eigrp_redistribute_set(struct eigrp *eigrp, int type,
|
||||
eigrp->dmetric[type] = metric;
|
||||
|
||||
zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type, 0,
|
||||
VRF_DEFAULT);
|
||||
eigrp->vrf_id);
|
||||
|
||||
++eigrp->redistribute;
|
||||
|
||||
@ -453,10 +455,10 @@ int eigrp_redistribute_set(struct eigrp *eigrp, int type,
|
||||
int eigrp_redistribute_unset(struct eigrp *eigrp, int type)
|
||||
{
|
||||
|
||||
if (eigrp_is_type_redistributed(type)) {
|
||||
if (eigrp_is_type_redistributed(type, eigrp->vrf_id)) {
|
||||
memset(&eigrp->dmetric[type], 0, sizeof(struct eigrp_metrics));
|
||||
zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP,
|
||||
type, 0, VRF_DEFAULT);
|
||||
type, 0, eigrp->vrf_id);
|
||||
--eigrp->redistribute;
|
||||
}
|
||||
|
||||
|
@ -33,11 +33,10 @@
|
||||
|
||||
extern void eigrp_zebra_init(void);
|
||||
|
||||
extern void eigrp_zebra_route_add(struct prefix *, struct list *,
|
||||
uint32_t distance);
|
||||
extern void eigrp_zebra_route_delete(struct prefix *);
|
||||
extern void eigrp_zebra_route_add(struct eigrp *eigrp, struct prefix *p,
|
||||
struct list *successors, uint32_t distance);
|
||||
extern void eigrp_zebra_route_delete(struct eigrp *eigrp, struct prefix *);
|
||||
extern int eigrp_redistribute_set(struct eigrp *, int, struct eigrp_metrics);
|
||||
extern int eigrp_redistribute_unset(struct eigrp *, int);
|
||||
extern int eigrp_is_type_redistributed(int);
|
||||
|
||||
#endif /* _ZEBRA_EIGRP_ZEBRA_H_ */
|
||||
|
@ -64,8 +64,6 @@ static struct eigrp_master eigrp_master;
|
||||
|
||||
struct eigrp_master *eigrp_om;
|
||||
|
||||
static struct eigrp *eigrp_new(const char *);
|
||||
|
||||
extern struct zclient *zclient;
|
||||
extern struct in_addr router_id_zebra;
|
||||
|
||||
@ -95,7 +93,7 @@ extern struct in_addr router_id_zebra;
|
||||
*/
|
||||
void eigrp_router_id_update(struct eigrp *eigrp)
|
||||
{
|
||||
struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
|
||||
struct vrf *vrf = vrf_lookup_by_id(eigrp->vrf_id);
|
||||
struct interface *ifp;
|
||||
struct in_addr router_id, router_id_old;
|
||||
|
||||
@ -136,14 +134,14 @@ void eigrp_master_init(void)
|
||||
}
|
||||
|
||||
/* Allocate new eigrp structure. */
|
||||
static struct eigrp *eigrp_new(const char *AS)
|
||||
static struct eigrp *eigrp_new(uint16_t as, vrf_id_t vrf_id)
|
||||
{
|
||||
struct eigrp *eigrp = XCALLOC(MTYPE_EIGRP_TOP, sizeof(struct eigrp));
|
||||
int eigrp_socket;
|
||||
|
||||
/* init information relevant to peers */
|
||||
eigrp->vrf_id = vrf_id;
|
||||
eigrp->vrid = 0;
|
||||
eigrp->AS = atoi(AS);
|
||||
eigrp->AS = as;
|
||||
eigrp->router_id.s_addr = 0;
|
||||
eigrp->router_id_static.s_addr = 0;
|
||||
eigrp->sequence_number = 1;
|
||||
@ -161,14 +159,15 @@ static struct eigrp *eigrp_new(const char *AS)
|
||||
eigrp->passive_interface_default = EIGRP_IF_ACTIVE;
|
||||
eigrp->networks = eigrp_topology_new();
|
||||
|
||||
if ((eigrp_socket = eigrp_sock_init()) < 0) {
|
||||
eigrp->fd = eigrp_sock_init(vrf_lookup_by_id(vrf_id));
|
||||
|
||||
if (eigrp->fd < 0) {
|
||||
flog_err_sys(
|
||||
EC_LIB_SOCKET,
|
||||
"eigrp_new: fatal error: eigrp_sock_init was unable to open a socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
eigrp->fd = eigrp_socket;
|
||||
eigrp->maxsndbuflen = getsockopt_so_sendbuf(eigrp->fd);
|
||||
|
||||
eigrp->ibuf = stream_new(EIGRP_PACKET_MAX_LEN + 1);
|
||||
@ -200,16 +199,15 @@ static struct eigrp *eigrp_new(const char *AS)
|
||||
eigrp->routemap[EIGRP_FILTER_OUT] = NULL;
|
||||
|
||||
/* Distribute list install. */
|
||||
eigrp->distribute_ctx = distribute_list_ctx_create(
|
||||
vrf_lookup_by_id(VRF_DEFAULT));
|
||||
eigrp->distribute_ctx =
|
||||
distribute_list_ctx_create(vrf_lookup_by_id(eigrp->vrf_id));
|
||||
distribute_list_add_hook(eigrp->distribute_ctx,
|
||||
eigrp_distribute_update);
|
||||
distribute_list_delete_hook(eigrp->distribute_ctx,
|
||||
eigrp_distribute_update);
|
||||
|
||||
/*
|
||||
eigrp->if_rmap_ctx = if_rmap_ctx_create(
|
||||
VRF_DEFAULT_NAME);
|
||||
eigrp->if_rmap_ctx = if_rmap_ctx_create(eigrp->vrf_id);
|
||||
if_rmap_hook_add (eigrp_if_rmap_update);
|
||||
if_rmap_hook_delete (eigrp_if_rmap_update);
|
||||
*/
|
||||
@ -217,13 +215,13 @@ static struct eigrp *eigrp_new(const char *AS)
|
||||
return eigrp;
|
||||
}
|
||||
|
||||
struct eigrp *eigrp_get(const char *AS)
|
||||
struct eigrp *eigrp_get(uint16_t as, vrf_id_t vrf_id)
|
||||
{
|
||||
struct eigrp *eigrp;
|
||||
|
||||
eigrp = eigrp_lookup();
|
||||
eigrp = eigrp_lookup(vrf_id);
|
||||
if (eigrp == NULL) {
|
||||
eigrp = eigrp_new(AS);
|
||||
eigrp = eigrp_new(as, vrf_id);
|
||||
listnode_add(eigrp_om->eigrp, eigrp);
|
||||
}
|
||||
|
||||
@ -285,7 +283,7 @@ void eigrp_finish_final(struct eigrp *eigrp)
|
||||
list_delete(&eigrp->eiflist);
|
||||
list_delete(&eigrp->oi_write_q);
|
||||
|
||||
eigrp_topology_free(eigrp->topology_table);
|
||||
eigrp_topology_free(eigrp, eigrp->topology_table);
|
||||
|
||||
eigrp_nbr_delete(eigrp->neighbor_self);
|
||||
|
||||
@ -300,10 +298,14 @@ void eigrp_finish_final(struct eigrp *eigrp)
|
||||
}
|
||||
|
||||
/*Look for existing eigrp process*/
|
||||
struct eigrp *eigrp_lookup(void)
|
||||
struct eigrp *eigrp_lookup(vrf_id_t vrf_id)
|
||||
{
|
||||
if (listcount(eigrp_om->eigrp) == 0)
|
||||
return NULL;
|
||||
struct eigrp *eigrp;
|
||||
struct listnode *node, *nnode;
|
||||
|
||||
return listgetdata(listhead(eigrp_om->eigrp));
|
||||
for (ALL_LIST_ELEMENTS(eigrp_om->eigrp, node, nnode, eigrp))
|
||||
if (eigrp->vrf_id == vrf_id)
|
||||
return eigrp;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -48,8 +48,8 @@ extern void eigrp_master_init(void);
|
||||
extern void eigrp_terminate(void);
|
||||
extern void eigrp_finish_final(struct eigrp *);
|
||||
extern void eigrp_finish(struct eigrp *);
|
||||
extern struct eigrp *eigrp_get(const char *);
|
||||
extern struct eigrp *eigrp_lookup(void);
|
||||
extern struct eigrp *eigrp_get(uint16_t as, vrf_id_t vrf_id);
|
||||
extern struct eigrp *eigrp_lookup(vrf_id_t vrf_id);
|
||||
extern void eigrp_router_id_update(struct eigrp *);
|
||||
|
||||
/* eigrp_cli.c */
|
||||
|
@ -35,6 +35,7 @@ eigrpd_libeigrp_a_SOURCES = \
|
||||
eigrpd/eigrp_snmp.c \
|
||||
eigrpd/eigrp_topology.c \
|
||||
eigrpd/eigrp_update.c \
|
||||
eigrpd/eigrp_vrf.c \
|
||||
eigrpd/eigrp_vty.c \
|
||||
eigrpd/eigrp_zebra.c \
|
||||
eigrpd/eigrpd.c \
|
||||
@ -66,6 +67,7 @@ noinst_HEADERS += \
|
||||
eigrpd/eigrp_packet.h \
|
||||
eigrpd/eigrp_snmp.h \
|
||||
eigrpd/eigrp_structs.h \
|
||||
eigrpd/eigrp_vrf.h \
|
||||
eigrpd/eigrp_vty.h \
|
||||
eigrpd/eigrp_zebra.h \
|
||||
# end
|
||||
|
@ -1599,10 +1599,11 @@ DEFUNSH(VTYSH_OSPFD, router_ospf, router_ospf_cmd,
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUNSH(VTYSH_EIGRPD, router_eigrp, router_eigrp_cmd, "router eigrp (1-65535)",
|
||||
DEFUNSH(VTYSH_EIGRPD, router_eigrp, router_eigrp_cmd, "router eigrp (1-65535) [vrf NAME]",
|
||||
"Enable a routing process\n"
|
||||
"Start EIGRP configuration\n"
|
||||
"AS number to use\n")
|
||||
"AS number to use\n"
|
||||
VRF_CMD_HELP_STR)
|
||||
{
|
||||
vty->node = EIGRP_NODE;
|
||||
return CMD_SUCCESS;
|
||||
|
Loading…
Reference in New Issue
Block a user