mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 06:15:47 +00:00
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: Yi Yang <yi.y.yang@intel.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
This commit is contained in:
1
NEWS
1
NEWS
@@ -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
|
||||
|
Reference in New Issue
Block a user