app/testpmd: support L2TPv2 and PPP protocol pattern
Add support for test-pmd to parse protocol pattern L2TPv2 and PPP. Signed-off-by: Wenjun Wu <wenjun1.wu@intel.com> Signed-off-by: Jie Wang <jie1x.wang@intel.com> Reviewed-by: Ferruh Yigit <ferruh.yigit@intel.com>
This commit is contained in:
parent
f30157d988
commit
748530f035
@ -321,6 +321,23 @@ enum index {
|
||||
ITEM_FLEX,
|
||||
ITEM_FLEX_ITEM_HANDLE,
|
||||
ITEM_FLEX_PATTERN_HANDLE,
|
||||
ITEM_L2TPV2,
|
||||
ITEM_L2TPV2_COMMON,
|
||||
ITEM_L2TPV2_COMMON_TYPE,
|
||||
ITEM_L2TPV2_COMMON_TYPE_DATA_L,
|
||||
ITEM_L2TPV2_COMMON_TYPE_CTRL,
|
||||
ITEM_L2TPV2_MSG_DATA_L_LENGTH,
|
||||
ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
|
||||
ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
|
||||
ITEM_L2TPV2_MSG_CTRL_LENGTH,
|
||||
ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
|
||||
ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
|
||||
ITEM_L2TPV2_MSG_CTRL_NS,
|
||||
ITEM_L2TPV2_MSG_CTRL_NR,
|
||||
ITEM_PPP,
|
||||
ITEM_PPP_ADDR,
|
||||
ITEM_PPP_CTRL,
|
||||
ITEM_PPP_PROTO_ID,
|
||||
|
||||
/* Validate/create actions. */
|
||||
ACTIONS,
|
||||
@ -1042,6 +1059,8 @@ static const enum index next_item[] = {
|
||||
ITEM_PORT_REPRESENTOR,
|
||||
ITEM_REPRESENTED_PORT,
|
||||
ITEM_FLEX,
|
||||
ITEM_L2TPV2,
|
||||
ITEM_PPP,
|
||||
END_SET,
|
||||
ZERO,
|
||||
};
|
||||
@ -1429,6 +1448,31 @@ static const enum index item_flex[] = {
|
||||
ZERO,
|
||||
};
|
||||
|
||||
static const enum index item_l2tpv2[] = {
|
||||
ITEM_L2TPV2_COMMON,
|
||||
ITEM_NEXT,
|
||||
ZERO,
|
||||
};
|
||||
|
||||
static const enum index item_l2tpv2_common[] = {
|
||||
ITEM_L2TPV2_COMMON_TYPE,
|
||||
ZERO,
|
||||
};
|
||||
|
||||
static const enum index item_l2tpv2_common_type[] = {
|
||||
ITEM_L2TPV2_COMMON_TYPE_DATA_L,
|
||||
ITEM_L2TPV2_COMMON_TYPE_CTRL,
|
||||
ZERO,
|
||||
};
|
||||
|
||||
static const enum index item_ppp[] = {
|
||||
ITEM_PPP_ADDR,
|
||||
ITEM_PPP_CTRL,
|
||||
ITEM_PPP_PROTO_ID,
|
||||
ITEM_NEXT,
|
||||
ZERO,
|
||||
};
|
||||
|
||||
static const enum index next_action[] = {
|
||||
ACTION_END,
|
||||
ACTION_VOID,
|
||||
@ -1815,6 +1859,9 @@ static int parse_vc_conf(struct context *, const struct token *,
|
||||
static int parse_vc_item_ecpri_type(struct context *, const struct token *,
|
||||
const char *, unsigned int,
|
||||
void *, unsigned int);
|
||||
static int parse_vc_item_l2tpv2_type(struct context *, const struct token *,
|
||||
const char *, unsigned int,
|
||||
void *, unsigned int);
|
||||
static int parse_vc_action_meter_color_type(struct context *,
|
||||
const struct token *,
|
||||
const char *, unsigned int, void *,
|
||||
@ -3789,6 +3836,153 @@ static const struct token token_list[] = {
|
||||
NEXT_ENTRY(ITEM_PARAM_IS)),
|
||||
.args = ARGS(ARGS_ENTRY(struct rte_flow_item_flex, pattern)),
|
||||
},
|
||||
[ITEM_L2TPV2] = {
|
||||
.name = "l2tpv2",
|
||||
.help = "match L2TPv2 header",
|
||||
.priv = PRIV_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
|
||||
.next = NEXT(item_l2tpv2),
|
||||
.call = parse_vc,
|
||||
},
|
||||
[ITEM_L2TPV2_COMMON] = {
|
||||
.name = "common",
|
||||
.help = "L2TPv2 common header",
|
||||
.next = NEXT(item_l2tpv2_common),
|
||||
},
|
||||
[ITEM_L2TPV2_COMMON_TYPE] = {
|
||||
.name = "type",
|
||||
.help = "type of common header",
|
||||
.next = NEXT(item_l2tpv2_common_type),
|
||||
.args = ARGS(ARG_ENTRY_HTON(struct rte_flow_item_l2tpv2)),
|
||||
},
|
||||
[ITEM_L2TPV2_COMMON_TYPE_DATA_L] = {
|
||||
.name = "data_l",
|
||||
.help = "Type #6: data message with length option",
|
||||
.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
|
||||
ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
|
||||
ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
|
||||
ITEM_NEXT)),
|
||||
.call = parse_vc_item_l2tpv2_type,
|
||||
},
|
||||
[ITEM_L2TPV2_MSG_DATA_L_LENGTH] = {
|
||||
.name = "length",
|
||||
.help = "message length",
|
||||
.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_LENGTH,
|
||||
ITEM_L2TPV2_COMMON, ITEM_NEXT),
|
||||
NEXT_ENTRY(COMMON_UNSIGNED),
|
||||
item_param),
|
||||
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
|
||||
hdr.type6.length)),
|
||||
},
|
||||
[ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID] = {
|
||||
.name = "tunnel_id",
|
||||
.help = "tunnel identifier",
|
||||
.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_TUNNEL_ID,
|
||||
ITEM_L2TPV2_COMMON, ITEM_NEXT),
|
||||
NEXT_ENTRY(COMMON_UNSIGNED),
|
||||
item_param),
|
||||
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
|
||||
hdr.type6.tunnel_id)),
|
||||
},
|
||||
[ITEM_L2TPV2_MSG_DATA_L_SESSION_ID] = {
|
||||
.name = "session_id",
|
||||
.help = "session identifier",
|
||||
.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_DATA_L_SESSION_ID,
|
||||
ITEM_L2TPV2_COMMON, ITEM_NEXT),
|
||||
NEXT_ENTRY(COMMON_UNSIGNED),
|
||||
item_param),
|
||||
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
|
||||
hdr.type6.session_id)),
|
||||
},
|
||||
[ITEM_L2TPV2_COMMON_TYPE_CTRL] = {
|
||||
.name = "control",
|
||||
.help = "Type #3: conrtol message contains length, ns, nr options",
|
||||
.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
|
||||
ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
|
||||
ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
|
||||
ITEM_L2TPV2_MSG_CTRL_NS,
|
||||
ITEM_L2TPV2_MSG_CTRL_NR,
|
||||
ITEM_NEXT)),
|
||||
.call = parse_vc_item_l2tpv2_type,
|
||||
},
|
||||
[ITEM_L2TPV2_MSG_CTRL_LENGTH] = {
|
||||
.name = "length",
|
||||
.help = "message length",
|
||||
.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_LENGTH,
|
||||
ITEM_L2TPV2_COMMON, ITEM_NEXT),
|
||||
NEXT_ENTRY(COMMON_UNSIGNED),
|
||||
item_param),
|
||||
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
|
||||
hdr.type3.length)),
|
||||
},
|
||||
[ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID] = {
|
||||
.name = "tunnel_id",
|
||||
.help = "tunnel identifier",
|
||||
.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_TUNNEL_ID,
|
||||
ITEM_L2TPV2_COMMON, ITEM_NEXT),
|
||||
NEXT_ENTRY(COMMON_UNSIGNED),
|
||||
item_param),
|
||||
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
|
||||
hdr.type3.tunnel_id)),
|
||||
},
|
||||
[ITEM_L2TPV2_MSG_CTRL_SESSION_ID] = {
|
||||
.name = "session_id",
|
||||
.help = "session identifier",
|
||||
.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_SESSION_ID,
|
||||
ITEM_L2TPV2_COMMON, ITEM_NEXT),
|
||||
NEXT_ENTRY(COMMON_UNSIGNED),
|
||||
item_param),
|
||||
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
|
||||
hdr.type3.session_id)),
|
||||
},
|
||||
[ITEM_L2TPV2_MSG_CTRL_NS] = {
|
||||
.name = "ns",
|
||||
.help = "sequence number for message",
|
||||
.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS,
|
||||
ITEM_L2TPV2_COMMON, ITEM_NEXT),
|
||||
NEXT_ENTRY(COMMON_UNSIGNED),
|
||||
item_param),
|
||||
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
|
||||
hdr.type3.ns)),
|
||||
},
|
||||
[ITEM_L2TPV2_MSG_CTRL_NR] = {
|
||||
.name = "nr",
|
||||
.help = "sequence number for next receive message",
|
||||
.next = NEXT(NEXT_ENTRY(ITEM_L2TPV2_MSG_CTRL_NS,
|
||||
ITEM_L2TPV2_COMMON, ITEM_NEXT),
|
||||
NEXT_ENTRY(COMMON_UNSIGNED),
|
||||
item_param),
|
||||
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_l2tpv2,
|
||||
hdr.type3.nr)),
|
||||
},
|
||||
[ITEM_PPP] = {
|
||||
.name = "ppp",
|
||||
.help = "match PPP header",
|
||||
.priv = PRIV_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
|
||||
.next = NEXT(item_ppp),
|
||||
.call = parse_vc,
|
||||
},
|
||||
[ITEM_PPP_ADDR] = {
|
||||
.name = "addr",
|
||||
.help = "PPP address",
|
||||
.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
|
||||
item_param),
|
||||
.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.addr)),
|
||||
},
|
||||
[ITEM_PPP_CTRL] = {
|
||||
.name = "ctrl",
|
||||
.help = "PPP control",
|
||||
.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
|
||||
item_param),
|
||||
.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp, hdr.ctrl)),
|
||||
},
|
||||
[ITEM_PPP_PROTO_ID] = {
|
||||
.name = "proto_id",
|
||||
.help = "PPP protocol identifier",
|
||||
.next = NEXT(item_ppp, NEXT_ENTRY(COMMON_UNSIGNED),
|
||||
item_param),
|
||||
.args = ARGS(ARGS_ENTRY(struct rte_flow_item_ppp,
|
||||
hdr.proto_id)),
|
||||
},
|
||||
/* Validate/create actions. */
|
||||
[ACTIONS] = {
|
||||
.name = "actions",
|
||||
@ -5676,6 +5870,57 @@ parse_vc_item_ecpri_type(struct context *ctx, const struct token *token,
|
||||
return len;
|
||||
}
|
||||
|
||||
/** Parse L2TPv2 common header type field. */
|
||||
static int
|
||||
parse_vc_item_l2tpv2_type(struct context *ctx, const struct token *token,
|
||||
const char *str, unsigned int len,
|
||||
void *buf, unsigned int size)
|
||||
{
|
||||
struct rte_flow_item_l2tpv2 *l2tpv2;
|
||||
struct rte_flow_item_l2tpv2 *l2tpv2_mask;
|
||||
struct rte_flow_item *item;
|
||||
uint32_t data_size;
|
||||
uint8_t msg_type = 0;
|
||||
struct buffer *out = buf;
|
||||
const struct arg *arg;
|
||||
|
||||
(void)size;
|
||||
/* Token name must match. */
|
||||
if (parse_default(ctx, token, str, len, NULL, 0) < 0)
|
||||
return -1;
|
||||
switch (ctx->curr) {
|
||||
case ITEM_L2TPV2_COMMON_TYPE_DATA_L:
|
||||
msg_type |= 0x4000;
|
||||
break;
|
||||
case ITEM_L2TPV2_COMMON_TYPE_CTRL:
|
||||
msg_type |= 0xC800;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
if (!ctx->object)
|
||||
return len;
|
||||
arg = pop_args(ctx);
|
||||
if (!arg)
|
||||
return -1;
|
||||
l2tpv2 = (struct rte_flow_item_l2tpv2 *)out->args.vc.data;
|
||||
l2tpv2->hdr.common.flags_version |= msg_type;
|
||||
data_size = ctx->objdata / 3; /* spec, last, mask */
|
||||
l2tpv2_mask = (struct rte_flow_item_l2tpv2 *)(out->args.vc.data +
|
||||
(data_size * 2));
|
||||
l2tpv2_mask->hdr.common.flags_version = 0xFFFF;
|
||||
if (arg->hton) {
|
||||
l2tpv2->hdr.common.flags_version =
|
||||
rte_cpu_to_be_16(l2tpv2->hdr.common.flags_version);
|
||||
l2tpv2_mask->hdr.common.flags_version =
|
||||
rte_cpu_to_be_16(l2tpv2_mask->hdr.common.flags_version);
|
||||
}
|
||||
item = &out->args.vc.pattern[out->args.vc.pattern_n - 1];
|
||||
item->spec = l2tpv2;
|
||||
item->mask = l2tpv2_mask;
|
||||
return len;
|
||||
}
|
||||
|
||||
/** Parse meter color action type. */
|
||||
static int
|
||||
parse_vc_action_meter_color_type(struct context *ctx, const struct token *token,
|
||||
@ -8701,6 +8946,12 @@ flow_item_default_mask(const struct rte_flow_item *item)
|
||||
case RTE_FLOW_ITEM_TYPE_REPRESENTED_PORT:
|
||||
mask = &rte_flow_item_ethdev_mask;
|
||||
break;
|
||||
case RTE_FLOW_ITEM_TYPE_L2TPV2:
|
||||
mask = &rte_flow_item_l2tpv2_mask;
|
||||
break;
|
||||
case RTE_FLOW_ITEM_TYPE_PPP:
|
||||
mask = &rte_flow_item_ppp_mask;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -3810,6 +3810,20 @@ This section lists supported pattern items and their attributes, if any.
|
||||
|
||||
- ``ethdev_port_id {unsigned}``: ethdev port ID
|
||||
|
||||
- ``l2tpv2``: match L2TPv2 header.
|
||||
|
||||
- ``length {unsigned}``: L2TPv2 option length.
|
||||
- ``tunnel_id {unsigned}``: L2TPv2 tunnel identifier.
|
||||
- ``session_id {unsigned}``: L2TPv2 session identifier.
|
||||
- ``ns {unsigned}``: L2TPv2 option ns.
|
||||
- ``nr {unsigned}``: L2TPv2 option nr.
|
||||
|
||||
- ``ppp``: match PPP header.
|
||||
|
||||
- ``addr {unsigned}``: PPP address.
|
||||
- ``ctrl {unsigned}``: PPP control.
|
||||
- ``proto_id {unsigned}``: PPP protocol identifier.
|
||||
|
||||
Actions list
|
||||
^^^^^^^^^^^^
|
||||
|
||||
@ -5036,6 +5050,20 @@ The meter policy action list: ``green -> green, yellow -> yellow, red -> red``.
|
||||
testpmd> create port meter 0 1 13 1 yes 0xffff 0 0
|
||||
testpmd> flow create 0 priority 0 ingress group 1 pattern eth / end actions meter mtr_id 1 / end
|
||||
|
||||
Sample PPPoL2TPv2oUDP RSS rules
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
PPPoL2TPv2oUDP RSS rules can be created by the following commands::
|
||||
|
||||
testpmd> flow create 0 ingress pattern eth / ipv4 / udp / l2tpv2 / ppp / ipv4
|
||||
/ end actions rss types ipv4 end queues end / end
|
||||
testpmd> flow create 0 ingress pattern eth / ipv4 / udp / l2tpv2 / ppp / ipv6
|
||||
/ udp / end actions rss types ipv6-udp end queues end / end
|
||||
testpmd> flow create 0 ingress pattern eth / ipv6 / udp / l2tpv2 / ppp / ipv4
|
||||
/ tcp / end actions rss types ipv4-tcp end queues end / end
|
||||
testpmd> flow create 0 ingress pattern eth / ipv6 / udp / l2tpv2 / ppp / ipv6
|
||||
/ end actions rss types ipv6 end queues end / end
|
||||
|
||||
BPF Functions
|
||||
--------------
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user