ofp-actions: Improve explanation of 'compat' member in struct ofpact.
[sliver-openvswitch.git] / lib / ofp-actions.h
index 59b9846..46e2d79 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Nicira Networks.
+ * Copyright (c) 2012 Nicira, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -69,7 +69,7 @@
     DEFINE_OFPACT(SET_L4_DST_PORT, ofpact_l4_port,       ofpact)    \
     DEFINE_OFPACT(REG_MOVE,        ofpact_reg_move,      ofpact)    \
     DEFINE_OFPACT(REG_LOAD,        ofpact_reg_load,      ofpact)    \
-    DEFINE_OFPACT(DEC_TTL,         ofpact_null,          ofpact)    \
+    DEFINE_OFPACT(DEC_TTL,         ofpact_cnt_ids,       cnt_ids)   \
                                                                     \
     /* Metadata. */                                                 \
     DEFINE_OFPACT(SET_TUNNEL,      ofpact_tunnel,        ofpact)    \
@@ -108,7 +108,31 @@ enum {
  *
  * Each action is a structure "struct ofpact_*" that begins with "struct
  * ofpact", usually followed by other data that describes the action.  Actions
- * are padded out to a multiple of OFPACT_ALIGNTO bytes in length. */
+ * are padded out to a multiple of OFPACT_ALIGNTO bytes in length.
+ *
+ * The 'compat' member is special:
+ *
+ *     - Most "struct ofpact"s correspond to one particular kind of OpenFlow
+ *       action, at least in a given OpenFlow version.  For example,
+ *       OFPACT_SET_VLAN_VID corresponds to OFPAT10_SET_VLAN_VID in OpenFlow
+ *       1.0.
+ *
+ *       For such actions, the 'compat' member is not meaningful and generally
+ *       should be zero.
+ *
+ *     - A few "struct ofpact"s correspond to multiple OpenFlow actions.  For
+ *       example, OFPACT_SET_TUNNEL can be NXAST_SET_TUNNEL or
+ *       NXAST_SET_TUNNEL64.  In these cases, if the "struct ofpact" originated
+ *       from OpenFlow, then we want to make sure that, if it gets translated
+ *       back to OpenFlow later, it is translated back to the same action type.
+ *       (Otherwise, we'd violate the promise made in DESIGN, in the "Action
+ *       Reproduction" section.)
+ *
+ *       For such actions, the 'compat' member should be the original action
+ *       type.  (If the action didn't originate from OpenFlow, then setting
+ *       'compat' to zero should be fine: code to translate the ofpact to
+ *       OpenFlow must tolerate this case.)
+ */
 struct ofpact {
     enum ofpact_type type;      /* OFPACT_*. */
     enum ofputil_action_code compat; /* Original type when added, if any. */
@@ -145,7 +169,7 @@ ofpact_end(const struct ofpact *ofpacts, size_t ofpacts_len)
 \f
 /* Action structure for each OFPACT_*. */
 
-/* OFPACT_STRIP_VLAN, OFPACT_DEC_TTL, OFPACT_POP_QUEUE, OFPACT_EXIT.
+/* OFPACT_STRIP_VLAN, OFPACT_POP_QUEUE, OFPACT_EXIT.
  *
  * Used for OFPAT10_STRIP_VLAN, NXAST_DEC_TTL, NXAST_POP_QUEUE, NXAST_EXIT.
  *
@@ -271,11 +295,11 @@ struct ofpact_reg_move {
 
 /* OFPACT_REG_LOAD.
  *
- * Used for NXAST_REG_LOAD. */
+ * Used for NXAST_REG_LOAD, OFPAT12_SET_FIELD. */
 struct ofpact_reg_load {
     struct ofpact ofpact;
     struct mf_subfield dst;
-    uint64_t value;
+    union mf_subvalue subvalue; /* Least-significant bits are used. */
 };
 
 /* OFPACT_SET_TUNNEL.
@@ -380,16 +404,39 @@ struct ofpact_note {
     uint8_t data[];
 };
 
+/* OFPACT_DEC_TTL.
+ *
+ * Used for NXAST_DEC_TTL and NXAST_DEC_TTL_CNT_IDS. */
+struct ofpact_cnt_ids {
+    struct ofpact ofpact;
+
+    /* Controller ids. */
+    unsigned int n_controllers;
+    uint16_t cnt_ids[];
+
+};
+
 /* Converting OpenFlow to ofpacts. */
-enum ofperr ofpacts_pull_openflow(struct ofpbuf *openflow,
-                                  unsigned int actions_len,
-                                  struct ofpbuf *ofpacts);
+enum ofperr ofpacts_pull_openflow10(struct ofpbuf *openflow,
+                                    unsigned int actions_len,
+                                    struct ofpbuf *ofpacts);
+enum ofperr ofpacts_pull_openflow11_actions(struct ofpbuf *openflow,
+                                            unsigned int actions_len,
+                                            struct ofpbuf *ofpacts);
+enum ofperr ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow,
+                                                 unsigned int instructions_len,
+                                                 struct ofpbuf *ofpacts);
 enum ofperr ofpacts_check(const struct ofpact[], size_t ofpacts_len,
                           const struct flow *, int max_ports);
 
 /* Converting ofpacts to OpenFlow. */
-void ofpacts_to_openflow(const struct ofpact[], size_t ofpacts_len,
-                         struct ofpbuf *openflow);
+void ofpacts_put_openflow10(const struct ofpact[], size_t ofpacts_len,
+                            struct ofpbuf *openflow);
+size_t ofpacts_put_openflow11_actions(const struct ofpact[], size_t ofpacts_len,
+                                      struct ofpbuf *openflow);
+void ofpacts_put_openflow11_instructions(const struct ofpact[],
+                                         size_t ofpacts_len,
+                                         struct ofpbuf *openflow);
 
 /* Working with ofpacts. */
 bool ofpacts_output_to_port(const struct ofpact[], size_t ofpacts_len,
@@ -482,4 +529,44 @@ OFPACTS
 void ofpact_update_len(struct ofpbuf *, struct ofpact *);
 void ofpact_pad(struct ofpbuf *);
 
+/* OpenFlow 1.1 instructions.
+ * The order is sorted in execution order. Not in the value of OFPIT11_xxx.
+ * It is enforced on parser from text string.
+ */
+#define OVS_INSTRUCTIONS                                    \
+    DEFINE_INST(OFPIT11_APPLY_ACTIONS,                      \
+                ofp11_instruction_actions,        true,     \
+                "apply_actions")                            \
+                                                            \
+    DEFINE_INST(OFPIT11_CLEAR_ACTIONS,                      \
+                ofp11_instruction,                false,    \
+                "clear_actions")                            \
+                                                            \
+    DEFINE_INST(OFPIT11_WRITE_ACTIONS,                      \
+                ofp11_instruction_actions,        true,     \
+                "write_actions")                            \
+                                                            \
+    DEFINE_INST(OFPIT11_WRITE_METADATA,                     \
+                ofp11_instruction_write_metadata, false,    \
+                "write_metadata")                           \
+                                                            \
+    DEFINE_INST(OFPIT11_GOTO_TABLE,                         \
+                ofp11_instruction_goto_table,     false,    \
+                "goto_table")
+
+enum ovs_instruction_type {
+#define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) OVSINST_##ENUM,
+    OVS_INSTRUCTIONS
+#undef DEFINE_INST
+};
+
+enum {
+#define DEFINE_INST(ENUM, STRUCT, EXTENSIBLE, NAME) + 1
+    N_OVS_INSTRUCTIONS = OVS_INSTRUCTIONS
+#undef DEFINE_INST
+};
+
+const char *ofpact_instruction_name_from_type(enum ovs_instruction_type type);
+int ofpact_instruction_type_from_name(const char *name);
+
 #endif /* ofp-actions.h */