2 * Copyright (c) 2015, 2016 Nicira, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at:
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include "byte-order.h"
26 #include "logical-fields.h"
28 #include "openvswitch/dynamic-string.h"
29 #include "openvswitch/ofp-actions.h"
30 #include "openvswitch/ofpbuf.h"
35 /* Context maintained during actions_parse(). */
36 struct action_context {
37 const struct action_params *ap; /* Parameters. */
38 struct lexer *lexer; /* Lexer for pulling more tokens. */
39 char *error; /* Error, if any, otherwise NULL. */
40 struct ofpbuf *ofpacts; /* Actions. */
41 struct expr *prereqs; /* Prerequisites to apply to match. */
44 static bool parse_action(struct action_context *);
45 static void parse_put_dhcp_opts_action(struct action_context *,
46 const struct expr_field *dst);
49 action_error_handle_common(struct action_context *ctx)
52 /* Already have an error, suppress this one since the cascade seems
53 * unlikely to be useful. */
55 } else if (ctx->lexer->token.type == LEX_T_ERROR) {
56 /* The lexer signaled an error. Nothing at the action level
57 * accepts an error token, so we'll inevitably end up here with some
58 * meaningless parse error. Report the lexical error instead. */
59 ctx->error = xstrdup(ctx->lexer->token.s);
66 static void OVS_PRINTF_FORMAT(2, 3)
67 action_error(struct action_context *ctx, const char *message, ...)
69 if (action_error_handle_common(ctx)) {
74 va_start(args, message);
75 ctx->error = xvasprintf(message, args);
79 static void OVS_PRINTF_FORMAT(2, 3)
80 action_syntax_error(struct action_context *ctx, const char *message, ...)
82 if (action_error_handle_common(ctx)) {
89 ds_put_cstr(&s, "Syntax error");
90 if (ctx->lexer->token.type == LEX_T_END) {
91 ds_put_cstr(&s, " at end of input");
92 } else if (ctx->lexer->start) {
93 ds_put_format(&s, " at `%.*s'",
94 (int) (ctx->lexer->input - ctx->lexer->start),
102 va_start(args, message);
103 ds_put_format_valist(&s, message, args);
106 ds_put_char(&s, '.');
108 ctx->error = ds_steal_cstr(&s);
111 /* Parses an assignment or exchange or put_dhcp_opts action. */
113 parse_set_action(struct action_context *ctx)
115 struct expr *prereqs = NULL;
116 struct expr_field dst;
119 error = expr_parse_field(ctx->lexer, ctx->ap->symtab, &dst);
121 if (lexer_match(ctx->lexer, LEX_T_EXCHANGE)) {
122 error = expr_parse_exchange(ctx->lexer, &dst, ctx->ap->symtab,
123 ctx->ap->lookup_port, ctx->ap->aux,
124 ctx->ofpacts, &prereqs);
125 } else if (lexer_match(ctx->lexer, LEX_T_EQUALS)) {
126 if (ctx->lexer->token.type == LEX_T_ID
127 && !strcmp(ctx->lexer->token.s, "put_dhcp_opts")
128 && lexer_lookahead(ctx->lexer) == LEX_T_LPAREN) {
129 lexer_get(ctx->lexer); /* Skip put_dhcp_opts. */
130 lexer_get(ctx->lexer); /* Skip '('. */
131 parse_put_dhcp_opts_action(ctx, &dst);
133 error = expr_parse_assignment(
134 ctx->lexer, &dst, ctx->ap->symtab, ctx->ap->lookup_port,
135 ctx->ap->aux, ctx->ofpacts, &prereqs);
138 action_syntax_error(ctx, "expecting `=' or `<->'");
141 ctx->prereqs = expr_combine(EXPR_T_AND, ctx->prereqs, prereqs);
146 expr_destroy(prereqs);
147 action_error(ctx, "%s", error);
153 emit_resubmit(struct action_context *ctx, uint8_t table_id)
155 struct ofpact_resubmit *resubmit = ofpact_put_RESUBMIT(ctx->ofpacts);
156 resubmit->in_port = OFPP_IN_PORT;
157 resubmit->table_id = table_id;
161 action_get_int(struct action_context *ctx, int *value)
163 bool ok = lexer_get_int(ctx->lexer, value);
165 action_syntax_error(ctx, "expecting small integer");
171 parse_next_action(struct action_context *ctx)
173 if (!ctx->ap->n_tables) {
174 action_error(ctx, "\"next\" action not allowed here.");
175 } else if (lexer_match(ctx->lexer, LEX_T_LPAREN)) {
178 if (!action_get_int(ctx, <able)) {
181 if (!lexer_match(ctx->lexer, LEX_T_RPAREN)) {
182 action_syntax_error(ctx, "expecting `)'");
186 if (ltable >= ctx->ap->n_tables) {
187 action_error(ctx, "\"next\" argument must be in range 0 to %d.",
188 ctx->ap->n_tables - 1);
192 emit_resubmit(ctx, ctx->ap->first_ptable + ltable);
194 if (ctx->ap->cur_ltable < ctx->ap->n_tables) {
196 ctx->ap->first_ptable + ctx->ap->cur_ltable + 1);
198 action_error(ctx, "\"next\" action not allowed in last table.");
203 /* Parses 'prerequisite' as an expression in the context of 'ctx', then adds it
204 * as a conjunction with the existing 'ctx->prereqs'. */
206 add_prerequisite(struct action_context *ctx, const char *prerequisite)
211 expr = expr_parse_string(prerequisite, ctx->ap->symtab, &error);
213 ctx->prereqs = expr_combine(EXPR_T_AND, ctx->prereqs, expr);
217 start_controller_op(struct ofpbuf *ofpacts, enum action_opcode opcode,
220 size_t ofs = ofpacts->size;
222 struct ofpact_controller *oc = ofpact_put_CONTROLLER(ofpacts);
223 oc->max_len = UINT16_MAX;
224 oc->reason = OFPR_ACTION;
227 struct action_header ah = { .opcode = htonl(opcode) };
228 ofpbuf_put(ofpacts, &ah, sizeof ah);
234 finish_controller_op(struct ofpbuf *ofpacts, size_t ofs)
236 struct ofpact_controller *oc = ofpbuf_at_assert(ofpacts, ofs, sizeof *oc);
237 ofpacts->header = oc;
238 oc->userdata_len = ofpacts->size - (ofs + sizeof *oc);
239 ofpact_finish_CONTROLLER(ofpacts, &oc);
243 put_controller_op(struct ofpbuf *ofpacts, enum action_opcode opcode)
245 size_t ofs = start_controller_op(ofpacts, opcode, false);
246 finish_controller_op(ofpacts, ofs);
250 parse_arp_action(struct action_context *ctx)
252 if (!lexer_match(ctx->lexer, LEX_T_LCURLY)) {
253 action_syntax_error(ctx, "expecting `{'");
257 struct ofpbuf *outer_ofpacts = ctx->ofpacts;
258 uint64_t inner_ofpacts_stub[1024 / 8];
259 struct ofpbuf inner_ofpacts = OFPBUF_STUB_INITIALIZER(inner_ofpacts_stub);
260 ctx->ofpacts = &inner_ofpacts;
262 /* Save prerequisites. (XXX What is the right treatment for prereqs?) */
263 struct expr *outer_prereqs = ctx->prereqs;
266 /* Parse inner actions. */
267 while (!lexer_match(ctx->lexer, LEX_T_RCURLY)) {
268 if (!parse_action(ctx)) {
273 ctx->ofpacts = outer_ofpacts;
275 /* Add a "controller" action with the actions nested inside "arp {...}",
276 * converted to OpenFlow, as its userdata. ovn-controller will convert the
277 * packet to an ARP and then send the packet and actions back to the switch
278 * inside an OFPT_PACKET_OUT message. */
280 size_t oc_offset = start_controller_op(ctx->ofpacts, ACTION_OPCODE_ARP,
282 ofpacts_put_openflow_actions(inner_ofpacts.data, inner_ofpacts.size,
283 ctx->ofpacts, OFP13_VERSION);
284 finish_controller_op(ctx->ofpacts, oc_offset);
286 /* Restore prerequisites. */
287 expr_destroy(ctx->prereqs);
288 ctx->prereqs = outer_prereqs;
289 add_prerequisite(ctx, "ip4");
292 ofpbuf_uninit(&inner_ofpacts);
296 action_force_match(struct action_context *ctx, enum lex_type t)
298 if (lexer_match(ctx->lexer, t)) {
301 struct lex_token token = { .type = t };
302 struct ds s = DS_EMPTY_INITIALIZER;
303 lex_token_format(&token, &s);
305 action_syntax_error(ctx, "expecting `%s'", ds_cstr(&s));
314 action_parse_field(struct action_context *ctx,
315 int n_bits, struct mf_subfield *sf)
317 struct expr_field field;
320 error = expr_parse_field(ctx->lexer, ctx->ap->symtab, &field);
322 struct expr *prereqs;
323 error = expr_expand_field(ctx->lexer, ctx->ap->symtab,
324 &field, n_bits, false, sf, &prereqs);
326 ctx->prereqs = expr_combine(EXPR_T_AND, ctx->prereqs, prereqs);
331 action_error(ctx, "%s", error);
337 init_stack(struct ofpact_stack *stack, enum mf_field_id field)
339 stack->subfield.field = mf_from_id(field);
340 stack->subfield.ofs = 0;
341 stack->subfield.n_bits = stack->subfield.field->n_bits;
345 const struct mf_subfield *src;
346 enum mf_field_id dst;
350 setup_args(struct action_context *ctx,
351 const struct arg args[], size_t n_args)
353 /* 1. Save all of the destinations that will be modified. */
354 for (const struct arg *a = args; a < &args[n_args]; a++) {
355 ovs_assert(a->src->n_bits == mf_from_id(a->dst)->n_bits);
356 if (a->src->field->id != a->dst) {
357 init_stack(ofpact_put_STACK_PUSH(ctx->ofpacts), a->dst);
361 /* 2. Push the sources, in reverse order. */
362 for (size_t i = n_args - 1; i < n_args; i--) {
363 const struct arg *a = &args[i];
364 if (a->src->field->id != a->dst) {
365 ofpact_put_STACK_PUSH(ctx->ofpacts)->subfield = *a->src;
369 /* 3. Pop the sources into the destinations. */
370 for (const struct arg *a = args; a < &args[n_args]; a++) {
371 if (a->src->field->id != a->dst) {
372 init_stack(ofpact_put_STACK_POP(ctx->ofpacts), a->dst);
378 restore_args(struct action_context *ctx,
379 const struct arg args[], size_t n_args)
381 for (size_t i = n_args - 1; i < n_args; i--) {
382 const struct arg *a = &args[i];
383 if (a->src->field->id != a->dst) {
384 init_stack(ofpact_put_STACK_POP(ctx->ofpacts), a->dst);
390 put_load(uint64_t value, enum mf_field_id dst, int ofs, int n_bits,
391 struct ofpbuf *ofpacts)
393 struct ofpact_set_field *sf = ofpact_put_SET_FIELD(ofpacts);
394 sf->field = mf_from_id(dst);
395 sf->flow_has_vlan = false;
397 ovs_be64 n_value = htonll(value);
398 bitwise_copy(&n_value, 8, 0, &sf->value, sf->field->n_bytes, ofs, n_bits);
399 bitwise_one(&sf->mask, sf->field->n_bytes, ofs, n_bits);
403 parse_get_arp_action(struct action_context *ctx)
405 struct mf_subfield port, ip;
407 if (!action_force_match(ctx, LEX_T_LPAREN)
408 || !action_parse_field(ctx, 0, &port)
409 || !action_force_match(ctx, LEX_T_COMMA)
410 || !action_parse_field(ctx, 32, &ip)
411 || !action_force_match(ctx, LEX_T_RPAREN)) {
415 const struct arg args[] = {
416 { &port, MFF_LOG_OUTPORT },
419 setup_args(ctx, args, ARRAY_SIZE(args));
421 put_load(0, MFF_ETH_DST, 0, 48, ctx->ofpacts);
422 emit_resubmit(ctx, ctx->ap->arp_ptable);
424 restore_args(ctx, args, ARRAY_SIZE(args));
428 parse_put_arp_action(struct action_context *ctx)
430 struct mf_subfield port, ip, mac;
432 if (!action_force_match(ctx, LEX_T_LPAREN)
433 || !action_parse_field(ctx, 0, &port)
434 || !action_force_match(ctx, LEX_T_COMMA)
435 || !action_parse_field(ctx, 32, &ip)
436 || !action_force_match(ctx, LEX_T_COMMA)
437 || !action_parse_field(ctx, 48, &mac)
438 || !action_force_match(ctx, LEX_T_RPAREN)) {
442 const struct arg args[] = {
443 { &port, MFF_LOG_INPORT },
445 { &mac, MFF_ETH_SRC }
447 setup_args(ctx, args, ARRAY_SIZE(args));
448 put_controller_op(ctx->ofpacts, ACTION_OPCODE_PUT_ARP);
449 restore_args(ctx, args, ARRAY_SIZE(args));
453 parse_dhcp_opt(struct action_context *ctx, struct ofpbuf *ofpacts)
455 if (ctx->lexer->token.type != LEX_T_ID) {
456 action_syntax_error(ctx, NULL);
459 const struct dhcp_opts_map *dhcp_opt = dhcp_opts_find(
460 ctx->ap->dhcp_opts, ctx->lexer->token.s);
462 action_syntax_error(ctx, "expecting DHCP option name");
465 lexer_get(ctx->lexer);
467 if (!action_force_match(ctx, LEX_T_EQUALS)) {
471 struct expr_constant_set cs;
472 memset(&cs, 0, sizeof(struct expr_constant_set));
473 char *error = expr_parse_constant_set(ctx->lexer, NULL, &cs);
475 action_error(ctx, "%s", error);
480 if (!strcmp(dhcp_opt->type, "str")) {
481 if (cs.type != EXPR_C_STRING) {
482 action_error(ctx, "DHCP option %s requires string value.",
487 if (cs.type != EXPR_C_INTEGER) {
488 action_error(ctx, "DHCP option %s requires numeric value.",
494 if (!lexer_match(ctx->lexer, LEX_T_COMMA) && (
495 ctx->lexer->token.type != LEX_T_RPAREN)) {
496 action_syntax_error(ctx, NULL);
501 if (dhcp_opt->code == 0) {
503 ofpbuf_put(ofpacts, &cs.values[0].value.ipv4, sizeof(ovs_be32));
507 uint8_t *opt_header = ofpbuf_put_uninit(ofpacts, 2);
508 opt_header[0] = dhcp_opt->code;
510 if (!strcmp(dhcp_opt->type, "bool") || !strcmp(dhcp_opt->type, "uint8")) {
512 ofpbuf_put(ofpacts, &cs.values[0].value.u8_val, 1);
513 } else if (!strcmp(dhcp_opt->type, "uint16")) {
515 ofpbuf_put(ofpacts, &cs.values[0].value.be16_int, 2);
516 } else if (!strcmp(dhcp_opt->type, "uint32")) {
518 ofpbuf_put(ofpacts, &cs.values[0].value.be32_int, 4);
519 } else if (!strcmp(dhcp_opt->type, "ipv4")) {
520 opt_header[1] = cs.n_values * sizeof(ovs_be32);
521 for (size_t i = 0; i < cs.n_values; i++) {
522 ofpbuf_put(ofpacts, &cs.values[i].value.ipv4, sizeof(ovs_be32));
524 } else if (!strcmp(dhcp_opt->type, "static_routes")) {
525 size_t no_of_routes = cs.n_values;
526 if (no_of_routes % 2) {
531 /* Calculating the length of this option first because when
532 * we call ofpbuf_put, it might reallocate the buffer if the
533 * tail room is short making "opt_header" pointer invalid.
534 * So running the for loop twice.
536 for (size_t i = 0; i < no_of_routes; i += 2) {
538 if (cs.values[i].masked) {
539 plen = (uint8_t) ip_count_cidr_bits(cs.values[i].mask.ipv4);
541 opt_header[1] += (1 + (plen / 8) + sizeof(ovs_be32)) ;
544 /* Copied from RFC 3442. Please refer to this RFC for the format of
545 * the classless static route option.
547 * The following table contains some examples of how various subnet
548 * number/mask combinations can be encoded:
550 * Subnet number Subnet mask Destination descriptor
552 * 10.0.0.0 255.0.0.0 8.10
553 * 10.0.0.0 255.255.255.0 24.10.0.0
554 * 10.17.0.0 255.255.0.0 16.10.17
555 * 10.27.129.0 255.255.255.0 24.10.27.129
556 * 10.229.0.128 255.255.255.128 25.10.229.0.128
557 * 10.198.122.47 255.255.255.255 32.10.198.122.47
560 for (size_t i = 0; i < no_of_routes; i += 2) {
562 if (cs.values[i].masked) {
563 plen = ip_count_cidr_bits(cs.values[i].mask.ipv4);
565 ofpbuf_put(ofpacts, &plen, 1);
566 ofpbuf_put(ofpacts, &cs.values[i].value.ipv4, plen / 8);
567 ofpbuf_put(ofpacts, &cs.values[i + 1].value.ipv4,
570 } else if (!strcmp(dhcp_opt->type, "str")) {
571 opt_header[1] = strlen(cs.values[0].string);
572 ofpbuf_put(ofpacts, cs.values[0].string, opt_header[1]);
576 expr_constant_set_destroy(&cs);
579 /* Parses the "put_dhcp_opts" action. The result should be stored into 'dst'.
581 * The caller has already consumed "put_dhcp_opts(", so this just parses the
584 parse_put_dhcp_opts_action(struct action_context *ctx,
585 const struct expr_field *dst)
587 /* Validate that the destination is a 1-bit, modifiable field. */
588 struct mf_subfield sf;
589 struct expr *prereqs;
590 char *error = expr_expand_field(ctx->lexer, ctx->ap->symtab,
591 dst, 1, true, &sf, &prereqs);
593 action_error(ctx, "%s", error);
597 ctx->prereqs = expr_combine(EXPR_T_AND, ctx->prereqs, prereqs);
599 /* Make sure the first option is "offer_ip" */
600 if (ctx->lexer->token.type != LEX_T_ID) {
601 action_syntax_error(ctx, NULL);
604 const struct dhcp_opts_map *dhcp_opt = dhcp_opts_find(
605 ctx->ap->dhcp_opts, ctx->lexer->token.s);
606 if (!dhcp_opt || dhcp_opt->code != 0) {
607 action_syntax_error(ctx, "expecting offerip option");
612 size_t oc_offset = start_controller_op(ctx->ofpacts,
613 ACTION_OPCODE_PUT_DHCP_OPTS, true);
614 nx_put_header(ctx->ofpacts, sf.field->id, OFP13_VERSION, false);
615 ovs_be32 ofs = htonl(sf.ofs);
616 ofpbuf_put(ctx->ofpacts, &ofs, sizeof ofs);
617 while (!lexer_match(ctx->lexer, LEX_T_RPAREN)) {
618 parse_dhcp_opt(ctx, ctx->ofpacts);
623 finish_controller_op(ctx->ofpacts, oc_offset);
627 emit_ct(struct action_context *ctx, bool recirc_next, bool commit,
628 int *ct_mark, int *ct_mark_mask,
629 ovs_be128 *ct_label, ovs_be128 *ct_label_mask)
631 struct ofpact_conntrack *ct = ofpact_put_CT(ctx->ofpacts);
632 ct->flags |= commit ? NX_CT_F_COMMIT : 0;
634 /* If "recirc" is set, we automatically go to the next table. */
636 if (ctx->ap->cur_ltable < ctx->ap->n_tables) {
637 ct->recirc_table = ctx->ap->first_ptable + ctx->ap->cur_ltable + 1;
639 action_error(ctx, "\"ct_next\" action not allowed in last table.");
643 ct->recirc_table = NX_CT_RECIRC_NONE;
646 ct->zone_src.field = mf_from_id(MFF_LOG_CT_ZONE);
647 ct->zone_src.ofs = 0;
648 ct->zone_src.n_bits = 16;
650 /* We do not support ALGs yet. */
653 /* CT only works with IP, so set up a prerequisite. */
654 add_prerequisite(ctx, "ip");
656 size_t set_field_offset = ctx->ofpacts->size;
657 ofpbuf_pull(ctx->ofpacts, set_field_offset);
660 struct ofpact_set_field *sf = ofpact_put_SET_FIELD(ctx->ofpacts);
661 sf->field = mf_from_id(MFF_CT_MARK);
662 sf->value.be32 = htonl(*ct_mark);
663 sf->mask.be32 = ct_mark_mask ? htonl(*ct_mark_mask) : OVS_BE32_MAX;
667 struct ofpact_set_field *sf = ofpact_put_SET_FIELD(ctx->ofpacts);
668 sf->field = mf_from_id(MFF_CT_LABEL);
669 sf->value.be128 = *ct_label;
670 sf->mask.be128 = ct_label_mask ? *ct_label_mask : OVS_BE128_MAX;
673 ctx->ofpacts->header = ofpbuf_push_uninit(ctx->ofpacts, set_field_offset);
674 ct = ctx->ofpacts->header;
675 ofpact_finish(ctx->ofpacts, &ct->ofpact);
678 /* Parse an argument to the ct_commit(); action. Supported arguments include:
680 * ct_mark=<value>[/<mask>]
681 * ct_label=<value>[/<mask>]
683 * If a comma separates the current argument from the next argument, this
684 * function will consume it.
686 * set_mark - This will be set to true if a value for ct_mark was successfully
687 * parsed. Otherwise, it will be unchanged.
688 * mark_value - If set_mark was set to true, this will contain the value
689 * parsed for ct_mark.
690 * mark_mask - If set_mark was set to true, this will contain the mask
691 * for ct_mark if one was found. Otherwise, it will be
692 * unchanged, so the caller should initialize this to an
694 * set_label - This will be set to true if a value for ct_label was successfully
695 * parsed. Otherwise, it will be unchanged.
696 * label_value - If set_label was set to true, this will contain the value
697 * parsed for ct_label.
698 * label_mask - If set_label was set to true, this will contain the mask
699 * for ct_label if one was found. Otherwise, it will be
700 * unchanged, so the caller should initialize this to an
703 * Return true after successfully parsing an argument. false on failure. */
705 parse_ct_commit_arg(struct action_context *ctx,
706 bool *set_mark, int *mark_value, int *mark_mask,
707 bool *set_label, ovs_be128 *label_value,
708 ovs_be128 *label_mask)
710 if (lexer_match_id(ctx->lexer, "ct_mark")) {
711 if (!lexer_match(ctx->lexer, LEX_T_EQUALS)) {
712 action_error(ctx, "Expected '=' after argument to ct_commit");
715 if (ctx->lexer->token.type == LEX_T_INTEGER) {
716 *mark_value = ntohll(ctx->lexer->token.value.integer);
717 } else if (ctx->lexer->token.type == LEX_T_MASKED_INTEGER) {
718 *mark_value = ntohll(ctx->lexer->token.value.integer);
719 *mark_mask = ntohll(ctx->lexer->token.mask.integer);
721 action_error(ctx, "Expected integer after 'ct_mark='");
724 lexer_get(ctx->lexer);
726 } else if (lexer_match_id(ctx->lexer, "ct_label")) {
727 if (!lexer_match(ctx->lexer, LEX_T_EQUALS)) {
728 action_error(ctx, "Expected '=' after argument to ct_commit");
731 if (ctx->lexer->token.type == LEX_T_INTEGER) {
732 label_value->be64.lo = ctx->lexer->token.value.integer;
733 } else if (ctx->lexer->token.type == LEX_T_MASKED_INTEGER) {
734 /* XXX Technically, ct_label is a 128-bit field. The lexer
735 * only supports 64-bit integers, so that's all we support
736 * here. More work is needed to use parse_int_string()
737 * to support the full 128-bits. */
738 label_value->be64.lo = ctx->lexer->token.value.integer;
739 label_mask->be64.hi = 0;
740 label_mask->be64.lo = ctx->lexer->token.mask.integer;
742 action_error(ctx, "Expected integer after 'ct_label='");
745 lexer_get(ctx->lexer);
748 action_error(ctx, "Expected argument to ct_commit()");
752 if (lexer_match(ctx->lexer, LEX_T_COMMA)) {
753 /* A comma is valid after an argument, but only if another
754 * argument is present (not a closing paren) */
755 if (lexer_lookahead(ctx->lexer) == LEX_T_RPAREN) {
756 action_error(ctx, "Another argument to ct_commit() expected "
766 parse_ct_commit_action(struct action_context *ctx)
768 if (!lexer_match(ctx->lexer, LEX_T_LPAREN)) {
770 emit_ct(ctx, false, true, NULL, NULL, NULL, NULL);
775 * ct_commit(ct_mark=0);
776 * ct_commit(ct_label=0);
777 * ct_commit(ct_mark=0, ct_label=0); */
779 bool set_mark = false;
780 bool set_label = false;
783 ovs_be128 label_value = { .be32 = { 0, }, };
784 ovs_be128 label_mask = OVS_BE128_MAX;
786 while (!lexer_match(ctx->lexer, LEX_T_RPAREN)) {
787 if (!parse_ct_commit_arg(ctx, &set_mark, &mark_value, &mark_mask,
788 &set_label, &label_value, &label_mask)) {
793 emit_ct(ctx, false, true,
794 set_mark ? &mark_value : NULL,
795 set_mark ? &mark_mask : NULL,
796 set_label ? &label_value : NULL,
797 set_label ? &label_mask : NULL);
801 parse_ct_nat(struct action_context *ctx, bool snat)
803 const size_t ct_offset = ctx->ofpacts->size;
804 ofpbuf_pull(ctx->ofpacts, ct_offset);
806 struct ofpact_conntrack *ct = ofpact_put_CT(ctx->ofpacts);
808 if (ctx->ap->cur_ltable < ctx->ap->n_tables) {
809 ct->recirc_table = ctx->ap->first_ptable + ctx->ap->cur_ltable + 1;
812 "\"ct_[sd]nat\" action not allowed in last table.");
817 ct->zone_src.field = mf_from_id(MFF_LOG_SNAT_ZONE);
819 ct->zone_src.field = mf_from_id(MFF_LOG_DNAT_ZONE);
821 ct->zone_src.ofs = 0;
822 ct->zone_src.n_bits = 16;
826 add_prerequisite(ctx, "ip");
828 struct ofpact_nat *nat;
830 nat_offset = ctx->ofpacts->size;
831 ofpbuf_pull(ctx->ofpacts, nat_offset);
833 nat = ofpact_put_NAT(ctx->ofpacts);
835 nat->range_af = AF_UNSPEC;
838 if (lexer_match(ctx->lexer, LEX_T_LPAREN)) {
840 if (ctx->lexer->token.type == LEX_T_INTEGER
841 && ctx->lexer->token.format == LEX_F_IPV4) {
842 ip = ctx->lexer->token.value.ipv4;
844 action_syntax_error(ctx, "invalid ip");
848 nat->range_af = AF_INET;
849 nat->range.addr.ipv4.min = ip;
851 nat->flags |= NX_NAT_F_SRC;
853 nat->flags |= NX_NAT_F_DST;
855 commit = NX_CT_F_COMMIT;
856 lexer_get(ctx->lexer);
857 if (!lexer_match(ctx->lexer, LEX_T_RPAREN)) {
858 action_syntax_error(ctx, "expecting `)'");
863 ctx->ofpacts->header = ofpbuf_push_uninit(ctx->ofpacts, nat_offset);
864 ct = ctx->ofpacts->header;
867 /* XXX: For performance reasons, we try to prevent additional
868 * recirculations. So far, ct_snat which is used in a gateway router
869 * does not need a recirculation. ct_snat(IP) does need a recirculation.
870 * Should we consider a method to let the actions specify whether a action
871 * needs recirculation if there more use cases?. */
872 if (!commit && snat) {
873 ct->recirc_table = NX_CT_RECIRC_NONE;
875 ofpact_finish(ctx->ofpacts, &ct->ofpact);
876 ofpbuf_push_uninit(ctx->ofpacts, ct_offset);
880 parse_action(struct action_context *ctx)
882 if (ctx->lexer->token.type != LEX_T_ID) {
883 action_syntax_error(ctx, NULL);
887 enum lex_type lookahead = lexer_lookahead(ctx->lexer);
888 if (lookahead == LEX_T_EQUALS || lookahead == LEX_T_EXCHANGE
889 || lookahead == LEX_T_LSQUARE) {
890 parse_set_action(ctx);
891 } else if (lexer_match_id(ctx->lexer, "next")) {
892 parse_next_action(ctx);
893 } else if (lexer_match_id(ctx->lexer, "output")) {
894 emit_resubmit(ctx, ctx->ap->output_ptable);
895 } else if (lexer_match_id(ctx->lexer, "ip.ttl")) {
896 if (lexer_match(ctx->lexer, LEX_T_DECREMENT)) {
897 add_prerequisite(ctx, "ip");
898 ofpact_put_DEC_TTL(ctx->ofpacts);
900 action_syntax_error(ctx, "expecting `--'");
902 } else if (lexer_match_id(ctx->lexer, "ct_next")) {
903 emit_ct(ctx, true, false, NULL, NULL, NULL, NULL);
904 } else if (lexer_match_id(ctx->lexer, "ct_commit")) {
905 parse_ct_commit_action(ctx);
906 } else if (lexer_match_id(ctx->lexer, "ct_dnat")) {
907 parse_ct_nat(ctx, false);
908 } else if (lexer_match_id(ctx->lexer, "ct_snat")) {
909 parse_ct_nat(ctx, true);
910 } else if (lexer_match_id(ctx->lexer, "arp")) {
911 parse_arp_action(ctx);
912 } else if (lexer_match_id(ctx->lexer, "get_arp")) {
913 parse_get_arp_action(ctx);
914 } else if (lexer_match_id(ctx->lexer, "put_arp")) {
915 parse_put_arp_action(ctx);
917 action_syntax_error(ctx, "expecting action");
919 if (!lexer_match(ctx->lexer, LEX_T_SEMICOLON)) {
920 action_syntax_error(ctx, "expecting ';'");
926 parse_actions(struct action_context *ctx)
928 /* "drop;" by itself is a valid (empty) set of actions, but it can't be
929 * combined with other actions because that doesn't make sense. */
930 if (ctx->lexer->token.type == LEX_T_ID
931 && !strcmp(ctx->lexer->token.s, "drop")
932 && lexer_lookahead(ctx->lexer) == LEX_T_SEMICOLON) {
933 lexer_get(ctx->lexer); /* Skip "drop". */
934 lexer_get(ctx->lexer); /* Skip ";". */
935 if (ctx->lexer->token.type != LEX_T_END) {
936 action_syntax_error(ctx, "expecting end of input");
941 while (ctx->lexer->token.type != LEX_T_END) {
942 if (!parse_action(ctx)) {
948 /* Parses OVN actions, in the format described for the "actions" column in the
949 * Logical_Flow table in ovn-sb(5), and appends the parsed versions of the
950 * actions to 'ofpacts' as "struct ofpact"s.
952 * 'ap' provides most of the parameters for translation.
954 * Some actions add extra requirements (prerequisites) to the flow's match. If
955 * so, this function sets '*prereqsp' to the actions' prerequisites; otherwise,
956 * it sets '*prereqsp' to NULL. The caller owns '*prereqsp' and must
957 * eventually free it.
959 * Returns NULL on success, otherwise a malloc()'d error message that the
960 * caller must free. On failure, 'ofpacts' has the same contents and
961 * '*prereqsp' is set to NULL, but some tokens may have been consumed from
964 char * OVS_WARN_UNUSED_RESULT
965 actions_parse(struct lexer *lexer, const struct action_params *ap,
966 struct ofpbuf *ofpacts, struct expr **prereqsp)
968 size_t ofpacts_start = ofpacts->size;
970 struct action_context ctx = {
980 *prereqsp = ctx.prereqs;
983 ofpacts->size = ofpacts_start;
984 expr_destroy(ctx.prereqs);
990 /* Like actions_parse(), but the actions are taken from 's'. */
991 char * OVS_WARN_UNUSED_RESULT
992 actions_parse_string(const char *s, const struct action_params *ap,
993 struct ofpbuf *ofpacts, struct expr **prereqsp)
998 lexer_init(&lexer, s);
1000 error = actions_parse(&lexer, ap, ofpacts, prereqsp);
1001 lexer_destroy(&lexer);