diff options
Diffstat (limited to 'pimd/pim_zlookup.c')
| -rw-r--r-- | pimd/pim_zlookup.c | 883 | 
1 files changed, 448 insertions, 435 deletions
diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c index f405a39c9d..027b18e123 100644 --- a/pimd/pim_zlookup.c +++ b/pimd/pim_zlookup.c @@ -43,491 +43,504 @@ static void zclient_lookup_sched(struct zclient *zlookup, int delay);  /* Connect to zebra for nexthop lookup. */  static int zclient_lookup_connect(struct thread *t)  { -  struct zclient *zlookup; - -  zlookup = THREAD_ARG(t); - -  if (zlookup->sock >= 0) { -    return 0; -  } - -  if (zclient_socket_connect(zlookup) < 0) { -    ++zlookup->fail; -    zlog_warn("%s: failure connecting zclient socket: failures=%d", -	      __PRETTY_FUNCTION__, zlookup->fail); -  } -  else { -    zlookup->fail = 0; /* reset counter on connection */ -  } - -  if (zlookup->sock < 0) { -    /* Since last connect failed, retry within 10 secs */ -    zclient_lookup_sched(zlookup, 10); -    return -1; -  } - -  return 0; +	struct zclient *zlookup; + +	zlookup = THREAD_ARG(t); + +	if (zlookup->sock >= 0) { +		return 0; +	} + +	if (zclient_socket_connect(zlookup) < 0) { +		++zlookup->fail; +		zlog_warn("%s: failure connecting zclient socket: failures=%d", +			  __PRETTY_FUNCTION__, zlookup->fail); +	} else { +		zlookup->fail = 0; /* reset counter on connection */ +	} + +	if (zlookup->sock < 0) { +		/* Since last connect failed, retry within 10 secs */ +		zclient_lookup_sched(zlookup, 10); +		return -1; +	} + +	return 0;  }  /* Schedule connection with delay. */  static void zclient_lookup_sched(struct zclient *zlookup, int delay)  { -  thread_add_timer(master, zclient_lookup_connect, zlookup, delay, -                   &zlookup->t_connect); +	thread_add_timer(master, zclient_lookup_connect, zlookup, delay, +			 &zlookup->t_connect); -  zlog_notice("%s: zclient lookup connection scheduled for %d seconds", -	      __PRETTY_FUNCTION__, delay); +	zlog_notice("%s: zclient lookup connection scheduled for %d seconds", +		    __PRETTY_FUNCTION__, delay);  }  /* Schedule connection for now. */  static void zclient_lookup_sched_now(struct zclient *zlookup)  { -  thread_add_event(master, zclient_lookup_connect, zlookup, 0, -                   &zlookup->t_connect); +	thread_add_event(master, zclient_lookup_connect, zlookup, 0, +			 &zlookup->t_connect); -  zlog_notice("%s: zclient lookup immediate connection scheduled", -	      __PRETTY_FUNCTION__); +	zlog_notice("%s: zclient lookup immediate connection scheduled", +		    __PRETTY_FUNCTION__);  }  /* Schedule reconnection, if needed. */  static void zclient_lookup_reconnect(struct zclient *zlookup)  { -  if (zlookup->t_connect) { -    return; -  } +	if (zlookup->t_connect) { +		return; +	} -  zclient_lookup_sched_now(zlookup); +	zclient_lookup_sched_now(zlookup);  }  static void zclient_lookup_failed(struct zclient *zlookup)  { -  if (zlookup->sock >= 0) { -    if (close(zlookup->sock)) { -      zlog_warn("%s: closing fd=%d: errno=%d %s", __func__, zlookup->sock, -		errno, safe_strerror(errno)); -    } -    zlookup->sock = -1; -  } - -  zclient_lookup_reconnect(zlookup); +	if (zlookup->sock >= 0) { +		if (close(zlookup->sock)) { +			zlog_warn("%s: closing fd=%d: errno=%d %s", __func__, +				  zlookup->sock, errno, safe_strerror(errno)); +		} +		zlookup->sock = -1; +	} + +	zclient_lookup_reconnect(zlookup);  } -void -zclient_lookup_free (void) +void zclient_lookup_free(void)  { -  zclient_stop (zlookup); -  zclient_free (zlookup); -  zlookup = NULL; +	zclient_stop(zlookup); +	zclient_free(zlookup); +	zlookup = NULL;  } -void -zclient_lookup_new (void) +void zclient_lookup_new(void)  { -  zlookup = zclient_new (master); -  if (!zlookup) { -    zlog_err("%s: zclient_new() failure", -	     __PRETTY_FUNCTION__); -    return; -  } - -  zlookup->sock = -1; -  zlookup->t_connect = NULL; +	zlookup = zclient_new(master); +	if (!zlookup) { +		zlog_err("%s: zclient_new() failure", __PRETTY_FUNCTION__); +		return; +	} -  zclient_lookup_sched_now(zlookup); +	zlookup->sock = -1; +	zlookup->t_connect = NULL; -  zlog_notice("%s: zclient lookup socket initialized", -	      __PRETTY_FUNCTION__); +	zclient_lookup_sched_now(zlookup); +	zlog_notice("%s: zclient lookup socket initialized", +		    __PRETTY_FUNCTION__);  }  static int zclient_read_nexthop(struct zclient *zlookup,  				struct pim_zlookup_nexthop nexthop_tab[], -				const int tab_size, -				struct in_addr addr) +				const int tab_size, struct in_addr addr)  { -  int num_ifindex = 0; -  struct stream *s; -  const uint16_t MIN_LEN = 10; /* getipv4=4 getc=1 getl=4 getc=1 */ -  uint16_t length; -  u_char marker; -  u_char version; -  vrf_id_t vrf_id; -  uint16_t command = 0; -  struct in_addr raddr; -  uint8_t distance; -  uint32_t metric; -  int nexthop_num; -  int i, err; - -  if (PIM_DEBUG_PIM_TRACE_DETAIL) { -    char addr_str[INET_ADDRSTRLEN]; -    pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str)); -    zlog_debug("%s: addr=%s",  -	       __PRETTY_FUNCTION__, -	       addr_str); -  } - -  s = zlookup->ibuf; - -  while (command != ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB) -    { -      stream_reset(s); -      err = zclient_read_header (s, zlookup->sock, &length, &marker, &version, -				 &vrf_id, &command); -      if (err < 0) { -	zlog_err("%s %s: zclient_read_header() failed", -		 __FILE__, __PRETTY_FUNCTION__); -	zclient_lookup_failed(zlookup); -	return -1; -      } - -      if (length < MIN_LEN) { -	zlog_err("%s %s: failure reading zclient lookup socket: len=%d < MIN_LEN=%d", -		 __FILE__, __PRETTY_FUNCTION__, length, MIN_LEN); -	zclient_lookup_failed(zlookup); -	return -2; -      } -    } - -  raddr.s_addr = stream_get_ipv4(s); - -  if (raddr.s_addr != addr.s_addr) { -    char addr_str[INET_ADDRSTRLEN]; -    char raddr_str[INET_ADDRSTRLEN]; -    pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str)); -    pim_inet4_dump("<raddr?>", raddr, raddr_str, sizeof(raddr_str)); -    zlog_warn("%s: address mismatch: addr=%s raddr=%s",  -	       __PRETTY_FUNCTION__, -	       addr_str, raddr_str); -    /* warning only */ -  } - -  distance = stream_getc(s); -  metric = stream_getl(s); -  nexthop_num = stream_getc(s); - -  if (nexthop_num < 1) { -    zlog_err("%s: socket %d bad nexthop_num=%d", -            __func__, zlookup->sock, nexthop_num); -    return -6; -  } - -  for (i = 0; i < nexthop_num; ++i) { -    enum nexthop_types_t nexthop_type; -    struct pim_neighbor *nbr; -    struct prefix p; - -    nexthop_type = stream_getc(s); -    if (num_ifindex >= tab_size) { -      char addr_str[INET_ADDRSTRLEN]; -      pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str)); -      zlog_warn("%s %s: found too many nexthop ifindexes (%d > %d) for address %s", -		__FILE__, __PRETTY_FUNCTION__, -		(num_ifindex + 1), tab_size, addr_str); -      return num_ifindex; -    } -    switch (nexthop_type) { -    case NEXTHOP_TYPE_IFINDEX: -    case NEXTHOP_TYPE_IPV4_IFINDEX: -    case NEXTHOP_TYPE_IPV4: -      nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET; -      if (nexthop_type == NEXTHOP_TYPE_IPV4_IFINDEX || -	  nexthop_type == NEXTHOP_TYPE_IPV4) { -	nexthop_tab[num_ifindex].nexthop_addr.u.prefix4.s_addr = stream_get_ipv4(s); -      } -      else { -	nexthop_tab[num_ifindex].nexthop_addr.u.prefix4.s_addr = PIM_NET_INADDR_ANY; -      } -      nexthop_tab[num_ifindex].ifindex           = stream_getl(s); -      nexthop_tab[num_ifindex].protocol_distance = distance; -      nexthop_tab[num_ifindex].route_metric      = metric; -      ++num_ifindex; -      break; -    case NEXTHOP_TYPE_IPV6_IFINDEX: -      nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET6; -      stream_get (&nexthop_tab[num_ifindex].nexthop_addr.u.prefix6, -		  s, -		  sizeof(struct in6_addr)); -      nexthop_tab[num_ifindex].ifindex = stream_getl (s); - -      p.family = AF_INET6; -      p.prefixlen = IPV6_MAX_PREFIXLEN; -      memcpy (&p.u.prefix6, -	      &nexthop_tab[num_ifindex].nexthop_addr.u.prefix6, -	      sizeof(struct in6_addr)); - -      /* -       * If we are sending v6 secondary assume we receive v6 secondary -       */ -      if (pimg->send_v6_secondary) -        nbr = pim_neighbor_find_by_secondary(if_lookup_by_index (nexthop_tab[num_ifindex].ifindex, VRF_DEFAULT), &p); -      else -        nbr = pim_neighbor_find_if (if_lookup_by_index (nexthop_tab[num_ifindex].ifindex, VRF_DEFAULT)); -      if (nbr) -        { -          nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET; -          nexthop_tab[num_ifindex].nexthop_addr.u.prefix4 = nbr->source_addr; -        } -        ++num_ifindex; -      break; -    default: -      /* do nothing */ -      { -	char addr_str[INET_ADDRSTRLEN]; -	pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str)); -	zlog_warn("%s %s: found non-ifindex nexthop type=%d for address %s", -		 __FILE__, __PRETTY_FUNCTION__, -		  nexthop_type, addr_str); -      } -      break; -    } -  } - -  return num_ifindex; +	int num_ifindex = 0; +	struct stream *s; +	const uint16_t MIN_LEN = 10; /* getipv4=4 getc=1 getl=4 getc=1 */ +	uint16_t length; +	u_char marker; +	u_char version; +	vrf_id_t vrf_id; +	uint16_t command = 0; +	struct in_addr raddr; +	uint8_t distance; +	uint32_t metric; +	int nexthop_num; +	int i, err; + +	if (PIM_DEBUG_PIM_TRACE_DETAIL) { +		char addr_str[INET_ADDRSTRLEN]; +		pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str)); +		zlog_debug("%s: addr=%s", __PRETTY_FUNCTION__, addr_str); +	} + +	s = zlookup->ibuf; + +	while (command != ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB) { +		stream_reset(s); +		err = zclient_read_header(s, zlookup->sock, &length, &marker, +					  &version, &vrf_id, &command); +		if (err < 0) { +			zlog_err("%s %s: zclient_read_header() failed", +				 __FILE__, __PRETTY_FUNCTION__); +			zclient_lookup_failed(zlookup); +			return -1; +		} + +		if (length < MIN_LEN) { +			zlog_err( +				"%s %s: failure reading zclient lookup socket: len=%d < MIN_LEN=%d", +				__FILE__, __PRETTY_FUNCTION__, length, MIN_LEN); +			zclient_lookup_failed(zlookup); +			return -2; +		} +	} + +	raddr.s_addr = stream_get_ipv4(s); + +	if (raddr.s_addr != addr.s_addr) { +		char addr_str[INET_ADDRSTRLEN]; +		char raddr_str[INET_ADDRSTRLEN]; +		pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str)); +		pim_inet4_dump("<raddr?>", raddr, raddr_str, sizeof(raddr_str)); +		zlog_warn("%s: address mismatch: addr=%s raddr=%s", +			  __PRETTY_FUNCTION__, addr_str, raddr_str); +		/* warning only */ +	} + +	distance = stream_getc(s); +	metric = stream_getl(s); +	nexthop_num = stream_getc(s); + +	if (nexthop_num < 1) { +		zlog_err("%s: socket %d bad nexthop_num=%d", __func__, +			 zlookup->sock, nexthop_num); +		return -6; +	} + +	for (i = 0; i < nexthop_num; ++i) { +		enum nexthop_types_t nexthop_type; +		struct pim_neighbor *nbr; +		struct prefix p; + +		nexthop_type = stream_getc(s); +		if (num_ifindex >= tab_size) { +			char addr_str[INET_ADDRSTRLEN]; +			pim_inet4_dump("<addr?>", addr, addr_str, +				       sizeof(addr_str)); +			zlog_warn( +				"%s %s: found too many nexthop ifindexes (%d > %d) for address %s", +				__FILE__, __PRETTY_FUNCTION__, +				(num_ifindex + 1), tab_size, addr_str); +			return num_ifindex; +		} +		switch (nexthop_type) { +		case NEXTHOP_TYPE_IFINDEX: +		case NEXTHOP_TYPE_IPV4_IFINDEX: +		case NEXTHOP_TYPE_IPV4: +			nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET; +			if (nexthop_type == NEXTHOP_TYPE_IPV4_IFINDEX +			    || nexthop_type == NEXTHOP_TYPE_IPV4) { +				nexthop_tab[num_ifindex] +					.nexthop_addr.u.prefix4.s_addr = +					stream_get_ipv4(s); +			} else { +				nexthop_tab[num_ifindex] +					.nexthop_addr.u.prefix4.s_addr = +					PIM_NET_INADDR_ANY; +			} +			nexthop_tab[num_ifindex].ifindex = stream_getl(s); +			nexthop_tab[num_ifindex].protocol_distance = distance; +			nexthop_tab[num_ifindex].route_metric = metric; +			++num_ifindex; +			break; +		case NEXTHOP_TYPE_IPV6_IFINDEX: +			nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET6; +			stream_get(&nexthop_tab[num_ifindex] +					    .nexthop_addr.u.prefix6, +				   s, sizeof(struct in6_addr)); +			nexthop_tab[num_ifindex].ifindex = stream_getl(s); + +			p.family = AF_INET6; +			p.prefixlen = IPV6_MAX_PREFIXLEN; +			memcpy(&p.u.prefix6, +			       &nexthop_tab[num_ifindex].nexthop_addr.u.prefix6, +			       sizeof(struct in6_addr)); + +			/* +			 * If we are sending v6 secondary assume we receive v6 +			 * secondary +			 */ +			if (pimg->send_v6_secondary) +				nbr = pim_neighbor_find_by_secondary( +					if_lookup_by_index( +						nexthop_tab[num_ifindex] +							.ifindex, +						VRF_DEFAULT), +					&p); +			else +				nbr = pim_neighbor_find_if(if_lookup_by_index( +					nexthop_tab[num_ifindex].ifindex, +					VRF_DEFAULT)); +			if (nbr) { +				nexthop_tab[num_ifindex].nexthop_addr.family = +					AF_INET; +				nexthop_tab[num_ifindex] +					.nexthop_addr.u.prefix4 = +					nbr->source_addr; +			} +			++num_ifindex; +			break; +		default: +			/* do nothing */ +			{ +				char addr_str[INET_ADDRSTRLEN]; +				pim_inet4_dump("<addr?>", addr, addr_str, +					       sizeof(addr_str)); +				zlog_warn( +					"%s %s: found non-ifindex nexthop type=%d for address %s", +					__FILE__, __PRETTY_FUNCTION__, +					nexthop_type, addr_str); +			} +			break; +		} +	} + +	return num_ifindex;  } -static int -zclient_lookup_nexthop_once (struct pim_zlookup_nexthop nexthop_tab[], -			     const int tab_size, -			     struct in_addr addr) +static int zclient_lookup_nexthop_once(struct pim_zlookup_nexthop nexthop_tab[], +				       const int tab_size, struct in_addr addr)  { -  struct stream *s; -  int ret; - -  if (PIM_DEBUG_PIM_TRACE_DETAIL) { -    char addr_str[INET_ADDRSTRLEN]; -    pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str)); -    zlog_debug("%s: addr=%s",  -	       __PRETTY_FUNCTION__, -	       addr_str); -  } - -  /* Check socket. */ -  if (zlookup->sock < 0) { -    zlog_err("%s %s: zclient lookup socket is not connected", -	     __FILE__, __PRETTY_FUNCTION__); -    zclient_lookup_failed(zlookup); -    return -1; -  } -   -  s = zlookup->obuf; -  stream_reset(s); -  zclient_create_header(s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, VRF_DEFAULT); -  stream_put_in_addr(s, &addr); -  stream_putw_at(s, 0, stream_get_endp(s)); -   -  ret = writen(zlookup->sock, s->data, stream_get_endp(s)); -  if (ret < 0) { -    zlog_err("%s %s: writen() failure: %d writing to zclient lookup socket", -	     __FILE__, __PRETTY_FUNCTION__, errno); -    zclient_lookup_failed(zlookup); -    return -2; -  } -  if (ret == 0) { -    zlog_err("%s %s: connection closed on zclient lookup socket", -	     __FILE__, __PRETTY_FUNCTION__); -    zclient_lookup_failed(zlookup); -    return -3; -  } -   -  return zclient_read_nexthop(zlookup, nexthop_tab, -			      tab_size, addr); +	struct stream *s; +	int ret; + +	if (PIM_DEBUG_PIM_TRACE_DETAIL) { +		char addr_str[INET_ADDRSTRLEN]; +		pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str)); +		zlog_debug("%s: addr=%s", __PRETTY_FUNCTION__, addr_str); +	} + +	/* Check socket. */ +	if (zlookup->sock < 0) { +		zlog_err("%s %s: zclient lookup socket is not connected", +			 __FILE__, __PRETTY_FUNCTION__); +		zclient_lookup_failed(zlookup); +		return -1; +	} + +	s = zlookup->obuf; +	stream_reset(s); +	zclient_create_header(s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, VRF_DEFAULT); +	stream_put_in_addr(s, &addr); +	stream_putw_at(s, 0, stream_get_endp(s)); + +	ret = writen(zlookup->sock, s->data, stream_get_endp(s)); +	if (ret < 0) { +		zlog_err( +			"%s %s: writen() failure: %d writing to zclient lookup socket", +			__FILE__, __PRETTY_FUNCTION__, errno); +		zclient_lookup_failed(zlookup); +		return -2; +	} +	if (ret == 0) { +		zlog_err("%s %s: connection closed on zclient lookup socket", +			 __FILE__, __PRETTY_FUNCTION__); +		zclient_lookup_failed(zlookup); +		return -3; +	} + +	return zclient_read_nexthop(zlookup, nexthop_tab, tab_size, addr);  } -int -zclient_lookup_nexthop (struct pim_zlookup_nexthop nexthop_tab[], -			const int tab_size, -			struct in_addr addr, -			int max_lookup) +int zclient_lookup_nexthop(struct pim_zlookup_nexthop nexthop_tab[], +			   const int tab_size, struct in_addr addr, +			   int max_lookup)  { -  int lookup; -  uint32_t route_metric = 0xFFFFFFFF; -  uint8_t  protocol_distance = 0xFF; - -  qpim_nexthop_lookups++; - -  for (lookup = 0; lookup < max_lookup; ++lookup) { -    int num_ifindex; -    int first_ifindex; -    struct prefix nexthop_addr; - -    num_ifindex = zclient_lookup_nexthop_once(nexthop_tab, -					      tab_size, addr); -    if (num_ifindex < 1) { -      if (PIM_DEBUG_ZEBRA) { -	char addr_str[INET_ADDRSTRLEN]; -	pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str)); -	zlog_debug("%s %s: lookup=%d/%d: could not find nexthop ifindex for address %s", -		   __FILE__, __PRETTY_FUNCTION__, -		   lookup, max_lookup, addr_str); -      } -      return -1; -    } - -    if (lookup < 1) { -      /* this is the non-recursive lookup - save original metric/distance */ -      route_metric = nexthop_tab[0].route_metric; -      protocol_distance = nexthop_tab[0].protocol_distance; -    } -     -    /* -     * FIXME: Non-recursive nexthop ensured only for first ifindex. -     * However, recursive route lookup should really be fixed in zebra daemon. -     * See also TODO T24. -     * -     * So Zebra for NEXTHOP_TYPE_IPV4 returns the ifindex now since -     * it was being stored.  This Doesn't solve all cases of -     * recursive lookup but for the most common types it does. -     */ -    first_ifindex = nexthop_tab[0].ifindex; -    nexthop_addr = nexthop_tab[0].nexthop_addr; -    if (first_ifindex > 0) { -      /* found: first ifindex is non-recursive nexthop */ - -      if (lookup > 0) { -	/* Report non-recursive success after first lookup */ +	int lookup; +	uint32_t route_metric = 0xFFFFFFFF; +	uint8_t protocol_distance = 0xFF; + +	qpim_nexthop_lookups++; + +	for (lookup = 0; lookup < max_lookup; ++lookup) { +		int num_ifindex; +		int first_ifindex; +		struct prefix nexthop_addr; + +		num_ifindex = zclient_lookup_nexthop_once(nexthop_tab, tab_size, +							  addr); +		if (num_ifindex < 1) { +			if (PIM_DEBUG_ZEBRA) { +				char addr_str[INET_ADDRSTRLEN]; +				pim_inet4_dump("<addr?>", addr, addr_str, +					       sizeof(addr_str)); +				zlog_debug( +					"%s %s: lookup=%d/%d: could not find nexthop ifindex for address %s", +					__FILE__, __PRETTY_FUNCTION__, lookup, +					max_lookup, addr_str); +			} +			return -1; +		} + +		if (lookup < 1) { +			/* this is the non-recursive lookup - save original +			 * metric/distance */ +			route_metric = nexthop_tab[0].route_metric; +			protocol_distance = nexthop_tab[0].protocol_distance; +		} + +		/* +		 * FIXME: Non-recursive nexthop ensured only for first ifindex. +		 * However, recursive route lookup should really be fixed in +		 * zebra daemon. +		 * See also TODO T24. +		 * +		 * So Zebra for NEXTHOP_TYPE_IPV4 returns the ifindex now since +		 * it was being stored.  This Doesn't solve all cases of +		 * recursive lookup but for the most common types it does. +		 */ +		first_ifindex = nexthop_tab[0].ifindex; +		nexthop_addr = nexthop_tab[0].nexthop_addr; +		if (first_ifindex > 0) { +			/* found: first ifindex is non-recursive nexthop */ + +			if (lookup > 0) { +				/* Report non-recursive success after first +				 * lookup */ +				if (PIM_DEBUG_ZEBRA) { +					char addr_str[INET_ADDRSTRLEN]; +					pim_inet4_dump("<addr?>", addr, +						       addr_str, +						       sizeof(addr_str)); +					zlog_debug( +						"%s %s: lookup=%d/%d: found non-recursive ifindex=%d for address %s dist=%d met=%d", +						__FILE__, __PRETTY_FUNCTION__, +						lookup, max_lookup, +						first_ifindex, addr_str, +						nexthop_tab[0] +							.protocol_distance, +						nexthop_tab[0].route_metric); +				} + +				/* use last address as nexthop address */ +				nexthop_tab[0].nexthop_addr.u.prefix4 = addr; + +				/* report original route metric/distance */ +				nexthop_tab[0].route_metric = route_metric; +				nexthop_tab[0].protocol_distance = +					protocol_distance; +			} + +			return num_ifindex; +		} + +		if (PIM_DEBUG_ZEBRA) { +			char addr_str[INET_ADDRSTRLEN]; +			char nexthop_str[PREFIX_STRLEN]; +			pim_inet4_dump("<addr?>", addr, addr_str, +				       sizeof(addr_str)); +			pim_addr_dump("<nexthop?>", &nexthop_addr, nexthop_str, +				      sizeof(nexthop_str)); +			zlog_debug( +				"%s %s: lookup=%d/%d: zebra returned recursive nexthop %s for address %s dist=%d met=%d", +				__FILE__, __PRETTY_FUNCTION__, lookup, +				max_lookup, nexthop_str, addr_str, +				nexthop_tab[0].protocol_distance, +				nexthop_tab[0].route_metric); +		} + +		addr = +			nexthop_addr.u.prefix4; /* use nexthop addr for +						   recursive lookup */ + +	} /* for (max_lookup) */ +  	if (PIM_DEBUG_ZEBRA) { -	  char addr_str[INET_ADDRSTRLEN]; -	  pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str)); -	  zlog_debug("%s %s: lookup=%d/%d: found non-recursive ifindex=%d for address %s dist=%d met=%d", -		     __FILE__, __PRETTY_FUNCTION__, -		     lookup, max_lookup, first_ifindex, addr_str, -		     nexthop_tab[0].protocol_distance, -		     nexthop_tab[0].route_metric); +		char addr_str[INET_ADDRSTRLEN]; +		pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str)); +		zlog_warn( +			"%s %s: lookup=%d/%d: failure searching recursive nexthop ifindex for address %s", +			__FILE__, __PRETTY_FUNCTION__, lookup, max_lookup, +			addr_str);  	} -	/* use last address as nexthop address */ -	nexthop_tab[0].nexthop_addr.u.prefix4 = addr; - -	/* report original route metric/distance */ -	nexthop_tab[0].route_metric = route_metric; -	nexthop_tab[0].protocol_distance = protocol_distance; -      } - -      return num_ifindex; -    } - -    if (PIM_DEBUG_ZEBRA) { -      char addr_str[INET_ADDRSTRLEN]; -      char nexthop_str[PREFIX_STRLEN]; -      pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str)); -      pim_addr_dump("<nexthop?>", &nexthop_addr, nexthop_str, sizeof(nexthop_str)); -      zlog_debug("%s %s: lookup=%d/%d: zebra returned recursive nexthop %s for address %s dist=%d met=%d", -		__FILE__, __PRETTY_FUNCTION__, -		lookup, max_lookup, nexthop_str, addr_str, -		nexthop_tab[0].protocol_distance, -		nexthop_tab[0].route_metric); -    } - -    addr = nexthop_addr.u.prefix4; /* use nexthop addr for recursive lookup */ - -  } /* for (max_lookup) */ - -  if (PIM_DEBUG_ZEBRA) { -    char addr_str[INET_ADDRSTRLEN]; -    pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str)); -    zlog_warn("%s %s: lookup=%d/%d: failure searching recursive nexthop ifindex for address %s", -	      __FILE__, __PRETTY_FUNCTION__, -	      lookup, max_lookup, addr_str); -  } - -  return -2; +	return -2;  } -void -pim_zlookup_show_ip_multicast (struct vty *vty) +void pim_zlookup_show_ip_multicast(struct vty *vty)  { -  vty_out(vty, "Zclient lookup socket: "); -  if (zlookup) { -    vty_out (vty, "%d failures=%d\n", zlookup->sock, -            zlookup->fail); -  } -  else { -    vty_out (vty, "<null zclient>\n"); -  } +	vty_out(vty, "Zclient lookup socket: "); +	if (zlookup) { +		vty_out(vty, "%d failures=%d\n", zlookup->sock, zlookup->fail); +	} else { +		vty_out(vty, "<null zclient>\n"); +	}  } -int -pim_zlookup_sg_statistics (struct channel_oil *c_oil) +int pim_zlookup_sg_statistics(struct channel_oil *c_oil)  { -  struct stream *s = zlookup->obuf; -  uint16_t command = 0; -  unsigned long long lastused; -  struct prefix_sg sg; -  int count = 0; -  int ret; -  struct interface *ifp = pim_if_find_by_vif_index (c_oil->oil.mfcc_parent); - -  if (PIM_DEBUG_ZEBRA) -    { -      struct prefix_sg more; - -      more.src = c_oil->oil.mfcc_origin; -      more.grp = c_oil->oil.mfcc_mcastgrp; -      zlog_debug ("Sending Request for New Channel Oil Information(%s) VIIF %d", -            pim_str_sg_dump (&more), c_oil->oil.mfcc_parent); -    } - -  if (!ifp) -    return -1; - -  stream_reset (s); -  zclient_create_header (s, ZEBRA_IPMR_ROUTE_STATS, VRF_DEFAULT); -  stream_put_in_addr (s, &c_oil->oil.mfcc_origin); -  stream_put_in_addr (s, &c_oil->oil.mfcc_mcastgrp); -  stream_putl (s,  ifp->ifindex); -  stream_putw_at(s, 0, stream_get_endp(s)); - -  count = stream_get_endp (s); -  ret = writen (zlookup->sock, s->data, count); -  if (ret <= 0) -    { -      zlog_err("%s %s: writen() failure: %d writing to zclient lookup socket", -               __FILE__, __PRETTY_FUNCTION__, errno); -      return -1; -    } - -  s = zlookup->ibuf; - -  while (command != ZEBRA_IPMR_ROUTE_STATS) -    { -      int err; -      uint16_t length = 0; -      vrf_id_t vrf_id; -      u_char marker; -      u_char version; - -      stream_reset (s); -      err = zclient_read_header (s, zlookup->sock, &length, &marker, &version, -				 &vrf_id, &command); -      if (err < 0) -        { -          zlog_err ("%s %s: zclient_read_header() failed", -                 __FILE__, __PRETTY_FUNCTION__); -        zclient_lookup_failed(zlookup); -        return -1; -        } -    } - -  sg.src.s_addr = stream_get_ipv4 (s); -  sg.grp.s_addr = stream_get_ipv4 (s); -  if (sg.src.s_addr != c_oil->oil.mfcc_origin.s_addr || -      sg.grp.s_addr != c_oil->oil.mfcc_mcastgrp.s_addr) -    { -       zlog_err ("%s: Received wrong %s information", -		 __PRETTY_FUNCTION__, pim_str_sg_dump (&sg)); -       zclient_lookup_failed (zlookup); -       return -3; -    } - -  stream_get (&lastused, s, sizeof (lastused)); -  ret = stream_getl (s); - -  if (PIM_DEBUG_ZEBRA) -    zlog_debug ("Received %lld for %s success: %d", lastused, pim_str_sg_dump (&sg), ret); - -  c_oil->cc.lastused = lastused; - -  return 0; +	struct stream *s = zlookup->obuf; +	uint16_t command = 0; +	unsigned long long lastused; +	struct prefix_sg sg; +	int count = 0; +	int ret; +	struct interface *ifp = +		pim_if_find_by_vif_index(c_oil->oil.mfcc_parent); + +	if (PIM_DEBUG_ZEBRA) { +		struct prefix_sg more; + +		more.src = c_oil->oil.mfcc_origin; +		more.grp = c_oil->oil.mfcc_mcastgrp; +		zlog_debug( +			"Sending Request for New Channel Oil Information(%s) VIIF %d", +			pim_str_sg_dump(&more), c_oil->oil.mfcc_parent); +	} + +	if (!ifp) +		return -1; + +	stream_reset(s); +	zclient_create_header(s, ZEBRA_IPMR_ROUTE_STATS, VRF_DEFAULT); +	stream_put_in_addr(s, &c_oil->oil.mfcc_origin); +	stream_put_in_addr(s, &c_oil->oil.mfcc_mcastgrp); +	stream_putl(s, ifp->ifindex); +	stream_putw_at(s, 0, stream_get_endp(s)); + +	count = stream_get_endp(s); +	ret = writen(zlookup->sock, s->data, count); +	if (ret <= 0) { +		zlog_err( +			"%s %s: writen() failure: %d writing to zclient lookup socket", +			__FILE__, __PRETTY_FUNCTION__, errno); +		return -1; +	} + +	s = zlookup->ibuf; + +	while (command != ZEBRA_IPMR_ROUTE_STATS) { +		int err; +		uint16_t length = 0; +		vrf_id_t vrf_id; +		u_char marker; +		u_char version; + +		stream_reset(s); +		err = zclient_read_header(s, zlookup->sock, &length, &marker, +					  &version, &vrf_id, &command); +		if (err < 0) { +			zlog_err("%s %s: zclient_read_header() failed", +				 __FILE__, __PRETTY_FUNCTION__); +			zclient_lookup_failed(zlookup); +			return -1; +		} +	} + +	sg.src.s_addr = stream_get_ipv4(s); +	sg.grp.s_addr = stream_get_ipv4(s); +	if (sg.src.s_addr != c_oil->oil.mfcc_origin.s_addr +	    || sg.grp.s_addr != c_oil->oil.mfcc_mcastgrp.s_addr) { +		zlog_err("%s: Received wrong %s information", +			 __PRETTY_FUNCTION__, pim_str_sg_dump(&sg)); +		zclient_lookup_failed(zlookup); +		return -3; +	} + +	stream_get(&lastused, s, sizeof(lastused)); +	ret = stream_getl(s); + +	if (PIM_DEBUG_ZEBRA) +		zlog_debug("Received %lld for %s success: %d", lastused, +			   pim_str_sg_dump(&sg), ret); + +	c_oil->cc.lastused = lastused; +	return 0;  }  | 
