mirror of
https://github.com/openvswitch/ovs
synced 2025-08-22 09:58:01 +00:00
odp-util: Add support OVS_ACTION_ATTR_PSAMPLE.
Add support for parsing and formatting the new action. Also, flag OVS_ACTION_ATTR_SAMPLE as requiring datapath assistance if it contains a nested OVS_ACTION_ATTR_PSAMPLE. The reason is that the sampling rate from the parent "sample" is made available to the nested "psample" by the kernel. Acked-by: Eelco Chaudron <echaudro@redhat.com> Signed-off-by: Adrian Moreno <amorenoz@redhat.com> Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
This commit is contained in:
parent
d9de6b01c2
commit
1a3bd96b4f
@ -992,6 +992,31 @@ struct check_pkt_len_arg {
|
|||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define OVS_PSAMPLE_COOKIE_MAX_SIZE 16
|
||||||
|
/**
|
||||||
|
* enum ovs_pample_attr - Attributes for %OVS_ACTION_ATTR_PSAMPLE
|
||||||
|
* action.
|
||||||
|
*
|
||||||
|
* @OVS_PSAMPLE_ATTR_GROUP: 32-bit number to identify the source of the
|
||||||
|
* sample.
|
||||||
|
* @OVS_PSAMPLE_ATTR_COOKIE: An optional variable-length binary cookie that
|
||||||
|
* contains user-defined metadata. The maximum length is
|
||||||
|
* OVS_PSAMPLE_COOKIE_MAX_SIZE bytes.
|
||||||
|
*
|
||||||
|
* Sends the packet to the psample multicast group with the specified group and
|
||||||
|
* cookie. It is possible to combine this action with the
|
||||||
|
* %OVS_ACTION_ATTR_TRUNC action to limit the size of the sample.
|
||||||
|
*/
|
||||||
|
enum ovs_psample_attr {
|
||||||
|
OVS_PSAMPLE_ATTR_GROUP = 1, /* u32 number. */
|
||||||
|
OVS_PSAMPLE_ATTR_COOKIE, /* Optional, user specified cookie. */
|
||||||
|
|
||||||
|
/* private: */
|
||||||
|
__OVS_PSAMPLE_ATTR_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
#define OVS_PSAMPLE_ATTR_MAX (__OVS_PSAMPLE_ATTR_MAX - 1)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum ovs_action_attr - Action types.
|
* enum ovs_action_attr - Action types.
|
||||||
*
|
*
|
||||||
@ -1056,6 +1081,8 @@ struct check_pkt_len_arg {
|
|||||||
* of l3 tunnel flag in the tun_flags field of OVS_ACTION_ATTR_ADD_MPLS
|
* of l3 tunnel flag in the tun_flags field of OVS_ACTION_ATTR_ADD_MPLS
|
||||||
* argument.
|
* argument.
|
||||||
* @OVS_ACTION_ATTR_DROP: Explicit drop action.
|
* @OVS_ACTION_ATTR_DROP: Explicit drop action.
|
||||||
|
* @OVS_ACTION_ATTR_PSAMPLE: Send a sample of the packet to external observers
|
||||||
|
* via psample.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum ovs_action_attr {
|
enum ovs_action_attr {
|
||||||
@ -1087,6 +1114,7 @@ enum ovs_action_attr {
|
|||||||
OVS_ACTION_ATTR_ADD_MPLS, /* struct ovs_action_add_mpls. */
|
OVS_ACTION_ATTR_ADD_MPLS, /* struct ovs_action_add_mpls. */
|
||||||
OVS_ACTION_ATTR_DEC_TTL, /* Nested OVS_DEC_TTL_ATTR_*. */
|
OVS_ACTION_ATTR_DEC_TTL, /* Nested OVS_DEC_TTL_ATTR_*. */
|
||||||
OVS_ACTION_ATTR_DROP, /* u32 xlate_error. */
|
OVS_ACTION_ATTR_DROP, /* u32 xlate_error. */
|
||||||
|
OVS_ACTION_ATTR_PSAMPLE, /* Nested OVS_PSAMPLE_ATTR_*. */
|
||||||
|
|
||||||
#ifndef __KERNEL__
|
#ifndef __KERNEL__
|
||||||
OVS_ACTION_ATTR_TUNNEL_PUSH, /* struct ovs_action_push_tnl*/
|
OVS_ACTION_ATTR_TUNNEL_PUSH, /* struct ovs_action_push_tnl*/
|
||||||
|
@ -9519,6 +9519,7 @@ dp_execute_cb(void *aux_, struct dp_packet_batch *packets_,
|
|||||||
case OVS_ACTION_ATTR_DROP:
|
case OVS_ACTION_ATTR_DROP:
|
||||||
case OVS_ACTION_ATTR_ADD_MPLS:
|
case OVS_ACTION_ATTR_ADD_MPLS:
|
||||||
case OVS_ACTION_ATTR_DEC_TTL:
|
case OVS_ACTION_ATTR_DEC_TTL:
|
||||||
|
case OVS_ACTION_ATTR_PSAMPLE:
|
||||||
case __OVS_ACTION_ATTR_MAX:
|
case __OVS_ACTION_ATTR_MAX:
|
||||||
OVS_NOT_REACHED();
|
OVS_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
@ -1192,6 +1192,8 @@ dpif_execute_helper_cb(void *aux_, struct dp_packet_batch *packets_,
|
|||||||
case OVS_ACTION_ATTR_TUNNEL_PUSH:
|
case OVS_ACTION_ATTR_TUNNEL_PUSH:
|
||||||
case OVS_ACTION_ATTR_TUNNEL_POP:
|
case OVS_ACTION_ATTR_TUNNEL_POP:
|
||||||
case OVS_ACTION_ATTR_USERSPACE:
|
case OVS_ACTION_ATTR_USERSPACE:
|
||||||
|
case OVS_ACTION_ATTR_PSAMPLE:
|
||||||
|
case OVS_ACTION_ATTR_SAMPLE:
|
||||||
case OVS_ACTION_ATTR_RECIRC: {
|
case OVS_ACTION_ATTR_RECIRC: {
|
||||||
struct dpif_execute execute;
|
struct dpif_execute execute;
|
||||||
struct ofpbuf execute_actions;
|
struct ofpbuf execute_actions;
|
||||||
@ -1278,7 +1280,6 @@ dpif_execute_helper_cb(void *aux_, struct dp_packet_batch *packets_,
|
|||||||
case OVS_ACTION_ATTR_POP_MPLS:
|
case OVS_ACTION_ATTR_POP_MPLS:
|
||||||
case OVS_ACTION_ATTR_SET:
|
case OVS_ACTION_ATTR_SET:
|
||||||
case OVS_ACTION_ATTR_SET_MASKED:
|
case OVS_ACTION_ATTR_SET_MASKED:
|
||||||
case OVS_ACTION_ATTR_SAMPLE:
|
|
||||||
case OVS_ACTION_ATTR_TRUNC:
|
case OVS_ACTION_ATTR_TRUNC:
|
||||||
case OVS_ACTION_ATTR_PUSH_ETH:
|
case OVS_ACTION_ATTR_PUSH_ETH:
|
||||||
case OVS_ACTION_ATTR_POP_ETH:
|
case OVS_ACTION_ATTR_POP_ETH:
|
||||||
|
@ -818,13 +818,13 @@ requires_datapath_assistance(const struct nlattr *a)
|
|||||||
case OVS_ACTION_ATTR_RECIRC:
|
case OVS_ACTION_ATTR_RECIRC:
|
||||||
case OVS_ACTION_ATTR_CT:
|
case OVS_ACTION_ATTR_CT:
|
||||||
case OVS_ACTION_ATTR_METER:
|
case OVS_ACTION_ATTR_METER:
|
||||||
|
case OVS_ACTION_ATTR_PSAMPLE:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case OVS_ACTION_ATTR_SET:
|
case OVS_ACTION_ATTR_SET:
|
||||||
case OVS_ACTION_ATTR_SET_MASKED:
|
case OVS_ACTION_ATTR_SET_MASKED:
|
||||||
case OVS_ACTION_ATTR_PUSH_VLAN:
|
case OVS_ACTION_ATTR_PUSH_VLAN:
|
||||||
case OVS_ACTION_ATTR_POP_VLAN:
|
case OVS_ACTION_ATTR_POP_VLAN:
|
||||||
case OVS_ACTION_ATTR_SAMPLE:
|
|
||||||
case OVS_ACTION_ATTR_HASH:
|
case OVS_ACTION_ATTR_HASH:
|
||||||
case OVS_ACTION_ATTR_PUSH_MPLS:
|
case OVS_ACTION_ATTR_PUSH_MPLS:
|
||||||
case OVS_ACTION_ATTR_POP_MPLS:
|
case OVS_ACTION_ATTR_POP_MPLS:
|
||||||
@ -841,6 +841,28 @@ requires_datapath_assistance(const struct nlattr *a)
|
|||||||
case OVS_ACTION_ATTR_DROP:
|
case OVS_ACTION_ATTR_DROP:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
case OVS_ACTION_ATTR_SAMPLE: {
|
||||||
|
/* Nested "psample" actions rely on the datapath executing the
|
||||||
|
* parent "sample", storing the probability and making it available
|
||||||
|
* when the nested "psample" is run. */
|
||||||
|
const struct nlattr *attr;
|
||||||
|
unsigned int left;
|
||||||
|
|
||||||
|
NL_NESTED_FOR_EACH (attr, left, a) {
|
||||||
|
if (nl_attr_type(attr) == OVS_SAMPLE_ATTR_ACTIONS) {
|
||||||
|
const struct nlattr *act;
|
||||||
|
unsigned int act_left;
|
||||||
|
|
||||||
|
NL_NESTED_FOR_EACH (act, act_left, attr) {
|
||||||
|
if (nl_attr_type(act) == OVS_ACTION_ATTR_PSAMPLE) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
case OVS_ACTION_ATTR_UNSPEC:
|
case OVS_ACTION_ATTR_UNSPEC:
|
||||||
case __OVS_ACTION_ATTR_MAX:
|
case __OVS_ACTION_ATTR_MAX:
|
||||||
OVS_NOT_REACHED();
|
OVS_NOT_REACHED();
|
||||||
@ -1229,6 +1251,7 @@ odp_execute_actions(void *dp, struct dp_packet_batch *batch, bool steal,
|
|||||||
case OVS_ACTION_ATTR_CT:
|
case OVS_ACTION_ATTR_CT:
|
||||||
case OVS_ACTION_ATTR_UNSPEC:
|
case OVS_ACTION_ATTR_UNSPEC:
|
||||||
case OVS_ACTION_ATTR_DEC_TTL:
|
case OVS_ACTION_ATTR_DEC_TTL:
|
||||||
|
case OVS_ACTION_ATTR_PSAMPLE:
|
||||||
case __OVS_ACTION_ATTR_MAX:
|
case __OVS_ACTION_ATTR_MAX:
|
||||||
/* The following actions are handled by the scalar implementation. */
|
/* The following actions are handled by the scalar implementation. */
|
||||||
case OVS_ACTION_ATTR_POP_VLAN:
|
case OVS_ACTION_ATTR_POP_VLAN:
|
||||||
|
@ -145,6 +145,7 @@ odp_action_len(uint16_t type)
|
|||||||
case OVS_ACTION_ATTR_ADD_MPLS: return sizeof(struct ovs_action_add_mpls);
|
case OVS_ACTION_ATTR_ADD_MPLS: return sizeof(struct ovs_action_add_mpls);
|
||||||
case OVS_ACTION_ATTR_DEC_TTL: return ATTR_LEN_VARIABLE;
|
case OVS_ACTION_ATTR_DEC_TTL: return ATTR_LEN_VARIABLE;
|
||||||
case OVS_ACTION_ATTR_DROP: return sizeof(uint32_t);
|
case OVS_ACTION_ATTR_DROP: return sizeof(uint32_t);
|
||||||
|
case OVS_ACTION_ATTR_PSAMPLE: return ATTR_LEN_VARIABLE;
|
||||||
|
|
||||||
case OVS_ACTION_ATTR_UNSPEC:
|
case OVS_ACTION_ATTR_UNSPEC:
|
||||||
case __OVS_ACTION_ATTR_MAX:
|
case __OVS_ACTION_ATTR_MAX:
|
||||||
@ -1150,6 +1151,28 @@ format_dec_ttl_action(struct ds *ds, const struct nlattr *attr,
|
|||||||
ds_put_format(ds, "))");
|
ds_put_format(ds, "))");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
format_odp_psample_action(struct ds *ds, const struct nlattr *attr)
|
||||||
|
{
|
||||||
|
const struct nlattr *a;
|
||||||
|
unsigned int left;
|
||||||
|
|
||||||
|
ds_put_cstr(ds, "psample(");
|
||||||
|
NL_NESTED_FOR_EACH (a, left, attr) {
|
||||||
|
switch (a->nla_type) {
|
||||||
|
case OVS_PSAMPLE_ATTR_GROUP:
|
||||||
|
ds_put_format(ds, "group=%"PRIu32",", nl_attr_get_u32(a));
|
||||||
|
break;
|
||||||
|
case OVS_PSAMPLE_ATTR_COOKIE:
|
||||||
|
ds_put_cstr(ds, "cookie=");
|
||||||
|
ds_put_hex(ds, nl_attr_get(a), nl_attr_get_size(a));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ds_chomp(ds, ',');
|
||||||
|
ds_put_char(ds, ')');
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
format_odp_action(struct ds *ds, const struct nlattr *a,
|
format_odp_action(struct ds *ds, const struct nlattr *a,
|
||||||
const struct hmap *portno_names)
|
const struct hmap *portno_names)
|
||||||
@ -1309,6 +1332,9 @@ format_odp_action(struct ds *ds, const struct nlattr *a,
|
|||||||
case OVS_ACTION_ATTR_DROP:
|
case OVS_ACTION_ATTR_DROP:
|
||||||
ds_put_cstr(ds, "drop");
|
ds_put_cstr(ds, "drop");
|
||||||
break;
|
break;
|
||||||
|
case OVS_ACTION_ATTR_PSAMPLE:
|
||||||
|
format_odp_psample_action(ds, a);
|
||||||
|
break;
|
||||||
case OVS_ACTION_ATTR_UNSPEC:
|
case OVS_ACTION_ATTR_UNSPEC:
|
||||||
case __OVS_ACTION_ATTR_MAX:
|
case __OVS_ACTION_ATTR_MAX:
|
||||||
default:
|
default:
|
||||||
@ -2358,6 +2384,50 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
parse_odp_psample_action(const char *s, struct ofpbuf *actions)
|
||||||
|
{
|
||||||
|
char buf[2 * OVS_PSAMPLE_COOKIE_MAX_SIZE + 1];
|
||||||
|
uint8_t cookie[OVS_PSAMPLE_COOKIE_MAX_SIZE];
|
||||||
|
bool has_group = false;
|
||||||
|
size_t cookie_len = 0;
|
||||||
|
uint32_t group;
|
||||||
|
int n = 0;
|
||||||
|
|
||||||
|
if (!ovs_scan_len(s, &n, "psample(")) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (s[n] != ')') {
|
||||||
|
n += strspn(s + n, delimiters);
|
||||||
|
|
||||||
|
if (!has_group && ovs_scan_len(s, &n, "group=%"SCNi32, &group)) {
|
||||||
|
has_group = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cookie_len &&
|
||||||
|
ovs_scan_len(s, &n, "cookie=0x%32[0-9a-fA-F]", buf) && n > 7) {
|
||||||
|
struct ofpbuf b;
|
||||||
|
|
||||||
|
ofpbuf_use_stub(&b, cookie, OVS_PSAMPLE_COOKIE_MAX_SIZE);
|
||||||
|
ofpbuf_put_hex(&b, buf, &cookie_len);
|
||||||
|
ofpbuf_uninit(&b);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
n++;
|
||||||
|
|
||||||
|
if (!has_group) {
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
odp_put_psample_action(actions, group, cookie_len ? cookie : NULL,
|
||||||
|
cookie_len);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
parse_action_list(struct parse_odp_context *context, const char *s,
|
parse_action_list(struct parse_odp_context *context, const char *s,
|
||||||
struct ofpbuf *actions)
|
struct ofpbuf *actions)
|
||||||
@ -2719,6 +2789,10 @@ parse_odp_action__(struct parse_odp_context *context, const char *s,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strncmp(s, "psample(", 8)) {
|
||||||
|
return parse_odp_psample_action(s, actions);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
struct ovs_action_push_tnl data;
|
struct ovs_action_push_tnl data;
|
||||||
int n;
|
int n;
|
||||||
@ -7828,6 +7902,23 @@ odp_put_tnl_push_action(struct ofpbuf *odp_actions,
|
|||||||
nl_msg_put_unspec(odp_actions, OVS_ACTION_ATTR_TUNNEL_PUSH, data, size);
|
nl_msg_put_unspec(odp_actions, OVS_ACTION_ATTR_TUNNEL_PUSH, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
odp_put_psample_action(struct ofpbuf *odp_actions, uint32_t group_id,
|
||||||
|
uint8_t *cookie, size_t cookie_len)
|
||||||
|
{
|
||||||
|
size_t offset = nl_msg_start_nested_with_flag(odp_actions,
|
||||||
|
OVS_ACTION_ATTR_PSAMPLE);
|
||||||
|
|
||||||
|
nl_msg_put_u32(odp_actions, OVS_PSAMPLE_ATTR_GROUP, group_id);
|
||||||
|
if (cookie && cookie_len) {
|
||||||
|
ovs_assert(cookie_len <= OVS_PSAMPLE_COOKIE_MAX_SIZE);
|
||||||
|
nl_msg_put_unspec(odp_actions, OVS_PSAMPLE_ATTR_COOKIE, cookie,
|
||||||
|
cookie_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
nl_msg_end_nested(odp_actions, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The commit_odp_actions() function and its helpers. */
|
/* The commit_odp_actions() function and its helpers. */
|
||||||
|
|
||||||
|
@ -376,6 +376,9 @@ void odp_put_pop_eth_action(struct ofpbuf *odp_actions);
|
|||||||
void odp_put_push_eth_action(struct ofpbuf *odp_actions,
|
void odp_put_push_eth_action(struct ofpbuf *odp_actions,
|
||||||
const struct eth_addr *eth_src,
|
const struct eth_addr *eth_src,
|
||||||
const struct eth_addr *eth_dst);
|
const struct eth_addr *eth_dst);
|
||||||
|
void odp_put_psample_action(struct ofpbuf *odp_actions,
|
||||||
|
uint32_t group_id, uint8_t *cookie,
|
||||||
|
size_t cookie_len);
|
||||||
|
|
||||||
static inline void odp_decode_gbp_raw(uint32_t gbp_raw,
|
static inline void odp_decode_gbp_raw(uint32_t gbp_raw,
|
||||||
ovs_be16 *id,
|
ovs_be16 *id,
|
||||||
|
@ -3136,6 +3136,7 @@ dpif_ipfix_read_actions(const struct flow *flow,
|
|||||||
case OVS_ACTION_ATTR_DROP:
|
case OVS_ACTION_ATTR_DROP:
|
||||||
case OVS_ACTION_ATTR_ADD_MPLS:
|
case OVS_ACTION_ATTR_ADD_MPLS:
|
||||||
case OVS_ACTION_ATTR_DEC_TTL:
|
case OVS_ACTION_ATTR_DEC_TTL:
|
||||||
|
case OVS_ACTION_ATTR_PSAMPLE:
|
||||||
case __OVS_ACTION_ATTR_MAX:
|
case __OVS_ACTION_ATTR_MAX:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -1237,6 +1237,7 @@ dpif_sflow_read_actions(const struct flow *flow,
|
|||||||
case OVS_ACTION_ATTR_DROP:
|
case OVS_ACTION_ATTR_DROP:
|
||||||
case OVS_ACTION_ATTR_ADD_MPLS:
|
case OVS_ACTION_ATTR_ADD_MPLS:
|
||||||
case OVS_ACTION_ATTR_DEC_TTL:
|
case OVS_ACTION_ATTR_DEC_TTL:
|
||||||
|
case OVS_ACTION_ATTR_PSAMPLE:
|
||||||
case __OVS_ACTION_ATTR_MAX:
|
case __OVS_ACTION_ATTR_MAX:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -343,6 +343,14 @@ class ODPFlow(Flow):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
"psample": nested_kv_decoder(
|
||||||
|
KVDecoders(
|
||||||
|
{
|
||||||
|
"group": decode_int,
|
||||||
|
"cookie": decode_default,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
_decoders["sample"] = nested_kv_decoder(
|
_decoders["sample"] = nested_kv_decoder(
|
||||||
|
16
tests/odp.at
16
tests/odp.at
@ -393,6 +393,10 @@ check_pkt_len(size=200,gt(ct(nat)),le(drop))
|
|||||||
check_pkt_len(size=200,gt(set(eth(src=00:01:02:03:04:05,dst=10:11:12:13:14:15))),le(set(eth(src=00:01:02:03:04:06,dst=10:11:12:13:14:16))))
|
check_pkt_len(size=200,gt(set(eth(src=00:01:02:03:04:05,dst=10:11:12:13:14:15))),le(set(eth(src=00:01:02:03:04:06,dst=10:11:12:13:14:16))))
|
||||||
lb_output(1)
|
lb_output(1)
|
||||||
add_mpls(label=200,tc=7,ttl=64,bos=1,eth_type=0x8847)
|
add_mpls(label=200,tc=7,ttl=64,bos=1,eth_type=0x8847)
|
||||||
|
psample(group=12,cookie=0xf1020304050607080910111213141516)
|
||||||
|
psample(group=12)
|
||||||
|
sample(sample=50.0%,actions(psample(group=12,cookie=0xf1020304)))
|
||||||
|
sample(sample=50.0%,actions(userspace(pid=42,userdata(0102030400000000)),psample(group=12)))
|
||||||
])
|
])
|
||||||
AT_CHECK_UNQUOTED([ovstest test-odp parse-actions < actions.txt], [0],
|
AT_CHECK_UNQUOTED([ovstest test-odp parse-actions < actions.txt], [0],
|
||||||
[`cat actions.txt`
|
[`cat actions.txt`
|
||||||
@ -406,11 +410,23 @@ AT_DATA([actions.txt], [dnl
|
|||||||
encap_nsh@:{@
|
encap_nsh@:{@
|
||||||
tnl_push(tnl_port(6),header(size=94,type=112,eth(dst=f8:bc:12:44:34:b6,src=f8:bc:12:46:58:e0,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=2001:cafe::92,label=0,proto=43,tclass=0x0,hlimit=64),srv6(segments_left=2,segs(2001:cafe::90,2001:cafe::91))),out_port(1))
|
tnl_push(tnl_port(6),header(size=94,type=112,eth(dst=f8:bc:12:44:34:b6,src=f8:bc:12:46:58:e0,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=2001:cafe::92,label=0,proto=43,tclass=0x0,hlimit=64),srv6(segments_left=2,segs(2001:cafe::90,2001:cafe::91))),out_port(1))
|
||||||
tnl_push(tnl_port(6),header(size=126,type=112,eth(dst=f8:bc:12:44:34:b6,src=f8:bc:12:46:58:e0,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=2001:cafe::92,label=0,proto=43,tclass=0x0,hlimit=64),srv6(segments_left=2,segs(2001:cafe::90,2001:cafe::91,2001:cafe::92,2001:cafe::93))),out_port(1))
|
tnl_push(tnl_port(6),header(size=126,type=112,eth(dst=f8:bc:12:44:34:b6,src=f8:bc:12:46:58:e0,dl_type=0x86dd),ipv6(src=2001:cafe::88,dst=2001:cafe::92,label=0,proto=43,tclass=0x0,hlimit=64),srv6(segments_left=2,segs(2001:cafe::90,2001:cafe::91,2001:cafe::92,2001:cafe::93))),out_port(1))
|
||||||
|
psample(group_id=12,cookie=0x0102030405060708090a0b0c0d0e0f0f0f)
|
||||||
|
psample(cookie=0x010203)
|
||||||
|
psample(group=12,cookie=0x010203,group=12)
|
||||||
|
psample(group=abc)
|
||||||
|
psample(group=12,cookie=wrong)
|
||||||
|
psample()
|
||||||
])
|
])
|
||||||
AT_CHECK_UNQUOTED([ovstest test-odp parse-actions < actions.txt], [0], [dnl
|
AT_CHECK_UNQUOTED([ovstest test-odp parse-actions < actions.txt], [0], [dnl
|
||||||
odp_actions_from_string: error
|
odp_actions_from_string: error
|
||||||
odp_actions_from_string: error
|
odp_actions_from_string: error
|
||||||
odp_actions_from_string: error
|
odp_actions_from_string: error
|
||||||
|
odp_actions_from_string: error
|
||||||
|
odp_actions_from_string: error
|
||||||
|
odp_actions_from_string: error
|
||||||
|
odp_actions_from_string: error
|
||||||
|
odp_actions_from_string: error
|
||||||
|
odp_actions_from_string: error
|
||||||
])
|
])
|
||||||
AT_CLEANUP
|
AT_CLEANUP
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user