summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ripd/rip_interface.c134
-rw-r--r--ripd/rip_main.c11
-rw-r--r--ripd/rip_northbound.c146
-rw-r--r--ripd/rip_offset.c18
-rw-r--r--ripd/rip_peer.c25
-rw-r--r--ripd/rip_snmp.c19
-rw-r--r--ripd/rip_zebra.c47
-rw-r--r--ripd/ripd.c343
-rw-r--r--ripd/ripd.h114
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. */