@@ -3504,6 +3504,13 @@ xlate_select_group(struct xlate_ctx *ctx, struct group_dpif *group)
{
const char *selection_method = group_dpif_get_selection_method(group);
+ /* Select groups may access flow keys beyond L2 in order to
+ * select a bucket. Recirculate as appropriate to make this possible.
+ */
+ if (ctx->was_mpls) {
+ ctx_trigger_freeze(ctx);
+ }
+
if (selection_method[0] == '\0') {
xlate_default_select_group(ctx, group);
} else if (!strcasecmp("hash", selection_method)) {
@@ -2,23 +2,43 @@ AT_BANNER([mpls-xlate])
AT_SETUP([MPLS xlate action])
-OVS_VSWITCHD_START([add-port br0 p0 -- set Interface p0 type=dummy ofport_request=1])
+OVS_VSWITCHD_START(
+ [add-port br0 p0 -- set Interface p0 type=dummy ofport_request=1 -- \
+ add-port br0 p1 -- set Interface p1 type=patch \
+ options:peer=p2 ofport_request=2 -- \
+ add-br br1 -- \
+ set bridge br1 other-config:hwaddr=aa:66:aa:66:00:00 -- \
+ set bridge br1 datapath-type=dummy other-config:datapath-id=1234 \
+ fail-mode=secure -- \
+ add-port br1 p2 -- set Interface p2 type=patch \
+ options:peer=p1])
AT_CHECK([ovs-appctl dpif/show], [0], [dnl
dummy@ovs-dummy: hit:0 missed:0
br0:
br0 65534/100: (dummy)
p0 1/1: (dummy)
+ p1 2/none: (patch: peer=p2)
+ br1:
+ br1 65534/101: (dummy)
+ p2 1/none: (patch: peer=p1)
])
dnl Setup single MPLS tags.
AT_CHECK([ovs-ofctl -O OpenFlow13 add-group br0 group_id=1232,type=select,bucket=output:LOCAL])
-AT_CHECK([ovs-ofctl -O OpenFlow13 add-group br0 group_id=1233,type=select,bucket=dec_ttl,output:LOCAL])
+AT_CHECK([ovs-ofctl -O OpenFlow13 add-group br0 group_id=1233,type=all,bucket=output:LOCAL])
+AT_CHECK([ovs-ofctl -O OpenFlow13 add-group br0 group_id=1234,type=all,bucket=dec_ttl,output:LOCAL])
AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 in_port=local,dl_type=0x0800,action=push_mpls:0x8847,set_field:10-\>mpls_label,output:1])
AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 dl_type=0x8847,in_port=1,mpls_label=20,action=pop_mpls:0x0800,output:LOCAL])
AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 dl_type=0x8847,in_port=1,mpls_label=21,action=pop_mpls:0x0800,dec_ttl,output:LOCAL])
AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 dl_type=0x8847,in_port=1,mpls_label=22,action=pop_mpls:0x0800,group:1232])
AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 dl_type=0x8847,in_port=1,mpls_label=23,action=pop_mpls:0x0800,group:1233])
+AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 dl_type=0x8847,in_port=1,mpls_label=24,action=pop_mpls:0x0800,group:1234])
+AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br0 dl_type=0x8847,in_port=1,mpls_label=25,action=pop_mpls:0x0800,output:2])
+
+AT_CHECK([ovs-ofctl -O OpenFlow13 add-flow br1 in_port=1,action=output:LOCAL])
+
+
dnl Test MPLS push
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(100),eth(src=f8:bc:12:44:34:b6,dst=f8:bc:12:46:58:e0),eth_type(0x0800),ipv4(src=1.1.2.92,dst=1.1.2.88,proto=17,tos=0,ttl=64,frag=no),udp(src=7777,dst=80)'], [0], [stdout])
@@ -43,23 +63,45 @@ AT_CHECK([tail -1 stdout], [0],
[Datapath actions: set(ipv4(ttl=63)),100
])
-dnl Test MPLS pop then group output (bucket actions do not trigger recirculation)
+dnl Test MPLS pop then select group output (group type triggers recirculation)
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=f8:bc:12:44:34:b6,dst=f8:bc:12:46:58:e0),eth_type(0x8847),mpls(label=22,tc=0,ttl=64,bos=1)'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
- [Datapath actions: pop_mpls(eth_type=0x800),100
+ [Datapath actions: pop_mpls(eth_type=0x800),recirc(0x2)
+])
+
+AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(2),in_port(1),eth(src=f8:bc:12:44:34:b6,dst=f8:bc:12:46:58:e0),eth_type(0x0800),ipv4(src=1.1.2.92,dst=1.1.2.88,proto=47,tos=0,ttl=64,frag=no)'], [0], [stdout])
+AT_CHECK([tail -1 stdout], [0],
+ [Datapath actions: 100
])
-dnl Test MPLS pop then group output (bucket actions trigger recirculation)
+dnl Test MPLS pop then all group output (bucket actions do not trigger recirculation)
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=f8:bc:12:44:34:b6,dst=f8:bc:12:46:58:e0),eth_type(0x8847),mpls(label=23,tc=0,ttl=64,bos=1)'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
- [Datapath actions: pop_mpls(eth_type=0x800),recirc(0x2)
+ [Datapath actions: pop_mpls(eth_type=0x800),100
])
-AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(2),in_port(1),eth(src=f8:bc:12:44:34:b6,dst=f8:bc:12:46:58:e0),eth_type(0x0800),ipv4(src=1.1.2.92,dst=1.1.2.88,proto=47,tos=0,ttl=64,frag=no)'], [0], [stdout])
+dnl Test MPLS pop then all group output (bucket actions trigger recirculation)
+AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=f8:bc:12:44:34:b6,dst=f8:bc:12:46:58:e0),eth_type(0x8847),mpls(label=24,tc=0,ttl=64,bos=1)'], [0], [stdout])
+AT_CHECK([tail -1 stdout], [0],
+ [Datapath actions: pop_mpls(eth_type=0x800),recirc(0x3)
+])
+
+AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(3),in_port(1),eth(src=f8:bc:12:44:34:b6,dst=f8:bc:12:46:58:e0),eth_type(0x0800),ipv4(src=1.1.2.92,dst=1.1.2.88,proto=47,tos=0,ttl=64,frag=no)'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
[Datapath actions: set(ipv4(ttl=63)),100
])
+dnl Test MPLS pop then all output to patch port
+AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=f8:bc:12:44:34:b6,dst=f8:bc:12:46:58:e0),eth_type(0x8847),mpls(label=25,tc=0,ttl=64,bos=1)'], [0], [stdout])
+AT_CHECK([tail -1 stdout], [0],
+ [Datapath actions: pop_mpls(eth_type=0x800),recirc(0x4)
+])
+
+AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(4),in_port(1),eth(src=f8:bc:12:44:34:b6,dst=f8:bc:12:46:58:e0),eth_type(0x0800),ipv4(src=1.1.2.92,dst=1.1.2.88,proto=47,tos=0,ttl=64,frag=no)'], [0], [stdout])
+AT_CHECK([tail -1 stdout], [0],
+ [Datapath actions: 101
+])
+
dnl Setup multiple MPLS tags.
AT_CHECK([ovs-ofctl del-flows br0])
@@ -80,10 +122,10 @@ AT_CHECK([tail -1 stdout], [0],
dnl Double MPLS pop
AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'in_port(1),eth(src=f8:bc:12:44:34:b6,dst=f8:bc:12:46:58:e0),eth_type(0x8847),mpls(label=60,tc=0,ttl=64,bos=0,label=50,tc=0,ttl=64,bos=1)'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
- [Datapath actions: pop_mpls(eth_type=0x8847),pop_mpls(eth_type=0x800),recirc(0x3)
+ [Datapath actions: pop_mpls(eth_type=0x8847),pop_mpls(eth_type=0x800),recirc(0x5)
])
-AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(3),in_port(1),eth(src=f8:bc:12:44:34:b6,dst=f8:bc:12:46:58:e0),eth_type(0x0800),ipv4(src=1.1.2.92,dst=1.1.2.88,proto=47,tos=0,ttl=64,frag=no)'], [0], [stdout])
+AT_CHECK([ovs-appctl ofproto/trace ovs-dummy 'recirc_id(5),in_port(1),eth(src=f8:bc:12:44:34:b6,dst=f8:bc:12:46:58:e0),eth_type(0x0800),ipv4(src=1.1.2.92,dst=1.1.2.88,proto=47,tos=0,ttl=64,frag=no)'], [0], [stdout])
AT_CHECK([tail -1 stdout], [0],
[Datapath actions: set(ipv4(ttl=10)),100
])