diff options
| -rw-r--r-- | pimd/pim_assert.c | 2 | ||||
| -rw-r--r-- | pimd/pim_ifchannel.c | 60 | ||||
| -rw-r--r-- | pimd/pim_ifchannel.h | 3 | ||||
| -rw-r--r-- | pimd/pim_mroute.c | 4 | ||||
| -rw-r--r-- | pimd/pim_msdp.c | 2 | ||||
| -rw-r--r-- | pimd/pim_register.c | 2 | ||||
| -rw-r--r-- | pimd/pim_upstream.c | 14 | ||||
| -rw-r--r-- | pimd/pim_upstream.h | 3 | 
8 files changed, 56 insertions, 34 deletions
diff --git a/pimd/pim_assert.c b/pimd/pim_assert.c index 6af52bbf4d..934fea5a9e 100644 --- a/pimd/pim_assert.c +++ b/pimd/pim_assert.c @@ -147,7 +147,7 @@ static int dispatch_assert(struct interface *ifp, struct in_addr source_addr,  	memset(&sg, 0, sizeof(struct prefix_sg));  	sg.src = source_addr;  	sg.grp = group_addr; -	ch = pim_ifchannel_add(ifp, &sg, 0); +	ch = pim_ifchannel_add(ifp, &sg, 0, 0);  	if (!ch) {  		zlog_warn(  			"%s: (S,G)=%s failure creating channel on interface %s", diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index 5f3901e49b..922ee647a5 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -509,7 +509,8 @@ static struct pim_ifchannel *pim_ifchannel_find_parent(struct pim_ifchannel *ch)  }  struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp, -					struct prefix_sg *sg, int flags) +					struct prefix_sg *sg, +					uint8_t source_flags, int up_flags)  {  	struct pim_interface *pim_ifp;  	struct pim_ifchannel *ch; @@ -521,27 +522,19 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp,  	pim_ifp = ifp->info; -	up = pim_upstream_add(pim_ifp->pim, sg, NULL, flags, -			      __PRETTY_FUNCTION__); -	if (!up) { -		zlog_err( -			"%s: could not attach upstream (S,G)=%s on interface %s", -			__PRETTY_FUNCTION__, pim_str_sg_dump(sg), ifp->name); -		return NULL; -	} -  	ch = XCALLOC(MTYPE_PIM_IFCHANNEL, sizeof(*ch));  	if (!ch) {  		zlog_warn(  			"%s: pim_ifchannel_new() failure for (S,G)=%s on interface %s",  			__PRETTY_FUNCTION__, up->sg_str, ifp->name); - -		pim_upstream_del(pim_ifp->pim, up, __PRETTY_FUNCTION__);  		return NULL;  	}  	ch->flags = 0; -	ch->upstream = up; +	if ((source_flags & PIM_ENCODE_RPT_BIT) +	    && !(source_flags & PIM_ENCODE_WC_BIT)) +		PIM_IF_FLAG_SET_S_G_RPT(ch->flags); +  	ch->interface = ifp;  	ch->sg = *sg;  	pim_str_sg_set(sg, ch->sg_str); @@ -561,6 +554,32 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp,  	ch->t_ifjoin_prune_pending_timer = NULL;  	ch->ifjoin_creation = 0; +	/* Attach to list */ +	listnode_add_sort(pim_ifp->pim_ifchannel_list, ch); +	ch = hash_get(pim_ifp->pim_ifchannel_hash, ch, hash_alloc_intern); +	listnode_add_sort(pim_ifp->pim->ifchannel_list, ch); + +	up = pim_upstream_add(pim_ifp->pim, sg, NULL, up_flags, +			      __PRETTY_FUNCTION__, ch); + +	if (!up) { +		zlog_err( +			"%s: could not attach upstream (S,G)=%s on interface %s", +			__PRETTY_FUNCTION__, pim_str_sg_dump(sg), ifp->name); + +		pim_ifchannel_remove_children(ch); +		if (ch) +			list_delete(ch->sources); + +		listnode_delete(pim_ifp->pim_ifchannel_list, ch); +		hash_release(pim_ifp->pim_ifchannel_hash, ch); +		listnode_delete(pim_ifp->pim->ifchannel_list, ch); +		XFREE(MTYPE_PIM_IFCHANNEL, ch); +		return NULL; +	} + +	listnode_add_sort(up->ifchannels, ch); +  	ch->ifassert_my_metric = pim_macro_ch_my_assert_metric_eval(ch);  	ch->ifassert_winner_metric = pim_macro_ch_my_assert_metric_eval(ch); @@ -580,13 +599,6 @@ struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp,  	else  		PIM_IF_FLAG_UNSET_ASSERT_TRACKING_DESIRED(ch->flags); -	/* Attach to list */ -	listnode_add_sort(pim_ifp->pim_ifchannel_list, ch); -	ch = hash_get(pim_ifp->pim_ifchannel_hash, ch, hash_alloc_intern); -	listnode_add_sort(pim_ifp->pim->ifchannel_list, ch); - -	listnode_add_sort(up->ifchannels, ch); -  	if (PIM_DEBUG_PIM_TRACE)  		zlog_debug("%s: ifchannel %s is created ", __PRETTY_FUNCTION__,  			   ch->sg_str); @@ -772,7 +784,8 @@ void pim_ifchannel_join_add(struct interface *ifp, struct in_addr neigh_addr,  		return;  	} -	ch = pim_ifchannel_add(ifp, sg, PIM_UPSTREAM_FLAG_MASK_SRC_PIM); +	ch = pim_ifchannel_add(ifp, sg, source_flags, +			       PIM_UPSTREAM_FLAG_MASK_SRC_PIM);  	if (!ch)  		return; @@ -914,7 +927,8 @@ void pim_ifchannel_prune(struct interface *ifp, struct in_addr upstream,  		return;  	} -	ch = pim_ifchannel_add(ifp, sg, PIM_UPSTREAM_FLAG_MASK_SRC_PIM); +	ch = pim_ifchannel_add(ifp, sg, source_flags, +			       PIM_UPSTREAM_FLAG_MASK_SRC_PIM);  	if (!ch)  		return; @@ -1027,7 +1041,7 @@ int pim_ifchannel_local_membership_add(struct interface *ifp,  		}  	} -	ch = pim_ifchannel_add(ifp, sg, PIM_UPSTREAM_FLAG_MASK_SRC_IGMP); +	ch = pim_ifchannel_add(ifp, sg, 0, PIM_UPSTREAM_FLAG_MASK_SRC_IGMP);  	if (!ch) {  		return 0;  	} diff --git a/pimd/pim_ifchannel.h b/pimd/pim_ifchannel.h index 2260fd451b..3fd717bec8 100644 --- a/pimd/pim_ifchannel.h +++ b/pimd/pim_ifchannel.h @@ -116,7 +116,8 @@ void pim_ifchannel_delete_on_noinfo(struct interface *ifp);  struct pim_ifchannel *pim_ifchannel_find(struct interface *ifp,  					 struct prefix_sg *sg);  struct pim_ifchannel *pim_ifchannel_add(struct interface *ifp, -					struct prefix_sg *sg, int flags); +					struct prefix_sg *sg, uint8_t ch_flags, +					int up_flags);  void pim_ifchannel_join_add(struct interface *ifp, struct in_addr neigh_addr,  			    struct in_addr upstream, struct prefix_sg *sg,  			    uint8_t source_flags, uint16_t holdtime); diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index fa53e568f4..0e0a275155 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -248,7 +248,7 @@ static int pim_mroute_msg_wholepkt(int fd, struct interface *ifp,  		if (up && PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(up->flags)) {  			up = pim_upstream_add(pim_ifp->pim, &sg, ifp,  					      PIM_UPSTREAM_FLAG_MASK_SRC_LHR, -					      __PRETTY_FUNCTION__); +					      __PRETTY_FUNCTION__, NULL);  			if (!up) {  				if (PIM_DEBUG_MROUTE)  					zlog_debug( @@ -520,7 +520,7 @@ static int pim_mroute_msg_wrvifwhole(int fd, struct interface *ifp,  	if (pim_if_connected_to_source(ifp, sg.src)) {  		up = pim_upstream_add(pim_ifp->pim, &sg, ifp,  				      PIM_UPSTREAM_FLAG_MASK_FHR, -				      __PRETTY_FUNCTION__); +				      __PRETTY_FUNCTION__, NULL);  		if (!up) {  			if (PIM_DEBUG_MROUTE)  				zlog_debug( diff --git a/pimd/pim_msdp.c b/pimd/pim_msdp.c index 3578f005dd..34962122a0 100644 --- a/pimd/pim_msdp.c +++ b/pimd/pim_msdp.c @@ -205,7 +205,7 @@ static void pim_msdp_sa_upstream_update(struct pim_msdp_sa *sa,  	 * as if a JP message was rxed addressed to the RP itself." */  	up = pim_upstream_add(sa->pim, &sa->sg, NULL /* iif */,  			      PIM_UPSTREAM_FLAG_MASK_SRC_MSDP, -			      __PRETTY_FUNCTION__); +			      __PRETTY_FUNCTION__, NULL);  	sa->up = up;  	if (up) { diff --git a/pimd/pim_register.c b/pimd/pim_register.c index 605dd43d5e..d0de91bb45 100644 --- a/pimd/pim_register.c +++ b/pimd/pim_register.c @@ -370,7 +370,7 @@ int pim_register_recv(struct interface *ifp, struct in_addr dest_addr,  			upstream = pim_upstream_add(  				pim_ifp->pim, &sg, ifp,  				PIM_UPSTREAM_FLAG_MASK_SRC_STREAM, -				__PRETTY_FUNCTION__); +				__PRETTY_FUNCTION__, NULL);  			if (!upstream) {  				zlog_warn("Failure to create upstream state");  				return 1; diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 7880bfd491..e7987eb6e7 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -602,7 +602,8 @@ int pim_upstream_compare(void *arg1, void *arg2)  static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,  					     struct prefix_sg *sg,  					     struct interface *incoming, -					     int flags) +					     int flags, +					     struct pim_ifchannel *ch)  {  	enum pim_rpf_result rpf_result;  	struct pim_interface *pim_ifp; @@ -617,6 +618,9 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,  	up->sg = *sg;  	pim_str_sg_set(sg, up->sg_str); +	if (ch) +		ch->upstream = up; +  	up = hash_get(pim->upstream_hash, up, hash_alloc_intern);  	if (!pim_rp_set_upstream_addr(pim, &up->upstream_addr, sg->src,  				      sg->grp)) { @@ -748,7 +752,8 @@ struct pim_upstream *pim_upstream_find_or_add(struct prefix_sg *sg,  					up->ref_count);  		}  	} else -		up = pim_upstream_add(pim_ifp->pim, sg, incoming, flags, name); +		up = pim_upstream_add(pim_ifp->pim, sg, incoming, flags, name, +				      NULL);  	return up;  } @@ -766,7 +771,8 @@ void pim_upstream_ref(struct pim_upstream *up, int flags, const char *name)  struct pim_upstream *pim_upstream_add(struct pim_instance *pim,  				      struct prefix_sg *sg,  				      struct interface *incoming, int flags, -				      const char *name) +				      const char *name, +				      struct pim_ifchannel *ch)  {  	struct pim_upstream *up = NULL;  	int found = 0; @@ -776,7 +782,7 @@ struct pim_upstream *pim_upstream_add(struct pim_instance *pim,  		pim_upstream_ref(up, flags, name);  		found = 1;  	} else { -		up = pim_upstream_new(pim, sg, incoming, flags); +		up = pim_upstream_new(pim, sg, incoming, flags, ch);  	}  	if (PIM_DEBUG_TRACE) { diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h index b261b8cbae..af4af2a369 100644 --- a/pimd/pim_upstream.h +++ b/pimd/pim_upstream.h @@ -146,7 +146,8 @@ struct pim_upstream *pim_upstream_find_or_add(struct prefix_sg *sg,  struct pim_upstream *pim_upstream_add(struct pim_instance *pim,  				      struct prefix_sg *sg,  				      struct interface *ifp, int flags, -				      const char *name); +				      const char *name, +				      struct pim_ifchannel *ch);  void pim_upstream_ref(struct pim_upstream *up, int flags, const char *name);  struct pim_upstream *pim_upstream_del(struct pim_instance *pim,  				      struct pim_upstream *up,  | 
