From: Jasvinder Singh Date: Thu, 29 Mar 2018 18:31:29 +0000 (+0100) Subject: pipeline: add load balance action X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=934db41a31a3806aabe26f7fdc2e1dfd3ec92705;p=dpdk.git pipeline: add load balance action Add implementation of the load balance action. Signed-off-by: Cristian Dumitrescu --- diff --git a/lib/librte_pipeline/rte_table_action.c b/lib/librte_pipeline/rte_table_action.c index 1a32c71d72..83ffa5dedd 100644 --- a/lib/librte_pipeline/rte_table_action.c +++ b/lib/librte_pipeline/rte_table_action.c @@ -44,6 +44,55 @@ fwd_apply(struct fwd_data *data, return 0; } +/** + * RTE_TABLE_ACTION_LB + */ +static int +lb_cfg_check(struct rte_table_action_lb_config *cfg) +{ + if ((cfg == NULL) || + (cfg->key_size < RTE_TABLE_ACTION_LB_KEY_SIZE_MIN) || + (cfg->key_size > RTE_TABLE_ACTION_LB_KEY_SIZE_MAX) || + (!rte_is_power_of_2(cfg->key_size)) || + (cfg->f_hash == NULL)) + return -1; + + return 0; +} + +struct lb_data { + uint32_t out[RTE_TABLE_ACTION_LB_TABLE_SIZE]; +} __attribute__((__packed__)); + +static int +lb_apply(struct lb_data *data, + struct rte_table_action_lb_params *p) +{ + memcpy(data->out, p->out, sizeof(data->out)); + + return 0; +} + +static __rte_always_inline void +pkt_work_lb(struct rte_mbuf *mbuf, + struct lb_data *data, + struct rte_table_action_lb_config *cfg) +{ + uint8_t *pkt_key = RTE_MBUF_METADATA_UINT8_PTR(mbuf, cfg->key_offset); + uint32_t *out = RTE_MBUF_METADATA_UINT32_PTR(mbuf, cfg->out_offset); + uint64_t digest, pos; + uint32_t out_val; + + digest = cfg->f_hash(pkt_key, + cfg->key_mask, + cfg->key_size, + cfg->seed); + pos = digest & (RTE_TABLE_ACTION_LB_TABLE_SIZE - 1); + out_val = data->out[pos]; + + *out = out_val; +} + /** * RTE_TABLE_ACTION_MTR */ @@ -1178,6 +1227,7 @@ action_valid(enum rte_table_action_type action) { switch (action) { case RTE_TABLE_ACTION_FWD: + case RTE_TABLE_ACTION_LB: case RTE_TABLE_ACTION_MTR: case RTE_TABLE_ACTION_TM: case RTE_TABLE_ACTION_ENCAP: @@ -1197,6 +1247,7 @@ action_valid(enum rte_table_action_type action) struct ap_config { uint64_t action_mask; struct rte_table_action_common_config common; + struct rte_table_action_lb_config lb; struct rte_table_action_mtr_config mtr; struct rte_table_action_tm_config tm; struct rte_table_action_encap_config encap; @@ -1209,6 +1260,8 @@ static size_t action_cfg_size(enum rte_table_action_type action) { switch (action) { + case RTE_TABLE_ACTION_LB: + return sizeof(struct rte_table_action_lb_config); case RTE_TABLE_ACTION_MTR: return sizeof(struct rte_table_action_mtr_config); case RTE_TABLE_ACTION_TM: @@ -1231,6 +1284,9 @@ action_cfg_get(struct ap_config *ap_config, enum rte_table_action_type type) { switch (type) { + case RTE_TABLE_ACTION_LB: + return &ap_config->lb; + case RTE_TABLE_ACTION_MTR: return &ap_config->mtr; @@ -1280,6 +1336,9 @@ action_data_size(enum rte_table_action_type action, case RTE_TABLE_ACTION_FWD: return sizeof(struct fwd_data); + case RTE_TABLE_ACTION_LB: + return sizeof(struct lb_data); + case RTE_TABLE_ACTION_MTR: return mtr_data_size(&ap_config->mtr); @@ -1373,6 +1432,10 @@ rte_table_action_profile_action_register(struct rte_table_action_profile *profil return -EINVAL; switch (type) { + case RTE_TABLE_ACTION_LB: + status = lb_cfg_check(action_config); + break; + case RTE_TABLE_ACTION_MTR: status = mtr_cfg_check(action_config); break; @@ -1507,6 +1570,10 @@ rte_table_action_apply(struct rte_table_action *action, return fwd_apply(action_data, action_params); + case RTE_TABLE_ACTION_LB: + return lb_apply(action_data, + action_params); + case RTE_TABLE_ACTION_MTR: return mtr_apply(action_data, action_params, @@ -1822,6 +1889,14 @@ pkt_work(struct rte_mbuf *mbuf, rte_ntohs(hdr->payload_len) + sizeof(struct ipv6_hdr); } + if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) { + void *data = + action_data_get(table_entry, action, RTE_TABLE_ACTION_LB); + + pkt_work_lb(mbuf, + data, + &cfg->lb); + } if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) { void *data = action_data_get(table_entry, action, RTE_TABLE_ACTION_MTR); @@ -1961,6 +2036,33 @@ pkt4_work(struct rte_mbuf **mbufs, rte_ntohs(hdr3->payload_len) + sizeof(struct ipv6_hdr); } + if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) { + void *data0 = + action_data_get(table_entry0, action, RTE_TABLE_ACTION_LB); + void *data1 = + action_data_get(table_entry1, action, RTE_TABLE_ACTION_LB); + void *data2 = + action_data_get(table_entry2, action, RTE_TABLE_ACTION_LB); + void *data3 = + action_data_get(table_entry3, action, RTE_TABLE_ACTION_LB); + + pkt_work_lb(mbuf0, + data0, + &cfg->lb); + + pkt_work_lb(mbuf1, + data1, + &cfg->lb); + + pkt_work_lb(mbuf2, + data2, + &cfg->lb); + + pkt_work_lb(mbuf3, + data3, + &cfg->lb); + } + if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) { void *data0 = action_data_get(table_entry0, action, RTE_TABLE_ACTION_MTR); diff --git a/lib/librte_pipeline/rte_table_action.h b/lib/librte_pipeline/rte_table_action.h index e9b30ab2fe..c7f751aae5 100644 --- a/lib/librte_pipeline/rte_table_action.h +++ b/lib/librte_pipeline/rte_table_action.h @@ -61,6 +61,7 @@ extern "C" { #include #include #include +#include #include "rte_pipeline.h" @@ -69,6 +70,9 @@ enum rte_table_action_type { /** Forward to next pipeline table, output port or drop. */ RTE_TABLE_ACTION_FWD = 0, + /** Load balance. */ + RTE_TABLE_ACTION_LB, + /** Traffic Metering and Policing. */ RTE_TABLE_ACTION_MTR, @@ -116,6 +120,54 @@ struct rte_table_action_fwd_params { uint32_t id; }; +/** + * RTE_TABLE_ACTION_LB + */ +/** Load balance key size min (number of bytes). */ +#define RTE_TABLE_ACTION_LB_KEY_SIZE_MIN 8 + +/** Load balance key size max (number of bytes). */ +#define RTE_TABLE_ACTION_LB_KEY_SIZE_MAX 64 + +/** Load balance table size. */ +#define RTE_TABLE_ACTION_LB_TABLE_SIZE 8 + +/** Load balance action configuration (per table action profile). */ +struct rte_table_action_lb_config { + /** Key size (number of bytes). */ + uint32_t key_size; + + /** Key offset within the input packet buffer. Offset 0 points to the + * first byte of the MBUF structure. + */ + uint32_t key_offset; + + /** Key mask (*key_size* bytes are valid). */ + uint8_t key_mask[RTE_TABLE_ACTION_LB_KEY_SIZE_MAX]; + + /** Hash function. */ + rte_table_hash_op_hash f_hash; + + /** Seed value for *f_hash*. */ + uint64_t seed; + + /** Output value offset within the input packet buffer. Offset 0 points + * to the first byte of the MBUF structure. + */ + uint32_t out_offset; +}; + +/** Load balance action parameters (per table rule). */ +struct rte_table_action_lb_params { + /** Table defining the output values and their weights. The weights are + * set in 1/RTE_TABLE_ACTION_LB_TABLE_SIZE increments. To assign a + * weight of N/RTE_TABLE_ACTION_LB_TABLE_SIZE to a given output value + * (0 <= N <= RTE_TABLE_ACTION_LB_TABLE_SIZE), the same output value + * needs to show up exactly N times in this table. + */ + uint32_t out[RTE_TABLE_ACTION_LB_TABLE_SIZE]; +}; + /** * RTE_TABLE_ACTION_MTR */