@@ -205,6 +205,15 @@ parse_actions(struct action_context *ctx)
parse_next_action(ctx);
} else if (lexer_match_id(ctx->lexer, "output")) {
emit_resubmit(ctx, ctx->output_table);
+ } else if (lexer_match_id(ctx->lexer, "ip4.ttl")) {
+ if (lexer_match(ctx->lexer, LEX_T_DECREMENT)) {
+ struct expr *e = expr_parse_string("ip4", ctx->symtab,
+ &ctx->error);
+ ctx->prereqs = expr_combine(EXPR_T_AND, ctx->prereqs, e);
+ ofpact_put_DEC_TTL(ctx->ofpacts);
+ } else {
+ action_syntax_error(ctx, "expecting `--'");
+ }
} else {
action_syntax_error(ctx, "expecting action");
}
@@ -241,6 +241,9 @@ lex_token_format(const struct lex_token *token, struct ds *s)
case LEX_T_EXCHANGE:
ds_put_cstr(s, "<->");
break;
+ case LEX_T_DECREMENT:
+ ds_put_cstr(s, "--");
+ break;
default:
OVS_NOT_REACHED();
}
@@ -640,6 +643,16 @@ next:
token->type = LEX_T_SEMICOLON;
break;
+ case '-':
+ p++;
+ if (*p == '-') {
+ token->type = LEX_T_DECREMENT;
+ p++;
+ } else {
+ lex_error(token, "`-' is only valid as part of `--'.");
+ }
+ break;
+
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case ':':
@@ -59,6 +59,7 @@ enum lex_type {
LEX_T_SEMICOLON, /* ; */
LEX_T_EQUALS, /* = */
LEX_T_EXCHANGE, /* <-> */
+ LEX_T_DECREMENT, /* -- */
};
/* Subtype for LEX_T_INTEGER and LEX_T_MASKED_INTEGER tokens.
@@ -82,9 +82,10 @@ fe:x => error("Invalid numeric constant.")
00:01:02:03:04:x => error("Invalid numeric constant.")
# Test that operators are tokenized as expected, even without white space.
-(){}[[]]==!=<<=>>=!&&||..,;=<-> => ( ) { } [[ ]] == != < <= > >= ! && || .. , ; = <->
+(){}[[]]==!=<<=>>=!&&||..,;=<->-- => ( ) { } [[ ]] == != < <= > >= ! && || .. , ; = <-> --
& => error("`&' is only valid as part of `&&'.")
| => error("`|' is only valid as part of `||'.")
+- => error("`-' is only valid as part of `--'.")
^ => error("Invalid character `^' in input.")
])
@@ -455,6 +456,8 @@ reg0 <-> reg1; => actions=push:OXM_OF_PKT_REG0[0..31],push:OXM_OF_PKT_REG0[32..6
vlan.pcp <-> reg0[0..2]; => actions=push:OXM_OF_PKT_REG0[32..34],push:NXM_OF_VLAN_TCI[13..15],pop:OXM_OF_PKT_REG0[32..34],pop:NXM_OF_VLAN_TCI[13..15], prereqs=vlan.tci[12]
reg0[10] <-> vlan.pcp[1]; => actions=push:NXM_OF_VLAN_TCI[14],push:OXM_OF_PKT_REG0[42],pop:NXM_OF_VLAN_TCI[14],pop:OXM_OF_PKT_REG0[42], prereqs=vlan.tci[12]
outport <-> inport; => actions=push:NXM_NX_REG6[],push:NXM_NX_REG7[],pop:NXM_NX_REG6[],pop:NXM_NX_REG7[], prereqs=1
+ip4.ttl--; => actions=dec_ttl, prereqs=ip4
+
# Contradictionary prerequisites (allowed but not useful):
ip4.src = ip6.src[0..31]; => actions=move:NXM_NX_IPV6_SRC[0..31]->NXM_OF_IP_SRC[], prereqs=eth.type == 0x800 && eth.type == 0x86dd
ip4.src <-> ip6.src[0..31]; => actions=push:NXM_NX_IPV6_SRC[0..31],push:NXM_OF_IP_SRC[],pop:NXM_NX_IPV6_SRC[0..31],pop:NXM_OF_IP_SRC[], prereqs=eth.type == 0x800 && eth.type == 0x86dd
@@ -498,6 +501,7 @@ inport <-> reg0; => Can't exchange string field (inport) with integer field (reg
inport <-> big_string; => String fields inport and big_string are incompatible for exchange.
ip.proto <-> reg0[0..7]; => Field ip.proto is not modifiable.
reg0[0..7] <-> ip.proto; => Field ip.proto is not modifiable.
+ip4.ttl => Syntax error at end of input expecting `--'.
]])
sed 's/ =>.*//' test-cases.txt > input.txt
sed 's/.* => //' test-cases.txt > expout
This is necessary for IPv4 routing. Signed-off-by: Ben Pfaff <blp@nicira.com> --- ovn/lib/actions.c | 9 +++++++++ ovn/lib/lex.c | 13 +++++++++++++ ovn/lib/lex.h | 1 + tests/ovn.at | 6 +++++- 4 files changed, 28 insertions(+), 1 deletion(-)