#undef vl_printfun
#include <vlibapi/api_helper_macros.h>
+#include <vnet/fib/fib_api.h>
#define foreach_bier_api_msg \
_(BIER_TABLE_ADD_DEL, bier_table_add_del) \
vnm = vnet_get_main ();
vnm->api_errno = 0;
- bier_table_id_t bti = {
- .bti_set = mp->bt_tbl_id.bt_set,
- .bti_sub_domain = mp->bt_tbl_id.bt_sub_domain,
- .bti_hdr_len = mp->bt_tbl_id.bt_hdr_len_id,
- .bti_type = BIER_TABLE_MPLS_SPF,
- .bti_ecmp = BIER_ECMP_TABLE_ID_MAIN,
- };
-
- if (mp->bt_is_add)
+ if (mp->bt_tbl_id.bt_hdr_len_id >= BIER_HDR_LEN_2048)
{
- bier_table_add_or_lock(&bti, ntohl(mp->bt_label));
+ rv = VNET_API_ERROR_BIER_BSL_UNSUP;
}
else
{
- bier_table_unlock(&bti);
- }
+ bier_table_id_t bti = {
+ .bti_set = mp->bt_tbl_id.bt_set,
+ .bti_sub_domain = mp->bt_tbl_id.bt_sub_domain,
+ .bti_hdr_len = mp->bt_tbl_id.bt_hdr_len_id,
+ .bti_type = BIER_TABLE_MPLS_SPF,
+ .bti_ecmp = BIER_ECMP_TABLE_ID_MAIN,
+ };
+
+ if (mp->bt_is_add)
+ {
+ mpls_label_t label = ntohl(mp->bt_label);
- rv = vnm->api_errno;
+ /*
+ * convert acceptable 'don't want a label' values from
+ * the API to the correct internal INVLID value
+ */
+ if ((0 == label) || (~0 == label))
+ {
+ label = MPLS_LABEL_INVALID;
+ }
+ bier_table_add_or_lock(&bti, label);
+ }
+ else
+ {
+ bier_table_unlock(&bti);
+ }
+
+ rv = vnm->api_errno;
+ }
REPLY_MACRO (VL_API_BIER_TABLE_ADD_DEL_REPLY);
}
static void
-send_bier_table_details (unix_shared_memory_queue_t * q,
+send_bier_table_details (vl_api_registration_t * reg,
u32 context,
const bier_table_t *bt)
{
mp = vl_msg_api_alloc(sizeof(*mp));
if (!mp)
return;
- memset(mp, 0, sizeof(*mp));
+ clib_memset(mp, 0, sizeof(*mp));
mp->_vl_msg_id = ntohs(VL_API_BIER_TABLE_DETAILS);
mp->context = context;
mp->bt_tbl_id.bt_sub_domain = bt->bt_id.bti_sub_domain;
mp->bt_tbl_id.bt_hdr_len_id = bt->bt_id.bti_hdr_len;
- vl_msg_api_send_shmem (q, (u8 *) & mp);
+ vl_api_send_msg (reg, (u8 *) mp);
}
static void
vl_api_bier_table_dump_t_handler (vl_api_bier_table_dump_t * mp)
{
- unix_shared_memory_queue_t *q;
+ vl_api_registration_t *reg;
bier_table_t *bt;
- q = vl_api_client_index_to_input_queue (mp->client_index);
- if (q == 0)
- return;
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
pool_foreach(bt, bier_table_pool,
({
*/
if (bier_table_is_main(bt))
{
- send_bier_table_details(q, mp->context, bt);
+ send_bier_table_details(reg, mp->context, bt);
}
}));
}
vnet_main_t *vnm;
bier_bp_t bp;
int rv = 0;
- u8 ii, jj;
+ u8 ii;
vnm = vnet_get_main ();
vnm->api_errno = 0;
-
- bp = ntohs(mp->br_bp);
+ bp = ntohl(mp->br_bp);
brpaths = NULL;
- if (0 == bp || bp > 0xffff)
+ if (mp->br_tbl_id.bt_hdr_len_id >= BIER_HDR_LEN_2048)
+ {
+ rv = VNET_API_ERROR_BIER_BSL_UNSUP;
+ goto done;
+ }
+ if (0 == bp || bp > BIER_BP_MAX)
{
rv = -1;
goto done;
vec_foreach_index(ii, brpaths)
{
brpath = &brpaths[ii];
- memset(brpath, 0, sizeof(*brpath));
- brpath->frp_flags = FIB_ROUTE_PATH_BIER_FMASK;
+ rv = fib_path_api_parse(&mp->br_paths[ii], brpath);
- vec_validate(brpath->frp_label_stack,
- mp->br_paths[ii].n_labels - 1);
- for (jj = 0; jj < mp->br_paths[ii].n_labels; jj++)
+ if (0 != rv)
{
- brpath->frp_label_stack[jj] =
- ntohl(mp->br_paths[ii].label_stack[jj]);
+ goto done;
}
+ }
- if (0 == mp->br_paths[ii].afi)
+ if (mp->br_is_replace)
+ {
+ if (0 == vec_len(brpaths))
{
- clib_memcpy (&brpath->frp_addr.ip4,
- mp->br_paths[ii].next_hop,
- sizeof (brpath->frp_addr.ip4));
+ bier_table_route_delete(&bti, bp);
}
else
{
- clib_memcpy (&brpath->frp_addr.ip6,
- mp->br_paths[ii].next_hop,
- sizeof (brpath->frp_addr.ip6));
- }
- if (ip46_address_is_zero(&brpath->frp_addr))
- {
- index_t bdti;
-
- bdti = bier_disp_table_find(ntohl(mp->br_paths[ii].table_id));
-
- if (INDEX_INVALID != bdti)
- brpath->frp_fib_index = bdti;
- else
- {
- rv = VNET_API_ERROR_NO_SUCH_FIB;
- goto done;
- }
+ bier_table_route_path_update(&bti, bp, brpaths);
}
}
-
- if (mp->br_is_add)
+ else if (mp->br_is_add)
{
- bier_table_route_add(&bti, ntohs(mp->br_bp), brpaths);
+ bier_table_route_path_add(&bti, bp, brpaths);
}
else
{
- bier_table_route_remove(&bti, ntohs(mp->br_bp), brpaths);
+ bier_table_route_path_remove(&bti, bp, brpaths);
}
+ vec_free(brpaths);
done:
- vec_free(brpaths);
rv = (rv == 0) ? vnm->api_errno : rv;
REPLY_MACRO (VL_API_BIER_ROUTE_ADD_DEL_REPLY);
typedef struct bier_route_details_walk_t_
{
- unix_shared_memory_queue_t * q;
+ vl_api_registration_t * reg;
u32 context;
} bier_route_details_walk_t;
fib_route_path_encode_t *api_rpaths = NULL, *api_rpath;
bier_route_details_walk_t *ctx = args;
vl_api_bier_route_details_t *mp;
- vl_api_fib_path3_t *fp;
+ vl_api_fib_path_t *fp;
u32 n_paths, m_size;
n_paths = fib_path_list_get_n_paths(be->be_path_list);
- m_size = sizeof(*mp) + (n_paths * sizeof(vl_api_fib_path3_t));
+ m_size = sizeof(*mp) + (n_paths * sizeof(vl_api_fib_path_t));
mp = vl_msg_api_alloc(m_size);
if (!mp)
return;
- memset(mp, 0, m_size);
+ clib_memset(mp, 0, m_size);
mp->_vl_msg_id = ntohs(VL_API_BIER_ROUTE_DETAILS);
mp->context = ctx->context;
fp = mp->br_paths;
vec_foreach (api_rpath, api_rpaths)
{
- fp->weight = api_rpath->rpath.frp_weight;
- fp->preference = api_rpath->rpath.frp_preference;
- fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
- fp->n_labels = 0;
- copy_fib_next_hop (api_rpath, fp);
+ fib_api_path_encode(api_rpath, fp);
fp++;
}
- vl_msg_api_send_shmem (ctx->q, (u8 *) & mp);
+ vl_api_send_msg (ctx->reg, (u8 *) mp);
}
static void
vl_api_bier_route_dump_t_handler (vl_api_bier_route_dump_t * mp)
{
- unix_shared_memory_queue_t *q;
+ vl_api_registration_t *reg;
- q = vl_api_client_index_to_input_queue (mp->client_index);
- if (q == 0)
- return;
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
bier_table_id_t bti = {
.bti_set = mp->br_tbl_id.bt_set,
.bti_ecmp = BIER_ECMP_TABLE_ID_MAIN,
};
bier_route_details_walk_t ctx = {
- .q = q,
+ .reg = reg,
.context = mp->context,
};
bier_table_walk(&bti, send_bier_route_details, &ctx);
{
vl_api_bier_imp_add_reply_t *rmp;
vnet_main_t *vnm;
- index_t bii;
+ index_t bii = ~0;
int rv = 0;
vnm = vnet_get_main ();
vnm->api_errno = 0;
- bier_table_id_t bti = {
- .bti_set = mp->bi_tbl_id.bt_set,
- .bti_sub_domain = mp->bi_tbl_id.bt_sub_domain,
- .bti_hdr_len = mp->bi_tbl_id.bt_hdr_len_id,
- .bti_type = BIER_TABLE_MPLS_SPF,
- .bti_ecmp = BIER_ECMP_TABLE_ID_MAIN,
- };
- bier_bit_string_t bs = {
- .bbs_len = mp->bi_n_bytes,
- .bbs_buckets = mp->bi_bytes,
- };
-
- bii = bier_imp_add_or_lock(&bti, ntohs(mp->bi_src), &bs);
+ /*
+ * The BSL support by VPP is limited to the size of the
+ * available space in the vlib_buffer_t
+ */
+ if (mp->bi_tbl_id.bt_hdr_len_id >= BIER_HDR_LEN_2048)
+ {
+ rv = VNET_API_ERROR_BIER_BSL_UNSUP;
+ }
+ else
+ {
+ bier_table_id_t bti = {
+ .bti_set = mp->bi_tbl_id.bt_set,
+ .bti_sub_domain = mp->bi_tbl_id.bt_sub_domain,
+ .bti_hdr_len = mp->bi_tbl_id.bt_hdr_len_id,
+ .bti_type = BIER_TABLE_MPLS_SPF,
+ .bti_ecmp = BIER_ECMP_TABLE_ID_MAIN,
+ };
+ bier_bit_string_t bs = {
+ .bbs_len = mp->bi_n_bytes,
+ .bbs_buckets = mp->bi_bytes,
+ };
+
+ bii = bier_imp_add_or_lock(&bti, ntohs(mp->bi_src), &bs);
+ }
- /* *INDENT-OFF* */
REPLY_MACRO2 (VL_API_BIER_IMP_ADD_REPLY,
({
- rmp->bi_index = bii;
+ rmp->bi_index = ntohl (bii);
}));
- /* *INDENT-OM* */
}
static void
}
static void
-send_bier_imp_details (unix_shared_memory_queue_t * q,
+send_bier_imp_details (vl_api_registration_t * reg,
u32 context,
const bier_imp_t *bi)
{
mp = vl_msg_api_alloc(sizeof(*mp) + n_bytes);
if (!mp)
return;
- memset(mp, 0, sizeof(*mp)+n_bytes);
+ clib_memset(mp, 0, sizeof(*mp)+n_bytes);
mp->_vl_msg_id = ntohs(VL_API_BIER_IMP_DETAILS);
mp->context = context;
mp->bi_tbl_id.bt_sub_domain = bi->bi_tbl.bti_sub_domain;
mp->bi_tbl_id.bt_hdr_len_id = bi->bi_tbl.bti_hdr_len;
-
mp->bi_src = htons(bier_hdr_get_src_id(©));
mp->bi_n_bytes = n_bytes;
- memcpy(mp->bi_bytes, bi->bi_bits.bits, n_bytes);
+ memcpy(mp->bi_bytes, bi->bi_bits, n_bytes);
- vl_msg_api_send_shmem (q, (u8 *) & mp);
+ vl_api_send_msg (reg, (u8 *) mp);
}
static void
vl_api_bier_imp_dump_t_handler (vl_api_bier_imp_dump_t * mp)
{
- unix_shared_memory_queue_t *q;
+ vl_api_registration_t *reg;
bier_imp_t *bi;
- q = vl_api_client_index_to_input_queue (mp->client_index);
- if (q == 0)
- return;
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
pool_foreach(bi, bier_imp_pool,
({
- send_bier_imp_details(q, mp->context, bi);
+ send_bier_imp_details(reg, mp->context, bi);
}));
}
}
static void
-send_bier_disp_table_details (unix_shared_memory_queue_t * q,
+send_bier_disp_table_details (vl_api_registration_t * reg,
u32 context,
const bier_disp_table_t *bdt)
{
mp = vl_msg_api_alloc(sizeof(*mp));
if (!mp)
return;
- memset(mp, 0, sizeof(*mp));
+ clib_memset(mp, 0, sizeof(*mp));
mp->_vl_msg_id = ntohs(VL_API_BIER_DISP_TABLE_DETAILS);
mp->context = context;
mp->bdt_tbl_id = htonl(bdt->bdt_table_id);
- vl_msg_api_send_shmem (q, (u8 *) & mp);
+ vl_api_send_msg (reg, (u8 *) mp);
}
static void
vl_api_bier_disp_table_dump_t_handler (vl_api_bier_disp_table_dump_t * mp)
{
- unix_shared_memory_queue_t *q;
+ vl_api_registration_t *reg;
bier_disp_table_t *bdt;
- q = vl_api_client_index_to_input_queue (mp->client_index);
- if (q == 0)
- return;
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
pool_foreach(bdt, bier_disp_table_pool,
({
- send_bier_disp_table_details(q, mp->context, bdt);
+ send_bier_disp_table_details(reg, mp->context, bdt);
}));
}
table_id = ntohl(mp->bde_tbl_id);
bp = ntohs(mp->bde_bp);
- if (0 == bp || bp > 0xffff)
+ /*
+ * BP=0 is the default route
+ */
+ if (bp > 0xffff)
{
rv = -1;
goto done;
if (0 == mp->bde_paths[ii].afi)
{
- clib_memcpy (&brp->frp_addr.ip4,
+ clib_memcpy_fast (&brp->frp_addr.ip4,
mp->bde_paths[ii].next_hop,
sizeof (brp->frp_addr.ip4));
}
else
{
- clib_memcpy (&brp->frp_addr.ip6,
+ clib_memcpy_fast (&brp->frp_addr.ip6,
mp->bde_paths[ii].next_hop,
sizeof (brp->frp_addr.ip6));
}
typedef struct bier_disp_entry_details_walk_t_
{
- unix_shared_memory_queue_t * q;
+ vl_api_registration_t * reg;
u32 context;
} bier_disp_entry_details_walk_t;
bier_disp_entry_details_walk_t *ctx = args;
vl_api_bier_disp_entry_details_t *mp;
bier_hdr_proto_id_t pproto;
- vl_api_fib_path3_t *fp;
+ vl_api_fib_path_t *fp;
u32 n_paths, m_size;
FOR_EACH_BIER_HDR_PROTO(pproto)
if (INDEX_INVALID != pl)
{
n_paths = fib_path_list_get_n_paths(pl);
- m_size = sizeof(*mp) + (n_paths * sizeof(vl_api_fib_path3_t));
+ m_size = sizeof(*mp) + (n_paths * sizeof(vl_api_fib_path_t));
mp = vl_msg_api_alloc(m_size);
if (!mp)
return;
- memset(mp, 0, m_size);
+ clib_memset(mp, 0, m_size);
mp->_vl_msg_id = ntohs(VL_API_BIER_DISP_ENTRY_DETAILS);
mp->context = ctx->context;
fp = mp->bde_paths;
vec_foreach (api_rpath, api_rpaths)
{
- fp->weight = api_rpath->rpath.frp_weight;
- fp->preference = api_rpath->rpath.frp_preference;
- fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
- fp->n_labels = 0;
- copy_fib_next_hop (api_rpath, fp);
+ fib_api_path_encode(api_rpath, fp);
fp++;
}
- vl_msg_api_send_shmem (ctx->q, (u8 *) & mp);
+ vl_api_send_msg (ctx->reg, (u8 *) mp);
}
}
}
static void
vl_api_bier_disp_entry_dump_t_handler (vl_api_bier_disp_entry_dump_t * mp)
{
- unix_shared_memory_queue_t *q;
+ vl_api_registration_t *reg;
- q = vl_api_client_index_to_input_queue (mp->client_index);
- if (q == 0)
- return;
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
bier_disp_entry_details_walk_t ctx = {
- .q = q,
+ .reg = reg,
.context = mp->context,
};
bier_disp_table_walk(ntohl(mp->bde_tbl_id),