static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command)
{
bool exact_match = false;
+ bool resolve_via_default = false;
int ret;
if (!zclient)
"%s: We have not connected yet, cannot send nexthops",
__func__);
}
- if ((command == ZEBRA_NEXTHOP_REGISTER
- || command == ZEBRA_IMPORT_ROUTE_REGISTER)
- && (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)
- || CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH)))
- exact_match = true;
+ if (command == ZEBRA_NEXTHOP_REGISTER) {
+ if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED))
+ exact_match = true;
+ if (CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH))
+ resolve_via_default = true;
+ }
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: sending cmd %s for %pFX (vrf %s)", __func__,
bnc->bgp->name_pretty);
ret = zclient_send_rnh(zclient, command, &bnc->prefix, exact_match,
- bnc->bgp->vrf_id);
+ resolve_via_default, bnc->bgp->vrf_id);
/* TBD: handle the failure */
if (ret == ZCLIENT_SEND_FAILURE)
flog_warn(EC_BGP_ZEBRA_SEND,
enum zclient_send_status zclient_send_rnh(struct zclient *zclient, int command,
const struct prefix *p,
- bool exact_match, vrf_id_t vrf_id)
+ bool exact_match,
+ bool resolve_via_def, vrf_id_t vrf_id)
{
struct stream *s;
stream_reset(s);
zclient_create_header(s, command, vrf_id);
stream_putc(s, (exact_match) ? 1 : 0);
-
+ stream_putc(s, (resolve_via_def) ? 1 : 0);
stream_putw(s, PREFIX_FAMILY(p));
stream_putc(s, p->prefixlen);
switch (PREFIX_FAMILY(p)) {
struct zapi_route *);
extern enum zclient_send_status
zclient_send_rnh(struct zclient *zclient, int command, const struct prefix *p,
- bool exact_match, vrf_id_t vrf_id);
+ bool exact_match, bool resolve_via_default, vrf_id_t vrf_id);
int zapi_nexthop_encode(struct stream *s, const struct zapi_nexthop *api_nh,
uint32_t api_flags, uint32_t api_message);
extern int zapi_route_encode(uint8_t, struct stream *, struct zapi_route *);
zserv_command_string(command), &prefix,
ospf6->vrf_id);
- if (zclient_send_rnh(zclient, command, &prefix, true, ospf6->vrf_id)
+ if (zclient_send_rnh(zclient, command, &prefix, false, true,
+ ospf6->vrf_id)
== ZCLIENT_SEND_FAILURE)
flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_send_rnh() failed",
__func__);
break;
}
- if (zclient_send_rnh(zclient, command, &p, false, nhop->vrf_id)
+ if (zclient_send_rnh(zclient, command, &p, false, false, nhop->vrf_id)
== ZCLIENT_SEND_FAILURE) {
zlog_warn("%s: Failure to send nexthop to zebra", __func__);
}
int ret;
p = &(pnc->rpf.rpf_addr);
- ret = zclient_send_rnh(zclient, command, p, false, pim->vrf->vrf_id);
+ ret = zclient_send_rnh(zclient, command, p, false, false,
+ pim->vrf->vrf_id);
if (ret == ZCLIENT_SEND_FAILURE)
zlog_warn("sendmsg_nexthop: zclient_send_message() failed");
command = ZEBRA_IMPORT_ROUTE_UNREGISTER;
}
- if (zclient_send_rnh(zclient, command, p, connected, vrf_id)
+ if (zclient_send_rnh(zclient, command, p, connected, false, vrf_id)
== ZCLIENT_SEND_FAILURE)
zlog_warn("%s: Failure to send nexthop to zebra", __func__);
}
static_nht_hash_free(nhtd);
}
- if (zclient_send_rnh(zclient, cmd, &p, false, nh->nh_vrf_id)
+ if (zclient_send_rnh(zclient, cmd, &p, false, false, nh->nh_vrf_id)
== ZCLIENT_SEND_FAILURE)
zlog_warn("%s: Failure to send nexthop to zebra", __func__);
}
struct rnh {
uint8_t flags;
-#define ZEBRA_NHT_CONNECTED 0x1
-#define ZEBRA_NHT_DELETED 0x2
-#define ZEBRA_NHT_EXACT_MATCH 0x4
+#define ZEBRA_NHT_CONNECTED 0x1
+#define ZEBRA_NHT_DELETED 0x2
+#define ZEBRA_NHT_EXACT_MATCH 0x4
+#define ZEBRA_NHT_RESOLVE_VIA_DEFAULT 0x8
/* VRF identifier. */
vrf_id_t vrf_id;
struct prefix p;
unsigned short l = 0;
uint8_t flags = 0;
+ uint8_t resolve_via_default;
uint16_t type = cmd2type[hdr->command];
bool exist;
bool flag_changed = false;
while (l < hdr->length) {
STREAM_GETC(s, flags);
+ STREAM_GETC(s, resolve_via_default);
STREAM_GETW(s, p.family);
STREAM_GETC(s, p.prefixlen);
- l += 4;
+ l += 5;
if (p.family == AF_INET) {
client->v4_nh_watch_add_cnt++;
if (p.prefixlen > IPV4_MAX_BITLEN) {
UNSET_FLAG(rnh->flags, ZEBRA_NHT_EXACT_MATCH);
}
+ if (resolve_via_default)
+ SET_FLAG(rnh->flags, ZEBRA_NHT_RESOLVE_VIA_DEFAULT);
+
if (orig_flags != rnh->flags)
flag_changed = true;
while (l < hdr->length) {
uint8_t flags;
+ STREAM_GETC(s, flags);
+ if (flags != 0)
+ goto stream_failure;
STREAM_GETC(s, flags);
if (flags != 0)
goto stream_failure;
STREAM_GETW(s, p.family);
STREAM_GETC(s, p.prefixlen);
- l += 4;
+ l += 5;
if (p.family == AF_INET) {
client->v4_nh_watch_rem_cnt++;
if (p.prefixlen > IPV4_MAX_BITLEN) {
* match route to be exact if so specified
*/
if (is_default_prefix(&rn->p)
- && !rnh_resolve_via_default(zvrf, rn->p.family)) {
+ && (!CHECK_FLAG(rnh->flags, ZEBRA_NHT_RESOLVE_VIA_DEFAULT)
+ && !rnh_resolve_via_default(zvrf, rn->p.family))) {
if (IS_ZEBRA_DEBUG_NHT_DETAILED)
zlog_debug(
- " Not allowed to resolve through default prefix");
+ " Not allowed to resolve through default prefix: rnh->resolve_via_default: %u",
+ CHECK_FLAG(
+ rnh->flags,
+ ZEBRA_NHT_RESOLVE_VIA_DEFAULT));
return NULL;
}