In the presence of VLAN tags there are two possibilities for pushing an MPLS LSE described in different versions of OpenFlow: before or after the VLAN tags.
* Pushing after any VLAN tags that are present is the behaviour described in OpenFlow1.1 and 1.2 and the behaviour that Open vSwitch currently uses for all OpenFlow versions. * Pushing before any VLAN tags that are present is the behaviour described in OpenFlow1.3 The difference the between these can alter the consistency of actions. For example, if an MPLS LSE is pushed before VLAN tags then it is valid to subsequently push a VLAN tag. This is because the body of an MPLS packet is opaque and thus after an MPLS LSE a VLAN packet becomes a non-VLAN packet for the purposes of action consistency checking. Conversely, if an MPLS LSE is pushed after VLAN tags then it is not valid to subsequently push a VLAN tag because Open vSwitch does not support pushing a VLAN tag onto a VLAN packet. As suggested by Ben Pfaff, in order to allow disambiguation of these cases a position parameter to push_mpls is exposed to ovs-ofctl by this patch. Currently the default and only supported value of position is 'before_vlan'. This requires OpenFlow1.2 or earlier. And an implication of this patch is that push_mpls is prohibited for OpenFlow1.3 and later. Prior to this patch push_mpls was allowed for OpenFlow1.3 and later but its implementation did not follow the specification in the presence of VLANS: the MPLS LSE was pushed after rather than before them. A subsequent patch enables pushing the MPLS before VLANs and adds allows 'after_vlan' as a value of the position parameter to push_mpls. 'after_vlan' will require OpenFlow1.3 or later. This patch has been broken out in order to aid review. It can trivially be combined with the subsequent patch if desired. This patch also: * Updates consistency checking to be dependent on the position argument of push_mpls actions. * Updates the test suite to use of the position argument for mpls_push actions. Signed-off-by: Simon Horman <[email protected]> --- v2.52 * First post This approach was suggested by Ben Pfaff. He also suggested adding a 'no_vlan' position which would be valid for all OpenFlow versions if no VLAN tag was present. I have not included that in this patch because I am not clear on how to handle it in conjunction with dumping flows. It seems to me that if OpenFlow 1.2 or earlier it would be translated to 'after_vlan' while if (in the presence of the subsequent patch described above) OpenFlow 1.3 or later was used it would be translated to 'before_vlan'. This is because ultimately flows are dumped using OpenFlow which does not have a position parameter. So it would be set when reading OpenFlow messages according to whichever OpenFlow version was used to dump the flows. It seems to me that this would be rather confusing for users. Other than the problem described immediately above implementing 'no_vlan' seems trivial and I had it working at one stage of my development of this patch. --- lib/ofp-actions.c | 32 ++++++++++++++++++-- lib/ofp-parse.c | 51 ++++++++++++++++++++++++++++--- tests/ofp-actions.at | 2 +- tests/ofproto-dpif.at | 78 ++++++++++++++++++++++++------------------------ utilities/ovs-ofctl.8.in | 8 +++++ 5 files changed, 125 insertions(+), 46 deletions(-) diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c index a02f842..97821b9 100644 --- a/lib/ofp-actions.c +++ b/lib/ofp-actions.c @@ -2066,6 +2066,21 @@ ofpact_check__(enum ofputil_protocol *usable_protocols, struct ofpact *a, return 0; case OFPACT_PUSH_MPLS: + switch (ofpact_get_PUSH_MPLS(a)->position) { + case OFPACT_MPLS_BEFORE_VLAN: + *usable_protocols &= OFPUTIL_P_OF13_UP; + /* MPLS LSE will be pushed before any existing VLAN tags. + * Thus the VLAN tag becomes opaque and for the purposes + * of action consistency checking not present */ + flow->vlan_tci = htons(0); + break; + case OFPACT_MPLS_AFTER_VLAN: + *usable_protocols &= ~OFPUTIL_P_OF13_UP; + break; + default: + NOT_REACHED(); + } + flow->dl_type = ofpact_get_PUSH_MPLS(a)->ethertype; /* The packet is now MPLS and the MPLS payload is opaque. * Thus nothing can be assumed about the network protocol. @@ -3270,6 +3285,7 @@ ofpact_format(const struct ofpact *a, struct ds *s) const struct ofpact_tunnel *tunnel; const struct ofpact_sample *sample; const struct ofpact_set_field *set_field; + const struct ofpact_push_mpls *push_mpls; const struct mf_field *mf; ofp_port_t port; @@ -3495,8 +3511,20 @@ ofpact_format(const struct ofpact *a, struct ds *s) break; case OFPACT_PUSH_MPLS: - ds_put_format(s, "push_mpls:0x%04"PRIx16, - ntohs(ofpact_get_PUSH_MPLS(a)->ethertype)); + push_mpls = ofpact_get_PUSH_MPLS(a); + + switch (push_mpls->position) { + case OFPACT_MPLS_AFTER_VLAN: + ds_put_format(s, "push_mpls(0x%04"PRIx16",after_vlan)", + ntohs(push_mpls->ethertype)); + break; + case OFPACT_MPLS_BEFORE_VLAN: + ds_put_format(s, "push_mpls:0x%04"PRIx16, + ntohs(push_mpls->ethertype)); + break; + default: + NOT_REACHED(); + } break; case OFPACT_POP_MPLS: diff --git a/lib/ofp-parse.c b/lib/ofp-parse.c index 5b07d14..2032edd 100644 --- a/lib/ofp-parse.c +++ b/lib/ofp-parse.c @@ -263,6 +263,52 @@ parse_resubmit(char *arg, struct ofpbuf *ofpacts) return NULL; } +/* Parses 'arg' as the argument to a "push_mpls" action, and appends such an + * action to 'ofpacts'. + * + * Returns NULL if successful, otherwise a malloc()'d string describing the + * error. The caller is responsible for freeing the returned string. */ +static char * WARN_UNUSED_RESULT +parse_push_mpls(struct ofpbuf *ofpacts, char *arg) +{ + struct ofpact_push_mpls *push_mpls; + char *ethertype_s, *position_s; + + push_mpls = ofpact_put_PUSH_MPLS(ofpacts); + + ethertype_s = strsep(&arg, ","); + if (ethertype_s && ethertype_s[0]) { + char *error; + uint16_t ethertype; + + error = str_to_u16(ethertype_s, "push_mpls", ðertype); + if (error) { + return error; + } + push_mpls->ethertype = htons(ethertype); + } else { + return xstrdup("'ethertype' must be spefified for 'push_mpls'"); + } + + position_s = strsep(&arg, ","); + if (position_s && position_s[0]) { + /* XXX: Pase "before_vlan" as OFPACT_MPLS_BEFORE_VLAN + * once pushing MPLS LSEs before VLAN tags is supported */ + if (!strcmp(position_s, "after_vlan")) { + push_mpls->position = OFPACT_MPLS_AFTER_VLAN; + } else { + return xasprintf("invalid tag_prder '%s' in 'push_mpls' argument", + position_s); + } + } else { + /* XXX: Use OFPACT_MPLS_BEFORE_VLAN as the default + * once pushing MPLS LSEs before VLAN tags is supported */ + push_mpls->position = OFPACT_MPLS_AFTER_VLAN; + } + + return NULL; +} + /* Parses 'arg' as the argument to a "note" action, and appends such an action * to 'ofpacts'. * @@ -877,10 +923,7 @@ parse_named_action(enum ofputil_action_code code, case OFPUTIL_OFPAT11_PUSH_MPLS: case OFPUTIL_NXAST_PUSH_MPLS: - error = str_to_u16(arg, "push_mpls", ðertype); - if (!error) { - ofpact_put_PUSH_MPLS(ofpacts)->ethertype = htons(ethertype); - } + error = parse_push_mpls(ofpacts, arg); break; case OFPUTIL_OFPAT11_POP_MPLS: diff --git a/tests/ofp-actions.at b/tests/ofp-actions.at index 452bdbf..e6e2b84 100644 --- a/tests/ofp-actions.at +++ b/tests/ofp-actions.at @@ -483,7 +483,7 @@ OVS_VSWITCHD_START dnl OK: Use fin_timeout action on TCP flow AT_CHECK([ovs-ofctl -O OpenFlow11 -vwarn add-flow br0 'tcp actions=fin_timeout(idle_timeout=1)']) dnl Bad: Use fin_timeout action on TCP flow that has been converted to MPLS -AT_CHECK([ovs-ofctl -O OpenFlow11 -vwarn add-flow br0 'tcp actions=push_mpls:0x8847,fin_timeout(idle_timeout=1)'], +AT_CHECK([ovs-ofctl -O OpenFlow11 -vwarn add-flow br0 'tcp actions=push_mpls(0x8847,after_vlan),fin_timeout(idle_timeout=1)'], [1], [], [dnl ovs-ofctl: none of the usable flow formats (OpenFlow10,NXM) is among the allowed flow formats (OpenFlow11) ]) diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index 1d674e8..104be04 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -402,17 +402,17 @@ cookie=0x7 table=5 in_port=84 actions=load:5->NXM_NX_REG4[[]],load:6->NXM_NX_TUN cookie=0x8 table=6 in_port=85 actions=mod_tp_src:85,controller,resubmit(86,7) cookie=0x9 table=7 in_port=86 actions=mod_tp_dst:86,controller,controller cookie=0xa dl_src=40:44:44:44:44:41 actions=mod_vlan_vid:99,mod_vlan_pcp:1,controller -cookie=0xa dl_src=40:44:44:44:44:42 actions=push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],controller -cookie=0xa dl_src=41:44:44:44:44:42 actions=push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],pop_mpls:0x0800,controller -cookie=0xa dl_src=40:44:44:44:44:43 actions=push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],controller -cookie=0xa dl_src=40:44:44:44:44:44 actions=push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],controller -cookie=0xa dl_src=40:44:44:44:44:45 actions=push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],dec_mpls_ttl,controller -cookie=0xa dl_src=40:44:44:44:44:46 actions=push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],set_mpls_ttl(10),controller -cookie=0xa dl_src=40:44:44:44:44:47 actions=push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],dec_mpls_ttl,set_mpls_ttl(10),controller -cookie=0xa dl_src=40:44:44:44:44:48 actions=push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],set_mpls_ttl(10),dec_mpls_ttl,controller +cookie=0xa dl_src=40:44:44:44:44:42 actions=push_mpls(0x8847,after_vlan),load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],controller +cookie=0xa dl_src=41:44:44:44:44:42 actions=push_mpls(0x8847,after_vlan),load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],pop_mpls:0x0800,controller +cookie=0xa dl_src=40:44:44:44:44:43 actions=push_mpls(0x8847,after_vlan),load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],controller +cookie=0xa dl_src=40:44:44:44:44:44 actions=push_mpls(0x8847,after_vlan),load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],controller +cookie=0xa dl_src=40:44:44:44:44:45 actions=push_mpls(0x8847,after_vlan),load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],dec_mpls_ttl,controller +cookie=0xa dl_src=40:44:44:44:44:46 actions=push_mpls(0x8847,after_vlan),load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],set_mpls_ttl(10),controller +cookie=0xa dl_src=40:44:44:44:44:47 actions=push_mpls(0x8847,after_vlan),load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],dec_mpls_ttl,set_mpls_ttl(10),controller +cookie=0xa dl_src=40:44:44:44:44:48 actions=push_mpls(0x8847,after_vlan),load:10->OXM_OF_MPLS_LABEL[[]],load:3->OXM_OF_MPLS_TC[[]],set_mpls_ttl(10),dec_mpls_ttl,controller cookie=0xb dl_src=50:55:55:55:55:55 dl_type=0x8847 actions=load:1000->OXM_OF_MPLS_LABEL[[]],controller cookie=0xd dl_src=60:66:66:66:66:66 actions=pop_mpls:0x0800,controller -cookie=0xc dl_src=70:77:77:77:77:77 actions=push_mpls:0x8848,load:1000->OXM_OF_MPLS_LABEL[[]],load:7->OXM_OF_MPLS_TC[[]],controller +cookie=0xc dl_src=70:77:77:77:77:77 actions=push_mpls(0x8848,after_vlan),load:1000->OXM_OF_MPLS_LABEL[[]],load:7->OXM_OF_MPLS_TC[[]],controller cookie=0xd dl_src=80:88:88:88:88:88 arp actions=load:2->OXM_OF_ARP_OP[[]],controller,load:0xc0a88001->OXM_OF_ARP_SPA[[]],controller,load:0x404444444441->OXM_OF_ARP_THA[[]],load:0x01010101->OXM_OF_ARP_SPA[[]],load:0x02020202->OXM_OF_ARP_TPA[[]],controller ]) AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) @@ -881,16 +881,16 @@ AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl cookie=0x8, table=6, n_packets=3, n_bytes=218, in_port=85 actions=mod_tp_src:85,CONTROLLER:65535,resubmit(86,7) cookie=0x9, table=7, n_packets=3, n_bytes=218, in_port=86 actions=mod_tp_dst:86,CONTROLLER:65535,CONTROLLER:65535 cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:44:41 actions=mod_vlan_vid:99,mod_vlan_pcp:1,CONTROLLER:65535 - cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:44:42 actions=push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[[]],load:0x3->OXM_OF_MPLS_TC[[]],CONTROLLER:65535 - cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:44:43 actions=push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[[]],load:0x3->OXM_OF_MPLS_TC[[]],CONTROLLER:65535 - cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:44:44 actions=push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[[]],load:0x3->OXM_OF_MPLS_TC[[]],CONTROLLER:65535 - cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:44:45 actions=push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[[]],load:0x3->OXM_OF_MPLS_TC[[]],dec_mpls_ttl,CONTROLLER:65535 - cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:44:46 actions=push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[[]],load:0x3->OXM_OF_MPLS_TC[[]],set_mpls_ttl(10),CONTROLLER:65535 - cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:44:47 actions=push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[[]],load:0x3->OXM_OF_MPLS_TC[[]],dec_mpls_ttl,set_mpls_ttl(10),CONTROLLER:65535 - cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:44:48 actions=push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[[]],load:0x3->OXM_OF_MPLS_TC[[]],set_mpls_ttl(10),dec_mpls_ttl,CONTROLLER:65535 - cookie=0xa, n_packets=3, n_bytes=180, dl_src=41:44:44:44:44:42 actions=push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[[]],load:0x3->OXM_OF_MPLS_TC[[]],pop_mpls:0x0800,CONTROLLER:65535 + cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:44:42 actions=push_mpls(0x8847,after_vlan),load:0xa->OXM_OF_MPLS_LABEL[[]],load:0x3->OXM_OF_MPLS_TC[[]],CONTROLLER:65535 + cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:44:43 actions=push_mpls(0x8847,after_vlan),load:0xa->OXM_OF_MPLS_LABEL[[]],load:0x3->OXM_OF_MPLS_TC[[]],CONTROLLER:65535 + cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:44:44 actions=push_mpls(0x8847,after_vlan),load:0xa->OXM_OF_MPLS_LABEL[[]],load:0x3->OXM_OF_MPLS_TC[[]],CONTROLLER:65535 + cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:44:45 actions=push_mpls(0x8847,after_vlan),load:0xa->OXM_OF_MPLS_LABEL[[]],load:0x3->OXM_OF_MPLS_TC[[]],dec_mpls_ttl,CONTROLLER:65535 + cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:44:46 actions=push_mpls(0x8847,after_vlan),load:0xa->OXM_OF_MPLS_LABEL[[]],load:0x3->OXM_OF_MPLS_TC[[]],set_mpls_ttl(10),CONTROLLER:65535 + cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:44:47 actions=push_mpls(0x8847,after_vlan),load:0xa->OXM_OF_MPLS_LABEL[[]],load:0x3->OXM_OF_MPLS_TC[[]],dec_mpls_ttl,set_mpls_ttl(10),CONTROLLER:65535 + cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:44:48 actions=push_mpls(0x8847,after_vlan),load:0xa->OXM_OF_MPLS_LABEL[[]],load:0x3->OXM_OF_MPLS_TC[[]],set_mpls_ttl(10),dec_mpls_ttl,CONTROLLER:65535 + cookie=0xa, n_packets=3, n_bytes=180, dl_src=41:44:44:44:44:42 actions=push_mpls(0x8847,after_vlan),load:0xa->OXM_OF_MPLS_LABEL[[]],load:0x3->OXM_OF_MPLS_TC[[]],pop_mpls:0x0800,CONTROLLER:65535 cookie=0xb, n_packets=3, n_bytes=180, mpls,dl_src=50:55:55:55:55:55 actions=load:0x3e8->OXM_OF_MPLS_LABEL[[]],CONTROLLER:65535 - cookie=0xc, n_packets=3, n_bytes=180, dl_src=70:77:77:77:77:77 actions=push_mpls:0x8848,load:0x3e8->OXM_OF_MPLS_LABEL[[]],load:0x7->OXM_OF_MPLS_TC[[]],CONTROLLER:65535 + cookie=0xc, n_packets=3, n_bytes=180, dl_src=70:77:77:77:77:77 actions=push_mpls(0x8848,after_vlan),load:0x3e8->OXM_OF_MPLS_LABEL[[]],load:0x7->OXM_OF_MPLS_TC[[]],CONTROLLER:65535 cookie=0xd, n_packets=3, n_bytes=180, arp,dl_src=80:88:88:88:88:88 actions=load:0x2->NXM_OF_ARP_OP[[]],CONTROLLER:65535,load:0xc0a88001->NXM_OF_ARP_SPA[[]],CONTROLLER:65535,load:0x404444444441->NXM_NX_ARP_THA[[]],load:0x1010101->NXM_OF_ARP_SPA[[]],load:0x2020202->NXM_OF_ARP_TPA[[]],CONTROLLER:65535 cookie=0xd, n_packets=3, n_bytes=186, dl_src=60:66:66:66:66:66 actions=pop_mpls:0x0800,CONTROLLER:65535 n_packets=3, n_bytes=180, dl_src=10:11:11:11:11:11 actions=CONTROLLER:65535 @@ -1071,16 +1071,16 @@ ON_EXIT([kill `cat ovs-ofctl.pid`]) AT_CAPTURE_FILE([ofctl_monitor.log]) AT_DATA([flows.txt], [dnl -cookie=0xa dl_src=40:44:44:44:54:50 actions=push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],push_vlan:0x8100,set_vlan_vid:99,set_vlan_pcp:1,controller -cookie=0xa dl_src=40:44:44:44:54:51 actions=push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],push_vlan:0x8100,set_vlan_vid:99,set_vlan_pcp:1,controller -cookie=0xa dl_src=40:44:44:44:54:52 actions=push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],push_vlan:0x8100,load:99->OXM_OF_VLAN_VID[[]],set_vlan_pcp:1,controller -cookie=0xa dl_src=40:44:44:44:54:53 actions=push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],push_vlan:0x8100,load:99->OXM_OF_VLAN_VID[[]],set_vlan_pcp:1,controller -cookie=0xa dl_src=40:44:44:44:54:54 actions=push_vlan:0x8100,set_vlan_vid:99,set_vlan_pcp:1,push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],controller -cookie=0xa dl_src=40:44:44:44:54:55 actions=push_vlan:0x8100,set_vlan_vid:99,set_vlan_pcp:1,push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],controller -cookie=0xa dl_src=40:44:44:44:54:56 actions=push_vlan:0x8100,load:99->OXM_OF_VLAN_VID[[]],set_vlan_pcp:1,push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],controller -cookie=0xa dl_src=40:44:44:44:54:57 actions=push_vlan:0x8100,load:99->OXM_OF_VLAN_VID[[]],set_vlan_pcp:1,push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],controller -cookie=0xa dl_src=40:44:44:44:54:58,vlan_tci=0x1000/0x1000 actions=load:99->OXM_OF_VLAN_VID[[]],set_vlan_pcp:1,push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],controller -cookie=0xa dl_src=40:44:44:44:54:59,vlan_tci=0x1000/0x1000 actions=push_mpls:0x8847,load:10->OXM_OF_MPLS_LABEL[[]],set_vlan_pcp:1,load:99->OXM_OF_VLAN_VID[[]],controller +cookie=0xa dl_src=40:44:44:44:54:50 actions=push_mpls(0x8847,after_vlan),load:10->OXM_OF_MPLS_LABEL[[]],push_vlan:0x8100,set_vlan_vid:99,set_vlan_pcp:1,controller +cookie=0xa dl_src=40:44:44:44:54:51 actions=push_mpls(0x8847,after_vlan),load:10->OXM_OF_MPLS_LABEL[[]],push_vlan:0x8100,set_vlan_vid:99,set_vlan_pcp:1,controller +cookie=0xa dl_src=40:44:44:44:54:52 actions=push_mpls(0x8847,after_vlan),load:10->OXM_OF_MPLS_LABEL[[]],push_vlan:0x8100,load:99->OXM_OF_VLAN_VID[[]],set_vlan_pcp:1,controller +cookie=0xa dl_src=40:44:44:44:54:53 actions=push_mpls(0x8847,after_vlan),load:10->OXM_OF_MPLS_LABEL[[]],push_vlan:0x8100,load:99->OXM_OF_VLAN_VID[[]],set_vlan_pcp:1,controller +cookie=0xa dl_src=40:44:44:44:54:54 actions=push_vlan:0x8100,set_vlan_vid:99,set_vlan_pcp:1,push_mpls(0x8847,after_vlan),load:10->OXM_OF_MPLS_LABEL[[]],controller +cookie=0xa dl_src=40:44:44:44:54:55 actions=push_vlan:0x8100,set_vlan_vid:99,set_vlan_pcp:1,push_mpls(0x8847,after_vlan),load:10->OXM_OF_MPLS_LABEL[[]],controller +cookie=0xa dl_src=40:44:44:44:54:56 actions=push_vlan:0x8100,load:99->OXM_OF_VLAN_VID[[]],set_vlan_pcp:1,push_mpls(0x8847,after_vlan),load:10->OXM_OF_MPLS_LABEL[[]],controller +cookie=0xa dl_src=40:44:44:44:54:57 actions=push_vlan:0x8100,load:99->OXM_OF_VLAN_VID[[]],set_vlan_pcp:1,push_mpls(0x8847,after_vlan),load:10->OXM_OF_MPLS_LABEL[[]],controller +cookie=0xa dl_src=40:44:44:44:54:58,vlan_tci=0x1000/0x1000 actions=load:99->OXM_OF_VLAN_VID[[]],set_vlan_pcp:1,push_mpls(0x8847,after_vlan),load:10->OXM_OF_MPLS_LABEL[[]],controller +cookie=0xa dl_src=40:44:44:44:54:59,vlan_tci=0x1000/0x1000 actions=push_mpls(0x8847,after_vlan),load:10->OXM_OF_MPLS_LABEL[[]],set_vlan_pcp:1,load:99->OXM_OF_VLAN_VID[[]],controller ]) AT_CHECK([ovs-ofctl --protocols=OpenFlow12 add-flows br0 flows.txt]) @@ -1436,16 +1436,16 @@ mpls,metadata=0,in_port=0,dl_vlan=99,dl_vlan_pcp=1,dl_src=40:44:44:44:54:59,dl_d AT_CHECK([ovs-appctl time/warp 5000], [0], [ignore]) AT_CHECK([ovs-ofctl --protocols=OpenFlow12 dump-flows br0 | ofctl_strip | sort], [0], [dnl - cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:54:50 actions=push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[[]],push_vlan:0x8100,set_field:4195->vlan_vid,set_field:1->vlan_pcp,CONTROLLER:65535 - cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:54:51 actions=push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[[]],push_vlan:0x8100,set_field:4195->vlan_vid,set_field:1->vlan_pcp,CONTROLLER:65535 - cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:54:52 actions=push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[[]],push_vlan:0x8100,load:0x63->OXM_OF_VLAN_VID[[]],set_field:1->vlan_pcp,CONTROLLER:65535 - cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:54:53 actions=push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[[]],push_vlan:0x8100,load:0x63->OXM_OF_VLAN_VID[[]],set_field:1->vlan_pcp,CONTROLLER:65535 - cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:54:54 actions=push_vlan:0x8100,set_field:4195->vlan_vid,set_field:1->vlan_pcp,push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[[]],CONTROLLER:65535 - cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:54:55 actions=push_vlan:0x8100,set_field:4195->vlan_vid,set_field:1->vlan_pcp,push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[[]],CONTROLLER:65535 - cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:54:56 actions=push_vlan:0x8100,load:0x63->OXM_OF_VLAN_VID[[]],set_field:1->vlan_pcp,push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[[]],CONTROLLER:65535 - cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:54:57 actions=push_vlan:0x8100,load:0x63->OXM_OF_VLAN_VID[[]],set_field:1->vlan_pcp,push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[[]],CONTROLLER:65535 - cookie=0xa, n_packets=3, n_bytes=180, vlan_tci=0x1000/0x1000,dl_src=40:44:44:44:54:58 actions=load:0x63->OXM_OF_VLAN_VID[[]],set_field:1->vlan_pcp,push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[[]],CONTROLLER:65535 - cookie=0xa, n_packets=3, n_bytes=180, vlan_tci=0x1000/0x1000,dl_src=40:44:44:44:54:59 actions=push_mpls:0x8847,load:0xa->OXM_OF_MPLS_LABEL[[]],set_field:1->vlan_pcp,load:0x63->OXM_OF_VLAN_VID[[]],CONTROLLER:65535 + cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:54:50 actions=push_mpls(0x8847,after_vlan),load:0xa->OXM_OF_MPLS_LABEL[[]],push_vlan:0x8100,set_field:4195->vlan_vid,set_field:1->vlan_pcp,CONTROLLER:65535 + cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:54:51 actions=push_mpls(0x8847,after_vlan),load:0xa->OXM_OF_MPLS_LABEL[[]],push_vlan:0x8100,set_field:4195->vlan_vid,set_field:1->vlan_pcp,CONTROLLER:65535 + cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:54:52 actions=push_mpls(0x8847,after_vlan),load:0xa->OXM_OF_MPLS_LABEL[[]],push_vlan:0x8100,load:0x63->OXM_OF_VLAN_VID[[]],set_field:1->vlan_pcp,CONTROLLER:65535 + cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:54:53 actions=push_mpls(0x8847,after_vlan),load:0xa->OXM_OF_MPLS_LABEL[[]],push_vlan:0x8100,load:0x63->OXM_OF_VLAN_VID[[]],set_field:1->vlan_pcp,CONTROLLER:65535 + cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:54:54 actions=push_vlan:0x8100,set_field:4195->vlan_vid,set_field:1->vlan_pcp,push_mpls(0x8847,after_vlan),load:0xa->OXM_OF_MPLS_LABEL[[]],CONTROLLER:65535 + cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:54:55 actions=push_vlan:0x8100,set_field:4195->vlan_vid,set_field:1->vlan_pcp,push_mpls(0x8847,after_vlan),load:0xa->OXM_OF_MPLS_LABEL[[]],CONTROLLER:65535 + cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:54:56 actions=push_vlan:0x8100,load:0x63->OXM_OF_VLAN_VID[[]],set_field:1->vlan_pcp,push_mpls(0x8847,after_vlan),load:0xa->OXM_OF_MPLS_LABEL[[]],CONTROLLER:65535 + cookie=0xa, n_packets=3, n_bytes=180, dl_src=40:44:44:44:54:57 actions=push_vlan:0x8100,load:0x63->OXM_OF_VLAN_VID[[]],set_field:1->vlan_pcp,push_mpls(0x8847,after_vlan),load:0xa->OXM_OF_MPLS_LABEL[[]],CONTROLLER:65535 + cookie=0xa, n_packets=3, n_bytes=180, vlan_tci=0x1000/0x1000,dl_src=40:44:44:44:54:58 actions=load:0x63->OXM_OF_VLAN_VID[[]],set_field:1->vlan_pcp,push_mpls(0x8847,after_vlan),load:0xa->OXM_OF_MPLS_LABEL[[]],CONTROLLER:65535 + cookie=0xa, n_packets=3, n_bytes=180, vlan_tci=0x1000/0x1000,dl_src=40:44:44:44:54:59 actions=push_mpls(0x8847,after_vlan),load:0xa->OXM_OF_MPLS_LABEL[[]],set_field:1->vlan_pcp,load:0x63->OXM_OF_VLAN_VID[[]],CONTROLLER:65535 OFPST_FLOW reply (OF1.2): ]) @@ -3007,7 +3007,7 @@ AT_SETUP([ofproto-dpif megaflow - mpls]) OVS_VSWITCHD_START ADD_OF_PORTS([br0], [1], [2]) AT_DATA([flows.txt], [dnl -table=0 dl_src=50:54:00:00:00:09 actions=push_mpls:0x8847,2 +table=0 dl_src=50:54:00:00:00:09 actions=push_mpls(0x8847,after_vlan),2 table=0 dl_src=50:54:00:00:00:0b actions=pop_mpls:0x0800,2 ]) AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in index 411ad64..c8fc8b9 100644 --- a/utilities/ovs-ofctl.8.in +++ b/utilities/ovs-ofctl.8.in @@ -1195,6 +1195,7 @@ allows isn't supported at the moment.) A priority of zero and the tag of zero are used for the new tag. . .IP \fBpush_mpls\fR:\fIethertype\fR +.IQ \fBpush_mpls\fR:(\fR\fIethertype\fR\fB,\fR[\fIposition\fR]\fB) Changes the packet's Ethertype to \fIethertype\fR, which must be either \fB0x8847\fR or \fB0x8848\fR, and pushes an MPLS LSE. .IP @@ -1207,6 +1208,13 @@ its TTL is copied from the IP TTL (64 if the packet is not IP). If the packet does already contain an MPLS label, pushes a new outermost label as a copy of the existing outermost label. .IP +If \fIposition\fR must be \fBafter_vlan\fR. +.RS +.IP \fBafter_vlan\fR +MPLS LSEs are after before any VLAN tags that are present. +Requres OpenFlow1.2 or earlier. +.RE +.IP A limitation of the implementation is that processing of actions will stop if \fBpush_mpls\fR follows another \fBpush_mpls\fR unless there is a \fBpop_mpls\fR in between. -- 1.8.4 _______________________________________________ dev mailing list [email protected] http://openvswitch.org/mailman/listinfo/dev
