[ovs-dev] [PATCH V3 32/40] erspan: Add flow-based erspan options
William Tu
u9012063 at gmail.com
Tue May 22 01:02:26 UTC 2018
On Fri, May 18, 2018 at 5:49 PM, Greg Rose <gvrose8192 at gmail.com> wrote:
> The patch add supports for flow-based erspan options.
> The erspan_ver, erspan_idx, erspan_dir, and erspan_hwid can be
> set as "flow" so that its value is set by the openflow rule,
> instead of statically configured at port creation time.
>
> Signed-off-by: William Tu <u9012063 at gmail.com>
> ---
>
> V2 - A portion of this patch from lib/match.c was folded in a prior
> commit "userspace: add erspan tunnel support" as per Ben's
> review comments.
> ---
Thanks for folding the review comments.
LGTM
Regards,
William
> lib/netdev-native-tnl.c | 38 +++++++++++++--
> lib/netdev-vport.c | 120 +++++++++++++++++++++++++++++++++--------------
> lib/netdev.h | 5 ++
> ofproto/tunnel.c | 11 +++--
> tests/tunnel-push-pop.at | 10 +++-
> tests/tunnel.at | 68 +++++++++++++++++++++++----
> 6 files changed, 198 insertions(+), 54 deletions(-)
>
> diff --git a/lib/netdev-native-tnl.c b/lib/netdev-native-tnl.c
> index c70811e..c97491e 100644
> --- a/lib/netdev-native-tnl.c
> +++ b/lib/netdev-native-tnl.c
> @@ -628,6 +628,7 @@ netdev_erspan_build_header(const struct netdev *netdev,
> struct erspan_base_hdr *ersh;
> unsigned int hlen;
> uint32_t tun_id;
> + int erspan_ver;
> uint16_t sid;
>
> /* XXX: RCUfy tnl_cfg. */
> @@ -645,7 +646,15 @@ netdev_erspan_build_header(const struct netdev *netdev,
> sid = (uint16_t) tun_id;
> }
>
> - if (tnl_cfg->erspan_ver == 1) {
> + if (tnl_cfg->erspan_ver_flow) {
> + erspan_ver = params->flow->tunnel.erspan_ver;
> + } else {
> + erspan_ver = tnl_cfg->erspan_ver;
> + }
> +
> + if (erspan_ver == 1) {
> + ovs_be32 *index;
> +
> greh->protocol = htons(ETH_TYPE_ERSPAN1);
> greh->flags = htons(GRE_SEQ);
> ersh->ver = 1;
> @@ -654,19 +663,38 @@ netdev_erspan_build_header(const struct netdev *netdev,
> put_16aligned_be32(ALIGNED_CAST(ovs_16aligned_be32 *, ersh + 1),
> htonl(tnl_cfg->erspan_idx));
>
> + index = (ovs_be32 *)(ersh + 1);
> +
> + if (tnl_cfg->erspan_idx_flow) {
> + *index = htonl(params->flow->tunnel.erspan_idx);
> + } else {
> + *index = htonl(tnl_cfg->erspan_idx);
> + }
> +
> hlen = ERSPAN_GREHDR_LEN + sizeof *ersh + ERSPAN_V1_MDSIZE;
> - } else if (tnl_cfg->erspan_ver == 2) {
> + } else if (erspan_ver == 2) {
> + struct erspan_md2 *md2 = ALIGNED_CAST(struct erspan_md2 *, ersh + 1);
> +
> greh->protocol = htons(ETH_TYPE_ERSPAN2);
> greh->flags = htons(GRE_SEQ);
> ersh->ver = 2;
> set_sid(ersh, sid);
>
> - struct erspan_md2 *md2 = ALIGNED_CAST(struct erspan_md2 *, ersh + 1);
> md2->sgt = 0; /* security group tag */
> md2->gra = 0;
> put_16aligned_be32(&md2->timestamp, 0);
> - set_hwid(md2, tnl_cfg->erspan_hwid);
> - md2->dir = tnl_cfg->erspan_dir;
> +
> + if (tnl_cfg->erspan_hwid_flow) {
> + set_hwid(md2, params->flow->tunnel.erspan_hwid);
> + } else {
> + set_hwid(md2, tnl_cfg->erspan_hwid);
> + }
> +
> + if (tnl_cfg->erspan_dir_flow) {
> + md2->dir = params->flow->tunnel.erspan_dir;
> + } else {
> + md2->dir = tnl_cfg->erspan_dir;
> + }
>
> hlen = ERSPAN_GREHDR_LEN + sizeof *ersh + ERSPAN_V2_MDSIZE;
> } else {
> diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
> index 805f130..1dae7e0 100644
> --- a/lib/netdev-vport.c
> +++ b/lib/netdev-vport.c
> @@ -545,36 +545,63 @@ set_tunnel_config(struct netdev *dev_, const struct smap *args, char **errp)
> tnl_cfg.egress_pkt_mark = strtoul(node->value, NULL, 10);
> tnl_cfg.set_egress_pkt_mark = true;
> } else if (!strcmp(node->key, "erspan_idx")) {
> - tnl_cfg.erspan_idx = strtol(node->value, NULL, 16);
> - if (tnl_cfg.erspan_idx & ~ERSPAN_IDX_MASK) {
> - ds_put_format(&errors, "%s: invalid erspan index: %s\n",
> - name, node->value);
> - err = EINVAL;
> - goto out;
> + if (!strcmp(node->value, "flow")) {
> + tnl_cfg.erspan_idx_flow = true;
> + } else {
> + tnl_cfg.erspan_idx_flow = false;
> + tnl_cfg.erspan_idx = strtol(node->value, NULL, 16);
> +
> + if (tnl_cfg.erspan_idx & ~ERSPAN_IDX_MASK) {
> + ds_put_format(&errors, "%s: invalid erspan index: %s\n",
> + name, node->value);
> + err = EINVAL;
> + goto out;
> + }
> }
> } else if (!strcmp(node->key, "erspan_ver")) {
> - tnl_cfg.erspan_ver = atoi(node->value);
> - if (tnl_cfg.erspan_ver != 1 && tnl_cfg.erspan_ver != 2) {
> - ds_put_format(&errors, "%s: invalid erspan version: %s\n",
> - name, node->value);
> - err = EINVAL;
> - goto out;
> + if (!strcmp(node->value, "flow")) {
> + tnl_cfg.erspan_ver_flow = true;
> + tnl_cfg.erspan_idx_flow = true;
> + tnl_cfg.erspan_dir_flow = true;
> + tnl_cfg.erspan_hwid_flow = true;
> + } else {
> + tnl_cfg.erspan_ver_flow = false;
> + tnl_cfg.erspan_ver = atoi(node->value);
> +
> + if (tnl_cfg.erspan_ver != 1 && tnl_cfg.erspan_ver != 2) {
> + ds_put_format(&errors, "%s: invalid erspan version: %s\n",
> + name, node->value);
> + err = EINVAL;
> + goto out;
> + }
> }
> } else if (!strcmp(node->key, "erspan_dir")) {
> - tnl_cfg.erspan_dir = atoi(node->value);
> - if (tnl_cfg.erspan_dir != 0 && tnl_cfg.erspan_dir != 1) {
> - ds_put_format(&errors, "%s: invalid erspan direction: %s\n",
> - name, node->value);
> - err = EINVAL;
> - goto out;
> + if (!strcmp(node->value, "flow")) {
> + tnl_cfg.erspan_dir_flow = true;
> + } else {
> + tnl_cfg.erspan_dir_flow = false;
> + tnl_cfg.erspan_dir = atoi(node->value);
> +
> + if (tnl_cfg.erspan_dir != 0 && tnl_cfg.erspan_dir != 1) {
> + ds_put_format(&errors, "%s: invalid erspan direction: %s\n",
> + name, node->value);
> + err = EINVAL;
> + goto out;
> + }
> }
> } else if (!strcmp(node->key, "erspan_hwid")) {
> - tnl_cfg.erspan_hwid = strtol(node->value, NULL, 16);
> - if (tnl_cfg.erspan_hwid & ~(ERSPAN_HWID_MASK >> 4)) {
> - ds_put_format(&errors, "%s: invalid erspan hardware ID: %s\n",
> - name, node->value);
> - err = EINVAL;
> - goto out;
> + if (!strcmp(node->value, "flow")) {
> + tnl_cfg.erspan_hwid_flow = true;
> + } else {
> + tnl_cfg.erspan_hwid_flow = false;
> + tnl_cfg.erspan_hwid = strtol(node->value, NULL, 16);
> +
> + if (tnl_cfg.erspan_hwid & ~(ERSPAN_HWID_MASK >> 4)) {
> + ds_put_format(&errors, "%s: invalid erspan hardware ID: %s\n",
> + name, node->value);
> + err = EINVAL;
> + goto out;
> + }
> }
> } else {
> ds_put_format(&errors, "%s: unknown %s argument '%s'\n", name,
> @@ -767,17 +794,40 @@ get_tunnel_config(const struct netdev *dev, struct smap *args)
> "%"PRIu32, tnl_cfg.egress_pkt_mark);
> }
>
> - if (tnl_cfg.erspan_idx) {
> - smap_add_format(args, "erspan_idx", "0x%x", tnl_cfg.erspan_idx);
> - }
> - if (tnl_cfg.erspan_ver) {
> - smap_add_format(args, "erspan_ver", "%d", tnl_cfg.erspan_ver);
> - }
> - if (tnl_cfg.erspan_dir) {
> - smap_add_format(args, "erspan_dir", "%d", tnl_cfg.erspan_dir);
> - }
> - if (tnl_cfg.erspan_hwid) {
> - smap_add_format(args, "erspan_hwid", "0x%x", tnl_cfg.erspan_hwid);
> + if (!strcmp("erspan", type) || !strcmp("ip6erspan", type)) {
> + if (tnl_cfg.erspan_ver_flow) {
> + /* since version number is not determined,
> + * assume print all other as flow
> + */
> + smap_add(args, "erspan_ver", "flow");
> + smap_add(args, "erspan_idx", "flow");
> + smap_add(args, "erspan_dir", "flow");
> + smap_add(args, "erspan_hwid", "flow");
> + } else {
> + smap_add_format(args, "erspan_ver", "%d", tnl_cfg.erspan_ver);
> +
> + if (tnl_cfg.erspan_ver == 1) {
> + if (tnl_cfg.erspan_idx_flow) {
> + smap_add(args, "erspan_idx", "flow");
> + } else {
> + smap_add_format(args, "erspan_idx", "0x%x",
> + tnl_cfg.erspan_idx);
> + }
> + } else if (tnl_cfg.erspan_ver == 2) {
> + if (tnl_cfg.erspan_dir_flow) {
> + smap_add(args, "erspan_dir", "flow");
> + } else {
> + smap_add_format(args, "erspan_dir", "%d",
> + tnl_cfg.erspan_dir);
> + }
> + if (tnl_cfg.erspan_hwid_flow) {
> + smap_add(args, "erspan_hwid", "flow");
> + } else {
> + smap_add_format(args, "erspan_hwid", "0x%x",
> + tnl_cfg.erspan_hwid);
> + }
> + }
> + }
> }
>
> return 0;
> diff --git a/lib/netdev.h b/lib/netdev.h
> index 0c74dfe..71ffdab 100644
> --- a/lib/netdev.h
> +++ b/lib/netdev.h
> @@ -134,6 +134,11 @@ struct netdev_tunnel_config {
> uint8_t erspan_ver;
> uint8_t erspan_dir;
> uint8_t erspan_hwid;
> +
> + bool erspan_ver_flow;
> + bool erspan_idx_flow;
> + bool erspan_dir_flow;
> + bool erspan_hwid_flow;
> };
>
> void netdev_run(void);
> diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c
> index 2fd6ffb..03f0ab7 100644
> --- a/ofproto/tunnel.c
> +++ b/ofproto/tunnel.c
> @@ -474,16 +474,19 @@ tnl_port_send(const struct ofport_dpif *ofport, struct flow *flow,
> wc->masks.pkt_mark = UINT32_MAX;
> }
>
> - if (cfg->erspan_ver) {
> + if (!cfg->erspan_ver_flow) {
> flow->tunnel.erspan_ver = cfg->erspan_ver;
> }
> - if (cfg->erspan_idx) {
> +
> + if (!cfg->erspan_idx_flow) {
> flow->tunnel.erspan_idx = cfg->erspan_idx;
> }
> - if (cfg->erspan_dir) {
> +
> + if (!cfg->erspan_dir_flow) {
> flow->tunnel.erspan_dir = cfg->erspan_dir;
> }
> - if (cfg->erspan_hwid) {
> +
> + if (!cfg->erspan_hwid_flow) {
> flow->tunnel.erspan_hwid = cfg->erspan_hwid;
> }
>
> diff --git a/tests/tunnel-push-pop.at b/tests/tunnel-push-pop.at
> index a3b284a..b2269df 100644
> --- a/tests/tunnel-push-pop.at
> +++ b/tests/tunnel-push-pop.at
> @@ -9,6 +9,12 @@ AT_CHECK([ovs-vsctl add-port int-br t1 -- set Interface t1 type=erspan \
> -- add-port int-br t2 -- set Interface t2 type=erspan \
> options:remote_ip=1.1.2.92 options:key=567 options:erspan_ver=2 \
> options:erspan_dir=1 options:erspan_hwid=0x7 ofport_request=3\
> + -- add-port int-br t3 -- set Interface t3 type=erspan \
> + options:remote_ip=flow options:erspan_ver=2 options:key=456 \
> + options:erspan_hwid=flow options:erspan_dir=flow ofport_request=4\
> + -- add-port int-br t4 -- set Interface t4 type=erspan \
> + options:remote_ip=flow options:erspan_ver=2 options:key=56 \
> + options:erspan_ver=flow ofport_request=5\
> ], [0])
>
> AT_CHECK([ovs-appctl dpif/show], [0], [dnl
> @@ -20,6 +26,8 @@ dummy at ovs-dummy: hit:0 missed:0
> int-br 65534/2: (dummy-internal)
> t1 2/3: (erspan: erspan_idx=0x3, erspan_ver=1, key=123, remote_ip=1.1.2.92)
> t2 3/3: (erspan: erspan_dir=1, erspan_hwid=0x7, erspan_ver=2, key=567, remote_ip=1.1.2.92)
> + t3 4/3: (erspan: erspan_dir=flow, erspan_hwid=flow, erspan_ver=2, key=456, remote_ip=flow)
> + t4 5/3: (erspan: erspan_dir=flow, erspan_hwid=flow, erspan_idx=flow, erspan_ver=flow, key=56, remote_ip=flow)
> ])
>
> dnl First setup dummy interface IP address, then add the route
> @@ -69,7 +77,7 @@ AT_CHECK([ovs-appctl tnl/neigh/show | tail -n+3 | sort], [0], [dnl
>
> AT_CHECK([ovs-appctl tnl/ports/show |sort], [0], [dnl
> Listening ports:
> -erspan_sys (3) ref_cnt=2
> +erspan_sys (3) ref_cnt=4
> ])
>
> dnl Check ERSPAN v1 tunnel push
> diff --git a/tests/tunnel.at b/tests/tunnel.at
> index 315453d..2bc004c 100644
> --- a/tests/tunnel.at
> +++ b/tests/tunnel.at
> @@ -408,11 +408,42 @@ AT_CLEANUP
>
> AT_SETUP([tunnel - ERSPAN])
> OVS_VSWITCHD_START([add-port br0 p1 -- set Interface p1 type=erspan \
> - options:remote_ip=1.1.1.1 ofport_request=1])
> + options:remote_ip=1.1.1.1 options:key=1 options:erspan_ver=1 \
> + options:erspan_idx=0x0 ofport_request=1 \
> + -- add-port br0 p2 -- set Interface p2 type=erspan \
> + options:remote_ip=1.1.1.1 ofport_request=2 \
> + options:key=flow options:erspan_ver=1 options:erspan_idx=flow \
> + -- add-port br0 p3 -- set Interface p3 type=erspan \
> + options:remote_ip=1.1.1.1 ofport_request=3 \
> + options:key=10 options:erspan_ver=2 options:erspan_dir=flow \
> + options:erspan_hwid=flow \
> + -- add-port br0 p4 -- set Interface p4 type=erspan \
> + options:remote_ip=1.2.3.4 ofport_request=4 \
> + options:key=flow options:erspan_ver=flow\
> + ])
>
> AT_CHECK([ovs-appctl dpif/show | tail -n +3], [0], [dnl
> br0 65534/100: (dummy-internal)
> - p1 1/1: (erspan: remote_ip=1.1.1.1)
> + p1 1/1: (erspan: erspan_idx=0x0, erspan_ver=1, key=1, remote_ip=1.1.1.1)
> + p2 2/1: (erspan: erspan_idx=flow, erspan_ver=1, key=flow, remote_ip=1.1.1.1)
> + p3 3/1: (erspan: erspan_dir=flow, erspan_hwid=flow, erspan_ver=2, key=10, remote_ip=1.1.1.1)
> + p4 4/1: (erspan: erspan_dir=flow, erspan_hwid=flow, erspan_idx=flow, erspan_ver=flow, key=flow, remote_ip=1.2.3.4)
> +])
> +
> +dnl Check ERSPAN v1 flow-based tunnel push
> +AT_CHECK([ovs-ofctl add-flow br0 "in_port=1, actions=set_tunnel:11,set_field:0x1->tun_erspan_idx,2"])
> +
> +dnl Check ERSPAN v2 flow-based tunnel push
> +AT_CHECK([ovs-ofctl add-flow br0 "in_port=2, actions=set_field:1->tun_erspan_dir,set_field:0x0->tun_erspan_hwid,3"])
> +
> +AT_CHECK([ovs-ofctl add-flow br0 "in_port=3, actions=set_field:2->tun_erspan_ver,set_field:1->tun_erspan_dir,set_field:0x0->tun_erspan_hwid,4"])
> +
> +AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip],
> +[0], [dnl
> +NXST_FLOW reply:
> + in_port=1 actions=set_tunnel:0xb,set_field:0x1->tun_erspan_idx,output:2
> + in_port=2 actions=set_field:1->tun_erspan_dir,set_field:0->tun_erspan_hwid,output:3
> + in_port=3 actions=set_field:2->tun_erspan_ver,set_field:1->tun_erspan_dir,set_field:0->tun_erspan_hwid,output:4
> ])
>
> OVS_VSWITCHD_STOP
> @@ -523,28 +554,28 @@ AT_CHECK([tail -1 stdout], [0],
> dnl receive packet from ERSPAN port with v1 metadata
> AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(0),tunnel(tun_id=0x1,src=1.1.1.1,dst=2.2.2.2,ttl=64,erspan(ver=1,idx=0x7),flags(df|key)),in_port(1),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'], [0], [stdout])
> AT_CHECK([tail -2 stdout], [0],
> - [Megaflow: recirc_id=0,eth,ip,tun_id=0x1,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=0,erspan_ver=1,erspan_idx=0x7,tun_flags=+df-csum+key,in_port=3,nw_frag=no
> + [Megaflow: recirc_id=0,eth,ip,tun_id=0x1,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=0,tun_erspan_ver=1,tun_erspan_idx=0x7,tun_flags=+df-csum+key,in_port=3,nw_frag=no
> Datapath actions: 3
> ])
>
> dnl receive packet from ERSPAN port with wrong v1 metadata
> AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(0),tunnel(tun_id=0x1,src=1.1.1.1,dst=2.2.2.2,ttl=64,erspan(ver=1,idx=0xabcd),flags(df|key)),in_port(1),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'], [0], [stdout])
> AT_CHECK([tail -2 stdout], [0],
> - [Megaflow: recirc_id=0,eth,ip,tun_id=0x1,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=0,erspan_ver=1,erspan_idx=0xabcd,tun_flags=+df-csum+key,in_port=3,nw_frag=no
> + [Megaflow: recirc_id=0,eth,ip,tun_id=0x1,tun_src=1.1.1.1,tun_dst=2.2.2.2,tun_tos=0,tun_erspan_ver=1,tun_erspan_idx=0xabcd,tun_flags=+df-csum+key,in_port=3,nw_frag=no
> Datapath actions: drop
> ])
>
> dnl receive packet from ERSPAN port with v2 metadata
> AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(0),tunnel(tun_id=0x2,src=1.1.1.2,dst=2.2.2.2,ttl=64,erspan(ver=2,dir=1,hwid=0x7),flags(df|key)),in_port(1),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'], [0], [stdout])
> AT_CHECK([tail -2 stdout], [0],
> - [Megaflow: recirc_id=0,eth,ip,tun_id=0x2,tun_src=1.1.1.2,tun_dst=2.2.2.2,tun_tos=0,erspan_ver=2,erspan_dir=1,erspan_hwid=0x1,tun_flags=+df-csum+key,in_port=4,nw_frag=no
> + [Megaflow: recirc_id=0,eth,ip,tun_id=0x2,tun_src=1.1.1.2,tun_dst=2.2.2.2,tun_tos=0,tun_erspan_ver=2,tun_erspan_dir=1,tun_erspan_hwid=0x1,tun_flags=+df-csum+key,in_port=4,nw_frag=no
> Datapath actions: 2
> ])
>
> dnl receive packet from ERSPAN port with wrong v2 metadata
> AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(0),tunnel(tun_id=0x2,src=1.1.1.2,dst=2.2.2.2,ttl=64,erspan(ver=2,dir=0,hwid=0x17),flags(df|key)),in_port(1),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'], [0], [stdout])
> AT_CHECK([tail -2 stdout], [0],
> - [Megaflow: recirc_id=0,eth,ip,tun_id=0x2,tun_src=1.1.1.2,tun_dst=2.2.2.2,tun_tos=0,erspan_ver=2,erspan_dir=0,erspan_hwid=0x1,tun_flags=+df-csum+key,in_port=4,nw_frag=no
> + [Megaflow: recirc_id=0,eth,ip,tun_id=0x2,tun_src=1.1.1.2,tun_dst=2.2.2.2,tun_tos=0,tun_erspan_ver=2,tun_erspan_dir=0,tun_erspan_hwid=0x1,tun_flags=+df-csum+key,in_port=4,nw_frag=no
> Datapath actions: drop
> ])
>
> @@ -557,17 +588,36 @@ AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip],
> NXST_FLOW reply:
> in_port=1 actions=output:3
> in_port=2 actions=output:4
> - erspan_ver=1,erspan_idx=0x7,in_port=3 actions=output:1
> - erspan_ver=2,in_port=4 actions=output:2
> + tun_erspan_ver=1,tun_erspan_idx=0x7,in_port=3 actions=output:1
> + tun_erspan_ver=2,in_port=4 actions=output:2
> ])
>
> dnl this time it won't drop
> AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(0),tunnel(tun_id=0x2,src=1.1.1.2,dst=2.2.2.2,ttl=64,erspan(ver=2,dir=0,hwid=0x17),flags(df|key)),in_port(1),skb_mark(0),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(frag=no)'], [0], [stdout])
> AT_CHECK([tail -2 stdout], [0],
> - [Megaflow: recirc_id=0,eth,ip,tun_id=0x2,tun_src=1.1.1.2,tun_dst=2.2.2.2,tun_tos=0,erspan_ver=2,tun_flags=+df-csum+key,in_port=4,nw_frag=no
> + [Megaflow: recirc_id=0,eth,ip,tun_id=0x2,tun_src=1.1.1.2,tun_dst=2.2.2.2,tun_tos=0,tun_erspan_ver=2,tun_flags=+df-csum+key,in_port=4,nw_frag=no
> Datapath actions: 2
> ])
>
> +dnl flow-based erspan_idx options
> +AT_CHECK([ovs-vsctl add-port br0 p5 -- set Interface p5 type=erspan \
> + options:remote_ip=1.1.1.2 ofport_request=5 \
> + options:key=flow options:erspan_ver=1 options:erspan_idx=flow])
> +
> +AT_CHECK([ovs-ofctl del-flows br0])
> +AT_CHECK([ovs-ofctl add-flow br0 "in_port=1, actions=set_tunnel:11,set_field:0x7->tun_erspan_idx,5"])
> +
> +AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip],
> +[0], [dnl
> +NXST_FLOW reply:
> + in_port=1 actions=set_tunnel:0xb,set_field:0x7->tun_erspan_idx,output:5
> +])
> +
> +AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(3),eth(src=50:54:00:00:00:05,dst=50:54:00:00:00:07),eth_type(0x0800),ipv4(src=192.168.0.1,dst=192.168.0.2,proto=1,tos=0,ttl=128,frag=no),icmp(type=8,code=0)'], [0], [stdout])
> +AT_CHECK([tail -1 stdout], [0],
> + [Datapath actions: set(tunnel(tun_id=0xb,dst=1.1.1.2,ttl=64,erspan(ver=1,idx=0x7),flags(df|key))),1
> +])
> +
> OVS_VSWITCHD_STOP
> AT_CLEANUP
>
> --
> 1.8.3.1
>
More information about the dev
mailing list