*/
#include <zebra.h>
-#include "zebra/rib.h"
#include "log.h"
#include "prefix.h"
#include "thread.h"
#include "prefix.h"
#include "vty.h"
+#include "lib_errors.h"
#include "pimd.h"
#include "pim_iface.h"
void zclient_lookup_new(void)
{
- zlookup = zclient_new(master);
+ zlookup = zclient_new(master, &zclient_options_default);
if (!zlookup) {
- zlog_err("%s: zclient_new() failure", __PRETTY_FUNCTION__);
+ flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_new() failure",
+ __PRETTY_FUNCTION__);
return;
}
zlookup->sock = -1;
zlookup->t_connect = NULL;
+ zlookup->privs = &pimd_privs;
zclient_lookup_sched_now(zlookup);
__PRETTY_FUNCTION__);
}
-static int zclient_read_nexthop(struct zclient *zlookup,
+static int zclient_read_nexthop(struct pim_instance *pim,
+ struct zclient *zlookup,
struct pim_zlookup_nexthop nexthop_tab[],
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;
+ uint8_t marker;
+ uint8_t version;
vrf_id_t vrf_id;
uint16_t command = 0;
struct in_addr raddr;
int nexthop_num;
int i, err;
- if (PIM_DEBUG_PIM_TRACE_DETAIL) {
+ if (PIM_DEBUG_PIM_NHT_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);
+ zlog_debug("%s: addr=%s(%s)", __PRETTY_FUNCTION__, addr_str,
+ pim->vrf->name);
}
s = zlookup->ibuf;
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__);
+ flog_err(EC_LIB_ZAPI_MISSMATCH,
+ "%s: zclient_read_header() failed",
+ __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);
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);
+ zlog_warn("%s: address mismatch: addr=%s(%s) raddr=%s",
+ __PRETTY_FUNCTION__, addr_str, pim->vrf->name,
+ raddr_str);
/* warning only */
}
nexthop_num = stream_getc(s);
if (nexthop_num < 1) {
- zlog_err("%s: socket %d bad nexthop_num=%d", __func__,
- zlookup->sock, nexthop_num);
+ if (PIM_DEBUG_PIM_NHT_DETAIL)
+ zlog_debug("%s: socket %d bad nexthop_num=%d", __func__,
+ zlookup->sock, nexthop_num);
return -6;
}
for (i = 0; i < nexthop_num; ++i) {
+ vrf_id_t nexthop_vrf_id;
enum nexthop_types_t nexthop_type;
struct pim_neighbor *nbr;
struct prefix p;
+ nexthop_vrf_id = stream_getl(s);
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);
+ "%s: found too many nexthop ifindexes (%d > %d) for address %s(%s)",
+ __PRETTY_FUNCTION__, (num_ifindex + 1),
+ tab_size, addr_str, pim->vrf->name);
return num_ifindex;
}
+ nexthop_tab[num_ifindex].protocol_distance = distance;
+ nexthop_tab[num_ifindex].route_metric = metric;
+ nexthop_tab[num_ifindex].vrf_id = nexthop_vrf_id;
switch (nexthop_type) {
case NEXTHOP_TYPE_IFINDEX:
+ nexthop_tab[num_ifindex].ifindex = stream_getl(s);
+ /*
+ * Connected route (i.e. no nexthop), use
+ * address passed in as PIM nexthop. This will
+ * allow us to work in cases where we are
+ * trying to find a route for this box.
+ */
+ nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET;
+ nexthop_tab[num_ifindex].nexthop_addr.prefixlen =
+ IPV4_MAX_BITLEN;
+ nexthop_tab[num_ifindex].nexthop_addr.u.prefix4 =
+ addr;
+ ++num_ifindex;
+ break;
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].nexthop_addr.u.prefix4.s_addr =
+ stream_get_ipv4(s);
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:
* If we are sending v6 secondary assume we receive v6
* secondary
*/
- if (pimg->send_v6_secondary)
+ if (pim->send_v6_secondary)
nbr = pim_neighbor_find_by_secondary(
if_lookup_by_index(
nexthop_tab[num_ifindex]
.ifindex,
- VRF_DEFAULT),
+ nexthop_vrf_id),
&p);
else
nbr = pim_neighbor_find_if(if_lookup_by_index(
nexthop_tab[num_ifindex].ifindex,
- VRF_DEFAULT));
+ nexthop_vrf_id));
if (nbr) {
nexthop_tab[num_ifindex].nexthop_addr.family =
AF_INET;
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);
+ "%s: found non-ifindex nexthop type=%d for address %s(%s)",
+ __PRETTY_FUNCTION__, nexthop_type,
+ addr_str, pim->vrf->name);
}
break;
}
return num_ifindex;
}
-static int zclient_lookup_nexthop_once(struct pim_zlookup_nexthop nexthop_tab[],
+static int zclient_lookup_nexthop_once(struct pim_instance *pim,
+ 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) {
+ if (PIM_DEBUG_PIM_NHT_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);
+ zlog_debug("%s: addr=%s(%s)", __PRETTY_FUNCTION__, addr_str,
+ pim->vrf->name);
}
/* Check socket. */
if (zlookup->sock < 0) {
- zlog_err("%s %s: zclient lookup socket is not connected",
- __FILE__, __PRETTY_FUNCTION__);
+ flog_err(EC_LIB_ZAPI_SOCKET,
+ "%s: zclient lookup socket is not connected",
+ __PRETTY_FUNCTION__);
zclient_lookup_failed(zlookup);
return -1;
}
+ if (pim->vrf->vrf_id == VRF_UNKNOWN) {
+ zlog_notice(
+ "%s: VRF: %s does not fully exist yet, delaying lookup",
+ __PRETTY_FUNCTION__, pim->vrf->name);
+ return -1;
+ }
+
s = zlookup->obuf;
stream_reset(s);
- zclient_create_header(s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, VRF_DEFAULT);
+ zclient_create_header(s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, pim->vrf_id);
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);
+ flog_err(
+ EC_LIB_SOCKET,
+ "%s: writen() failure: %d writing to zclient lookup socket",
+ __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__);
+ flog_err_sys(EC_LIB_SOCKET,
+ "%s: connection closed on zclient lookup socket",
+ __PRETTY_FUNCTION__);
zclient_lookup_failed(zlookup);
return -3;
}
- return zclient_read_nexthop(zlookup, nexthop_tab, tab_size, addr);
+ return zclient_read_nexthop(pim, zlookup, nexthop_tab, tab_size, addr);
}
-int zclient_lookup_nexthop(struct pim_zlookup_nexthop nexthop_tab[],
+int zclient_lookup_nexthop(struct pim_instance *pim,
+ struct pim_zlookup_nexthop nexthop_tab[],
const int tab_size, struct in_addr addr,
int max_lookup)
{
uint32_t route_metric = 0xFFFFFFFF;
uint8_t protocol_distance = 0xFF;
- qpim_nexthop_lookups++;
+ pim->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);
+ num_ifindex = zclient_lookup_nexthop_once(pim, nexthop_tab,
+ tab_size, addr);
if (num_ifindex < 1) {
- if (PIM_DEBUG_ZEBRA) {
+ if (PIM_DEBUG_PIM_NHT) {
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);
+ "%s: lookup=%d/%d: could not find nexthop ifindex for address %s(%s)",
+ __PRETTY_FUNCTION__, lookup, max_lookup,
+ addr_str, pim->vrf->name);
}
return -1;
}
if (lookup > 0) {
/* Report non-recursive success after first
* lookup */
- if (PIM_DEBUG_ZEBRA) {
+ if (PIM_DEBUG_PIM_NHT) {
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,
+ "%s: lookup=%d/%d: found non-recursive ifindex=%d for address %s(%s) dist=%d met=%d",
+ __PRETTY_FUNCTION__, lookup,
+ max_lookup, first_ifindex,
+ addr_str, pim->vrf->name,
nexthop_tab[0]
.protocol_distance,
nexthop_tab[0].route_metric);
return num_ifindex;
}
- if (PIM_DEBUG_ZEBRA) {
+ if (PIM_DEBUG_PIM_NHT) {
char addr_str[INET_ADDRSTRLEN];
char nexthop_str[PREFIX_STRLEN];
pim_inet4_dump("<addr?>", addr, 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,
+ "%s: lookup=%d/%d: zebra returned recursive nexthop %s for address %s(%s) dist=%d met=%d",
+ __PRETTY_FUNCTION__, lookup, max_lookup,
+ nexthop_str, addr_str, pim->vrf->name,
nexthop_tab[0].protocol_distance,
nexthop_tab[0].route_metric);
}
- addr =
- nexthop_addr.u.prefix4; /* use nexthop addr for
- recursive lookup */
+ addr = nexthop_addr.u.prefix4; /* use nexthop addr for
+ recursive lookup */
} /* for (max_lookup) */
- if (PIM_DEBUG_ZEBRA) {
+ if (PIM_DEBUG_PIM_NHT) {
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);
+ "%s: lookup=%d/%d: failure searching recursive nexthop ifindex for address %s(%s)",
+ __PRETTY_FUNCTION__, lookup, max_lookup, addr_str,
+ pim->vrf->name);
}
return -2;
int count = 0;
int ret;
struct interface *ifp =
- pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
+ pim_if_find_by_vif_index(c_oil->pim, 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);
+ "Sending Request for New Channel Oil Information(%s) VIIF %d(%s)",
+ pim_str_sg_dump(&more), c_oil->oil.mfcc_parent,
+ c_oil->pim->vrf->name);
}
if (!ifp)
return -1;
stream_reset(s);
- zclient_create_header(s, ZEBRA_IPMR_ROUTE_STATS, VRF_DEFAULT);
+ zclient_create_header(s, ZEBRA_IPMR_ROUTE_STATS, c_oil->pim->vrf_id);
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);
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);
+ flog_err(
+ EC_LIB_SOCKET,
+ "%s: writen() failure: %d writing to zclient lookup socket",
+ __PRETTY_FUNCTION__, errno);
return -1;
}
int err;
uint16_t length = 0;
vrf_id_t vrf_id;
- u_char marker;
- u_char version;
+ uint8_t marker;
+ uint8_t 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__);
+ flog_err(EC_LIB_ZAPI_MISSMATCH,
+ "%s: zclient_read_header() failed",
+ __PRETTY_FUNCTION__);
zclient_lookup_failed(zlookup);
return -1;
}
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));
+ if (PIM_DEBUG_ZEBRA) {
+ struct prefix_sg more;
+
+ more.src = c_oil->oil.mfcc_origin;
+ more.grp = c_oil->oil.mfcc_mcastgrp;
+ flog_err(
+ EC_LIB_ZAPI_MISSMATCH,
+ "%s: Received wrong %s(%s) information requested",
+ __PRETTY_FUNCTION__, pim_str_sg_dump(&more),
+ c_oil->pim->vrf->name);
+ }
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);
+ stream_getl(s);
c_oil->cc.lastused = lastused;