zebra: Move the supports_nh bool to a better place

Move the supports_nh bool indicating whether the kernel we are
using supports nexthop objects into the netlink kernel interface
itself. Since only linux and netlink support nexthop object APIs
for now this is fine.

Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
This commit is contained in:
Stephen Worley 2019-08-01 14:53:06 -04:00
parent 9a1588c4ce
commit 815059466c
5 changed files with 48 additions and 41 deletions

View File

@ -1482,15 +1482,7 @@ void interface_list(struct zebra_ns *zns)
* so we need to get the nexthop info
* from the kernel before we can do that
*/
if (netlink_nexthop_read(zns)) {
/* If the nexthop read fails, assume the kernel
* cannot handle nexthop objects.
*/
zlog_debug("Nexthop objects disabled on this kernel");
zns->supports_nh = false;
} else
zns->supports_nh = true;
netlink_nexthop_read(zns);
interface_addr_lookup_netlink(zns);
}

View File

@ -74,6 +74,8 @@
static vlanid_t filter_vlan = 0;
static bool supports_nh = false;
struct gw_family_t {
uint16_t filler;
uint16_t family;
@ -1644,7 +1646,7 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx)
RTA_PAYLOAD(rta));
}
if (dplane_ctx_get_nhe_id(ctx)) {
if (supports_nh) {
/* Kernel supports nexthop objects */
addattr32(&req.n, sizeof(req), RTA_NH_ID,
dplane_ctx_get_nhe_id(ctx));
@ -1938,6 +1940,10 @@ static int netlink_nexthop(int cmd, struct zebra_dplane_ctx *ctx)
char buf[NL_PKT_BUF_SIZE];
} req;
/* Nothing to do if the kernel doesn't support nexthop objects */
if (!supports_nh)
return 0;
memset(&req, 0, sizeof(req));
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct nhmsg));
@ -2424,6 +2430,15 @@ int netlink_nexthop_read(struct zebra_ns *zns)
return ret;
ret = netlink_parse_info(netlink_nexthop_change, &zns->netlink_cmd,
&dp_info, 0, 1);
if (!ret)
/* If we succesfully read in nexthop objects,
* this kernel must support them.
*/
supports_nh = true;
else if (IS_ZEBRA_DEBUG_KERNEL)
zlog_debug("Nexthop objects not supported on this kernel");
return ret;
}

View File

@ -1526,7 +1526,7 @@ static int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx,
dplane_ctx_ns_init(ctx, zns, (op == DPLANE_OP_ROUTE_UPDATE));
#ifdef HAVE_NETLINK
if (re->nhe_id && zns->supports_nh) {
if (re->nhe_id) {
struct nhg_hash_entry *nhe =
zebra_nhg_resolve(zebra_nhg_lookup_id(re->nhe_id));
@ -1594,11 +1594,6 @@ static int dplane_ctx_nexthop_init(struct zebra_dplane_ctx *ctx,
zns = ((struct zebra_vrf *)vrf_info_lookup(nhe->vrf_id))->zns;
if (!zns->supports_nh) {
ret = EOPNOTSUPP;
goto done;
}
/*
* TODO: Might not need to mark this as an update, since
* it probably won't require two messages
@ -1896,12 +1891,8 @@ done:
if (ret == AOK)
result = ZEBRA_DPLANE_REQUEST_QUEUED;
else {
if (ret == EOPNOTSUPP)
result = ZEBRA_DPLANE_REQUEST_SUCCESS;
else
atomic_fetch_add_explicit(
&zdplane_info.dg_nexthop_errors, 1,
memory_order_relaxed);
atomic_fetch_add_explicit(&zdplane_info.dg_nexthop_errors, 1,
memory_order_relaxed);
if (ctx)
dplane_ctx_free(&ctx);
}
@ -2078,6 +2069,8 @@ enum zebra_dplane_result dplane_nexthop_add(struct nhg_hash_entry *nhe)
/*
* Enqueue a nexthop update for the dataplane.
*
* Might not need this func since zebra's nexthop objects should be immutable?
*/
enum zebra_dplane_result dplane_nexthop_update(struct nhg_hash_entry *nhe)
{

View File

@ -553,6 +553,29 @@ static enum nhg_ctx_op_e nhg_ctx_get_op(const struct nhg_ctx *ctx)
return ctx->op;
}
static struct nhg_ctx *nhg_ctx_init(uint32_t id, struct nexthop *nh,
struct nh_grp *grp, vrf_id_t vrf_id,
afi_t afi, int type, uint8_t count)
{
struct nhg_ctx *ctx = NULL;
ctx = nhg_ctx_new();
ctx->id = id;
ctx->vrf_id = vrf_id;
ctx->afi = afi;
ctx->type = type;
ctx->count = count;
if (count)
/* Copy over the array */
memcpy(&ctx->u.grp, grp, count * sizeof(struct nh_grp));
else if (nh)
ctx->u.nh = *nh;
return ctx;
}
static bool zebra_nhg_contains_dup(struct nhg_hash_entry *nhe)
{
struct nhg_connected *rb_node_dep = NULL;
@ -717,7 +740,7 @@ static int nhg_ctx_process_del(struct nhg_ctx *ctx)
EC_ZEBRA_BAD_NHG_MESSAGE,
"Kernel delete message received for nexthop group ID (%u) that we do not have in our ID table",
ctx->id);
return 0;
return -1;
}
zebra_nhg_handle_kernel_state_change(nhe, true);
@ -786,20 +809,7 @@ int zebra_nhg_kernel_find(uint32_t id, struct nexthop *nh, struct nh_grp *grp,
*/
id_counter = id;
ctx = nhg_ctx_new();
ctx->id = id;
ctx->vrf_id = vrf_id;
ctx->afi = afi;
ctx->type = type;
ctx->count = count;
if (count)
/* Copy over the array */
memcpy(&ctx->u.grp, grp, count * sizeof(struct nh_grp));
else
ctx->u.nh = *nh;
ctx = nhg_ctx_init(id, nh, grp, vrf_id, afi, type, count);
nhg_ctx_set_op(ctx, NHG_CTX_OP_NEW);
/* Under statup conditions, we need to handle them immediately
@ -822,9 +832,7 @@ int zebra_nhg_kernel_del(uint32_t id)
{
struct nhg_ctx *ctx = NULL;
ctx = nhg_ctx_new();
ctx->id = id;
ctx = nhg_ctx_init(id, NULL, NULL, 0, 0, 0, 0);
nhg_ctx_set_op(ctx, NHG_CTX_OP_DEL);

View File

@ -54,7 +54,6 @@ struct zebra_ns {
struct nlsock netlink_cmd; /* command channel */
struct nlsock netlink_dplane; /* dataplane channel */
struct thread *t_netlink;
bool supports_nh; /* Does kernel support nexthop objects? */
#endif
struct route_table *if_table;