diff options
| author | whitespace / reindent <invalid@invalid.invalid> | 2017-07-17 14:03:14 +0200 | 
|---|---|---|
| committer | whitespace / reindent <invalid@invalid.invalid> | 2017-07-17 14:04:07 +0200 | 
| commit | d62a17aedeb0eebdba98238874bb13d62c48dbf9 (patch) | |
| tree | 3b319b1d61c8b85b4d1f06adf8b844bb8a9b5107 /pimd/pim_join.c | |
| parent | 888ac268a0077fc9ebd1218cec6ae472af0bfc40 (diff) | |
*: reindentreindent-master-after
indent.py `git ls-files | pcregrep '\.[ch]$' | pcregrep -v '^(ldpd|babeld|nhrpd)/'`
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'pimd/pim_join.c')
| -rw-r--r-- | pimd/pim_join.c | 918 | 
1 files changed, 461 insertions, 457 deletions
diff --git a/pimd/pim_join.c b/pimd/pim_join.c index 35deecfd81..9bc5c2d9cc 100644 --- a/pimd/pim_join.c +++ b/pimd/pim_join.c @@ -39,301 +39,295 @@  #include "pim_rp.h"  #include "pim_jp_agg.h" -static void -on_trace (const char *label, -	  struct interface *ifp, struct in_addr src) +static void on_trace(const char *label, struct interface *ifp, +		     struct in_addr src)  { -  if (PIM_DEBUG_PIM_TRACE) { -    char src_str[INET_ADDRSTRLEN]; -    pim_inet4_dump("<src?>", src, src_str, sizeof(src_str)); -    zlog_debug("%s: from %s on %s", -	       label, src_str, ifp->name); -  } +	if (PIM_DEBUG_PIM_TRACE) { +		char src_str[INET_ADDRSTRLEN]; +		pim_inet4_dump("<src?>", src, src_str, sizeof(src_str)); +		zlog_debug("%s: from %s on %s", label, src_str, ifp->name); +	}  } -static void recv_join(struct interface *ifp, -		      struct pim_neighbor *neigh, -		      uint16_t holdtime, -		      struct in_addr upstream, -		      struct prefix_sg *sg, -		      uint8_t source_flags) +static void recv_join(struct interface *ifp, struct pim_neighbor *neigh, +		      uint16_t holdtime, struct in_addr upstream, +		      struct prefix_sg *sg, uint8_t source_flags)  { -  struct pim_interface *pim_ifp = NULL; - -  if (PIM_DEBUG_PIM_TRACE) { -    char up_str[INET_ADDRSTRLEN]; -    char neigh_str[INET_ADDRSTRLEN]; -    pim_inet4_dump("<upstream?>", upstream, up_str, sizeof(up_str)); -    pim_inet4_dump("<neigh?>", neigh->source_addr, neigh_str, sizeof(neigh_str)); -    zlog_warn("%s: join (S,G)=%s rpt=%d wc=%d upstream=%s holdtime=%d from %s on %s", -	      __PRETTY_FUNCTION__, -	      pim_str_sg_dump (sg), -	      source_flags & PIM_RPT_BIT_MASK, -	      source_flags & PIM_WILDCARD_BIT_MASK, -	      up_str, holdtime, neigh_str, ifp->name); -  } - -  pim_ifp = ifp->info; -  zassert(pim_ifp); - -  ++pim_ifp->pim_ifstat_join_recv; - -  /* -   * If the RPT and WC are set it's a (*,G) -   * and the source is the RP -   */ -  if ((source_flags & PIM_RPT_BIT_MASK) && -      (source_flags & PIM_WILDCARD_BIT_MASK)) -    { -      struct pim_rpf *rp = RP (sg->grp); - -      /* -       * If the RP sent in the message is not -       * our RP for the group, drop the message -       */ -      if (sg->src.s_addr != rp->rpf_addr.u.prefix4.s_addr) -	return; - -      sg->src.s_addr = INADDR_ANY; -    } - -  /* Restart join expiry timer */ -  pim_ifchannel_join_add(ifp, neigh->source_addr, upstream, -			 sg, source_flags, holdtime); - +	struct pim_interface *pim_ifp = NULL; + +	if (PIM_DEBUG_PIM_TRACE) { +		char up_str[INET_ADDRSTRLEN]; +		char neigh_str[INET_ADDRSTRLEN]; +		pim_inet4_dump("<upstream?>", upstream, up_str, sizeof(up_str)); +		pim_inet4_dump("<neigh?>", neigh->source_addr, neigh_str, +			       sizeof(neigh_str)); +		zlog_warn( +			"%s: join (S,G)=%s rpt=%d wc=%d upstream=%s holdtime=%d from %s on %s", +			__PRETTY_FUNCTION__, pim_str_sg_dump(sg), +			source_flags & PIM_RPT_BIT_MASK, +			source_flags & PIM_WILDCARD_BIT_MASK, up_str, holdtime, +			neigh_str, ifp->name); +	} + +	pim_ifp = ifp->info; +	zassert(pim_ifp); + +	++pim_ifp->pim_ifstat_join_recv; + +	/* +	 * If the RPT and WC are set it's a (*,G) +	 * and the source is the RP +	 */ +	if ((source_flags & PIM_RPT_BIT_MASK) +	    && (source_flags & PIM_WILDCARD_BIT_MASK)) { +		struct pim_rpf *rp = RP(sg->grp); + +		/* +		 * If the RP sent in the message is not +		 * our RP for the group, drop the message +		 */ +		if (sg->src.s_addr != rp->rpf_addr.u.prefix4.s_addr) +			return; + +		sg->src.s_addr = INADDR_ANY; +	} + +	/* Restart join expiry timer */ +	pim_ifchannel_join_add(ifp, neigh->source_addr, upstream, sg, +			       source_flags, holdtime);  } -static void recv_prune(struct interface *ifp, -		       struct pim_neighbor *neigh, -		       uint16_t holdtime, -		       struct in_addr upstream, -		       struct prefix_sg *sg, -		       uint8_t source_flags) +static void recv_prune(struct interface *ifp, struct pim_neighbor *neigh, +		       uint16_t holdtime, struct in_addr upstream, +		       struct prefix_sg *sg, uint8_t source_flags)  { -  struct pim_interface *pim_ifp = NULL; - -  if (PIM_DEBUG_PIM_TRACE) { -    char up_str[INET_ADDRSTRLEN]; -    char neigh_str[INET_ADDRSTRLEN]; -    pim_inet4_dump("<upstream?>", upstream, up_str, sizeof(up_str)); -    pim_inet4_dump("<neigh?>", neigh->source_addr, neigh_str, sizeof(neigh_str)); -    zlog_warn("%s: prune (S,G)=%s rpt=%d wc=%d upstream=%s holdtime=%d from %s on %s", -	      __PRETTY_FUNCTION__, -	      pim_str_sg_dump (sg), -	      source_flags & PIM_RPT_BIT_MASK, -	      source_flags & PIM_WILDCARD_BIT_MASK, -	      up_str, holdtime, neigh_str, ifp->name); -  } - -  pim_ifp = ifp->info; -  zassert(pim_ifp); - -  ++pim_ifp->pim_ifstat_prune_recv; - -  if ((source_flags & PIM_RPT_BIT_MASK) && -      (source_flags & PIM_WILDCARD_BIT_MASK)) -    { -      struct pim_rpf *rp = RP (sg->grp); - -      // Ignoring Prune *,G's at the moment. -      if (sg->src.s_addr != rp->rpf_addr.u.prefix4.s_addr) -	return; - -      sg->src.s_addr = INADDR_ANY; -    } - -  pim_ifchannel_prune(ifp, upstream, sg, source_flags, holdtime); - +	struct pim_interface *pim_ifp = NULL; + +	if (PIM_DEBUG_PIM_TRACE) { +		char up_str[INET_ADDRSTRLEN]; +		char neigh_str[INET_ADDRSTRLEN]; +		pim_inet4_dump("<upstream?>", upstream, up_str, sizeof(up_str)); +		pim_inet4_dump("<neigh?>", neigh->source_addr, neigh_str, +			       sizeof(neigh_str)); +		zlog_warn( +			"%s: prune (S,G)=%s rpt=%d wc=%d upstream=%s holdtime=%d from %s on %s", +			__PRETTY_FUNCTION__, pim_str_sg_dump(sg), +			source_flags & PIM_RPT_BIT_MASK, +			source_flags & PIM_WILDCARD_BIT_MASK, up_str, holdtime, +			neigh_str, ifp->name); +	} + +	pim_ifp = ifp->info; +	zassert(pim_ifp); + +	++pim_ifp->pim_ifstat_prune_recv; + +	if ((source_flags & PIM_RPT_BIT_MASK) +	    && (source_flags & PIM_WILDCARD_BIT_MASK)) { +		struct pim_rpf *rp = RP(sg->grp); + +		// Ignoring Prune *,G's at the moment. +		if (sg->src.s_addr != rp->rpf_addr.u.prefix4.s_addr) +			return; + +		sg->src.s_addr = INADDR_ANY; +	} + +	pim_ifchannel_prune(ifp, upstream, sg, source_flags, holdtime);  } -int pim_joinprune_recv(struct interface *ifp, -		       struct pim_neighbor *neigh, -		       struct in_addr src_addr, -		       uint8_t *tlv_buf, int tlv_buf_size) +int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh, +		       struct in_addr src_addr, uint8_t *tlv_buf, +		       int tlv_buf_size)  { -  struct prefix   msg_upstream_addr; -  uint8_t         msg_num_groups; -  uint16_t        msg_holdtime; -  int             addr_offset; -  uint8_t        *buf; -  uint8_t        *pastend; -  int             remain; -  int             group; - -  buf     = tlv_buf; -  pastend = tlv_buf + tlv_buf_size; - -  /* -    Parse ucast addr -  */ -  addr_offset = pim_parse_addr_ucast (&msg_upstream_addr, -				      buf, pastend - buf); -  if (addr_offset < 1) { -    char src_str[INET_ADDRSTRLEN]; -    pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str)); -    zlog_warn("%s: pim_parse_addr_ucast() failure: from %s on %s", -	      __PRETTY_FUNCTION__, -	      src_str, ifp->name); -    return -1; -  } -  buf += addr_offset; - -  /* -    Check upstream address family -   */ -  if (msg_upstream_addr.family != AF_INET) { -    if (PIM_DEBUG_PIM_J_P) { -      char src_str[INET_ADDRSTRLEN]; -      pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str)); -      zlog_warn("%s: ignoring join/prune directed to unexpected addr family=%d from %s on %s", -		__PRETTY_FUNCTION__, -		msg_upstream_addr.family, src_str, ifp->name); -    } -    return -2; -  } - -  remain = pastend - buf; -  if (remain < 4) { -    char src_str[INET_ADDRSTRLEN]; -    pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str)); -    zlog_warn("%s: short join/prune message buffer for group list: size=%d minimum=%d from %s on %s", -	      __PRETTY_FUNCTION__, -	      remain, 4, src_str, ifp->name); -    return -4; -  } - -  ++buf; /* skip reserved byte */ -  msg_num_groups = *(const uint8_t *) buf; -  ++buf; -  msg_holdtime = ntohs(*(const uint16_t *) buf); -  ++buf; -  ++buf; - -  if (PIM_DEBUG_PIM_J_P) { -    char src_str[INET_ADDRSTRLEN]; -    char upstream_str[INET_ADDRSTRLEN]; -    pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str)); -    pim_inet4_dump("<addr?>", msg_upstream_addr.u.prefix4, -		   upstream_str, sizeof(upstream_str)); -    zlog_debug ("%s: join/prune upstream=%s groups=%d holdtime=%d from %s on %s", -		__PRETTY_FUNCTION__, -		upstream_str, msg_num_groups, msg_holdtime, -		src_str, ifp->name); -  } - -  /* Scan groups */ -  for (group = 0; group < msg_num_groups; ++group) { -    struct prefix_sg sg; -    uint8_t       msg_source_flags; -    uint16_t      msg_num_joined_sources; -    uint16_t      msg_num_pruned_sources; -    int           source; -    struct        pim_ifchannel *starg_ch = NULL, *sg_ch = NULL; -    uint8_t       starg_alone = 0; - -    memset (&sg, 0, sizeof (struct prefix_sg)); -    addr_offset = pim_parse_addr_group (&sg, -					buf, pastend - buf); -    if (addr_offset < 1) { -      return -5; -    } -    buf += addr_offset; - -    remain = pastend - buf; -    if (remain < 4) { -      char src_str[INET_ADDRSTRLEN]; -      pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str)); -      zlog_warn("%s: short join/prune buffer for source list: size=%d minimum=%d from %s on %s", -		__PRETTY_FUNCTION__, -		remain, 4, src_str, ifp->name); -      return -6; -    } - -    msg_num_joined_sources = ntohs(*(const uint16_t *) buf); -    buf += 2; -    msg_num_pruned_sources = ntohs(*(const uint16_t *) buf); -    buf += 2; - -    if (PIM_DEBUG_PIM_J_P) { -      char src_str[INET_ADDRSTRLEN]; -      char upstream_str[INET_ADDRSTRLEN]; -      char group_str[INET_ADDRSTRLEN]; -      pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str)); -      pim_inet4_dump("<addr?>", msg_upstream_addr.u.prefix4, -		     upstream_str, sizeof(upstream_str)); -      pim_inet4_dump("<grp?>", sg.grp, -		     group_str, sizeof(group_str)); -      zlog_warn("%s: join/prune upstream=%s group=%s/32 join_src=%d prune_src=%d from %s on %s", -		__PRETTY_FUNCTION__, -		upstream_str, group_str, -		msg_num_joined_sources, msg_num_pruned_sources, -		src_str, ifp->name); -    } - -    /* Scan joined sources */ -    for (source = 0; source < msg_num_joined_sources; ++source) { -      addr_offset = pim_parse_addr_source (&sg, -					   &msg_source_flags, -					   buf, pastend - buf); -      if (addr_offset < 1) { -	return -7; -      } - -      buf += addr_offset; - -      recv_join(ifp, neigh, msg_holdtime, -		msg_upstream_addr.u.prefix4, -		&sg, -		msg_source_flags); - -      if (sg.src.s_addr == INADDR_ANY) -        { -          starg_alone = 1; -          starg_ch = pim_ifchannel_find (ifp, &sg); -	  if (starg_ch) -	    pim_ifchannel_set_star_g_join_state (starg_ch, 0, msg_source_flags, 1, starg_alone); -        } -    } - -    /* Scan pruned sources */ -    for (source = 0; source < msg_num_pruned_sources; ++source) { -      addr_offset = pim_parse_addr_source (&sg, -					   &msg_source_flags, -					   buf, pastend - buf); -      if (addr_offset < 1) { -	return -8; -      } - -      sg_ch = pim_ifchannel_find (ifp, &sg); - -      buf += addr_offset; -      starg_alone = 0; -      recv_prune(ifp, neigh, msg_holdtime, -		 msg_upstream_addr.u.prefix4, -		 &sg, -		 msg_source_flags); - -      /* Received SG-RPT Prune delete oif from specific S,G */ -      if (starg_ch && sg_ch && (msg_source_flags & PIM_RPT_BIT_MASK) -               && !(msg_source_flags & PIM_WILDCARD_BIT_MASK)) -        { -          struct pim_upstream *up = sg_ch->upstream; -          PIM_IF_FLAG_SET_S_G_RPT(sg_ch->flags); -          if (up) -            { -              if (PIM_DEBUG_TRACE) -                zlog_debug ("%s: SGRpt flag is set, del inherit oif from up %s", -                     __PRETTY_FUNCTION__, up->sg_str); -              pim_channel_del_oif (up->channel_oil, starg_ch->interface, PIM_OIF_FLAG_PROTO_STAR); -            } -        } -    } -    if (starg_ch) -      pim_ifchannel_set_star_g_join_state (starg_ch, 1, msg_source_flags, 0, starg_alone); -    starg_ch = NULL; -  } /* scan groups */ - -  return 0; +	struct prefix msg_upstream_addr; +	uint8_t msg_num_groups; +	uint16_t msg_holdtime; +	int addr_offset; +	uint8_t *buf; +	uint8_t *pastend; +	int remain; +	int group; + +	buf = tlv_buf; +	pastend = tlv_buf + tlv_buf_size; + +	/* +	  Parse ucast addr +	*/ +	addr_offset = +		pim_parse_addr_ucast(&msg_upstream_addr, buf, pastend - buf); +	if (addr_offset < 1) { +		char src_str[INET_ADDRSTRLEN]; +		pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str)); +		zlog_warn("%s: pim_parse_addr_ucast() failure: from %s on %s", +			  __PRETTY_FUNCTION__, src_str, ifp->name); +		return -1; +	} +	buf += addr_offset; + +	/* +	  Check upstream address family +	 */ +	if (msg_upstream_addr.family != AF_INET) { +		if (PIM_DEBUG_PIM_J_P) { +			char src_str[INET_ADDRSTRLEN]; +			pim_inet4_dump("<src?>", src_addr, src_str, +				       sizeof(src_str)); +			zlog_warn( +				"%s: ignoring join/prune directed to unexpected addr family=%d from %s on %s", +				__PRETTY_FUNCTION__, msg_upstream_addr.family, +				src_str, ifp->name); +		} +		return -2; +	} + +	remain = pastend - buf; +	if (remain < 4) { +		char src_str[INET_ADDRSTRLEN]; +		pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str)); +		zlog_warn( +			"%s: short join/prune message buffer for group list: size=%d minimum=%d from %s on %s", +			__PRETTY_FUNCTION__, remain, 4, src_str, ifp->name); +		return -4; +	} + +	++buf; /* skip reserved byte */ +	msg_num_groups = *(const uint8_t *)buf; +	++buf; +	msg_holdtime = ntohs(*(const uint16_t *)buf); +	++buf; +	++buf; + +	if (PIM_DEBUG_PIM_J_P) { +		char src_str[INET_ADDRSTRLEN]; +		char upstream_str[INET_ADDRSTRLEN]; +		pim_inet4_dump("<src?>", src_addr, src_str, sizeof(src_str)); +		pim_inet4_dump("<addr?>", msg_upstream_addr.u.prefix4, +			       upstream_str, sizeof(upstream_str)); +		zlog_debug( +			"%s: join/prune upstream=%s groups=%d holdtime=%d from %s on %s", +			__PRETTY_FUNCTION__, upstream_str, msg_num_groups, +			msg_holdtime, src_str, ifp->name); +	} + +	/* Scan groups */ +	for (group = 0; group < msg_num_groups; ++group) { +		struct prefix_sg sg; +		uint8_t msg_source_flags; +		uint16_t msg_num_joined_sources; +		uint16_t msg_num_pruned_sources; +		int source; +		struct pim_ifchannel *starg_ch = NULL, *sg_ch = NULL; +		uint8_t starg_alone = 0; + +		memset(&sg, 0, sizeof(struct prefix_sg)); +		addr_offset = pim_parse_addr_group(&sg, buf, pastend - buf); +		if (addr_offset < 1) { +			return -5; +		} +		buf += addr_offset; + +		remain = pastend - buf; +		if (remain < 4) { +			char src_str[INET_ADDRSTRLEN]; +			pim_inet4_dump("<src?>", src_addr, src_str, +				       sizeof(src_str)); +			zlog_warn( +				"%s: short join/prune buffer for source list: size=%d minimum=%d from %s on %s", +				__PRETTY_FUNCTION__, remain, 4, src_str, +				ifp->name); +			return -6; +		} + +		msg_num_joined_sources = ntohs(*(const uint16_t *)buf); +		buf += 2; +		msg_num_pruned_sources = ntohs(*(const uint16_t *)buf); +		buf += 2; + +		if (PIM_DEBUG_PIM_J_P) { +			char src_str[INET_ADDRSTRLEN]; +			char upstream_str[INET_ADDRSTRLEN]; +			char group_str[INET_ADDRSTRLEN]; +			pim_inet4_dump("<src?>", src_addr, src_str, +				       sizeof(src_str)); +			pim_inet4_dump("<addr?>", msg_upstream_addr.u.prefix4, +				       upstream_str, sizeof(upstream_str)); +			pim_inet4_dump("<grp?>", sg.grp, group_str, +				       sizeof(group_str)); +			zlog_warn( +				"%s: join/prune upstream=%s group=%s/32 join_src=%d prune_src=%d from %s on %s", +				__PRETTY_FUNCTION__, upstream_str, group_str, +				msg_num_joined_sources, msg_num_pruned_sources, +				src_str, ifp->name); +		} + +		/* Scan joined sources */ +		for (source = 0; source < msg_num_joined_sources; ++source) { +			addr_offset = pim_parse_addr_source( +				&sg, &msg_source_flags, buf, pastend - buf); +			if (addr_offset < 1) { +				return -7; +			} + +			buf += addr_offset; + +			recv_join(ifp, neigh, msg_holdtime, +				  msg_upstream_addr.u.prefix4, &sg, +				  msg_source_flags); + +			if (sg.src.s_addr == INADDR_ANY) { +				starg_alone = 1; +				starg_ch = pim_ifchannel_find(ifp, &sg); +				if (starg_ch) +					pim_ifchannel_set_star_g_join_state( +						starg_ch, 0, msg_source_flags, +						1, starg_alone); +			} +		} + +		/* Scan pruned sources */ +		for (source = 0; source < msg_num_pruned_sources; ++source) { +			addr_offset = pim_parse_addr_source( +				&sg, &msg_source_flags, buf, pastend - buf); +			if (addr_offset < 1) { +				return -8; +			} + +			sg_ch = pim_ifchannel_find(ifp, &sg); + +			buf += addr_offset; +			starg_alone = 0; +			recv_prune(ifp, neigh, msg_holdtime, +				   msg_upstream_addr.u.prefix4, &sg, +				   msg_source_flags); + +			/* Received SG-RPT Prune delete oif from specific S,G */ +			if (starg_ch && sg_ch +			    && (msg_source_flags & PIM_RPT_BIT_MASK) +			    && !(msg_source_flags & PIM_WILDCARD_BIT_MASK)) { +				struct pim_upstream *up = sg_ch->upstream; +				PIM_IF_FLAG_SET_S_G_RPT(sg_ch->flags); +				if (up) { +					if (PIM_DEBUG_TRACE) +						zlog_debug( +							"%s: SGRpt flag is set, del inherit oif from up %s", +							__PRETTY_FUNCTION__, +							up->sg_str); +					pim_channel_del_oif( +						up->channel_oil, +						starg_ch->interface, +						PIM_OIF_FLAG_PROTO_STAR); +				} +			} +		} +		if (starg_ch) +			pim_ifchannel_set_star_g_join_state( +				starg_ch, 1, msg_source_flags, 0, starg_alone); +		starg_ch = NULL; +	} /* scan groups */ + +	return 0;  }  /* @@ -402,177 +396,187 @@ int pim_joinprune_recv(struct interface *ifp,   *  |        Pruned Source Address n (Encoded-Source format)        |   *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   */ -int pim_joinprune_send(struct pim_rpf *rpf, -                       struct list *groups) +int pim_joinprune_send(struct pim_rpf *rpf, struct list *groups)  { -  struct pim_jp_agg_group *group; -  struct pim_interface *pim_ifp = NULL; -  struct pim_jp_groups *grp = NULL; -  struct pim_jp *msg; -  struct listnode *node, *nnode; -  uint8_t pim_msg[10000]; -  uint8_t *curr_ptr = pim_msg; -  bool new_packet = true; -  size_t packet_left = 0; -  size_t packet_size = 0; -  size_t group_size = 0; - -  on_trace (__PRETTY_FUNCTION__, rpf->source_nexthop.interface, rpf->rpf_addr.u.prefix4); - -  if (rpf->source_nexthop.interface) -    pim_ifp = rpf->source_nexthop.interface->info; -  else -    { -      zlog_warn ("%s: RPF interface is not present", __PRETTY_FUNCTION__); -      return -1; -    } - -  if (!pim_ifp) -    { -      zlog_warn ("%s: multicast not enabled on interface %s", -              __PRETTY_FUNCTION__, -              rpf->source_nexthop.interface->name); -      return -1; -    } - -  if (PIM_INADDR_IS_ANY(rpf->rpf_addr.u.prefix4)) -    { -      if (PIM_DEBUG_PIM_J_P) { -        char dst_str[INET_ADDRSTRLEN]; -        pim_inet4_dump("<dst?>", rpf->rpf_addr.u.prefix4, dst_str, sizeof(dst_str)); -        zlog_debug("%s: upstream=%s is myself on interface %s", -                   __PRETTY_FUNCTION__, -                   dst_str, rpf->source_nexthop.interface->name); -      } -      return 0; -    } - -  /* -    RFC 4601: 4.3.1.  Sending Hello Messages - -    Thus, if a router needs to send a Join/Prune or Assert message on -    an interface on which it has not yet sent a Hello message with the -    currently configured IP address, then it MUST immediately send the -    relevant Hello message without waiting for the Hello Timer to -    expire, followed by the Join/Prune or Assert message. -  */ -  pim_hello_require(rpf->source_nexthop.interface); - -  for (ALL_LIST_ELEMENTS(groups, node, nnode, group)) -    { -      if (new_packet) -        { -          msg = (struct pim_jp *)pim_msg; - -          memset(msg, 0, sizeof (*msg)); - -          pim_msg_addr_encode_ipv4_ucast ((uint8_t *)&msg->addr, rpf->rpf_addr.u.prefix4); -          msg->reserved   = 0; -          msg->holdtime   = htons(PIM_JP_HOLDTIME); - -          new_packet = false; - -          grp = &msg->groups[0]; -          curr_ptr = (uint8_t *)grp; -          packet_size  = sizeof (struct pim_msg_header); -          packet_size += sizeof (struct pim_encoded_ipv4_unicast); -          packet_size += 4;  // reserved (1) + groups (1) + holdtime (2) - -          packet_left = rpf->source_nexthop.interface->mtu - 24; -          packet_left -= packet_size; -        } -      if (PIM_DEBUG_PIM_J_P) { -        char dst_str[INET_ADDRSTRLEN]; -        char grp_str[INET_ADDRSTRLEN]; -        pim_inet4_dump("<dst?>", rpf->rpf_addr.u.prefix4, dst_str, sizeof(dst_str)); -        pim_inet4_dump("<grp?>", group->group, grp_str, sizeof(grp_str)); -        zlog_debug("%s: sending (G)=%s to upstream=%s on interface %s", -                   __PRETTY_FUNCTION__, -                   grp_str, dst_str, rpf->source_nexthop.interface->name); -      } - -      group_size = pim_msg_get_jp_group_size (group->sources); -      if (group_size > packet_left) -        { -          pim_msg_build_header (pim_msg, packet_size, PIM_MSG_TYPE_JOIN_PRUNE); -          if (pim_msg_send(pim_ifp->pim_sock_fd, -                           pim_ifp->primary_address, -                           qpim_all_pim_routers_addr, -                           pim_msg, -                           packet_size, -                           rpf->source_nexthop.interface->name)) { -            zlog_warn("%s: could not send PIM message on interface %s", -                      __PRETTY_FUNCTION__, rpf->source_nexthop.interface->name); -          } - -          msg = (struct pim_jp *)pim_msg; -          memset(msg, 0, sizeof (*msg)); - -          pim_msg_addr_encode_ipv4_ucast ((uint8_t *)&msg->addr, rpf->rpf_addr.u.prefix4); -          msg->reserved   = 0; -          msg->holdtime   = htons(PIM_JP_HOLDTIME); - -          new_packet = false; - -          grp = &msg->groups[0]; -          curr_ptr = (uint8_t *)grp; -          packet_size  = sizeof (struct pim_msg_header); -          packet_size += sizeof (struct pim_encoded_ipv4_unicast); -          packet_size += 4;  // reserved (1) + groups (1) + holdtime (2) - -          packet_left = rpf->source_nexthop.interface->mtu - 24; -          packet_left -= packet_size; -        } - -      msg->num_groups++; -      /* -        Build PIM message -      */ - -      curr_ptr += group_size; -      packet_left -= group_size; -      packet_size += group_size; -      pim_msg_build_jp_groups (grp, group, group_size); - -      pim_ifp->pim_ifstat_join_send += ntohs(grp->joins); -      pim_ifp->pim_ifstat_prune_send += ntohs(grp->prunes); - -      if (PIM_DEBUG_PIM_TRACE) -        zlog_debug ("%s: interface %s num_joins %u num_prunes %u", __PRETTY_FUNCTION__, -          rpf->source_nexthop.interface->name, ntohs(grp->joins), ntohs (grp->prunes)); - -      grp = (struct pim_jp_groups *)curr_ptr; -      if (packet_left < sizeof (struct pim_jp_groups) || msg->num_groups == 255) -        { -          pim_msg_build_header (pim_msg, packet_size, PIM_MSG_TYPE_JOIN_PRUNE); -          if (pim_msg_send(pim_ifp->pim_sock_fd, -                           pim_ifp->primary_address, -                           qpim_all_pim_routers_addr, -                           pim_msg, -                           packet_size, -                           rpf->source_nexthop.interface->name)) { -            zlog_warn("%s: could not send PIM message on interface %s", -                      __PRETTY_FUNCTION__, rpf->source_nexthop.interface->name); -          } - -          new_packet = true; -        } -    } - - -  if (!new_packet) -    { -      //msg->num_groups = htons (msg->num_groups); -      pim_msg_build_header (pim_msg, packet_size, PIM_MSG_TYPE_JOIN_PRUNE); -      if (pim_msg_send(pim_ifp->pim_sock_fd, -                       pim_ifp->primary_address, -                       qpim_all_pim_routers_addr, -                       pim_msg, -                       packet_size, -                       rpf->source_nexthop.interface->name)) { -        zlog_warn("%s: could not send PIM message on interface %s", -                  __PRETTY_FUNCTION__, rpf->source_nexthop.interface->name); -      } -    } -  return 0; +	struct pim_jp_agg_group *group; +	struct pim_interface *pim_ifp = NULL; +	struct pim_jp_groups *grp = NULL; +	struct pim_jp *msg; +	struct listnode *node, *nnode; +	uint8_t pim_msg[10000]; +	uint8_t *curr_ptr = pim_msg; +	bool new_packet = true; +	size_t packet_left = 0; +	size_t packet_size = 0; +	size_t group_size = 0; + +	on_trace(__PRETTY_FUNCTION__, rpf->source_nexthop.interface, +		 rpf->rpf_addr.u.prefix4); + +	if (rpf->source_nexthop.interface) +		pim_ifp = rpf->source_nexthop.interface->info; +	else { +		zlog_warn("%s: RPF interface is not present", +			  __PRETTY_FUNCTION__); +		return -1; +	} + +	if (!pim_ifp) { +		zlog_warn("%s: multicast not enabled on interface %s", +			  __PRETTY_FUNCTION__, +			  rpf->source_nexthop.interface->name); +		return -1; +	} + +	if (PIM_INADDR_IS_ANY(rpf->rpf_addr.u.prefix4)) { +		if (PIM_DEBUG_PIM_J_P) { +			char dst_str[INET_ADDRSTRLEN]; +			pim_inet4_dump("<dst?>", rpf->rpf_addr.u.prefix4, +				       dst_str, sizeof(dst_str)); +			zlog_debug("%s: upstream=%s is myself on interface %s", +				   __PRETTY_FUNCTION__, dst_str, +				   rpf->source_nexthop.interface->name); +		} +		return 0; +	} + +	/* +	  RFC 4601: 4.3.1.  Sending Hello Messages + +	  Thus, if a router needs to send a Join/Prune or Assert message on +	  an interface on which it has not yet sent a Hello message with the +	  currently configured IP address, then it MUST immediately send the +	  relevant Hello message without waiting for the Hello Timer to +	  expire, followed by the Join/Prune or Assert message. +	*/ +	pim_hello_require(rpf->source_nexthop.interface); + +	for (ALL_LIST_ELEMENTS(groups, node, nnode, group)) { +		if (new_packet) { +			msg = (struct pim_jp *)pim_msg; + +			memset(msg, 0, sizeof(*msg)); + +			pim_msg_addr_encode_ipv4_ucast((uint8_t *)&msg->addr, +						       rpf->rpf_addr.u.prefix4); +			msg->reserved = 0; +			msg->holdtime = htons(PIM_JP_HOLDTIME); + +			new_packet = false; + +			grp = &msg->groups[0]; +			curr_ptr = (uint8_t *)grp; +			packet_size = sizeof(struct pim_msg_header); +			packet_size += sizeof(struct pim_encoded_ipv4_unicast); +			packet_size += +				4; // reserved (1) + groups (1) + holdtime (2) + +			packet_left = rpf->source_nexthop.interface->mtu - 24; +			packet_left -= packet_size; +		} +		if (PIM_DEBUG_PIM_J_P) { +			char dst_str[INET_ADDRSTRLEN]; +			char grp_str[INET_ADDRSTRLEN]; +			pim_inet4_dump("<dst?>", rpf->rpf_addr.u.prefix4, +				       dst_str, sizeof(dst_str)); +			pim_inet4_dump("<grp?>", group->group, grp_str, +				       sizeof(grp_str)); +			zlog_debug( +				"%s: sending (G)=%s to upstream=%s on interface %s", +				__PRETTY_FUNCTION__, grp_str, dst_str, +				rpf->source_nexthop.interface->name); +		} + +		group_size = pim_msg_get_jp_group_size(group->sources); +		if (group_size > packet_left) { +			pim_msg_build_header(pim_msg, packet_size, +					     PIM_MSG_TYPE_JOIN_PRUNE); +			if (pim_msg_send(pim_ifp->pim_sock_fd, +					 pim_ifp->primary_address, +					 qpim_all_pim_routers_addr, pim_msg, +					 packet_size, +					 rpf->source_nexthop.interface->name)) { +				zlog_warn( +					"%s: could not send PIM message on interface %s", +					__PRETTY_FUNCTION__, +					rpf->source_nexthop.interface->name); +			} + +			msg = (struct pim_jp *)pim_msg; +			memset(msg, 0, sizeof(*msg)); + +			pim_msg_addr_encode_ipv4_ucast((uint8_t *)&msg->addr, +						       rpf->rpf_addr.u.prefix4); +			msg->reserved = 0; +			msg->holdtime = htons(PIM_JP_HOLDTIME); + +			new_packet = false; + +			grp = &msg->groups[0]; +			curr_ptr = (uint8_t *)grp; +			packet_size = sizeof(struct pim_msg_header); +			packet_size += sizeof(struct pim_encoded_ipv4_unicast); +			packet_size += +				4; // reserved (1) + groups (1) + holdtime (2) + +			packet_left = rpf->source_nexthop.interface->mtu - 24; +			packet_left -= packet_size; +		} + +		msg->num_groups++; +		/* +		  Build PIM message +		*/ + +		curr_ptr += group_size; +		packet_left -= group_size; +		packet_size += group_size; +		pim_msg_build_jp_groups(grp, group, group_size); + +		pim_ifp->pim_ifstat_join_send += ntohs(grp->joins); +		pim_ifp->pim_ifstat_prune_send += ntohs(grp->prunes); + +		if (PIM_DEBUG_PIM_TRACE) +			zlog_debug( +				"%s: interface %s num_joins %u num_prunes %u", +				__PRETTY_FUNCTION__, +				rpf->source_nexthop.interface->name, +				ntohs(grp->joins), ntohs(grp->prunes)); + +		grp = (struct pim_jp_groups *)curr_ptr; +		if (packet_left < sizeof(struct pim_jp_groups) +		    || msg->num_groups == 255) { +			pim_msg_build_header(pim_msg, packet_size, +					     PIM_MSG_TYPE_JOIN_PRUNE); +			if (pim_msg_send(pim_ifp->pim_sock_fd, +					 pim_ifp->primary_address, +					 qpim_all_pim_routers_addr, pim_msg, +					 packet_size, +					 rpf->source_nexthop.interface->name)) { +				zlog_warn( +					"%s: could not send PIM message on interface %s", +					__PRETTY_FUNCTION__, +					rpf->source_nexthop.interface->name); +			} + +			new_packet = true; +		} +	} + + +	if (!new_packet) { +		// msg->num_groups = htons (msg->num_groups); +		pim_msg_build_header(pim_msg, packet_size, +				     PIM_MSG_TYPE_JOIN_PRUNE); +		if (pim_msg_send(pim_ifp->pim_sock_fd, pim_ifp->primary_address, +				 qpim_all_pim_routers_addr, pim_msg, +				 packet_size, +				 rpf->source_nexthop.interface->name)) { +			zlog_warn( +				"%s: could not send PIM message on interface %s", +				__PRETTY_FUNCTION__, +				rpf->source_nexthop.interface->name); +		} +	} +	return 0;  }  | 
