Commit 491e05c2 authored by Yi Yang's avatar Yi Yang Committed by Ben Pfaff

nsh: add dec_nsh_ttl action

NSH ttl 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: default avatarYi Yang <yi.y.yang@intel.com>
Signed-off-by: default avatarBen Pfaff <blp@ovn.org>
parent 81fdabb9
......@@ -2,6 +2,7 @@ Post-v2.8.0
--------------------
- NSH implementation now conforms to latest draft (draft-ietf-sfc-nsh-28).
* Add ttl field.
* Add a new action dec_nsh_ttl.
- OVSDB:
* New high-level documentation in ovsdb(7).
* New file format documentation for developers in ovsdb(5).
......
......@@ -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") \
......
......@@ -350,6 +350,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. ## */
/* ## ------------------ ## */
......@@ -486,6 +489,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:
......@@ -4336,6 +4340,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.
......@@ -7156,6 +7193,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:
......@@ -7234,6 +7272,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
......@@ -7348,6 +7387,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);
......@@ -7490,6 +7530,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;
}
......@@ -8177,6 +8218,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();
}
......@@ -8673,6 +8721,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;
}
......
......@@ -4647,6 +4647,28 @@ compose_set_mpls_tc_action(struct xlate_ctx *ctx, uint8_t tc)
}
}
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 {
xlate_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
compose_set_mpls_ttl_action(struct xlate_ctx *ctx, uint8_t ttl)
{
......@@ -5196,6 +5218,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;
}
}
......@@ -5423,6 +5446,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. */
......@@ -5971,6 +5995,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:
......@@ -6295,6 +6320,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))) {
......
......@@ -542,7 +542,7 @@ AT_DATA([br-in2.txt], [dnl
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=77:88:99:aa:bb:cc,actions=dec_nsh_ttl,decap(),resubmit(,2)
])
# br-in3 is SFC classifier (table 1) and final SFF (tables 2,3)
......@@ -607,7 +607,7 @@ AT_CHECK([
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=77:88:99:aa:bb:cc,dl_type=0x894f actions=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
......@@ -661,7 +661,7 @@ 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, dl_dst=77:88:99:aa:bb:cc,dl_type=0x894f actions=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,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
......
......@@ -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
......@@ -1587,6 +1596,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
......@@ -1647,7 +1658,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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment