forked from Mirror/frr
lib,zebra,sharpd: add code for backup proto-NHs but disabled
Add the zapi code for encoding/decoding of backup nexthops for when we are ready for it, but disable it for now so that we revert to the old way with them. When zebra gets a proto-NHG with a backup in it, we early fail and tell the upper level proto. In this case sharpd. Sharpd then reverts to the old way of installation with the route. Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
This commit is contained in:
parent
c6ce9334b5
commit
2173535298
|
@ -1017,9 +1017,10 @@ done:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int zapi_nhg_encode(struct stream *s, uint16_t proto, int cmd,
|
||||
struct zapi_nhg *api_nhg)
|
||||
int zapi_nhg_encode(struct stream *s, int cmd, struct zapi_nhg *api_nhg)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (cmd != ZEBRA_NHG_DEL && cmd != ZEBRA_NHG_ADD) {
|
||||
flog_err(EC_LIB_ZAPI_ENCODE,
|
||||
"%s: Specified zapi NHG command (%d) doesn't exist\n",
|
||||
|
@ -1030,17 +1031,26 @@ static int zapi_nhg_encode(struct stream *s, uint16_t proto, int cmd,
|
|||
stream_reset(s);
|
||||
zclient_create_header(s, cmd, VRF_DEFAULT);
|
||||
|
||||
stream_putw(s, proto);
|
||||
stream_putw(s, api_nhg->proto);
|
||||
stream_putl(s, api_nhg->id);
|
||||
|
||||
if (cmd == ZEBRA_NHG_ADD) {
|
||||
/* Nexthops */
|
||||
zapi_nexthop_group_sort(api_nhg->nexthops,
|
||||
api_nhg->nexthop_num);
|
||||
|
||||
stream_putw(s, api_nhg->nexthop_num);
|
||||
|
||||
for (int i = 0; i < api_nhg->nexthop_num; i++)
|
||||
for (i = 0; i < api_nhg->nexthop_num; i++)
|
||||
zapi_nexthop_encode(s, &api_nhg->nexthops[i], 0, 0);
|
||||
|
||||
/* Backup nexthops */
|
||||
|
||||
stream_putw(s, api_nhg->backup_nexthop_num);
|
||||
|
||||
for (i = 0; i < api_nhg->backup_nexthop_num; i++)
|
||||
zapi_nexthop_encode(s, &api_nhg->backup_nexthops[i], 0,
|
||||
0);
|
||||
}
|
||||
|
||||
stream_putw_at(s, 0, stream_get_endp(s));
|
||||
|
@ -1050,8 +1060,9 @@ static int zapi_nhg_encode(struct stream *s, uint16_t proto, int cmd,
|
|||
|
||||
int zclient_nhg_send(struct zclient *zclient, int cmd, struct zapi_nhg *api_nhg)
|
||||
{
|
||||
if (zapi_nhg_encode(zclient->obuf, zclient->redist_default, cmd,
|
||||
api_nhg))
|
||||
api_nhg->proto = zclient->redist_default;
|
||||
|
||||
if (zapi_nhg_encode(zclient->obuf, cmd, api_nhg))
|
||||
return -1;
|
||||
|
||||
return zclient_send_message(zclient);
|
||||
|
|
|
@ -442,9 +442,14 @@ struct zapi_nexthop {
|
|||
* ZAPI Nexthop Group. For use with protocol creation of nexthop groups.
|
||||
*/
|
||||
struct zapi_nhg {
|
||||
uint16_t proto;
|
||||
uint32_t id;
|
||||
|
||||
uint16_t nexthop_num;
|
||||
struct zapi_nexthop nexthops[MULTIPATH_NUM];
|
||||
|
||||
uint16_t backup_nexthop_num;
|
||||
struct zapi_nexthop backup_nexthops[MULTIPATH_NUM];
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -907,6 +912,9 @@ bool zapi_ipset_notify_decode(struct stream *s,
|
|||
uint32_t *unique,
|
||||
enum zapi_ipset_notify_owner *note);
|
||||
|
||||
|
||||
extern int zapi_nhg_encode(struct stream *s, int cmd, struct zapi_nhg *api_nhg);
|
||||
extern int zapi_nhg_decode(struct stream *s, int cmd, struct zapi_nhg *api_nhg);
|
||||
extern int zclient_nhg_send(struct zclient *zclient, int cmd,
|
||||
struct zapi_nhg *api_nhg);
|
||||
|
||||
|
|
|
@ -133,11 +133,15 @@ static void sharp_nhgroup_add_nexthop_cb(const struct nexthop_group_cmd *nhgc,
|
|||
{
|
||||
struct sharp_nhg lookup;
|
||||
struct sharp_nhg *snhg;
|
||||
struct nexthop_group_cmd *bnhgc = NULL;
|
||||
|
||||
strlcpy(lookup.name, nhgc->name, sizeof(lookup.name));
|
||||
snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
|
||||
|
||||
nhg_add(snhg->id, &nhgc->nhg);
|
||||
if (nhgc->backup_list_name[0])
|
||||
bnhgc = nhgc_find(nhgc->backup_list_name);
|
||||
|
||||
nhg_add(snhg->id, &nhgc->nhg, (bnhgc ? &bnhgc->nhg : NULL));
|
||||
}
|
||||
|
||||
static void sharp_nhgroup_del_nexthop_cb(const struct nexthop_group_cmd *nhgc,
|
||||
|
@ -145,11 +149,15 @@ static void sharp_nhgroup_del_nexthop_cb(const struct nexthop_group_cmd *nhgc,
|
|||
{
|
||||
struct sharp_nhg lookup;
|
||||
struct sharp_nhg *snhg;
|
||||
struct nexthop_group_cmd *bnhgc = NULL;
|
||||
|
||||
strlcpy(lookup.name, nhgc->name, sizeof(lookup.name));
|
||||
snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
|
||||
|
||||
nhg_add(snhg->id, &nhgc->nhg);
|
||||
if (nhgc->backup_list_name[0])
|
||||
bnhgc = nhgc_find(nhgc->backup_list_name);
|
||||
|
||||
nhg_add(snhg->id, &nhgc->nhg, (bnhgc ? &bnhgc->nhg : NULL));
|
||||
}
|
||||
|
||||
static void sharp_nhgroup_delete_cb(const char *name)
|
||||
|
|
|
@ -357,7 +357,8 @@ void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label)
|
|||
zclient_send_vrf_label(zclient, vrf_id, afi, label, ZEBRA_LSP_SHARP);
|
||||
}
|
||||
|
||||
void nhg_add(uint32_t id, const struct nexthop_group *nhg)
|
||||
void nhg_add(uint32_t id, const struct nexthop_group *nhg,
|
||||
const struct nexthop_group *backup_nhg)
|
||||
{
|
||||
struct zapi_nhg api_nhg = {};
|
||||
struct zapi_nexthop *api_nh;
|
||||
|
@ -378,6 +379,22 @@ void nhg_add(uint32_t id, const struct nexthop_group *nhg)
|
|||
api_nhg.nexthop_num++;
|
||||
}
|
||||
|
||||
if (backup_nhg) {
|
||||
for (ALL_NEXTHOPS_PTR(backup_nhg, nh)) {
|
||||
if (api_nhg.backup_nexthop_num >= MULTIPATH_NUM) {
|
||||
zlog_warn(
|
||||
"%s: number of backup nexthops greater than max multipath size, truncating",
|
||||
__func__);
|
||||
break;
|
||||
}
|
||||
api_nh = &api_nhg.backup_nexthops
|
||||
[api_nhg.backup_nexthop_num];
|
||||
|
||||
zapi_backup_nexthop_from_nexthop(api_nh, nh);
|
||||
api_nhg.backup_nexthop_num++;
|
||||
}
|
||||
}
|
||||
|
||||
zclient_nhg_send(zclient, ZEBRA_NHG_ADD, &api_nhg);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,8 @@ int sharp_zclient_create(uint32_t session_id);
|
|||
int sharp_zclient_delete(uint32_t session_id);
|
||||
|
||||
extern void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label);
|
||||
extern void nhg_add(uint32_t id, const struct nexthop_group *nhg);
|
||||
extern void nhg_add(uint32_t id, const struct nexthop_group *nhg,
|
||||
const struct nexthop_group *backup_nhg);
|
||||
extern void nhg_del(uint32_t id);
|
||||
extern void route_add(const struct prefix *p, vrf_id_t, uint8_t instance,
|
||||
uint32_t nhgid, const struct nexthop_group *nhg,
|
||||
|
|
152
zebra/zapi_msg.c
152
zebra/zapi_msg.c
|
@ -1732,84 +1732,134 @@ static bool zapi_read_nexthops(struct zserv *client, struct prefix *p,
|
|||
return true;
|
||||
}
|
||||
|
||||
int zapi_nhg_decode(struct stream *s, int cmd, struct zapi_nhg *api_nhg)
|
||||
{
|
||||
uint16_t i;
|
||||
struct zapi_nexthop *znh;
|
||||
|
||||
STREAM_GETW(s, api_nhg->proto);
|
||||
STREAM_GETL(s, api_nhg->id);
|
||||
|
||||
if (cmd == ZEBRA_NHG_DEL)
|
||||
goto done;
|
||||
|
||||
/* Nexthops */
|
||||
STREAM_GETW(s, api_nhg->nexthop_num);
|
||||
|
||||
if (zserv_nexthop_num_warn(__func__, NULL, api_nhg->nexthop_num))
|
||||
return -1;
|
||||
|
||||
if (api_nhg->nexthop_num <= 0) {
|
||||
flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED,
|
||||
"%s: No nexthops sent", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < api_nhg->nexthop_num; i++) {
|
||||
znh = &((api_nhg->nexthops)[i]);
|
||||
|
||||
if (zapi_nexthop_decode(s, znh, 0, 0) != 0) {
|
||||
flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED,
|
||||
"%s: Nexthop creation failed", __func__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Backup Nexthops */
|
||||
STREAM_GETW(s, api_nhg->backup_nexthop_num);
|
||||
|
||||
if (zserv_nexthop_num_warn(__func__, NULL, api_nhg->backup_nexthop_num))
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < api_nhg->backup_nexthop_num; i++) {
|
||||
znh = &((api_nhg->backup_nexthops)[i]);
|
||||
|
||||
if (zapi_nexthop_decode(s, znh, 0, 0) != 0) {
|
||||
flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED,
|
||||
"%s: Backup Nexthop creation failed",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
return 0;
|
||||
|
||||
stream_failure:
|
||||
flog_warn(
|
||||
EC_ZEBRA_NEXTHOP_CREATION_FAILED,
|
||||
"%s: Nexthop Group decode failed with some sort of stream read failure",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void zread_nhg_del(ZAPI_HANDLER_ARGS)
|
||||
{
|
||||
struct stream *s = msg;
|
||||
uint32_t id;
|
||||
uint16_t proto;
|
||||
struct stream *s;
|
||||
struct zapi_nhg api_nhg = {};
|
||||
struct nhg_hash_entry *nhe;
|
||||
|
||||
STREAM_GETW(s, proto);
|
||||
STREAM_GETL(s, id);
|
||||
s = msg;
|
||||
if (zapi_nhg_decode(s, hdr->command, &api_nhg) < 0) {
|
||||
if (IS_ZEBRA_DEBUG_RECV)
|
||||
zlog_debug("%s: Unable to decode zapi_nhg sent",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete the received nhg id
|
||||
*/
|
||||
|
||||
nhe = zebra_nhg_proto_del(id, proto);
|
||||
nhe = zebra_nhg_proto_del(api_nhg.id, api_nhg.proto);
|
||||
|
||||
if (nhe) {
|
||||
zebra_nhg_decrement_ref(nhe);
|
||||
nhg_notify(proto, client->instance, id, ZAPI_NHG_REMOVED);
|
||||
nhg_notify(api_nhg.proto, client->instance, api_nhg.id,
|
||||
ZAPI_NHG_REMOVED);
|
||||
} else
|
||||
nhg_notify(proto, client->instance, id, ZAPI_NHG_REMOVE_FAIL);
|
||||
|
||||
return;
|
||||
|
||||
stream_failure:
|
||||
flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED,
|
||||
"%s: Nexthop group deletion failed", __func__);
|
||||
return;
|
||||
nhg_notify(api_nhg.proto, client->instance, api_nhg.id,
|
||||
ZAPI_NHG_REMOVE_FAIL);
|
||||
}
|
||||
|
||||
static void zread_nhg_add(ZAPI_HANDLER_ARGS)
|
||||
{
|
||||
struct stream *s;
|
||||
uint32_t id;
|
||||
size_t nhops, i;
|
||||
struct zapi_nexthop zapi_nexthops[MULTIPATH_NUM];
|
||||
struct zapi_nhg api_nhg = {};
|
||||
struct nexthop_group *nhg = NULL;
|
||||
uint16_t proto;
|
||||
struct nhg_backup_info *bnhg = NULL;
|
||||
struct nhg_hash_entry *nhe;
|
||||
|
||||
s = msg;
|
||||
|
||||
STREAM_GETW(s, proto);
|
||||
STREAM_GETL(s, id);
|
||||
STREAM_GETW(s, nhops);
|
||||
|
||||
if (zserv_nexthop_num_warn(__func__, NULL, nhops))
|
||||
return;
|
||||
|
||||
if (nhops <= 0) {
|
||||
flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED,
|
||||
"%s: No nexthops sent", __func__);
|
||||
if (zapi_nhg_decode(s, hdr->command, &api_nhg) < 0) {
|
||||
if (IS_ZEBRA_DEBUG_RECV)
|
||||
zlog_debug("%s: Unable to decode zapi_nhg sent",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < nhops; i++) {
|
||||
struct zapi_nexthop *znh = &zapi_nexthops[i];
|
||||
if ((!zapi_read_nexthops(client, NULL, api_nhg.nexthops, 0, 0,
|
||||
api_nhg.nexthop_num,
|
||||
api_nhg.backup_nexthop_num, &nhg, NULL))
|
||||
|| (!zapi_read_nexthops(client, NULL, api_nhg.backup_nexthops, 0, 0,
|
||||
api_nhg.backup_nexthop_num,
|
||||
api_nhg.backup_nexthop_num, NULL, &bnhg))) {
|
||||
|
||||
if (zapi_nexthop_decode(s, znh, 0, 0) != 0) {
|
||||
flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED,
|
||||
"%s: Nexthop creation failed", __func__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!zapi_read_nexthops(client, NULL, zapi_nexthops, 0, 0, nhops, 0,
|
||||
&nhg, NULL)) {
|
||||
flog_warn(EC_ZEBRA_NEXTHOP_CREATION_FAILED,
|
||||
"%s: Nexthop Group Creation failed", __func__);
|
||||
|
||||
nexthop_group_delete(&nhg);
|
||||
zebra_nhg_backup_free(&bnhg);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the nhg
|
||||
*/
|
||||
nhe = zebra_nhg_proto_add(id, proto, nhg, 0);
|
||||
nhe = zebra_nhg_proto_add(api_nhg.id, api_nhg.proto, nhg, 0);
|
||||
|
||||
nexthop_group_delete(&nhg);
|
||||
zebra_nhg_backup_free(&bnhg);
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
|
@ -1818,18 +1868,11 @@ static void zread_nhg_add(ZAPI_HANDLER_ARGS)
|
|||
* Resolution is going to need some more work.
|
||||
*/
|
||||
if (nhe)
|
||||
nhg_notify(proto, client->instance, id, ZAPI_NHG_INSTALLED);
|
||||
nhg_notify(api_nhg.proto, client->instance, api_nhg.id,
|
||||
ZAPI_NHG_INSTALLED);
|
||||
else
|
||||
nhg_notify(proto, client->instance, id, ZAPI_NHG_FAIL_INSTALL);
|
||||
|
||||
return;
|
||||
|
||||
stream_failure:
|
||||
flog_warn(
|
||||
EC_ZEBRA_NEXTHOP_CREATION_FAILED,
|
||||
"%s: Nexthop Group creation failed with some sort of stream read failure",
|
||||
__func__);
|
||||
return;
|
||||
nhg_notify(api_nhg.proto, client->instance, api_nhg.id,
|
||||
ZAPI_NHG_FAIL_INSTALL);
|
||||
}
|
||||
|
||||
static void zread_route_add(ZAPI_HANDLER_ARGS)
|
||||
|
@ -1911,6 +1954,9 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
|
|||
api.flags, api.message,
|
||||
api.backup_nexthop_num,
|
||||
api.backup_nexthop_num, NULL, &bnhg))) {
|
||||
|
||||
nexthop_group_delete(&ng);
|
||||
zebra_nhg_backup_free(&bnhg);
|
||||
XFREE(MTYPE_RE, re);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2759,6 +2759,14 @@ struct nhg_hash_entry *zebra_nhg_proto_add(uint32_t id, int type,
|
|||
* Once resolution is figured out, we won't need this!
|
||||
*/
|
||||
for (ALL_NEXTHOPS_PTR(nhg, newhop)) {
|
||||
if (CHECK_FLAG(newhop->flags, NEXTHOP_FLAG_HAS_BACKUP)) {
|
||||
if (IS_ZEBRA_DEBUG_NHG)
|
||||
zlog_debug(
|
||||
"%s: id %u, backup nexthops not supported",
|
||||
__func__, id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (newhop->type == NEXTHOP_TYPE_BLACKHOLE) {
|
||||
if (IS_ZEBRA_DEBUG_NHG)
|
||||
zlog_debug(
|
||||
|
|
Loading…
Reference in a new issue