From patchwork Tue Aug 29 18:21:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Yang, Yi" X-Patchwork-Id: 807218 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3xhcWs6lRXz9sMN for ; Wed, 30 Aug 2017 04:25:45 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id C9B13B1F; Tue, 29 Aug 2017 18:25:05 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 23787B1F for ; Tue, 29 Aug 2017 18:25:05 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from mga07.intel.com (mga07.intel.com [134.134.136.100]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id DDEF2196 for ; Tue, 29 Aug 2017 18:25:03 +0000 (UTC) Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga105.jf.intel.com with ESMTP; 29 Aug 2017 11:25:03 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos; i="5.41,445,1498546800"; d="scan'208"; a="1008955831" Received: from unknown (HELO localhost.localdomain.bj.intel.com) ([10.240.224.185]) by orsmga003.jf.intel.com with ESMTP; 29 Aug 2017 11:25:01 -0700 From: Yi Yang To: dev@openvswitch.org Date: Wed, 30 Aug 2017 02:21:02 +0800 Message-Id: <1504030862-14591-3-git-send-email-yi.y.yang@intel.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1504030862-14591-1-git-send-email-yi.y.yang@intel.com> References: <1504030862-14591-1-git-send-email-yi.y.yang@intel.com> X-Spam-Status: No, score=-2.3 required=5.0 tests=RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD autolearn=disabled version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: e@erig.me, jbenc@redhat.com Subject: [ovs-dev] [PATCH v5 2/2] nsh: add dec_nsh_ttl action X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org IETF NSH spec defines a ttl field in NSH header, it is a 6-bit field ranged from 0 to 63, it should be decremented by 1 every hop, if it is 0 or it is so after decremented, the packet should be dropped and a packet-in message is sent to main controller. Signed-off-by: Yi Yang --- include/openvswitch/ofp-actions.h | 1 + lib/ofp-actions.c | 49 +++++++++++++++++++++++++++++++++++++++ ofproto/ofproto-dpif-xlate.c | 31 +++++++++++++++++++++++++ tests/nsh.at | 23 +++++++++--------- utilities/ovs-ofctl.8.in | 13 ++++++++++- 5 files changed, 105 insertions(+), 12 deletions(-) diff --git a/include/openvswitch/ofp-actions.h b/include/openvswitch/ofp-actions.h index ad8e1be..1296a9c 100644 --- a/include/openvswitch/ofp-actions.h +++ b/include/openvswitch/ofp-actions.h @@ -93,6 +93,7 @@ struct vl_mff_map; OFPACT(DEC_MPLS_TTL, ofpact_null, ofpact, "dec_mpls_ttl") \ OFPACT(PUSH_MPLS, ofpact_push_mpls, ofpact, "push_mpls") \ OFPACT(POP_MPLS, ofpact_pop_mpls, ofpact, "pop_mpls") \ + OFPACT(DEC_NSH_TTL, ofpact_null, ofpact, "dec_nsh_ttl") \ \ /* Generic encap & decap */ \ OFPACT(ENCAP, ofpact_encap, props, "encap") \ diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c index 71eb70c..1a92b95 100644 --- a/lib/ofp-actions.c +++ b/lib/ofp-actions.c @@ -348,6 +348,9 @@ enum ofp_raw_action_type { /* NX1.3+(47): struct nx_action_decap, ... */ NXAST_RAW_DECAP, + /* NX1.3+(48): void. */ + NXAST_RAW_DEC_NSH_TTL, + /* ## ------------------ ## */ /* ## Debugging actions. ## */ /* ## ------------------ ## */ @@ -480,6 +483,7 @@ ofpact_next_flattened(const struct ofpact *ofpact) case OFPACT_NAT: case OFPACT_ENCAP: case OFPACT_DECAP: + case OFPACT_DEC_NSH_TTL: return ofpact_next(ofpact); case OFPACT_CLONE: @@ -4330,6 +4334,39 @@ format_DECAP(const struct ofpact_decap *a, ds_put_format(s, "%s)%s", colors.paren, colors.end); } +/* Action dec_nsh_ttl */ + +static enum ofperr +decode_NXAST_RAW_DEC_NSH_TTL(struct ofpbuf *out) +{ + ofpact_put_DEC_NSH_TTL(out); + return 0; +} + +static void +encode_DEC_NSH_TTL(const struct ofpact_null *null OVS_UNUSED, + enum ofp_version ofp_version OVS_UNUSED, struct ofpbuf *out) +{ + put_NXAST_DEC_NSH_TTL(out); +} + +static char * OVS_WARN_UNUSED_RESULT +parse_DEC_NSH_TTL(char *arg OVS_UNUSED, + const struct ofputil_port_map *port_map OVS_UNUSED, + struct ofpbuf *ofpacts, + enum ofputil_protocol *usable_protocols OVS_UNUSED) +{ + ofpact_put_DEC_NSH_TTL(ofpacts); + return NULL; +} + +static void +format_DEC_NSH_TTL(const struct ofpact_null *a OVS_UNUSED, + const struct ofputil_port_map *port_map OVS_UNUSED, struct ds *s) +{ + ds_put_format(s, "%sdec_nsh_ttl%s", colors.special, colors.end); +} + /* Action structures for NXAST_RESUBMIT, NXAST_RESUBMIT_TABLE, and * NXAST_RESUBMIT_TABLE_CT. @@ -7114,6 +7151,7 @@ ofpact_is_set_or_move_action(const struct ofpact *a) case OFPACT_SET_VLAN_VID: case OFPACT_ENCAP: case OFPACT_DECAP: + case OFPACT_DEC_NSH_TTL: return true; case OFPACT_BUNDLE: case OFPACT_CLEAR_ACTIONS: @@ -7191,6 +7229,7 @@ ofpact_is_allowed_in_actions_set(const struct ofpact *a) case OFPACT_STRIP_VLAN: case OFPACT_ENCAP: case OFPACT_DECAP: + case OFPACT_DEC_NSH_TTL: return true; /* In general these actions are excluded because they are not part of @@ -7304,6 +7343,7 @@ ofpacts_execute_action_set(struct ofpbuf *action_list, ofpacts_copy_last(action_list, action_set, OFPACT_PUSH_VLAN); ofpacts_copy_last(action_list, action_set, OFPACT_DEC_TTL); ofpacts_copy_last(action_list, action_set, OFPACT_DEC_MPLS_TTL); + ofpacts_copy_last(action_list, action_set, OFPACT_DEC_NSH_TTL); ofpacts_copy_all(action_list, action_set, ofpact_is_set_or_move_action); ofpacts_copy_last(action_list, action_set, OFPACT_SET_QUEUE); @@ -7445,6 +7485,7 @@ ovs_instruction_type_from_ofpact_type(enum ofpact_type type) case OFPACT_NAT: case OFPACT_ENCAP: case OFPACT_DECAP: + case OFPACT_DEC_NSH_TTL: default: return OVSINST_OFPIT11_APPLY_ACTIONS; } @@ -8131,6 +8172,13 @@ ofpact_check__(enum ofputil_protocol *usable_protocols, struct ofpact *a, } return 0; + case OFPACT_DEC_NSH_TTL: + if ((flow->packet_type != htonl(PT_NSH)) && + (flow->dl_type != htons(ETH_TYPE_NSH))) { + inconsistent_match(usable_protocols); + } + return 0; + default: OVS_NOT_REACHED(); } @@ -8626,6 +8674,7 @@ ofpact_outputs_to_port(const struct ofpact *ofpact, ofp_port_t port) case OFPACT_NAT: case OFPACT_ENCAP: case OFPACT_DECAP: + case OFPACT_DEC_NSH_TTL: default: return false; } diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 933256e..d24e22c 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -4832,6 +4832,28 @@ compose_dec_mpls_ttl_action(struct xlate_ctx *ctx) return true; } +static bool +compose_dec_nsh_ttl_action(struct xlate_ctx *ctx) +{ + struct flow *flow = &ctx->xin->flow; + + if ((flow->packet_type == htonl(PT_NSH)) || + (flow->dl_type == htons(ETH_TYPE_NSH))) { + ctx->wc->masks.nsh.ttl = 0xff; + if (flow->nsh.ttl > 1) { + flow->nsh.ttl--; + return false; + } else { + execute_controller_action(ctx, UINT16_MAX, OFPR_INVALID_TTL, 0, + NULL, 0); + } + } + + /* Stop processing for current table. */ + xlate_report(ctx, OFT_WARN, "NSH decrement TTL exception"); + return true; +} + static void xlate_output_action(struct xlate_ctx *ctx, ofp_port_t port, uint16_t max_len, bool may_packet_in) @@ -5327,6 +5349,7 @@ reversible_actions(const struct ofpact *ofpacts, size_t ofpacts_len) case OFPACT_OUTPUT_TRUNC: case OFPACT_ENCAP: case OFPACT_DECAP: + case OFPACT_DEC_NSH_TTL: return false; } } @@ -5537,6 +5560,7 @@ freeze_unroll_actions(const struct ofpact *a, const struct ofpact *end, case OFPACT_OUTPUT: case OFPACT_CONTROLLER: case OFPACT_DEC_MPLS_TTL: + case OFPACT_DEC_NSH_TTL: case OFPACT_DEC_TTL: /* These actions may generate asynchronous messages, which include * table ID and flow cookie information. */ @@ -6082,6 +6106,7 @@ recirc_for_mpls(const struct ofpact *a, struct xlate_ctx *ctx) case OFPACT_CLONE: case OFPACT_ENCAP: case OFPACT_DECAP: + case OFPACT_DEC_NSH_TTL: case OFPACT_UNROLL_XLATE: case OFPACT_CT: case OFPACT_CT_CLEAR: @@ -6404,6 +6429,12 @@ do_xlate_actions(const struct ofpact *ofpacts, size_t ofpacts_len, } break; + case OFPACT_DEC_NSH_TTL: + if (compose_dec_nsh_ttl_action(ctx)) { + return; + } + break; + case OFPACT_DEC_TTL: wc->masks.nw_ttl = 0xff; if (compose_dec_ttl(ctx, ofpact_get_DEC_TTL(a))) { diff --git a/tests/nsh.at b/tests/nsh.at index 93d8b42..521365b 100644 --- a/tests/nsh.at +++ b/tests/nsh.at @@ -13,7 +13,7 @@ OVS_VSWITCHD_START([dnl add-port br0 p2 -- set Interface p2 type=dummy ofport_request=2]) AT_DATA([flows.txt], [dnl - table=0,in_port=1,dl_type=0x894f,nsh_ttl=63,nsh_mdtype=1,nsh_np=3,nsh_spi=0x123456,nsh_si=255,nsh_c1=0x11223344,actions=set_field:0x2->nsh_flags,set_field:254->nsh_si,set_field:0x44332211->nsh_c1,2 + table=0,in_port=1,dl_type=0x894f,nsh_ttl=63,nsh_mdtype=1,nsh_np=3,nsh_spi=0x123456,nsh_si=255,nsh_c1=0x11223344,actions=set_field:0x2->nsh_flags,set_field:254->nsh_si,set_field:0x44332211->nsh_c1,dec_nsh_ttl,2 ]) AT_CHECK([ @@ -21,7 +21,7 @@ AT_CHECK([ ovs-ofctl -Oopenflow13 add-flows br0 flows.txt ovs-ofctl -Oopenflow13 dump-flows br0 | ofctl_strip | sort | grep actions ], [0], [dnl - in_port=1,dl_type=0x894f,nsh_ttl=63,nsh_mdtype=1,nsh_np=3,nsh_spi=0x123456,nsh_si=255,nsh_c1=0x11223344 actions=set_field:2->nsh_flags,set_field:254->nsh_si,set_field:0x44332211->nsh_c1,output:2 + in_port=1,dl_type=0x894f,nsh_ttl=63,nsh_mdtype=1,nsh_np=3,nsh_spi=0x123456,nsh_si=255,nsh_c1=0x11223344 actions=set_field:2->nsh_flags,set_field:254->nsh_si,set_field:0x44332211->nsh_c1,dec_nsh_ttl,output:2 ]) AT_CHECK([ @@ -35,11 +35,12 @@ bridge("br0") set_field:2->nsh_flags set_field:254->nsh_si set_field:0x44332211->nsh_c1 + dec_nsh_ttl output:2 -Final flow: in_port=1,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x894f,nsh_flags=2,nsh_ttl=63,nsh_mdtype=1,nsh_np=3,nsh_spi=0x123456,nsh_si=254,nsh_c1=0x44332211,nsh_c2=0x55667788,nsh_c3=0x99aabbcc,nsh_c4=0xddeeff00,nw_proto=0,nw_tos=0,nw_ecn=0,nw_ttl=0 +Final flow: in_port=1,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x894f,nsh_flags=2,nsh_ttl=62,nsh_mdtype=1,nsh_np=3,nsh_spi=0x123456,nsh_si=254,nsh_c1=0x44332211,nsh_c2=0x55667788,nsh_c3=0x99aabbcc,nsh_c4=0xddeeff00,nw_proto=0,nw_tos=0,nw_ecn=0,nw_ttl=0 Megaflow: recirc_id=0,eth,in_port=1,dl_type=0x894f,nsh_flags=0,nsh_ttl=63,nsh_mdtype=1,nsh_np=3,nsh_spi=0x123456,nsh_si=255,nsh_c1=0x11223344 -Datapath actions: set(nsh(flags=2,ttl=63,spi=0x123456,si=254,c1=0x44332211)),2 +Datapath actions: set(nsh(flags=2,ttl=62,spi=0x123456,si=254,c1=0x44332211)),2 ]) OVS_VSWITCHD_STOP @@ -539,8 +540,8 @@ AT_DATA([br-in2.txt], [dnl table=2,packet_type=(1,0x894f),nsh_spi=0x3020,nsh_si=254,actions=output:2030 table=2,packet_type=(1,0x894f),nsh_spi=0x1020,nsh_si=255,actions=encap(ethernet),set_field:77:88:99:aa:bb:cc->dl_dst,goto_table:4 table=2,packet_type=(1,0x894f),nsh_spi=0x1020,nsh_si=254,actions=output:2010 - table=4,dl_type=0x894f,dl_dst=11:22:33:44:55:66,actions=set_field:254->nsh_si,decap(),resubmit(,2) - table=4,dl_type=0x894f,dl_dst=77:88:99:aa:bb:cc,actions=set_field:254->nsh_si,decap(),resubmit(,2) + table=4,dl_type=0x894f,dl_dst=11:22:33:44:55:66,actions=set_field:254->nsh_si,dec_nsh_ttl,decap(),resubmit(,2) + table=4,dl_type=0x894f,dl_dst=77:88:99:aa:bb:cc,actions=set_field:254->nsh_si,dec_nsh_ttl,decap(),resubmit(,2) ]) # br-in3 is SFC classifier (table 1) and final SFF (tables 2,3) @@ -603,8 +604,8 @@ AT_CHECK([ table=2, packet_type=(1,0x894f),nsh_spi=0x1020,nsh_si=255 actions=encap(ethernet),set_field:77:88:99:aa:bb:cc->eth_dst,goto_table:4 table=2, packet_type=(1,0x894f),nsh_spi=0x3020,nsh_si=254 actions=output:2030 table=2, packet_type=(1,0x894f),nsh_spi=0x3020,nsh_si=255 actions=encap(ethernet),set_field:11:22:33:44:55:66->eth_dst,goto_table:4 - table=4, dl_dst=11:22:33:44:55:66,dl_type=0x894f actions=set_field:254->nsh_si,decap(),resubmit(,2) - table=4, dl_dst=77:88:99:aa:bb:cc,dl_type=0x894f actions=set_field:254->nsh_si,decap(),resubmit(,2) + table=4, dl_dst=11:22:33:44:55:66,dl_type=0x894f actions=set_field:254->nsh_si,dec_nsh_ttl,decap(),resubmit(,2) + table=4, dl_dst=77:88:99:aa:bb:cc,dl_type=0x894f actions=set_field:254->nsh_si,dec_nsh_ttl,decap(),resubmit(,2) ip,in_port=30 actions=decap(),goto_table:1 n_packets=2, n_bytes=216, packet_type=(1,0x894f),in_port=3010 actions=goto_table:2 packet_type=(1,0x800),in_port=30 actions=goto_table:1 @@ -632,7 +633,7 @@ AT_CHECK([ ovs-appctl dpctl/dump-flows dummy@ovs-dummy | strip_used | grep -v ipv6 | sort ], [0], [flow-dump from non-dpdk interfaces: recirc_id(0),in_port(4),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=192.168.10.20/255.255.255.248,frag=no), packets:1, bytes:98, used:0.0s, actions:pop_eth,encap_nsh(flags=0,ttl=63,mdtype=1,np=1,spi=0x3020,si=255,c1=0x0,c2=0x0,c3=0x0,c4=0x0),clone(tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=aa:55:00:00:00:02,src=aa:55:00:00:00:01,dl_type=0x0800),ipv4(src=10.0.0.1,dst=10.0.0.2,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0xc000004,vni=0x0)),out_port(1)),set(ipv4(src=20.0.0.1,dst=20.0.0.2)),tnl_pop(4789)) -tunnel(tun_id=0x0,src=20.0.0.1,dst=20.0.0.2,flags(-df-csum+key)),recirc_id(0),in_port(4789),packet_type(ns=1,id=0x894f),nsh(spi=0x3020,si=255), packets:1, bytes:108, used:0.0s, actions:push_eth(src=00:00:00:00:00:00,dst=11:22:33:44:55:66),set(nsh(spi=0x3020,si=254)),pop_eth,clone(tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=aa:55:00:00:00:03,src=aa:55:00:00:00:02,dl_type=0x0800),ipv4(src=20.0.0.2,dst=20.0.0.3,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0xc000004,vni=0x0)),out_port(2)),set(ipv4(src=30.0.0.2,dst=30.0.0.3)),tnl_pop(4789)) +tunnel(tun_id=0x0,src=20.0.0.1,dst=20.0.0.2,flags(-df-csum+key)),recirc_id(0),in_port(4789),packet_type(ns=1,id=0x894f),nsh(ttl=63,spi=0x3020,si=255), packets:1, bytes:108, used:0.0s, actions:push_eth(src=00:00:00:00:00:00,dst=11:22:33:44:55:66),set(nsh(ttl=62,spi=0x3020,si=254)),pop_eth,clone(tnl_push(tnl_port(4789),header(size=50,type=4,eth(dst=aa:55:00:00:00:03,src=aa:55:00:00:00:02,dl_type=0x0800),ipv4(src=20.0.0.2,dst=20.0.0.3,proto=17,tos=0,ttl=64,frag=0x4000),udp(src=0,dst=4789,csum=0x0),vxlan(flags=0xc000004,vni=0x0)),out_port(2)),set(ipv4(src=30.0.0.2,dst=30.0.0.3)),tnl_pop(4789)) tunnel(tun_id=0x0,src=30.0.0.2,dst=30.0.0.3,flags(-df-csum+key)),recirc_id(0),in_port(4789),packet_type(ns=1,id=0x894f),nsh(np=1,spi=0x3020,si=254), packets:1, bytes:108, used:0.0s, actions:decap_nsh(),recirc(0x2) tunnel(tun_id=0x0,src=30.0.0.2,dst=30.0.0.3,flags(-df-csum+key)),recirc_id(0x2),in_port(4789),packet_type(ns=1,id=0x800),ipv4(frag=no), packets:1, bytes:84, used:0.0s, actions:push_eth(src=00:00:00:00:00:00,dst=aa:55:aa:55:00:03),6 ]) @@ -658,8 +659,8 @@ AT_CHECK([ table=2, n_packets=2, n_bytes=216, packet_type=(1,0x894f),nsh_spi=0x3020,nsh_si=255 actions=encap(ethernet),set_field:11:22:33:44:55:66->eth_dst,goto_table:4 table=2, packet_type=(1,0x894f),nsh_spi=0x1020,nsh_si=254 actions=output:2010 table=2, packet_type=(1,0x894f),nsh_spi=0x1020,nsh_si=255 actions=encap(ethernet),set_field:77:88:99:aa:bb:cc->eth_dst,goto_table:4 - table=4, dl_dst=77:88:99:aa:bb:cc,dl_type=0x894f actions=set_field:254->nsh_si,decap(),resubmit(,2) - table=4, n_packets=2, n_bytes=216, dl_dst=11:22:33:44:55:66,dl_type=0x894f actions=set_field:254->nsh_si,decap(),resubmit(,2) + table=4, dl_dst=77:88:99:aa:bb:cc,dl_type=0x894f actions=set_field:254->nsh_si,dec_nsh_ttl,decap(),resubmit(,2) + table=4, n_packets=2, n_bytes=216, dl_dst=11:22:33:44:55:66,dl_type=0x894f actions=set_field:254->nsh_si,dec_nsh_ttl,decap(),resubmit(,2) ip,in_port=30 actions=decap(),goto_table:1 n_packets=2, n_bytes=216, packet_type=(1,0x894f),in_port=3010 actions=goto_table:2 n_packets=2, n_bytes=216, packet_type=(1,0x894f),in_port=3020 actions=goto_table:2 diff --git a/utilities/ovs-ofctl.8.in b/utilities/ovs-ofctl.8.in index c65de97..9b3e72d 100644 --- a/utilities/ovs-ofctl.8.in +++ b/utilities/ovs-ofctl.8.in @@ -1280,6 +1280,15 @@ Processing the current set of actions then stops. However, if the current set of actions was reached through ``resubmit'' then remaining actions in outer levels resume processing. . +.IP \fBdec_nsh_ttl\fR +Decrement TTL of the outer NSH header of a packet. If the TTL +is initially zero or decrementing would make it so, no decrement occurs. +Instead, a ``packet-in'' message with reason code \fBOFPR_INVALID_TTL\fR +is sent to the main controller (id zero), if it has enabled receiving them. +Processing the current set of actions then stops. However, if the current +set of actions was reached through ``resubmit'' then remaining actions in +outer levels resume processing. +. .IP \fBnote:\fR[\fIhh\fR]... Does nothing at all. Any number of bytes represented as hex digits \fIhh\fR may be included. Pairs of hex digits may be separated by @@ -1578,6 +1587,8 @@ the action set, the one written later replaces the earlier action: \fBdec_ttl\fR .IQ \fBdec_mpls_ttl\fR +.IQ +\fBdec_nsh_ttl\fR . .IP 7. \fBload\fR @@ -1638,7 +1649,7 @@ not visible.) .RE .IP Only the actions listed above may be written to the action set. -\fBencap\fR and \fBdecap\fR actions are nonstandard. +\fBencap\fR, \fBdecap\fR and \fBdec_nsh_ttl\fR actions are nonstandard. . .IP \fBwrite_metadata\fB:\fIvalue\fR[/\fImask\fR] Updates the metadata field for the flow. If \fImask\fR is omitted, the