diff options
author | Renato Westphal <renato@opensourcerouting.org> | 2019-01-04 22:08:10 +0100 |
---|---|---|
committer | Renato Westphal <renato@opensourcerouting.org> | 2019-01-18 19:15:41 +0100 |
commit | 045c5389c26347d47b2af6020c3a122398f13efb (patch) | |
tree | 82470cd9147b5032bac1d74a2e5b0d6eb42722c3 | |
parent | ripd: clear list of peers when RIP is deconfigured (diff) | |
download | frr-045c5389c26347d47b2af6020c3a122398f13efb.tar.xz frr-045c5389c26347d47b2af6020c3a122398f13efb.zip |
ripd: remove the rip global variable
This is the last step to make ripd ready for multi-instance support.
Remove the rip global variable and add a "rip" parameter to all
functions that need to know the RIP instance they are working
on. On some functions, retrieve the RIP instance from the interface
variable when it exists (this assumes interfaces can pertain to
one RIP instance at most, which is ok for VRF support).
In preparation for the next commits (VRF support), add a "vrd_id"
member to the rip structure, and use rip->vrf_id instead of
VRF_DEFAULT wherever possible.
Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
-rw-r--r-- | ripd/rip_interface.c | 134 | ||||
-rw-r--r-- | ripd/rip_main.c | 11 | ||||
-rw-r--r-- | ripd/rip_northbound.c | 146 | ||||
-rw-r--r-- | ripd/rip_offset.c | 18 | ||||
-rw-r--r-- | ripd/rip_peer.c | 25 | ||||
-rw-r--r-- | ripd/rip_snmp.c | 19 | ||||
-rw-r--r-- | ripd/rip_zebra.c | 47 | ||||
-rw-r--r-- | ripd/ripd.c | 343 | ||||
-rw-r--r-- | ripd/ripd.h | 114 |
9 files changed, 538 insertions, 319 deletions
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index 2e432ec79..ca6dea1b3 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -50,9 +50,9 @@ DEFINE_HOOK(rip_ifaddr_del, (struct connected * ifc), (ifc)) static void rip_enable_apply(struct interface *); static void rip_passive_interface_apply(struct interface *); static int rip_if_down(struct interface *ifp); -static int rip_enable_if_lookup(const char *ifname); +static int rip_enable_if_lookup(struct rip *rip, const char *ifname); static int rip_enable_network_lookup2(struct connected *connected); -static void rip_enable_apply_all(void); +static void rip_enable_apply_all(struct rip *rip); const struct message ri_version_msg[] = {{RI_RIP_VERSION_1, "1"}, {RI_RIP_VERSION_2, "2"}, @@ -94,12 +94,17 @@ static int ipv4_multicast_leave(int sock, struct in_addr group, static void rip_interface_reset(struct rip_interface *); /* Allocate new RIP's interface configuration. */ -static struct rip_interface *rip_interface_new(void) +static struct rip_interface *rip_interface_new(struct interface *ifp) { + struct vrf *vrf; struct rip_interface *ri; ri = XCALLOC(MTYPE_RIP_INTERFACE, sizeof(struct rip_interface)); + vrf = vrf_lookup_by_id(ifp->vrf_id); + if (vrf) + ri->rip = vrf->info; + rip_interface_reset(ri); return ri; @@ -199,7 +204,7 @@ static void rip_request_interface(struct interface *ifp) /* If there is no version configuration in the interface, use rip's version setting. */ - vsend = ((ri->ri_send == RI_RIP_UNSPEC) ? rip->version_send + vsend = ((ri->ri_send == RI_RIP_UNSPEC) ? ri->rip->version_send : ri->ri_send); if (vsend & RIPv1) rip_request_interface_send(ifp, RIPv1); @@ -320,9 +325,9 @@ static int rip_if_ipv4_address_check(struct interface *ifp) /* Does this address belongs to me ? */ -int if_check_address(struct in_addr addr) +int if_check_address(struct rip *rip, struct in_addr addr) { - struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); + struct vrf *vrf = vrf_lookup_by_id(rip->vrf_id); struct interface *ifp; FOR_ALL_INTERFACES (vrf, ifp) { @@ -474,9 +479,9 @@ static void rip_interface_clean(struct rip_interface *ri) } } -void rip_interfaces_clean(void) +void rip_interfaces_clean(struct rip *rip) { - struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); + struct vrf *vrf = vrf_lookup_by_id(rip->vrf_id); struct interface *ifp; FOR_ALL_INTERFACES (vrf, ifp) @@ -524,20 +529,22 @@ static void rip_interface_reset(struct rip_interface *ri) int rip_if_down(struct interface *ifp) { + struct rip *rip; struct route_node *rp; struct rip_info *rinfo; struct rip_interface *ri = NULL; struct list *list = NULL; struct listnode *listnode = NULL, *nextnode = NULL; + + ri = ifp->info; + rip = ri->rip; if (rip) { for (rp = route_top(rip->table); rp; rp = route_next(rp)) if ((list = rp->info) != NULL) for (ALL_LIST_ELEMENTS(list, listnode, nextnode, rinfo)) if (rinfo->nh.ifindex == ifp->ifindex) - rip_ecmp_delete(rinfo); - - ri = ifp->info; + rip_ecmp_delete(rip, rinfo); if (ri->running) { if (IS_RIP_DEBUG_EVENT) @@ -555,6 +562,8 @@ int rip_if_down(struct interface *ifp) static void rip_apply_address_add(struct connected *ifc) { + struct rip_interface *ri = ifc->ifp->info; + struct rip *rip = ri->rip; struct prefix_ipv4 address; struct nexthop nh; struct prefix *p; @@ -580,10 +589,11 @@ static void rip_apply_address_add(struct connected *ifc) /* Check if this interface is RIP enabled or not or Check if this address's prefix is RIP enabled */ - if ((rip_enable_if_lookup(ifc->ifp->name) >= 0) + if ((rip_enable_if_lookup(rip, ifc->ifp->name) >= 0) || (rip_enable_network_lookup2(ifc) >= 0)) - rip_redistribute_add(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE, - &address, &nh, 0, 0, 0); + rip_redistribute_add(rip, ZEBRA_ROUTE_CONNECT, + RIP_ROUTE_INTERFACE, &address, &nh, 0, 0, + 0); } int rip_interface_address_add(int command, struct zclient *zclient, @@ -617,6 +627,8 @@ int rip_interface_address_add(int command, struct zclient *zclient, static void rip_apply_address_del(struct connected *ifc) { + struct rip_interface *ri = ifc->ifp->info; + struct rip *rip = ri->rip; struct prefix_ipv4 address; struct prefix *p; @@ -634,7 +646,7 @@ static void rip_apply_address_del(struct connected *ifc) address.prefixlen = p->prefixlen; apply_mask_ipv4(&address); - rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE, + rip_redistribute_delete(rip, ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE, &address, ifc->ifp->ifindex); } @@ -672,6 +684,8 @@ int rip_interface_address_delete(int command, struct zclient *zclient, * is within the ripng_enable_network table. */ static int rip_enable_network_lookup_if(struct interface *ifp) { + struct rip_interface *ri = ifp->info; + struct rip *rip = ri->rip; struct listnode *node, *nnode; struct connected *connected; struct prefix_ipv4 address; @@ -702,8 +716,10 @@ static int rip_enable_network_lookup_if(struct interface *ifp) } /* Check wether connected is within the ripng_enable_network table. */ -int rip_enable_network_lookup2(struct connected *connected) +static int rip_enable_network_lookup2(struct connected *connected) { + struct rip_interface *ri = connected->ifp->info; + struct rip *rip = ri->rip; struct prefix_ipv4 address; struct prefix *p; @@ -730,7 +746,7 @@ int rip_enable_network_lookup2(struct connected *connected) return -1; } /* Add RIP enable network. */ -int rip_enable_network_add(struct prefix *p) +int rip_enable_network_add(struct rip *rip, struct prefix *p) { struct route_node *node; @@ -743,13 +759,13 @@ int rip_enable_network_add(struct prefix *p) node->info = (void *)1; /* XXX: One should find a better solution than a generic one */ - rip_enable_apply_all(); + rip_enable_apply_all(rip); return NB_OK; } /* Delete RIP enable network. */ -int rip_enable_network_delete(struct prefix *p) +int rip_enable_network_delete(struct rip *rip, struct prefix *p) { struct route_node *node; @@ -764,7 +780,7 @@ int rip_enable_network_delete(struct prefix *p) route_unlock_node(node); /* XXX: One should find a better solution than a generic one */ - rip_enable_apply_all(); + rip_enable_apply_all(rip); return NB_OK; } @@ -773,7 +789,7 @@ int rip_enable_network_delete(struct prefix *p) } /* Check interface is enabled by ifname statement. */ -static int rip_enable_if_lookup(const char *ifname) +static int rip_enable_if_lookup(struct rip *rip, const char *ifname) { unsigned int i; char *str; @@ -789,29 +805,29 @@ static int rip_enable_if_lookup(const char *ifname) } /* Add interface to rip_enable_if. */ -int rip_enable_if_add(const char *ifname) +int rip_enable_if_add(struct rip *rip, const char *ifname) { int ret; - ret = rip_enable_if_lookup(ifname); + ret = rip_enable_if_lookup(rip, ifname); if (ret >= 0) return NB_ERR_INCONSISTENCY; vector_set(rip->enable_interface, XSTRDUP(MTYPE_RIP_INTERFACE_STRING, ifname)); - rip_enable_apply_all(); /* TODOVJ */ + rip_enable_apply_all(rip); /* TODOVJ */ return NB_OK; } /* Delete interface from rip_enable_if. */ -int rip_enable_if_delete(const char *ifname) +int rip_enable_if_delete(struct rip *rip, const char *ifname) { int index; char *str; - index = rip_enable_if_lookup(ifname); + index = rip_enable_if_lookup(rip, ifname); if (index < 0) return NB_ERR_INCONSISTENCY; @@ -819,7 +835,7 @@ int rip_enable_if_delete(const char *ifname) XFREE(MTYPE_RIP_INTERFACE_STRING, str); vector_unset(rip->enable_interface, index); - rip_enable_apply_all(); /* TODOVJ */ + rip_enable_apply_all(rip); /* TODOVJ */ return NB_OK; } @@ -837,7 +853,7 @@ static int rip_interface_wakeup(struct thread *t) ri->t_wakeup = NULL; /* Join to multicast group. */ - if (rip_multicast_join(ifp, rip->sock) < 0) { + if (rip_multicast_join(ifp, ri->rip->sock) < 0) { flog_err_sys(EC_LIB_SOCKET, "multicast join failed, interface %s not running", ifp->name); @@ -855,6 +871,8 @@ static int rip_interface_wakeup(struct thread *t) static void rip_connect_set(struct interface *ifp, int set) { + struct rip_interface *ri = ifp->info; + struct rip *rip = ri->rip; struct listnode *node, *nnode; struct connected *connected; struct prefix_ipv4 address; @@ -879,17 +897,18 @@ static void rip_connect_set(struct interface *ifp, int set) if (set) { /* Check once more wether this prefix is within a * "network IF_OR_PREF" one */ - if ((rip_enable_if_lookup(connected->ifp->name) >= 0) + if ((rip_enable_if_lookup(rip, connected->ifp->name) + >= 0) || (rip_enable_network_lookup2(connected) >= 0)) - rip_redistribute_add(ZEBRA_ROUTE_CONNECT, + rip_redistribute_add(rip, ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE, &address, &nh, 0, 0, 0); } else { - rip_redistribute_delete(ZEBRA_ROUTE_CONNECT, + rip_redistribute_delete(rip, ZEBRA_ROUTE_CONNECT, RIP_ROUTE_INTERFACE, &address, connected->ifp->ifindex); - if (rip_redistribute_check(ZEBRA_ROUTE_CONNECT)) - rip_redistribute_add(ZEBRA_ROUTE_CONNECT, + if (rip_redistribute_check(rip, ZEBRA_ROUTE_CONNECT)) + rip_redistribute_add(rip, ZEBRA_ROUTE_CONNECT, RIP_ROUTE_REDISTRIBUTE, &address, &nh, 0, 0, 0); } @@ -918,7 +937,7 @@ void rip_enable_apply(struct interface *ifp) ri->enable_network = 0; /* Check interface name configuration. */ - ret = rip_enable_if_lookup(ifp->name); + ret = rip_enable_if_lookup(ri->rip, ifp->name); if (ret >= 0) ri->enable_interface = 1; else @@ -951,9 +970,9 @@ void rip_enable_apply(struct interface *ifp) } /* Apply network configuration to all interface. */ -void rip_enable_apply_all() +static void rip_enable_apply_all(struct rip *rip) { - struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); + struct vrf *vrf = vrf_lookup_by_id(rip->vrf_id); struct interface *ifp; /* Check each interface. */ @@ -961,7 +980,7 @@ void rip_enable_apply_all() rip_enable_apply(ifp); } -int rip_neighbor_lookup(struct sockaddr_in *from) +int rip_neighbor_lookup(struct rip *rip, struct sockaddr_in *from) { struct prefix_ipv4 p; struct route_node *node; @@ -980,7 +999,7 @@ int rip_neighbor_lookup(struct sockaddr_in *from) } /* Add new RIP neighbor to the neighbor tree. */ -int rip_neighbor_add(struct prefix_ipv4 *p) +int rip_neighbor_add(struct rip *rip, struct prefix_ipv4 *p) { struct route_node *node; @@ -995,7 +1014,7 @@ int rip_neighbor_add(struct prefix_ipv4 *p) } /* Delete RIP neighbor from the neighbor tree. */ -int rip_neighbor_delete(struct prefix_ipv4 *p) +int rip_neighbor_delete(struct rip *rip, struct prefix_ipv4 *p) { struct route_node *node; @@ -1016,7 +1035,7 @@ int rip_neighbor_delete(struct prefix_ipv4 *p) } /* Clear all network and neighbor configuration. */ -void rip_clean_network() +void rip_clean_network(struct rip *rip) { unsigned int i; char *str; @@ -1038,7 +1057,7 @@ void rip_clean_network() } /* Utility function for looking up passive interface settings. */ -static int rip_passive_nondefault_lookup(const char *ifname) +static int rip_passive_nondefault_lookup(struct rip *rip, const char *ifname) { unsigned int i; char *str; @@ -1050,16 +1069,17 @@ static int rip_passive_nondefault_lookup(const char *ifname) return -1; } -void rip_passive_interface_apply(struct interface *ifp) +static void rip_passive_interface_apply(struct interface *ifp) { + struct rip *rip; struct rip_interface *ri; + ri = ifp->info; + rip = ri->rip; if (rip == NULL) return; - ri = ifp->info; - - ri->passive = ((rip_passive_nondefault_lookup(ifp->name) < 0) + ri->passive = ((rip_passive_nondefault_lookup(rip, ifp->name) < 0) ? rip->passive_default : !rip->passive_default); @@ -1068,9 +1088,9 @@ void rip_passive_interface_apply(struct interface *ifp) ri->passive); } -static void rip_passive_interface_apply_all(void) +static void rip_passive_interface_apply_all(struct rip *rip) { - struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); + struct vrf *vrf = vrf_lookup_by_id(rip->vrf_id); struct interface *ifp; FOR_ALL_INTERFACES (vrf, ifp) @@ -1078,9 +1098,9 @@ static void rip_passive_interface_apply_all(void) } /* Passive interface. */ -int rip_passive_nondefault_set(const char *ifname) +int rip_passive_nondefault_set(struct rip *rip, const char *ifname) { - if (rip_passive_nondefault_lookup(ifname) >= 0) + if (rip_passive_nondefault_lookup(rip, ifname) >= 0) /* * Don't return an error, this can happen after changing * 'passive-default'. @@ -1090,17 +1110,17 @@ int rip_passive_nondefault_set(const char *ifname) vector_set(rip->passive_nondefault, XSTRDUP(MTYPE_RIP_INTERFACE_STRING, ifname)); - rip_passive_interface_apply_all(); + rip_passive_interface_apply_all(rip); return NB_OK; } -int rip_passive_nondefault_unset(const char *ifname) +int rip_passive_nondefault_unset(struct rip *rip, const char *ifname) { int i; char *str; - i = rip_passive_nondefault_lookup(ifname); + i = rip_passive_nondefault_lookup(rip, ifname); if (i < 0) /* * Don't return an error, this can happen after changing @@ -1112,13 +1132,13 @@ int rip_passive_nondefault_unset(const char *ifname) XFREE(MTYPE_RIP_INTERFACE_STRING, str); vector_unset(rip->passive_nondefault, i); - rip_passive_interface_apply_all(); + rip_passive_interface_apply_all(rip); return NB_OK; } /* Free all configured RIP passive-interface settings. */ -void rip_passive_nondefault_clean(void) +void rip_passive_nondefault_clean(struct rip *rip) { unsigned int i; char *str; @@ -1128,7 +1148,7 @@ void rip_passive_nondefault_clean(void) XFREE(MTYPE_RIP_INTERFACE_STRING, str); vector_slot(rip->passive_nondefault, i) = NULL; } - rip_passive_interface_apply_all(); + rip_passive_interface_apply_all(rip); } /* Write rip configuration of each interface. */ @@ -1155,7 +1175,7 @@ static int rip_interface_config_write(struct vty *vty) return write; } -int rip_show_network_config(struct vty *vty) +int rip_show_network_config(struct vty *vty, struct rip *rip) { unsigned int i; char *ifname; @@ -1189,7 +1209,7 @@ static struct cmd_node interface_node = { /* Called when interface structure allocated. */ static int rip_interface_new_hook(struct interface *ifp) { - ifp->info = rip_interface_new(); + ifp->info = rip_interface_new(ifp); return 0; } diff --git a/ripd/rip_main.c b/ripd/rip_main.c index 8c6340f6c..46babe2e0 100644 --- a/ripd/rip_main.c +++ b/ripd/rip_main.c @@ -79,10 +79,17 @@ static void sighup(void) /* SIGINT handler. */ static void sigint(void) { + struct vrf *vrf; + zlog_notice("Terminating on signal"); - if (rip) - rip_clean(); + RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { + struct rip *rip; + + rip = vrf->info; + if (rip) + rip_clean(rip); + } rip_zclient_stop(); frr_fini(); diff --git a/ripd/rip_northbound.c b/ripd/rip_northbound.c index b0f2b62a5..f5a75707e 100644 --- a/ripd/rip_northbound.c +++ b/ripd/rip_northbound.c @@ -40,6 +40,8 @@ static int ripd_instance_create(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; + struct vrf *vrf; int socket; switch (event) { @@ -56,8 +58,10 @@ static int ripd_instance_create(enum nb_event event, close(socket); break; case NB_EV_APPLY: + vrf = vrf_lookup_by_id(VRF_DEFAULT); socket = resource->fd; - rip_create(socket); + rip = rip_create(vrf, socket); + yang_dnode_set_entry(dnode, rip); break; } @@ -67,10 +71,13 @@ static int ripd_instance_create(enum nb_event event, static int ripd_instance_delete(enum nb_event event, const struct lyd_node *dnode) { + struct rip *rip; + if (event != NB_EV_APPLY) return NB_OK; - rip_clean(); + rip = yang_dnode_get_entry(dnode, true); + rip_clean(rip); return NB_OK; } @@ -82,12 +89,15 @@ static int ripd_instance_allow_ecmp_modify(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; + if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); rip->ecmp = yang_dnode_get_bool(dnode, NULL); if (!rip->ecmp) - rip_ecmp_disable(); + rip_ecmp_disable(rip); return NB_OK; } @@ -100,12 +110,14 @@ ripd_instance_default_information_originate_modify(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; bool default_information; struct prefix_ipv4 p; if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); default_information = yang_dnode_get_bool(dnode, NULL); memset(&p, 0, sizeof(struct prefix_ipv4)); @@ -115,11 +127,11 @@ ripd_instance_default_information_originate_modify(enum nb_event event, memset(&nh, 0, sizeof(nh)); nh.type = NEXTHOP_TYPE_IPV4; - rip_redistribute_add(ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, - &nh, 0, 0, 0); + rip_redistribute_add(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, + &p, &nh, 0, 0, 0); } else { - rip_redistribute_delete(ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, &p, - 0); + rip_redistribute_delete(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_DEFAULT, + &p, 0); } return NB_OK; @@ -132,9 +144,12 @@ static int ripd_instance_default_metric_modify(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; + if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); rip->default_metric = yang_dnode_get_uint8(dnode, NULL); /* rip_update_default_metric (); */ @@ -148,9 +163,12 @@ static int ripd_instance_distance_default_modify(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; + if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); rip->distance = yang_dnode_get_uint8(dnode, NULL); return NB_OK; @@ -163,6 +181,7 @@ static int ripd_instance_distance_source_create(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; struct prefix_ipv4 prefix; struct route_node *rn; @@ -173,6 +192,7 @@ static int ripd_instance_distance_source_create(enum nb_event event, apply_mask_ipv4(&prefix); /* Get RIP distance node. */ + rip = yang_dnode_get_entry(dnode, true); rn = route_node_get(rip->distance_table, (struct prefix *)&prefix); rn->info = rip_distance_new(); yang_dnode_set_entry(dnode, rn); @@ -275,31 +295,35 @@ static int ripd_instance_explicit_neighbor_create(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; struct prefix_ipv4 p; if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); p.family = AF_INET; p.prefixlen = IPV4_MAX_BITLEN; yang_dnode_get_ipv4(&p.prefix, dnode, NULL); - return rip_neighbor_add(&p); + return rip_neighbor_add(rip, &p); } static int ripd_instance_explicit_neighbor_delete(enum nb_event event, const struct lyd_node *dnode) { + struct rip *rip; struct prefix_ipv4 p; if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); p.family = AF_INET; p.prefixlen = IPV4_MAX_BITLEN; yang_dnode_get_ipv4(&p.prefix, dnode, NULL); - return rip_neighbor_delete(&p); + return rip_neighbor_delete(rip, &p); } /* @@ -309,29 +333,33 @@ static int ripd_instance_network_create(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; struct prefix p; if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); yang_dnode_get_ipv4p(&p, dnode, NULL); apply_mask_ipv4((struct prefix_ipv4 *)&p); - return rip_enable_network_add(&p); + return rip_enable_network_add(rip, &p); } static int ripd_instance_network_delete(enum nb_event event, const struct lyd_node *dnode) { + struct rip *rip; struct prefix p; if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); yang_dnode_get_ipv4p(&p, dnode, NULL); apply_mask_ipv4((struct prefix_ipv4 *)&p); - return rip_enable_network_delete(&p); + return rip_enable_network_delete(rip, &p); } /* @@ -341,27 +369,31 @@ static int ripd_instance_interface_create(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; const char *ifname; if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); ifname = yang_dnode_get_string(dnode, NULL); - return rip_enable_if_add(ifname); + return rip_enable_if_add(rip, ifname); } static int ripd_instance_interface_delete(enum nb_event event, const struct lyd_node *dnode) { + struct rip *rip; const char *ifname; if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); ifname = yang_dnode_get_string(dnode, NULL); - return rip_enable_if_delete(ifname); + return rip_enable_if_delete(rip, ifname); } /* @@ -371,15 +403,17 @@ static int ripd_instance_offset_list_create(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; const char *ifname; struct rip_offset_list *offset; if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); ifname = yang_dnode_get_string(dnode, "./interface"); - offset = rip_offset_list_new(ifname); + offset = rip_offset_list_new(rip, ifname); yang_dnode_set_entry(dnode, offset); return NB_OK; @@ -464,11 +498,14 @@ static int ripd_instance_passive_default_modify(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; + if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); rip->passive_default = yang_dnode_get_bool(dnode, NULL); - rip_passive_nondefault_clean(); + rip_passive_nondefault_clean(rip); return NB_OK; } @@ -480,27 +517,31 @@ static int ripd_instance_passive_interface_create(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; const char *ifname; if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); ifname = yang_dnode_get_string(dnode, NULL); - return rip_passive_nondefault_set(ifname); + return rip_passive_nondefault_set(rip, ifname); } static int ripd_instance_passive_interface_delete(enum nb_event event, const struct lyd_node *dnode) { + struct rip *rip; const char *ifname; if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); ifname = yang_dnode_get_string(dnode, NULL); - return rip_passive_nondefault_unset(ifname); + return rip_passive_nondefault_unset(rip, ifname); } /* @@ -511,28 +552,32 @@ ripd_instance_non_passive_interface_create(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; const char *ifname; if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); ifname = yang_dnode_get_string(dnode, NULL); - return rip_passive_nondefault_unset(ifname); + return rip_passive_nondefault_unset(rip, ifname); } static int ripd_instance_non_passive_interface_delete(enum nb_event event, const struct lyd_node *dnode) { + struct rip *rip; const char *ifname; if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); ifname = yang_dnode_get_string(dnode, NULL); - return rip_passive_nondefault_set(ifname); + return rip_passive_nondefault_set(rip, ifname); } /* @@ -548,14 +593,16 @@ static int ripd_instance_redistribute_create(enum nb_event event, static int ripd_instance_redistribute_delete(enum nb_event event, const struct lyd_node *dnode) { + struct rip *rip; int type; if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); type = yang_dnode_get_enum(dnode, "./protocol"); - rip_redistribute_conf_delete(type); + rip_redistribute_conf_delete(rip, type); return NB_OK; } @@ -563,10 +610,13 @@ static int ripd_instance_redistribute_delete(enum nb_event event, static void ripd_instance_redistribute_apply_finish(const struct lyd_node *dnode) { + struct rip *rip; int type; + rip = yang_dnode_get_entry(dnode, true); type = yang_dnode_get_enum(dnode, "./protocol"); - rip_redistribute_conf_update(type); + + rip_redistribute_conf_update(rip, type); } /* @@ -577,12 +627,14 @@ ripd_instance_redistribute_route_map_modify(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; int type; const char *rmap_name; if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); type = yang_dnode_get_enum(dnode, "../protocol"); rmap_name = yang_dnode_get_string(dnode, NULL); @@ -598,11 +650,13 @@ static int ripd_instance_redistribute_route_map_delete(enum nb_event event, const struct lyd_node *dnode) { + struct rip *rip; int type; if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); type = yang_dnode_get_enum(dnode, "../protocol"); free(rip->route_map[type].name); @@ -620,12 +674,14 @@ ripd_instance_redistribute_metric_modify(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; int type; uint8_t metric; if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); type = yang_dnode_get_enum(dnode, "../protocol"); metric = yang_dnode_get_uint8(dnode, NULL); @@ -639,11 +695,13 @@ static int ripd_instance_redistribute_metric_delete(enum nb_event event, const struct lyd_node *dnode) { + struct rip *rip; int type; if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); type = yang_dnode_get_enum(dnode, "../protocol"); rip->route_map[type].metric_config = false; @@ -659,19 +717,21 @@ static int ripd_instance_static_route_create(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; struct nexthop nh; struct prefix_ipv4 p; if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); yang_dnode_get_ipv4p(&p, dnode, NULL); apply_mask_ipv4(&p); memset(&nh, 0, sizeof(nh)); nh.type = NEXTHOP_TYPE_IPV4; - rip_redistribute_add(ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, &nh, 0, 0, - 0); + rip_redistribute_add(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, &nh, 0, + 0, 0); return NB_OK; } @@ -679,15 +739,17 @@ static int ripd_instance_static_route_create(enum nb_event event, static int ripd_instance_static_route_delete(enum nb_event event, const struct lyd_node *dnode) { + struct rip *rip; struct prefix_ipv4 p; if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); yang_dnode_get_ipv4p(&p, dnode, NULL); apply_mask_ipv4(&p); - rip_redistribute_delete(ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0); + rip_redistribute_delete(rip, ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0); return NB_OK; } @@ -697,8 +759,12 @@ static int ripd_instance_static_route_delete(enum nb_event event, */ static void ripd_instance_timers_apply_finish(const struct lyd_node *dnode) { + struct rip *rip; + + rip = yang_dnode_get_entry(dnode, true); + /* Reset update timer thread. */ - rip_event(RIP_UPDATE_EVENT, 0); + rip_event(rip, RIP_UPDATE_EVENT, 0); } /* @@ -709,9 +775,12 @@ ripd_instance_timers_flush_interval_modify(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; + if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); rip->garbage_time = yang_dnode_get_uint32(dnode, NULL); return NB_OK; @@ -725,9 +794,12 @@ ripd_instance_timers_holddown_interval_modify(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; + if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); rip->timeout_time = yang_dnode_get_uint32(dnode, NULL); return NB_OK; @@ -741,9 +813,12 @@ ripd_instance_timers_update_interval_modify(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; + if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); rip->update_time = yang_dnode_get_uint32(dnode, NULL); return NB_OK; @@ -756,9 +831,12 @@ static int ripd_instance_version_receive_modify(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; + if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); rip->version_recv = yang_dnode_get_enum(dnode, NULL); return NB_OK; @@ -771,9 +849,12 @@ static int ripd_instance_version_send_modify(enum nb_event event, const struct lyd_node *dnode, union nb_resource *resource) { + struct rip *rip; + if (event != NB_EV_APPLY) return NB_OK; + rip = yang_dnode_get_entry(dnode, true); rip->version_send = yang_dnode_get_enum(dnode, NULL); return NB_OK; @@ -1007,8 +1088,10 @@ static const void * ripd_state_neighbors_neighbor_get_next(const void *parent_list_entry, const void *list_entry) { + struct rip *rip; struct listnode *node; + rip = rip_lookup_by_vrf_id(VRF_DEFAULT); if (rip == NULL) return NULL; @@ -1037,12 +1120,14 @@ static const void * ripd_state_neighbors_neighbor_lookup_entry(const void *parent_list_entry, const struct yang_list_keys *keys) { + struct rip *rip; struct in_addr address; struct rip_peer *peer; struct listnode *node; yang_str2ipv4(keys->key[0], &address); + rip = rip_lookup_by_vrf_id(VRF_DEFAULT); if (rip == NULL) return NULL; @@ -1111,8 +1196,10 @@ static const void * ripd_state_routes_route_get_next(const void *parent_list_entry, const void *list_entry) { + struct rip *rip; struct route_node *rn; + rip = rip_lookup_by_vrf_id(VRF_DEFAULT); if (rip == NULL) return NULL; @@ -1141,11 +1228,16 @@ static const void * ripd_state_routes_route_lookup_entry(const void *parent_list_entry, const struct yang_list_keys *keys) { + struct rip *rip; struct prefix prefix; struct route_node *rn; yang_str2ipv4p(keys->key[0], &prefix); + rip = rip_lookup_by_vrf_id(VRF_DEFAULT); + if (rip == NULL) + return NULL; + rn = route_node_lookup(rip->table, &prefix); if (!rn || !rn->info) return NULL; @@ -1226,11 +1318,13 @@ ripd_state_routes_route_metric_get_elem(const char *xpath, static int clear_rip_route_rpc(const char *xpath, const struct list *input, struct list *output) { + struct rip *rip; struct route_node *rp; struct rip_info *rinfo; struct list *list; struct listnode *listnode; + rip = rip_lookup_by_vrf_id(VRF_DEFAULT); if (!rip) return NB_OK; @@ -1245,7 +1339,7 @@ static int clear_rip_route_rpc(const char *xpath, const struct list *input, continue; if (CHECK_FLAG(rinfo->flags, RIP_RTF_FIB)) - rip_zebra_ipv4_delete(rp); + rip_zebra_ipv4_delete(rip, rp); break; } diff --git a/ripd/rip_offset.c b/ripd/rip_offset.c index 94dc175d1..b3f84fe50 100644 --- a/ripd/rip_offset.c +++ b/ripd/rip_offset.c @@ -35,11 +35,12 @@ #define OFFSET_LIST_OUT_NAME(O) ((O)->direct[RIP_OFFSET_LIST_OUT].alist_name) #define OFFSET_LIST_OUT_METRIC(O) ((O)->direct[RIP_OFFSET_LIST_OUT].metric) -struct rip_offset_list *rip_offset_list_new(const char *ifname) +struct rip_offset_list *rip_offset_list_new(struct rip *rip, const char *ifname) { struct rip_offset_list *offset; offset = XCALLOC(MTYPE_RIP_OFFSET_LIST, sizeof(struct rip_offset_list)); + offset->rip = rip; offset->ifname = strdup(ifname); listnode_add_sort(rip->offset_list_master, offset); @@ -48,7 +49,7 @@ struct rip_offset_list *rip_offset_list_new(const char *ifname) void offset_list_del(struct rip_offset_list *offset) { - listnode_delete(rip->offset_list_master, offset); + listnode_delete(offset->rip->offset_list_master, offset); if (OFFSET_LIST_IN_NAME(offset)) free(OFFSET_LIST_IN_NAME(offset)); if (OFFSET_LIST_OUT_NAME(offset)) @@ -57,7 +58,8 @@ void offset_list_del(struct rip_offset_list *offset) XFREE(MTYPE_RIP_OFFSET_LIST, offset); } -struct rip_offset_list *rip_offset_list_lookup(const char *ifname) +struct rip_offset_list *rip_offset_list_lookup(struct rip *rip, + const char *ifname) { struct rip_offset_list *offset; struct listnode *node, *nnode; @@ -73,11 +75,12 @@ struct rip_offset_list *rip_offset_list_lookup(const char *ifname) int rip_offset_list_apply_in(struct prefix_ipv4 *p, struct interface *ifp, uint32_t *metric) { + struct rip_interface *ri = ifp->info; struct rip_offset_list *offset; struct access_list *alist; /* Look up offset-list with interface name. */ - offset = rip_offset_list_lookup(ifp->name); + offset = rip_offset_list_lookup(ri->rip, ifp->name); if (offset && OFFSET_LIST_IN_NAME(offset)) { alist = access_list_lookup(AFI_IP, OFFSET_LIST_IN_NAME(offset)); @@ -90,7 +93,7 @@ int rip_offset_list_apply_in(struct prefix_ipv4 *p, struct interface *ifp, return 0; } /* Look up offset-list without interface name. */ - offset = rip_offset_list_lookup("*"); + offset = rip_offset_list_lookup(ri->rip, "*"); if (offset && OFFSET_LIST_IN_NAME(offset)) { alist = access_list_lookup(AFI_IP, OFFSET_LIST_IN_NAME(offset)); @@ -109,11 +112,12 @@ int rip_offset_list_apply_in(struct prefix_ipv4 *p, struct interface *ifp, int rip_offset_list_apply_out(struct prefix_ipv4 *p, struct interface *ifp, uint32_t *metric) { + struct rip_interface *ri = ifp->info; struct rip_offset_list *offset; struct access_list *alist; /* Look up offset-list with interface name. */ - offset = rip_offset_list_lookup(ifp->name); + offset = rip_offset_list_lookup(ri->rip, ifp->name); if (offset && OFFSET_LIST_OUT_NAME(offset)) { alist = access_list_lookup(AFI_IP, OFFSET_LIST_OUT_NAME(offset)); @@ -128,7 +132,7 @@ int rip_offset_list_apply_out(struct prefix_ipv4 *p, struct interface *ifp, } /* Look up offset-list without interface name. */ - offset = rip_offset_list_lookup("*"); + offset = rip_offset_list_lookup(ri->rip, "*"); if (offset && OFFSET_LIST_OUT_NAME(offset)) { alist = access_list_lookup(AFI_IP, OFFSET_LIST_OUT_NAME(offset)); diff --git a/ripd/rip_peer.c b/ripd/rip_peer.c index 07b295030..08aa61257 100644 --- a/ripd/rip_peer.c +++ b/ripd/rip_peer.c @@ -40,7 +40,7 @@ static void rip_peer_free(struct rip_peer *peer) XFREE(MTYPE_RIP_PEER, peer); } -struct rip_peer *rip_peer_lookup(struct in_addr *addr) +struct rip_peer *rip_peer_lookup(struct rip *rip, struct in_addr *addr) { struct rip_peer *peer; struct listnode *node, *nnode; @@ -52,7 +52,7 @@ struct rip_peer *rip_peer_lookup(struct in_addr *addr) return NULL; } -struct rip_peer *rip_peer_lookup_next(struct in_addr *addr) +struct rip_peer *rip_peer_lookup_next(struct rip *rip, struct in_addr *addr) { struct rip_peer *peer; struct listnode *node, *nnode; @@ -70,24 +70,25 @@ static int rip_peer_timeout(struct thread *t) struct rip_peer *peer; peer = THREAD_ARG(t); - listnode_delete(rip->peer_list, peer); + listnode_delete(peer->rip->peer_list, peer); rip_peer_free(peer); return 0; } /* Get RIP peer. At the same time update timeout thread. */ -static struct rip_peer *rip_peer_get(struct in_addr *addr) +static struct rip_peer *rip_peer_get(struct rip *rip, struct in_addr *addr) { struct rip_peer *peer; - peer = rip_peer_lookup(addr); + peer = rip_peer_lookup(rip, addr); if (peer) { if (peer->t_timeout) thread_cancel(peer->t_timeout); } else { peer = rip_peer_new(); + peer->rip = rip; peer->addr = *addr; listnode_add_sort(rip->peer_list, peer); } @@ -103,24 +104,24 @@ static struct rip_peer *rip_peer_get(struct in_addr *addr) return peer; } -void rip_peer_update(struct sockaddr_in *from, uint8_t version) +void rip_peer_update(struct rip *rip, struct sockaddr_in *from, uint8_t version) { struct rip_peer *peer; - peer = rip_peer_get(&from->sin_addr); + peer = rip_peer_get(rip, &from->sin_addr); peer->version = version; } -void rip_peer_bad_route(struct sockaddr_in *from) +void rip_peer_bad_route(struct rip *rip, struct sockaddr_in *from) { struct rip_peer *peer; - peer = rip_peer_get(&from->sin_addr); + peer = rip_peer_get(rip, &from->sin_addr); peer->recv_badroutes++; } -void rip_peer_bad_packet(struct sockaddr_in *from) +void rip_peer_bad_packet(struct rip *rip, struct sockaddr_in *from) { struct rip_peer *peer; - peer = rip_peer_get(&from->sin_addr); + peer = rip_peer_get(rip, &from->sin_addr); peer->recv_badpackets++; } @@ -153,7 +154,7 @@ static char *rip_peer_uptime(struct rip_peer *peer, char *buf, size_t len) return buf; } -void rip_peer_display(struct vty *vty) +void rip_peer_display(struct vty *vty, struct rip *rip) { struct rip_peer *peer; struct listnode *node, *nnode; diff --git a/ripd/rip_snmp.c b/ripd/rip_snmp.c index 54c8a2eb8..5a6b71fba 100644 --- a/ripd/rip_snmp.c +++ b/ripd/rip_snmp.c @@ -156,10 +156,13 @@ static uint8_t *rip2Globals(struct variable *v, oid name[], size_t *length, int exact, size_t *var_len, WriteMethod **write_method) { + struct rip *rip; + if (smux_header_generic(v, name, length, exact, var_len, write_method) == MATCH_FAILED) return NULL; + rip = rip_lookup_by_vrf_id(VRF_DEFAULT); if (!rip) return NULL; @@ -284,9 +287,11 @@ static struct rip_peer *rip2PeerLookup(struct variable *v, oid name[], size_t *length, struct in_addr *addr, int exact) { + struct rip *rip; int len; struct rip_peer *peer; + rip = rip_lookup_by_vrf_id(VRF_DEFAULT); if (!rip) return NULL; @@ -297,7 +302,7 @@ static struct rip_peer *rip2PeerLookup(struct variable *v, oid name[], oid2in_addr(name + v->namelen, sizeof(struct in_addr), addr); - peer = rip_peer_lookup(addr); + peer = rip_peer_lookup(rip, addr); if (peer->domain == (int)name[v->namelen + sizeof(struct in_addr)]) @@ -312,7 +317,7 @@ static struct rip_peer *rip2PeerLookup(struct variable *v, oid name[], oid2in_addr(name + v->namelen, len, addr); len = *length - v->namelen; - peer = rip_peer_lookup(addr); + peer = rip_peer_lookup(rip, addr); if (peer) { if ((len < (int)sizeof(struct in_addr) + 1) || (peer->domain @@ -327,7 +332,7 @@ static struct rip_peer *rip2PeerLookup(struct variable *v, oid name[], return peer; } } - peer = rip_peer_lookup_next(addr); + peer = rip_peer_lookup_next(rip, addr); if (!peer) return NULL; @@ -408,10 +413,10 @@ static long rip2IfConfSend(struct rip_interface *ri) return ripVersion2; else if (ri->ri_send & RIPv1) return ripVersion1; - else if (rip) { - if (rip->version_send == RIPv2) + else if (ri->rip) { + if (ri->rip->version_send == RIPv2) return ripVersion2; - else if (rip->version_send == RIPv1) + else if (ri->rip->version_send == RIPv1) return ripVersion1; } return doNotSend; @@ -429,7 +434,7 @@ static long rip2IfConfReceive(struct rip_interface *ri) if (!ri->running) return doNotReceive; - recvv = (ri->ri_receive == RI_RIP_UNSPEC) ? rip->version_recv + recvv = (ri->ri_receive == RI_RIP_UNSPEC) ? ri->rip->version_recv : ri->ri_receive; if (recvv == RI_RIP_VERSION_1_AND_2) return rip1OrRip2; diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c index 607dc168f..6fbc170cb 100644 --- a/ripd/rip_zebra.c +++ b/ripd/rip_zebra.c @@ -36,7 +36,8 @@ struct zclient *zclient = NULL; /* Send ECMP routes to zebra. */ -static void rip_zebra_ipv4_send(struct route_node *rp, uint8_t cmd) +static void rip_zebra_ipv4_send(struct rip *rip, struct route_node *rp, + uint8_t cmd) { struct list *list = (struct list *)rp->info; struct zapi_route api; @@ -46,7 +47,7 @@ static void rip_zebra_ipv4_send(struct route_node *rp, uint8_t cmd) int count = 0; memset(&api, 0, sizeof(api)); - api.vrf_id = VRF_DEFAULT; + api.vrf_id = rip->vrf_id; api.type = ZEBRA_ROUTE_RIP; api.safi = SAFI_UNICAST; @@ -55,7 +56,7 @@ static void rip_zebra_ipv4_send(struct route_node *rp, uint8_t cmd) if (count >= MULTIPATH_NUM) break; api_nh = &api.nexthops[count]; - api_nh->vrf_id = VRF_DEFAULT; + api_nh->vrf_id = rip->vrf_id; api_nh->gate = rinfo->nh.gate; api_nh->type = NEXTHOP_TYPE_IPV4; if (cmd == ZEBRA_ROUTE_ADD) @@ -105,24 +106,26 @@ static void rip_zebra_ipv4_send(struct route_node *rp, uint8_t cmd) } /* Add/update ECMP routes to zebra. */ -void rip_zebra_ipv4_add(struct route_node *rp) +void rip_zebra_ipv4_add(struct rip *rip, struct route_node *rp) { - rip_zebra_ipv4_send(rp, ZEBRA_ROUTE_ADD); + rip_zebra_ipv4_send(rip, rp, ZEBRA_ROUTE_ADD); } /* Delete ECMP routes from zebra. */ -void rip_zebra_ipv4_delete(struct route_node *rp) +void rip_zebra_ipv4_delete(struct rip *rip, struct route_node *rp) { - rip_zebra_ipv4_send(rp, ZEBRA_ROUTE_DELETE); + rip_zebra_ipv4_send(rip, rp, ZEBRA_ROUTE_DELETE); } /* Zebra route add and delete treatment. */ static int rip_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length, vrf_id_t vrf_id) { + struct rip *rip; struct zapi_route api; struct nexthop nh; + rip = rip_lookup_by_vrf_id(vrf_id); if (!rip) return 0; @@ -136,59 +139,59 @@ static int rip_zebra_read_route(int command, struct zclient *zclient, /* Then fetch IPv4 prefixes. */ if (command == ZEBRA_REDISTRIBUTE_ROUTE_ADD) - rip_redistribute_add(api.type, RIP_ROUTE_REDISTRIBUTE, + rip_redistribute_add(rip, api.type, RIP_ROUTE_REDISTRIBUTE, (struct prefix_ipv4 *)&api.prefix, &nh, api.metric, api.distance, api.tag); else if (command == ZEBRA_REDISTRIBUTE_ROUTE_DEL) - rip_redistribute_delete(api.type, RIP_ROUTE_REDISTRIBUTE, + rip_redistribute_delete(rip, api.type, RIP_ROUTE_REDISTRIBUTE, (struct prefix_ipv4 *)&api.prefix, nh.ifindex); return 0; } -void rip_redistribute_conf_update(int type) +void rip_redistribute_conf_update(struct rip *rip, int type) { zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type, - 0, VRF_DEFAULT); + 0, rip->vrf_id); } -void rip_redistribute_conf_delete(int type) +void rip_redistribute_conf_delete(struct rip *rip, int type) { if (zclient->sock > 0) zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, - AFI_IP, type, 0, VRF_DEFAULT); + AFI_IP, type, 0, rip->vrf_id); /* Remove the routes from RIP table. */ - rip_redistribute_withdraw(type); + rip_redistribute_withdraw(rip, type); } -int rip_redistribute_check(int type) +int rip_redistribute_check(struct rip *rip, int type) { - return vrf_bitmap_check(zclient->redist[AFI_IP][type], VRF_DEFAULT); + return vrf_bitmap_check(zclient->redist[AFI_IP][type], rip->vrf_id); } -void rip_redistribute_clean(void) +void rip_redistribute_clean(struct rip *rip) { for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) { - if (!vrf_bitmap_check(zclient->redist[AFI_IP][i], VRF_DEFAULT)) + if (!vrf_bitmap_check(zclient->redist[AFI_IP][i], rip->vrf_id)) continue; if (zclient->sock > 0) zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, i, 0, - VRF_DEFAULT); + rip->vrf_id); - vrf_bitmap_unset(zclient->redist[AFI_IP][i], VRF_DEFAULT); + vrf_bitmap_unset(zclient->redist[AFI_IP][i], rip->vrf_id); } } -void rip_show_redistribute_config(struct vty *vty) +void rip_show_redistribute_config(struct vty *vty, struct rip *rip) { for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) { if (i == zclient->redist_default || !vrf_bitmap_check(zclient->redist[AFI_IP][i], - VRF_DEFAULT)) + rip->vrf_id)) continue; vty_out(vty, " %s", zebra_route_string(i)); diff --git a/ripd/ripd.c b/ripd/ripd.c index a6cfd9b15..6b9c5fe88 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -50,9 +50,6 @@ /* UDP receive buffer size */ #define RIP_UDP_RCV_BUF 41600 -/* RIP Structure. */ -struct rip *rip = NULL; - /* Prototypes. */ static void rip_output_process(struct connected *, struct sockaddr_in *, int, uint8_t); @@ -107,6 +104,11 @@ void rip_info_free(struct rip_info *rinfo) XFREE(MTYPE_RIP_INFO, rinfo); } +struct rip *rip_info_get_instance(const struct rip_info *rinfo) +{ + return route_table_get_info(rinfo->rp->table); +} + /* RIP route garbage collect timer. */ static int rip_garbage_collect(struct thread *t) { @@ -135,13 +137,13 @@ static int rip_garbage_collect(struct thread *t) return 0; } -static void rip_timeout_update(struct rip_info *rinfo); +static void rip_timeout_update(struct rip *rip, struct rip_info *rinfo); /* Add new route to the ECMP list. * RETURN: the new entry added in the list, or NULL if it is not the first * entry and ECMP is not allowed. */ -struct rip_info *rip_ecmp_add(struct rip_info *rinfo_new) +struct rip_info *rip_ecmp_add(struct rip *rip, struct rip_info *rinfo_new) { struct route_node *rp = rinfo_new->rp; struct rip_info *rinfo = NULL; @@ -161,8 +163,8 @@ struct rip_info *rip_ecmp_add(struct rip_info *rinfo_new) listnode_add(list, rinfo); if (rip_route_rte(rinfo)) { - rip_timeout_update(rinfo); - rip_zebra_ipv4_add(rp); + rip_timeout_update(rip, rinfo); + rip_zebra_ipv4_add(rip, rp); } /* Set the route change flag on the first entry. */ @@ -170,7 +172,7 @@ struct rip_info *rip_ecmp_add(struct rip_info *rinfo_new) SET_FLAG(rinfo->flags, RIP_RTF_CHANGED); /* Signal the output process to trigger an update (see section 2.5). */ - rip_event(RIP_TRIGGERED_UPDATE, 0); + rip_event(rip, RIP_TRIGGERED_UPDATE, 0); return rinfo; } @@ -178,7 +180,7 @@ struct rip_info *rip_ecmp_add(struct rip_info *rinfo_new) /* Replace the ECMP list with the new route. * RETURN: the new entry added in the list */ -struct rip_info *rip_ecmp_replace(struct rip_info *rinfo_new) +struct rip_info *rip_ecmp_replace(struct rip *rip, struct rip_info *rinfo_new) { struct route_node *rp = rinfo_new->rp; struct list *list = (struct list *)rp->info; @@ -186,7 +188,7 @@ struct rip_info *rip_ecmp_replace(struct rip_info *rinfo_new) struct listnode *node = NULL, *nextnode = NULL; if (list == NULL || listcount(list) == 0) - return rip_ecmp_add(rinfo_new); + return rip_ecmp_add(rip, rinfo_new); /* Get the first entry */ rinfo = listgetdata(listhead(list)); @@ -194,7 +196,7 @@ struct rip_info *rip_ecmp_replace(struct rip_info *rinfo_new) /* Learnt route replaced by a local one. Delete it from zebra. */ if (rip_route_rte(rinfo) && !rip_route_rte(rinfo_new)) if (CHECK_FLAG(rinfo->flags, RIP_RTF_FIB)) - rip_zebra_ipv4_delete(rp); + rip_zebra_ipv4_delete(rip, rp); /* Re-use the first entry, and delete the others. */ for (ALL_LIST_ELEMENTS(list, node, nextnode, tmp_rinfo)) @@ -210,16 +212,16 @@ struct rip_info *rip_ecmp_replace(struct rip_info *rinfo_new) memcpy(rinfo, rinfo_new, sizeof(struct rip_info)); if (rip_route_rte(rinfo)) { - rip_timeout_update(rinfo); + rip_timeout_update(rip, rinfo); /* The ADD message implies an update. */ - rip_zebra_ipv4_add(rp); + rip_zebra_ipv4_add(rip, rp); } /* Set the route change flag. */ SET_FLAG(rinfo->flags, RIP_RTF_CHANGED); /* Signal the output process to trigger an update (see section 2.5). */ - rip_event(RIP_TRIGGERED_UPDATE, 0); + rip_event(rip, RIP_TRIGGERED_UPDATE, 0); return rinfo; } @@ -230,7 +232,7 @@ struct rip_info *rip_ecmp_replace(struct rip_info *rinfo_new) * the entry - the entry is the last one in the list; its metric is set * to INFINITY, and the garbage collector is started for it */ -struct rip_info *rip_ecmp_delete(struct rip_info *rinfo) +struct rip_info *rip_ecmp_delete(struct rip *rip, struct rip_info *rinfo) { struct route_node *rp = rinfo->rp; struct list *list = (struct list *)rp->info; @@ -245,7 +247,7 @@ struct rip_info *rip_ecmp_delete(struct rip_info *rinfo) if (rip_route_rte(rinfo) && CHECK_FLAG(rinfo->flags, RIP_RTF_FIB)) /* The ADD message implies the update. */ - rip_zebra_ipv4_add(rp); + rip_zebra_ipv4_add(rip, rp); rip_info_free(rinfo); rinfo = NULL; } else { @@ -261,7 +263,7 @@ struct rip_info *rip_ecmp_delete(struct rip_info *rinfo) if (rip_route_rte(rinfo) && CHECK_FLAG(rinfo->flags, RIP_RTF_FIB)) - rip_zebra_ipv4_delete(rp); + rip_zebra_ipv4_delete(rip, rp); } /* Set the route change flag on the first entry. */ @@ -269,7 +271,7 @@ struct rip_info *rip_ecmp_delete(struct rip_info *rinfo) SET_FLAG(rinfo->flags, RIP_RTF_CHANGED); /* Signal the output process to trigger an update (see section 2.5). */ - rip_event(RIP_TRIGGERED_UPDATE, 0); + rip_event(rip, RIP_TRIGGERED_UPDATE, 0); return rinfo; } @@ -277,15 +279,20 @@ struct rip_info *rip_ecmp_delete(struct rip_info *rinfo) /* Timeout RIP routes. */ static int rip_timeout(struct thread *t) { - rip_ecmp_delete((struct rip_info *)THREAD_ARG(t)); + struct rip_info *rinfo = THREAD_ARG(t); + struct rip *rip = rip_info_get_instance(rinfo); + + rip_ecmp_delete(rip, rinfo); + return 0; } -static void rip_timeout_update(struct rip_info *rinfo) +static void rip_timeout_update(struct rip *rip, struct rip_info *rinfo) { if (rinfo->metric != RIP_METRIC_INFINITY) { RIP_TIMER_OFF(rinfo->t_timeout); - RIP_TIMER_ON(rinfo->t_timeout, rip_timeout, rip->timeout_time); + thread_add_timer(master, rip_timeout, rinfo, rip->timeout_time, + &rinfo->t_timeout); } } @@ -324,7 +331,7 @@ static int rip_filter(int rip_distribute, struct prefix_ipv4 *p, } /* All interface filter check. */ - dist = distribute_lookup(rip->distribute_ctx, NULL); + dist = distribute_lookup(ri->rip->distribute_ctx, NULL); if (dist) { if (dist->list[distribute]) { alist = access_list_lookup(AFI_IP, @@ -363,9 +370,9 @@ static int rip_filter(int rip_distribute, struct prefix_ipv4 *p, } /* Check nexthop address validity. */ -static int rip_nexthop_check(struct in_addr *addr) +static int rip_nexthop_check(struct rip *rip, struct in_addr *addr) { - struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); + struct vrf *vrf = vrf_lookup_by_id(rip->vrf_id); struct interface *ifp; struct listnode *cnode; struct connected *ifc; @@ -390,6 +397,7 @@ static int rip_nexthop_check(struct in_addr *addr) static void rip_rte_process(struct rte *rte, struct sockaddr_in *from, struct interface *ifp) { + struct rip *rip; int ret; struct prefix_ipv4 p; struct route_node *rp; @@ -410,9 +418,10 @@ static void rip_rte_process(struct rte *rte, struct sockaddr_in *from, /* Make sure mask is applied. */ apply_mask_ipv4(&p); - /* Apply input filters. */ ri = ifp->info; + rip = ri->rip; + /* Apply input filters. */ ret = rip_filter(RIP_FILTER_IN, &p, ri); if (ret < 0) return; @@ -471,7 +480,7 @@ static void rip_rte_process(struct rte *rte, struct sockaddr_in *from, nexthop = &rte->nexthop; /* Check if nexthop address is myself, then do nothing. */ - if (rip_nexthop_check(nexthop) < 0) { + if (rip_nexthop_check(rip, nexthop) < 0) { if (IS_RIP_DEBUG_PACKET) zlog_debug("Nexthop address %s is myself", inet_ntoa(*nexthop)); @@ -486,7 +495,7 @@ static void rip_rte_process(struct rte *rte, struct sockaddr_in *from, newinfo.nh.type = NEXTHOP_TYPE_IPV4; newinfo.metric = rte->metric; newinfo.tag = ntohs(rte->tag); - newinfo.distance = rip_distance_apply(&newinfo); + newinfo.distance = rip_distance_apply(rip, &newinfo); new_dist = newinfo.distance ? newinfo.distance : ZEBRA_RIP_DISTANCE_DEFAULT; @@ -570,7 +579,7 @@ static void rip_rte_process(struct rte *rte, struct sockaddr_in *from, mark it as a ghost */ if (new_dist <= old_dist && rte->metric != RIP_METRIC_INFINITY) - rip_ecmp_replace(&newinfo); + rip_ecmp_replace(rip, &newinfo); route_unlock_node(rp); return; @@ -587,7 +596,7 @@ static void rip_rte_process(struct rte *rte, struct sockaddr_in *from, infinity (there is no point in adding a route which unusable). */ if (rte->metric != RIP_METRIC_INFINITY) - rip_ecmp_add(&newinfo); + rip_ecmp_add(rip, &newinfo); } else { /* Route is there but we are not sure the route is RIP or not. */ @@ -616,18 +625,18 @@ static void rip_rte_process(struct rte *rte, struct sockaddr_in *from, || ((old_dist != new_dist) && same)) { if (listcount(list) == 1) { if (newinfo.metric != RIP_METRIC_INFINITY) - rip_ecmp_replace(&newinfo); + rip_ecmp_replace(rip, &newinfo); else - rip_ecmp_delete(rinfo); + rip_ecmp_delete(rip, rinfo); } else { if (newinfo.metric < rinfo->metric) - rip_ecmp_replace(&newinfo); + rip_ecmp_replace(rip, &newinfo); else if (newinfo.metric > rinfo->metric) - rip_ecmp_delete(rinfo); + rip_ecmp_delete(rip, rinfo); else if (new_dist < old_dist) - rip_ecmp_replace(&newinfo); + rip_ecmp_replace(rip, &newinfo); else if (new_dist > old_dist) - rip_ecmp_delete(rinfo); + rip_ecmp_delete(rip, rinfo); else { int update = CHECK_FLAG(rinfo->flags, RIP_RTF_FIB) @@ -641,20 +650,20 @@ static void rip_rte_process(struct rte *rte, struct sockaddr_in *from, RIP_TIMER_OFF(rinfo->t_garbage_collect); memcpy(rinfo, &newinfo, sizeof(struct rip_info)); - rip_timeout_update(rinfo); + rip_timeout_update(rip, rinfo); if (update) - rip_zebra_ipv4_add(rp); + rip_zebra_ipv4_add(rip, rp); /* - Set the route change flag on the * first entry. */ rinfo = listgetdata(listhead(list)); SET_FLAG(rinfo->flags, RIP_RTF_CHANGED); - rip_event(RIP_TRIGGERED_UPDATE, 0); + rip_event(rip, RIP_TRIGGERED_UPDATE, 0); } } } else /* same & no change */ - rip_timeout_update(rinfo); + rip_timeout_update(rip, rinfo); /* Unlock tempolary lock of the route. */ route_unlock_node(rp); @@ -1080,6 +1089,8 @@ static void rip_response_process(struct rip_packet *packet, int size, struct sockaddr_in *from, struct connected *ifc) { + struct rip_interface *ri = ifc->ifp->info; + struct rip *rip = ri->rip; caddr_t lim; struct rte *rte; struct prefix_ipv4 ifaddr; @@ -1095,7 +1106,7 @@ static void rip_response_process(struct rip_packet *packet, int size, if (from->sin_port != htons(RIP_PORT_DEFAULT)) { zlog_info("response doesn't come from RIP port: %d", from->sin_port); - rip_peer_bad_packet(from); + rip_peer_bad_packet(rip, from); return; } @@ -1103,12 +1114,12 @@ static void rip_response_process(struct rip_packet *packet, int size, whether the datagram is from a valid neighbor; the source of the datagram must be on a directly connected network (RFC2453 - Sec. 3.9.2) */ - if (if_lookup_address((void *)&from->sin_addr, AF_INET, VRF_DEFAULT) + if (if_lookup_address((void *)&from->sin_addr, AF_INET, rip->vrf_id) == NULL) { zlog_info( "This datagram doesn't came from a valid neighbor: %s", inet_ntoa(from->sin_addr)); - rip_peer_bad_packet(from); + rip_peer_bad_packet(rip, from); return; } @@ -1118,7 +1129,7 @@ static void rip_response_process(struct rip_packet *packet, int size, ; /* Alredy done in rip_read () */ /* Update RIP peer. */ - rip_peer_update(from, packet->version); + rip_peer_update(rip, from, packet->version); /* Set RTE pointer. */ rte = packet->rte; @@ -1147,7 +1158,7 @@ static void rip_response_process(struct rip_packet *packet, int size, if (!rip_destination_check(rte->prefix)) { zlog_info( "Network is net 0 or net 127 or it is not unicast network"); - rip_peer_bad_route(from); + rip_peer_bad_route(rip, from); continue; } @@ -1157,7 +1168,7 @@ static void rip_response_process(struct rip_packet *packet, int size, /* - is the metric valid (i.e., between 1 and 16, inclusive) */ if (!(rte->metric >= 1 && rte->metric <= 16)) { zlog_info("Route's metric is not in the 1-16 range."); - rip_peer_bad_route(from); + rip_peer_bad_route(rip, from); continue; } @@ -1165,7 +1176,7 @@ static void rip_response_process(struct rip_packet *packet, int size, if (packet->version == RIPv1 && rte->nexthop.s_addr != 0) { zlog_info("RIPv1 packet with nexthop value %s", inet_ntoa(rte->nexthop)); - rip_peer_bad_route(from); + rip_peer_bad_route(rip, from); continue; } @@ -1186,7 +1197,7 @@ static void rip_response_process(struct rip_packet *packet, int size, } if (!if_lookup_address((void *)&rte->nexthop, AF_INET, - VRF_DEFAULT)) { + rip->vrf_id)) { struct route_node *rn; struct rip_info *rinfo; @@ -1297,7 +1308,7 @@ static void rip_response_process(struct rip_packet *packet, int size, zlog_warn( "RIPv2 address %s is not mask /%d applied one", inet_ntoa(rte->prefix), ip_masklen(rte->mask)); - rip_peer_bad_route(from); + rip_peer_bad_route(rip, from); continue; } @@ -1371,10 +1382,14 @@ int rip_create_socket(void) static int rip_send_packet(uint8_t *buf, int size, struct sockaddr_in *to, struct connected *ifc) { + struct rip_interface *ri; + struct rip *rip; int ret; struct sockaddr_in sin; assert(ifc != NULL); + ri = ifc->ifp->info; + rip = ri->rip; if (IS_RIP_DEBUG_PACKET) { #define ADDRESS_SIZE 20 @@ -1447,9 +1462,10 @@ static int rip_send_packet(uint8_t *buf, int size, struct sockaddr_in *to, } /* Add redistributed route to RIP table. */ -void rip_redistribute_add(int type, int sub_type, struct prefix_ipv4 *p, - struct nexthop *nh, unsigned int metric, - unsigned char distance, route_tag_t tag) +void rip_redistribute_add(struct rip *rip, int type, int sub_type, + struct prefix_ipv4 *p, struct nexthop *nh, + unsigned int metric, unsigned char distance, + route_tag_t tag) { int ret; struct route_node *rp = NULL; @@ -1496,22 +1512,22 @@ void rip_redistribute_add(int type, int sub_type, struct prefix_ipv4 *p, } } - (void)rip_ecmp_replace(&newinfo); + (void)rip_ecmp_replace(rip, &newinfo); route_unlock_node(rp); } else - (void)rip_ecmp_add(&newinfo); + (void)rip_ecmp_add(rip, &newinfo); if (IS_RIP_DEBUG_EVENT) { zlog_debug("Redistribute new prefix %s/%d", inet_ntoa(p->prefix), p->prefixlen); } - rip_event(RIP_TRIGGERED_UPDATE, 0); + rip_event(rip, RIP_TRIGGERED_UPDATE, 0); } /* Delete redistributed route from RIP table. */ -void rip_redistribute_delete(int type, int sub_type, struct prefix_ipv4 *p, - ifindex_t ifindex) +void rip_redistribute_delete(struct rip *rip, int type, int sub_type, + struct prefix_ipv4 *p, ifindex_t ifindex) { int ret; struct route_node *rp; @@ -1545,9 +1561,9 @@ void rip_redistribute_delete(int type, int sub_type, struct prefix_ipv4 *p, inet_ntoa(p->prefix), p->prefixlen, ifindex2ifname(ifindex, - VRF_DEFAULT)); + rip->vrf_id)); - rip_event(RIP_TRIGGERED_UPDATE, 0); + rip_event(rip, RIP_TRIGGERED_UPDATE, 0); } } route_unlock_node(rp); @@ -1558,6 +1574,7 @@ void rip_redistribute_delete(int type, int sub_type, struct prefix_ipv4 *p, static void rip_request_process(struct rip_packet *packet, int size, struct sockaddr_in *from, struct connected *ifc) { + struct rip *rip; caddr_t lim; struct rte *rte; struct prefix_ipv4 p; @@ -1573,13 +1590,14 @@ static void rip_request_process(struct rip_packet *packet, int size, ri = ifc->ifp->info; if (!ri->running) return; + rip = ri->rip; /* When passive interface is specified, suppress responses */ if (ri->passive) return; /* RIP peer update. */ - rip_peer_update(from, packet->version); + rip_peer_update(rip, from, packet->version); lim = ((caddr_t)packet) + size; rte = packet->rte; @@ -1635,6 +1653,7 @@ static void rip_request_process(struct rip_packet *packet, int size, /* First entry point of RIP packet. */ static int rip_read(struct thread *t) { + struct rip *rip = THREAD_ARG(t); int sock; int ret; int rtenum; @@ -1654,7 +1673,7 @@ static int rip_read(struct thread *t) rip->t_read = NULL; /* Add myself to tne next event */ - rip_event(RIP_READ, sock); + rip_event(rip, RIP_READ, sock); /* RIPd manages only IPv4. */ memset(&from, 0, sizeof(struct sockaddr_in)); @@ -1668,14 +1687,14 @@ static int rip_read(struct thread *t) } /* Check is this packet comming from myself? */ - if (if_check_address(from.sin_addr)) { + if (if_check_address(rip, from.sin_addr)) { if (IS_RIP_DEBUG_PACKET) zlog_debug("ignore packet comes from myself"); return -1; } /* Which interface is this packet comes from. */ - ifc = if_lookup_address((void *)&from.sin_addr, AF_INET, VRF_DEFAULT); + ifc = if_lookup_address((void *)&from.sin_addr, AF_INET, rip->vrf_id); if (ifc) ifp = ifc->ifp; @@ -1712,13 +1731,13 @@ static int rip_read(struct thread *t) if (len < RIP_PACKET_MINSIZ) { zlog_warn("packet size %d is smaller than minimum size %d", len, RIP_PACKET_MINSIZ); - rip_peer_bad_packet(&from); + rip_peer_bad_packet(rip, &from); return len; } if (len > RIP_PACKET_MAXSIZ) { zlog_warn("packet size %d is larger than max size %d", len, RIP_PACKET_MAXSIZ); - rip_peer_bad_packet(&from); + rip_peer_bad_packet(rip, &from); return len; } @@ -1726,7 +1745,7 @@ static int rip_read(struct thread *t) if ((len - RIP_PACKET_MINSIZ) % 20) { zlog_warn("packet size %d is wrong for RIP packet alignment", len); - rip_peer_bad_packet(&from); + rip_peer_bad_packet(rip, &from); return len; } @@ -1740,7 +1759,7 @@ static int rip_read(struct thread *t) if (packet->version == 0) { zlog_info("version 0 with command %d received.", packet->command); - rip_peer_bad_packet(&from); + rip_peer_bad_packet(rip, &from); return -1; } @@ -1757,11 +1776,11 @@ static int rip_read(struct thread *t) /* Is RIP running or is this RIP neighbor ?*/ ri = ifp->info; - if (!ri->running && !rip_neighbor_lookup(&from)) { + if (!ri->running && !rip_neighbor_lookup(rip, &from)) { if (IS_RIP_DEBUG_EVENT) zlog_debug("RIP is not enabled on interface %s.", ifp->name); - rip_peer_bad_packet(&from); + rip_peer_bad_packet(rip, &from); return -1; } @@ -1775,7 +1794,7 @@ static int rip_read(struct thread *t) zlog_debug( " packet's v%d doesn't fit to if version spec", packet->version); - rip_peer_bad_packet(&from); + rip_peer_bad_packet(rip, &from); return -1; } @@ -1790,7 +1809,7 @@ static int rip_read(struct thread *t) "packet RIPv%d is dropped because authentication disabled", packet->version); ripd_notif_send_auth_type_failure(ifp->name); - rip_peer_bad_packet(&from); + rip_peer_bad_packet(rip, &from); return -1; } @@ -1827,7 +1846,7 @@ static int rip_read(struct thread *t) "RIPv1" " dropped because authentication enabled"); ripd_notif_send_auth_type_failure(ifp->name); - rip_peer_bad_packet(&from); + rip_peer_bad_packet(rip, &from); return -1; } } else if (ri->auth_type != RIP_NO_AUTH) { @@ -1840,7 +1859,7 @@ static int rip_read(struct thread *t) zlog_debug( "RIPv2 authentication failed: no auth RTE in packet"); ripd_notif_send_auth_type_failure(ifp->name); - rip_peer_bad_packet(&from); + rip_peer_bad_packet(rip, &from); return -1; } @@ -1851,7 +1870,7 @@ static int rip_read(struct thread *t) "RIPv2" " dropped because authentication enabled"); ripd_notif_send_auth_type_failure(ifp->name); - rip_peer_bad_packet(&from); + rip_peer_bad_packet(rip, &from); return -1; } @@ -1887,7 +1906,7 @@ static int rip_read(struct thread *t) zlog_debug("RIPv2 %s authentication failure", auth_desc); ripd_notif_send_auth_failure(ifp->name); - rip_peer_bad_packet(&from); + rip_peer_bad_packet(rip, &from); return -1; } } @@ -1906,16 +1925,16 @@ static int rip_read(struct thread *t) zlog_info( "Obsolete command %s received, please sent it to routed", lookup_msg(rip_msg, packet->command, NULL)); - rip_peer_bad_packet(&from); + rip_peer_bad_packet(rip, &from); break; case RIP_POLL_ENTRY: zlog_info("Obsolete command %s received", lookup_msg(rip_msg, packet->command, NULL)); - rip_peer_bad_packet(&from); + rip_peer_bad_packet(rip, &from); break; default: zlog_info("Unknown RIP command %d received", packet->command); - rip_peer_bad_packet(&from); + rip_peer_bad_packet(rip, &from); break; } @@ -1955,6 +1974,7 @@ static int rip_write_rte(int num, struct stream *s, struct prefix_ipv4 *p, void rip_output_process(struct connected *ifc, struct sockaddr_in *to, int route_type, uint8_t version) { + struct rip *rip; int ret; struct stream *s; struct route_node *rp; @@ -1984,6 +2004,10 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to, ifc->ifp->name, ifc->ifp->ifindex); } + /* Get RIP interface. */ + ri = ifc->ifp->info; + rip = ri->rip; + /* Set output stream. */ s = rip->obuf; @@ -1991,9 +2015,6 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to, stream_reset(s); rtemax = RIP_MAX_RTE; - /* Get RIP interface. */ - ri = ifc->ifp->info; - /* If output interface is in simple password authentication mode, we need space for authentication data. */ if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD) @@ -2366,9 +2387,9 @@ static void rip_update_interface(struct connected *ifc, uint8_t version, } /* Update send to all interface and neighbor. */ -static void rip_update_process(int route_type) +static void rip_update_process(struct rip *rip, int route_type) { - struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); + struct vrf *vrf = vrf_lookup_by_id(rip->vrf_id); struct listnode *ifnode, *ifnnode; struct connected *connected; struct interface *ifp; @@ -2431,7 +2452,7 @@ static void rip_update_process(int route_type) p = &rp->p; connected = if_lookup_address(&p->u.prefix4, AF_INET, - VRF_DEFAULT); + rip->vrf_id); if (!connected) { zlog_warn( "Neighbor %s doesn't have connected interface!", @@ -2453,6 +2474,8 @@ static void rip_update_process(int route_type) /* RIP's periodical timer. */ static int rip_update(struct thread *t) { + struct rip *rip = THREAD_ARG(t); + /* Clear timer pointer. */ rip->t_update = NULL; @@ -2460,7 +2483,7 @@ static int rip_update(struct thread *t) zlog_debug("update timer fire!"); /* Process update output. */ - rip_update_process(rip_all_route); + rip_update_process(rip, rip_all_route); /* Triggered updates may be suppressed if a regular update is due by the time the triggered update would be sent. */ @@ -2468,13 +2491,13 @@ static int rip_update(struct thread *t) rip->trigger = 0; /* Register myself. */ - rip_event(RIP_UPDATE_EVENT, 0); + rip_event(rip, RIP_UPDATE_EVENT, 0); return 0; } /* Walk down the RIP routing table then clear changed flag. */ -static void rip_clear_changed_flag(void) +static void rip_clear_changed_flag(struct rip *rip) { struct route_node *rp; struct rip_info *rinfo = NULL; @@ -2494,7 +2517,7 @@ static void rip_clear_changed_flag(void) /* Triggered update interval timer. */ static int rip_triggered_interval(struct thread *t) { - int rip_triggered_update(struct thread *); + struct rip *rip = THREAD_ARG(t); rip->t_triggered_interval = NULL; @@ -2508,6 +2531,7 @@ static int rip_triggered_interval(struct thread *t) /* Execute triggered update. */ static int rip_triggered_update(struct thread *t) { + struct rip *rip = THREAD_ARG(t); int interval; /* Clear thred pointer. */ @@ -2523,11 +2547,11 @@ static int rip_triggered_update(struct thread *t) /* Split Horizon processing is done when generating triggered updates as well as normal updates (see section 2.6). */ - rip_update_process(rip_changed_route); + rip_update_process(rip, rip_changed_route); /* Once all of the triggered updates have been generated, the route change flags should be cleared. */ - rip_clear_changed_flag(); + rip_clear_changed_flag(rip); /* After a triggered update is sent, a timer should be set for a random interval between 1 and 5 seconds. If other changes that @@ -2536,14 +2560,14 @@ static int rip_triggered_update(struct thread *t) interval = (random() % 5) + 1; rip->t_triggered_interval = NULL; - thread_add_timer(master, rip_triggered_interval, NULL, interval, + thread_add_timer(master, rip_triggered_interval, rip, interval, &rip->t_triggered_interval); return 0; } /* Withdraw redistributed route. */ -void rip_redistribute_withdraw(int type) +void rip_redistribute_withdraw(struct rip *rip, int type) { struct route_node *rp; struct rip_info *rinfo = NULL; @@ -2572,17 +2596,31 @@ void rip_redistribute_withdraw(int type) p->prefixlen, ifindex2ifname( rinfo->nh.ifindex, - VRF_DEFAULT)); + rip->vrf_id)); } - rip_event(RIP_TRIGGERED_UPDATE, 0); + rip_event(rip, RIP_TRIGGERED_UPDATE, 0); } } } +struct rip *rip_lookup_by_vrf_id(vrf_id_t vrf_id) +{ + struct vrf *vrf; + + vrf = vrf_lookup_by_id(vrf_id); + if (!vrf) + return NULL; + + return vrf->info; +} + /* Create new RIP instance and set it to global variable. */ -int rip_create(int socket) +struct rip *rip_create(struct vrf *vrf, int socket) { + struct rip *rip; + struct interface *ifp; + rip = XCALLOC(MTYPE_RIP, sizeof(struct rip)); /* Set initial value. */ @@ -2606,6 +2644,7 @@ int rip_create(int socket) /* Initialize RIP data structures. */ rip->table = route_table_init(); + route_table_set_info(rip->table, rip); rip->neighbor = route_table_init(); rip->peer_list = list_new(); rip->peer_list->cmp = (int (*)(void *, void *))rip_peer_list_cmp; @@ -2632,10 +2671,20 @@ int rip_create(int socket) rip->sock = socket; /* Create read and timer thread. */ - rip_event(RIP_READ, rip->sock); - rip_event(RIP_UPDATE_EVENT, 1); + rip_event(rip, RIP_READ, rip->sock); + rip_event(rip, RIP_UPDATE_EVENT, 1); - return 0; + /* Link RIP instance to VRF. */ + rip->vrf_id = vrf->vrf_id; + vrf->info = rip; + FOR_ALL_INTERFACES (vrf, ifp) { + struct rip_interface *ri; + + ri = ifp->info; + ri->rip = rip; + } + + return rip; } /* Sned RIP request to the destination. */ @@ -2704,19 +2753,19 @@ static int rip_update_jitter(unsigned long time) return jitter / JITTER_BOUND; } -void rip_event(enum rip_event event, int sock) +void rip_event(struct rip *rip, enum rip_event event, int sock) { int jitter = 0; switch (event) { case RIP_READ: rip->t_read = NULL; - thread_add_read(master, rip_read, NULL, sock, &rip->t_read); + thread_add_read(master, rip_read, rip, sock, &rip->t_read); break; case RIP_UPDATE_EVENT: RIP_TIMER_OFF(rip->t_update); jitter = rip_update_jitter(rip->update_time); - thread_add_timer(master, rip_update, NULL, + thread_add_timer(master, rip_update, rip, sock ? 2 : rip->update_time + jitter, &rip->t_update); break; @@ -2724,7 +2773,7 @@ void rip_event(enum rip_event event, int sock) if (rip->t_triggered_interval) rip->trigger = 1; else - thread_add_event(master, rip_triggered_update, NULL, 0, + thread_add_event(master, rip_triggered_update, rip, 0, &rip->t_triggered_update); break; default: @@ -2772,16 +2821,13 @@ static void rip_distance_table_node_cleanup(struct route_table *table, } /* Apply RIP information to distance method. */ -uint8_t rip_distance_apply(struct rip_info *rinfo) +uint8_t rip_distance_apply(struct rip *rip, struct rip_info *rinfo) { struct route_node *rn; struct prefix_ipv4 p; struct rip_distance *rdistance; struct access_list *alist; - if (!rip) - return 0; - memset(&p, 0, sizeof(struct prefix_ipv4)); p.family = AF_INET; p.prefix = rinfo->from; @@ -2813,7 +2859,7 @@ uint8_t rip_distance_apply(struct rip_info *rinfo) return 0; } -static void rip_distance_show(struct vty *vty) +static void rip_distance_show(struct vty *vty, struct rip *rip) { struct route_node *rn; struct rip_distance *rdistance; @@ -2840,16 +2886,13 @@ static void rip_distance_show(struct vty *vty) } /* Update ECMP routes to zebra when ECMP is disabled. */ -void rip_ecmp_disable(void) +void rip_ecmp_disable(struct rip *rip) { struct route_node *rp; struct rip_info *rinfo, *tmp_rinfo; struct list *list; struct listnode *node, *nextnode; - if (!rip) - return; - for (rp = route_top(rip->table); rp; rp = route_next(rp)) if ((list = rp->info) != NULL && listcount(list) > 1) { rinfo = listgetdata(listhead(list)); @@ -2867,13 +2910,13 @@ void rip_ecmp_disable(void) } /* Update zebra. */ - rip_zebra_ipv4_add(rp); + rip_zebra_ipv4_add(rip, rp); /* Set the route change flag. */ SET_FLAG(rinfo->flags, RIP_RTF_CHANGED); /* Signal the output process to trigger an update. */ - rip_event(RIP_TRIGGERED_UPDATE, 0); + rip_event(rip, RIP_TRIGGERED_UPDATE, 0); } } @@ -2924,11 +2967,13 @@ DEFUN (show_ip_rip, IP_STR "Show RIP routes\n") { + struct rip *rip; struct route_node *np; struct rip_info *rinfo = NULL; struct list *list = NULL; struct listnode *listnode = NULL; + rip = rip_lookup_by_vrf_id(VRF_DEFAULT); if (!rip) return CMD_SUCCESS; @@ -3028,13 +3073,15 @@ DEFUN (show_ip_rip_status, "Show RIP routes\n" "IP routing protocol process parameters and statistics\n") { - struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); + struct rip *rip; + struct vrf *vrf; struct interface *ifp; struct rip_interface *ri; extern const struct message ri_version_msg[]; const char *send_version; const char *receive_version; + rip = rip_lookup_by_vrf_id(VRF_DEFAULT); if (!rip) return CMD_SUCCESS; @@ -3055,7 +3102,7 @@ DEFUN (show_ip_rip_status, /* Redistribute information. */ vty_out(vty, " Redistributing:"); - rip_show_redistribute_config(vty); + rip_show_redistribute_config(vty, rip); vty_out(vty, "\n"); vty_out(vty, " Default version control: send version %s,", @@ -3068,6 +3115,7 @@ DEFUN (show_ip_rip_status, vty_out(vty, " Interface Send Recv Key-chain\n"); + vrf = vrf_lookup_by_id(rip->vrf_id); FOR_ALL_INTERFACES (vrf, ifp) { ri = ifp->info; @@ -3098,7 +3146,7 @@ DEFUN (show_ip_rip_status, } vty_out(vty, " Routing for Networks:\n"); - rip_show_network_config(vty); + rip_show_network_config(vty, rip); { int found_passive = 0; @@ -3120,9 +3168,9 @@ DEFUN (show_ip_rip_status, vty_out(vty, " Routing Information Sources:\n"); vty_out(vty, " Gateway BadPackets BadRoutes Distance Last Update\n"); - rip_peer_display(vty); + rip_peer_display(vty, rip); - rip_distance_show(vty); + rip_distance_show(vty, rip); return CMD_SUCCESS; } @@ -3136,16 +3184,21 @@ static int config_write_rip(struct vty *vty) dnode = yang_dnode_get(running_config->dnode, "/frr-ripd:ripd/instance"); if (dnode) { + struct rip *rip; + write++; nb_cli_show_dnode_cmds(vty, dnode, false); - /* Distribute configuration. */ - write += config_write_distribute(vty, - rip->distribute_ctx); + rip = rip_lookup_by_vrf_id(VRF_DEFAULT); + if (rip) { + /* Distribute configuration. */ + write += config_write_distribute(vty, + rip->distribute_ctx); - /* Interface routemap configuration */ - write += config_write_if_rmap(vty); + /* Interface routemap configuration */ + write += config_write_if_rmap(vty); + } } return write; } @@ -3214,6 +3267,8 @@ static void rip_distribute_update(struct distribute_ctx *ctx, void rip_distribute_update_interface(struct interface *ifp) { + struct rip_interface *ri = ifp->info; + struct rip *rip = ri->rip; struct distribute *dist; if (!rip) @@ -3240,8 +3295,10 @@ static void rip_distribute_update_all_wrapper(struct access_list *notused) } /* Delete all added rip route. */ -void rip_clean(void) +void rip_clean(struct rip *rip) { + struct vrf *vrf; + struct interface *ifp; struct route_node *rp; /* Clear RIP routes */ @@ -3255,7 +3312,7 @@ void rip_clean(void) rinfo = listgetdata(listhead(list)); if (rip_route_rte(rinfo)) - rip_zebra_ipv4_delete(rp); + rip_zebra_ipv4_delete(rip, rp); for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) { RIP_TIMER_OFF(rinfo->t_timeout); @@ -3292,15 +3349,25 @@ void rip_clean(void) list_delete(&rip->peer_list); distribute_list_delete(&rip->distribute_ctx); - rip_clean_network(); - rip_passive_nondefault_clean(); + rip_clean_network(rip); + rip_passive_nondefault_clean(rip); vector_free(rip->enable_interface); route_table_finish(rip->enable_network); vector_free(rip->passive_nondefault); list_delete(&rip->offset_list_master); - rip_interfaces_clean(); + rip_interfaces_clean(rip); route_table_finish(rip->distance_table); - rip_redistribute_clean(); + rip_redistribute_clean(rip); + + vrf = vrf_lookup_by_id(rip->vrf_id); + vrf->info = NULL; + + FOR_ALL_INTERFACES (vrf, ifp) { + struct rip_interface *ri; + + ri = ifp->info; + ri->rip = NULL; + } XFREE(MTYPE_RIP, rip); } @@ -3344,17 +3411,12 @@ void rip_if_rmap_update_interface(struct interface *ifp) rip_if_rmap_update(if_rmap); } -static void rip_routemap_update_redistribute(void) +static void rip_routemap_update_redistribute(struct rip *rip) { - int i; - - if (rip) { - for (i = 0; i < ZEBRA_ROUTE_MAX; i++) { - if (rip->route_map[i].name) - rip->route_map[i].map = - route_map_lookup_by_name( - rip->route_map[i].name); - } + for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) { + if (rip->route_map[i].name) + rip->route_map[i].map = route_map_lookup_by_name( + rip->route_map[i].name); } } @@ -3362,12 +3424,15 @@ static void rip_routemap_update_redistribute(void) static void rip_routemap_update(const char *notused) { struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT); + struct rip *rip; struct interface *ifp; FOR_ALL_INTERFACES (vrf, ifp) rip_if_rmap_update_interface(ifp); - rip_routemap_update_redistribute(); + rip = vrf->info; + if (rip) + rip_routemap_update_redistribute(rip); } /* Allocate new rip structure and set default value. */ diff --git a/ripd/ripd.h b/ripd/ripd.h index af0d3021a..a18a74157 100644 --- a/ripd/ripd.h +++ b/ripd/ripd.h @@ -99,6 +99,9 @@ /* RIP structure. */ struct rip { + /* VRF ID. */ + vrf_id_t vrf_id; + /* RIP socket. */ int sock; @@ -256,6 +259,9 @@ typedef enum { /* RIP specific interface configuration. */ struct rip_interface { + /* Parent routing instance. */ + struct rip *rip; + /* RIP is enabled on this interface. */ int enable_network; int enable_interface; @@ -313,6 +319,9 @@ struct rip_interface { /* RIP peer information. */ struct rip_peer { + /* Parent routing instance. */ + struct rip *rip; + /* Peer address. */ struct in_addr addr; @@ -385,6 +394,9 @@ enum rip_event { #define RIP_OFFSET_LIST_MAX 2 struct rip_offset_list { + /* Parent routing instance. */ + struct rip *rip; + char *ifname; struct { @@ -396,75 +408,86 @@ struct rip_offset_list { /* Prototypes. */ extern void rip_init(void); -extern void rip_clean(void); -extern void rip_clean_network(void); -extern void rip_interfaces_clean(void); -extern int rip_passive_nondefault_set(const char *ifname); -extern int rip_passive_nondefault_unset(const char *ifname); -extern void rip_passive_nondefault_clean(void); +extern void rip_clean(struct rip *rip); +extern void rip_clean_network(struct rip *rip); +extern void rip_interfaces_clean(struct rip *rip); +extern int rip_passive_nondefault_set(struct rip *rip, const char *ifname); +extern int rip_passive_nondefault_unset(struct rip *rip, const char *ifname); +extern void rip_passive_nondefault_clean(struct rip *rip); extern void rip_if_init(void); extern void rip_route_map_init(void); extern void rip_zclient_init(struct thread_master *); extern void rip_zclient_stop(void); -extern int if_check_address(struct in_addr addr); -extern int rip_create(int socket); +extern int if_check_address(struct rip *rip, struct in_addr addr); +extern struct rip *rip_lookup_by_vrf_id(vrf_id_t vrf_id); +extern struct rip *rip_create(struct vrf *vrf, int socket); extern int rip_request_send(struct sockaddr_in *, struct interface *, uint8_t, struct connected *); -extern int rip_neighbor_lookup(struct sockaddr_in *); -extern int rip_neighbor_add(struct prefix_ipv4 *p); -extern int rip_neighbor_delete(struct prefix_ipv4 *p); +extern int rip_neighbor_lookup(struct rip *rip, struct sockaddr_in *from); +extern int rip_neighbor_add(struct rip *rip, struct prefix_ipv4 *p); +extern int rip_neighbor_delete(struct rip *rip, struct prefix_ipv4 *p); -extern int rip_enable_network_add(struct prefix *p); -extern int rip_enable_network_delete(struct prefix *p); -extern int rip_enable_if_add(const char *ifname); -extern int rip_enable_if_delete(const char *ifname); +extern int rip_enable_network_add(struct rip *rip, struct prefix *p); +extern int rip_enable_network_delete(struct rip *rip, struct prefix *p); +extern int rip_enable_if_add(struct rip *rip, const char *ifname); +extern int rip_enable_if_delete(struct rip *rip, const char *ifname); -extern void rip_event(enum rip_event, int); -extern void rip_ecmp_disable(void); +extern void rip_event(struct rip *rip, enum rip_event event, int sock); +extern void rip_ecmp_disable(struct rip *rip); extern int rip_create_socket(void); -extern int rip_redistribute_check(int); -extern void rip_redistribute_conf_update(int type); -extern void rip_redistribute_conf_delete(int type); -extern void rip_redistribute_add(int type, int sub_type, struct prefix_ipv4 *p, - struct nexthop *nh, unsigned int metric, - unsigned char distance, route_tag_t tag); -extern void rip_redistribute_delete(int, int, struct prefix_ipv4 *, ifindex_t); -extern void rip_redistribute_withdraw(int); -extern void rip_zebra_ipv4_add(struct route_node *); -extern void rip_zebra_ipv4_delete(struct route_node *); +extern int rip_redistribute_check(struct rip *rip, int type); +extern void rip_redistribute_conf_update(struct rip *rip, int type); +extern void rip_redistribute_conf_delete(struct rip *rip, int type); +extern void rip_redistribute_add(struct rip *rip, int type, int sub_type, + struct prefix_ipv4 *p, struct nexthop *nh, + unsigned int metric, unsigned char distance, + route_tag_t tag); +extern void rip_redistribute_delete(struct rip *rip, int type, int sub_type, + struct prefix_ipv4 *p, ifindex_t ifindex); +extern void rip_redistribute_withdraw(struct rip *rip, int type); +extern void rip_zebra_ipv4_add(struct rip *rip, struct route_node *rp); +extern void rip_zebra_ipv4_delete(struct rip *rip, struct route_node *rp); extern void rip_interface_multicast_set(int, struct connected *); extern void rip_distribute_update_interface(struct interface *); extern void rip_if_rmap_update_interface(struct interface *); -extern int rip_show_network_config(struct vty *); -extern void rip_show_redistribute_config(struct vty *); - -extern void rip_peer_update(struct sockaddr_in *, uint8_t); -extern void rip_peer_bad_route(struct sockaddr_in *); -extern void rip_peer_bad_packet(struct sockaddr_in *); -extern void rip_peer_display(struct vty *); -extern struct rip_peer *rip_peer_lookup(struct in_addr *); -extern struct rip_peer *rip_peer_lookup_next(struct in_addr *); +extern int rip_show_network_config(struct vty *vty, struct rip *rip); +extern void rip_show_redistribute_config(struct vty *vty, struct rip *rip); + +extern void rip_peer_update(struct rip *rip, struct sockaddr_in *from, + uint8_t version); +extern void rip_peer_bad_route(struct rip *rip, struct sockaddr_in *from); +extern void rip_peer_bad_packet(struct rip *rip, struct sockaddr_in *from); +extern void rip_peer_display(struct vty *vty, struct rip *rip); +extern struct rip_peer *rip_peer_lookup(struct rip *rip, struct in_addr *addr); +extern struct rip_peer *rip_peer_lookup_next(struct rip *rip, + struct in_addr *addr); extern int rip_peer_list_cmp(struct rip_peer *p1, struct rip_peer *p2); extern void rip_peer_list_del(void *arg); extern void rip_info_free(struct rip_info *); +extern struct rip *rip_info_get_instance(const struct rip_info *rinfo); extern struct rip_distance *rip_distance_new(void); extern void rip_distance_free(struct rip_distance *rdistance); -extern uint8_t rip_distance_apply(struct rip_info *); -extern void rip_redistribute_clean(void); +extern uint8_t rip_distance_apply(struct rip *rip, struct rip_info *rinfo); +extern void rip_redistribute_clean(struct rip *rip); extern int rip_route_rte(struct rip_info *rinfo); -extern struct rip_info *rip_ecmp_add(struct rip_info *); -extern struct rip_info *rip_ecmp_replace(struct rip_info *); -extern struct rip_info *rip_ecmp_delete(struct rip_info *); - -extern struct rip_offset_list *rip_offset_list_new(const char *ifname); +extern struct rip_info *rip_ecmp_add(struct rip *rip, + struct rip_info *rinfo_new); +extern struct rip_info *rip_ecmp_replace(struct rip *rip, + struct rip_info *rinfo_new); +extern struct rip_info *rip_ecmp_delete(struct rip *rip, + struct rip_info *rinfo); + +extern struct rip_offset_list *rip_offset_list_new(struct rip *rip, + const char *ifname); extern void offset_list_del(struct rip_offset_list *offset); -extern struct rip_offset_list *rip_offset_list_lookup(const char *ifname); +extern struct rip_offset_list *rip_offset_list_lookup(struct rip *rip, + const char *ifname); extern int rip_offset_list_apply_in(struct prefix_ipv4 *, struct interface *, uint32_t *); extern int rip_offset_list_apply_out(struct prefix_ipv4 *, struct interface *, @@ -476,9 +499,6 @@ extern int offset_list_cmp(struct rip_offset_list *o1, extern void ripd_notif_send_auth_type_failure(const char *ifname); extern void ripd_notif_send_auth_failure(const char *ifname); -/* There is only one rip strucutre. */ -extern struct rip *rip; - extern struct zebra_privs_t ripd_privs; /* Master thread strucutre. */ |