diff options
Diffstat (limited to 'src/vnet/dpo')
-rw-r--r-- | src/vnet/dpo/dpo.c | 53 | ||||
-rw-r--r-- | src/vnet/dpo/dpo.h | 24 | ||||
-rw-r--r-- | src/vnet/dpo/load_balance.c | 20 | ||||
-rw-r--r-- | src/vnet/dpo/mpls_label_dpo.c | 33 | ||||
-rw-r--r-- | src/vnet/dpo/replicate_dpo.h | 10 |
5 files changed, 114 insertions, 26 deletions
diff --git a/src/vnet/dpo/dpo.c b/src/vnet/dpo/dpo.c index 85f2c5d3622..19e3714c536 100644 --- a/src/vnet/dpo/dpo.c +++ b/src/vnet/dpo/dpo.c @@ -153,20 +153,22 @@ format_dpo_id (u8 * s, va_list * args) if (NULL != dpo_vfts[dpo->dpoi_type].dv_format) { - return (format(s, "%U", - dpo_vfts[dpo->dpoi_type].dv_format, - dpo->dpoi_index, - indent)); + s = format(s, "%U", + dpo_vfts[dpo->dpoi_type].dv_format, + dpo->dpoi_index, + indent); } - - switch (dpo->dpoi_type) + else { - case DPO_FIRST: - s = format(s, "unset"); - break; - default: - s = format(s, "unknown"); - break; + switch (dpo->dpoi_type) + { + case DPO_FIRST: + s = format(s, "unset"); + break; + default: + s = format(s, "unknown"); + break; + } } return (s); } @@ -303,6 +305,18 @@ dpo_default_get_next_node (const dpo_id_t *dpo) return (node_indices); } +/** + * A default variant of the make interpose function that just returns + * the original + */ +static void +dpo_default_mk_interpose (const dpo_id_t *original, + const dpo_id_t *parent, + dpo_id_t *clone) +{ + dpo_copy(clone, original); +} + void dpo_register (dpo_type_t type, const dpo_vft_t *vft, @@ -314,6 +328,10 @@ dpo_register (dpo_type_t type, { dpo_vfts[type].dv_get_next_node = dpo_default_get_next_node; } + if (NULL == dpo_vfts[type].dv_mk_interpose) + { + dpo_vfts[type].dv_mk_interpose = dpo_default_mk_interpose; + } vec_validate(dpo_nodes, type); dpo_nodes[type] = nodes; @@ -331,6 +349,17 @@ dpo_register_new_type (const dpo_vft_t *vft, } void +dpo_mk_interpose (const dpo_id_t *original, + const dpo_id_t *parent, + dpo_id_t *clone) +{ + if (!dpo_id_is_valid(original)) + return; + + dpo_vfts[original->dpoi_type].dv_mk_interpose(original, parent, clone); +} + +void dpo_lock (dpo_id_t *dpo) { if (!dpo_id_is_valid(dpo)) diff --git a/src/vnet/dpo/dpo.h b/src/vnet/dpo/dpo.h index 21a2ae2a33d..0eeca67b74b 100644 --- a/src/vnet/dpo/dpo.h +++ b/src/vnet/dpo/dpo.h @@ -225,6 +225,14 @@ extern void dpo_lock(dpo_id_t *dpo); extern void dpo_unlock(dpo_id_t *dpo); /** + * @brief + * Make an interpose DPO from an original + */ +extern void dpo_mk_interpose(const dpo_id_t *original, + const dpo_id_t *parent, + dpo_id_t *clone); + +/** * @brief Set/create a DPO ID * The DPO will be locked. * @@ -374,6 +382,18 @@ typedef u32* (*dpo_get_next_node_t)(const dpo_id_t *dpo); typedef u32 (*dpo_get_urpf_t)(const dpo_id_t *dpo); /** + * @brief Called during FIB interposition when the originally + * registered DPO is used to 'clone' an instance for interposition + * at a particular location in the FIB graph. + * The parent is the next DPO in the chain that the clone will + * be used instead of. The clone may then choose to stack itself + * on the parent. + */ +typedef void (*dpo_mk_interpose_t)(const dpo_id_t *original, + const dpo_id_t *parent, + dpo_id_t *clone); + +/** * @brief A virtual function table regisitered for a DPO type */ typedef struct dpo_vft_t_ @@ -405,6 +425,10 @@ typedef struct dpo_vft_t_ * Get uRPF interface */ dpo_get_urpf_t dv_get_urpf; + /** + * Signal on an interposed child that the parent has changed + */ + dpo_mk_interpose_t dv_mk_interpose; } dpo_vft_t; diff --git a/src/vnet/dpo/load_balance.c b/src/vnet/dpo/load_balance.c index db0ebcdceb8..bb38233a55e 100644 --- a/src/vnet/dpo/load_balance.c +++ b/src/vnet/dpo/load_balance.c @@ -198,16 +198,6 @@ load_balance_create (u32 n_buckets, return (load_balance_get_index(load_balance_create_i(n_buckets, lb_proto, fhc))); } -u16 -load_balance_n_buckets (index_t lbi) -{ - load_balance_t *lb; - - lb = load_balance_get(lbi); - - return (lb->lb_n_buckets); -} - static inline void load_balance_set_bucket_i (load_balance_t *lb, u32 bucket, @@ -250,6 +240,16 @@ load_balance_is_drop (const dpo_id_t *dpo) return (0); } +u16 +load_balance_n_buckets (index_t lbi) +{ + load_balance_t *lb; + + lb = load_balance_get(lbi); + + return (lb->lb_n_buckets); +} + void load_balance_set_fib_entry_flags (index_t lbi, fib_entry_flag_t flags) diff --git a/src/vnet/dpo/mpls_label_dpo.c b/src/vnet/dpo/mpls_label_dpo.c index ebbbbec9b64..0a7063cc99a 100644 --- a/src/vnet/dpo/mpls_label_dpo.c +++ b/src/vnet/dpo/mpls_label_dpo.c @@ -1204,11 +1204,44 @@ mpls_label_dpo_mem_show (void) sizeof(mpls_label_dpo_t)); } +/** + * Interpose a label DPO. used in the FIB unit tests + */ +static void +mpls_label_interpose (const dpo_id_t *original, + const dpo_id_t *parent, + dpo_id_t *clone) +{ + mpls_label_dpo_t *mld, *mld_clone; + + mld_clone = mpls_label_dpo_alloc(); + mld = mpls_label_dpo_get(original->dpoi_index); + + mld_clone->mld_locks = 0; + clib_memcpy(&mld_clone->mld_hdr, + &mld->mld_hdr, + sizeof(mld_clone->mld_hdr)); + mld_clone->mld_payload_proto = mld->mld_payload_proto; + mld_clone->mld_n_labels = mld->mld_n_labels; + mld_clone->mld_n_hdr_bytes = mld->mld_n_hdr_bytes; + + dpo_stack(mpls_label_dpo_types[MPLS_LABEL_DPO_FLAG_NONE], + mld_clone->mld_payload_proto, + &mld_clone->mld_dpo, + parent); + + dpo_set(clone, + mpls_label_dpo_types[MPLS_LABEL_DPO_FLAG_NONE], + mld_clone->mld_payload_proto, + mpls_label_dpo_get_index(mld_clone)); +} + const static dpo_vft_t mld_vft = { .dv_lock = mpls_label_dpo_lock, .dv_unlock = mpls_label_dpo_unlock, .dv_format = format_mpls_label_dpo, .dv_mem_show = mpls_label_dpo_mem_show, + .dv_mk_interpose = mpls_label_interpose, }; const static char* const mpls_label_imp_pipe_ip4_nodes[] = diff --git a/src/vnet/dpo/replicate_dpo.h b/src/vnet/dpo/replicate_dpo.h index 7383184a2ea..ccb25630e16 100644 --- a/src/vnet/dpo/replicate_dpo.h +++ b/src/vnet/dpo/replicate_dpo.h @@ -53,7 +53,7 @@ extern replicate_main_t replicate_main; */ typedef struct replicate_t_ { /** - * number of buckets in the load-balance. always a power of 2. + * number of buckets in the replicate. */ u16 rep_n_buckets; @@ -104,15 +104,17 @@ extern void replicate_multipath_update( load_balance_path_t *next_hops); extern void replicate_set_bucket(index_t repi, - u32 bucket, - const dpo_id_t *next); + u32 bucket, + const dpo_id_t *next); extern u8* format_replicate(u8 * s, va_list * args); extern const dpo_id_t *replicate_get_bucket(index_t repi, - u32 bucket); + u32 bucket); extern int replicate_is_drop(const dpo_id_t *dpo); +extern u16 replicate_n_buckets(index_t repi); + /** * The encapsulation breakages are for fast DP access */ |