summaryrefslogtreecommitdiffstats
path: root/pimd/pim_zlookup.c
diff options
context:
space:
mode:
Diffstat (limited to 'pimd/pim_zlookup.c')
-rw-r--r--pimd/pim_zlookup.c883
1 files changed, 448 insertions, 435 deletions
diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c
index f405a39c9..027b18e12 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;
}