diff options
| -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 2e432ec79c..ca6dea1b37 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 8c6340f6c7..46babe2e0b 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 b0f2b62a5d..f5a75707e8 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 94dc175d14..b3f84fe50f 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 07b295030e..08aa61257d 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 54c8a2eb8c..5a6b71fbaa 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 607dc168f4..6fbc170cb9 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 a6cfd9b151..6b9c5fe886 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 af0d3021a6..a18a741579 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. */  | 
