Allow OFPACT_SET_IP_DSCP to act on both IPv4 and IPv6 packets.
[sliver-openvswitch.git] / lib / ofp-actions.h
index af63833..25e95aa 100644 (file)
@@ -17,6 +17,7 @@
 #ifndef OFP_ACTIONS_H
 #define OFP_ACTIONS_H 1
 
+#include <stddef.h>
 #include <stdint.h>
 #include "meta-flow.h"
 #include "ofp-errors.h"
@@ -51,6 +52,7 @@
 #define OFPACTS                                                     \
     /* Output. */                                                   \
     DEFINE_OFPACT(OUTPUT,          ofpact_output,        ofpact)    \
+    DEFINE_OFPACT(GROUP,           ofpact_group,         ofpact)    \
     DEFINE_OFPACT(CONTROLLER,      ofpact_controller,    ofpact)    \
     DEFINE_OFPACT(ENQUEUE,         ofpact_enqueue,       ofpact)    \
     DEFINE_OFPACT(OUTPUT_REG,      ofpact_output_reg,    ofpact)    \
@@ -65,7 +67,7 @@
     DEFINE_OFPACT(SET_ETH_DST,     ofpact_mac,           ofpact)    \
     DEFINE_OFPACT(SET_IPV4_SRC,    ofpact_ipv4,          ofpact)    \
     DEFINE_OFPACT(SET_IPV4_DST,    ofpact_ipv4,          ofpact)    \
-    DEFINE_OFPACT(SET_IPV4_DSCP,   ofpact_dscp,          ofpact)    \
+    DEFINE_OFPACT(SET_IP_DSCP,     ofpact_dscp,          ofpact)    \
     DEFINE_OFPACT(SET_L4_SRC_PORT, ofpact_l4_port,       ofpact)    \
     DEFINE_OFPACT(SET_L4_DST_PORT, ofpact_l4_port,       ofpact)    \
     DEFINE_OFPACT(REG_MOVE,        ofpact_reg_move,      ofpact)    \
     DEFINE_OFPACT(SAMPLE,          ofpact_sample,        ofpact)    \
                                                                     \
     /* Instructions */                                              \
-    /* XXX Write-Actions */                                         \
-    DEFINE_OFPACT(WRITE_METADATA,  ofpact_metadata,      ofpact)    \
+    DEFINE_OFPACT(METER,           ofpact_meter,         ofpact)    \
     DEFINE_OFPACT(CLEAR_ACTIONS,   ofpact_null,          ofpact)    \
+    DEFINE_OFPACT(WRITE_ACTIONS,   ofpact_nest,          ofpact)    \
+    DEFINE_OFPACT(WRITE_METADATA,  ofpact_metadata,      ofpact)    \
     DEFINE_OFPACT(GOTO_TABLE,      ofpact_goto_table,    ofpact)
 
 /* enum ofpact_type, with a member OFPACT_<ENUM> for each action. */
@@ -282,7 +285,7 @@ struct ofpact_ipv4 {
     ovs_be32 ipv4;
 };
 
-/* OFPACT_SET_IPV4_DSCP.
+/* OFPACT_SET_IP_DSCP.
  *
  * Used for OFPAT10_SET_NW_TOS. */
 struct ofpact_dscp {
@@ -324,12 +327,26 @@ struct ofpact_reg_load {
     union mf_subvalue subvalue; /* Least-significant bits are used. */
 };
 
+/* The position in the packet at which to insert an MPLS header.
+ *
+ * Used NXAST_PUSH_MPLS, OFPAT11_PUSH_MPLS. */
+enum ofpact_mpls_position {
+    /* Add the MPLS LSE after the Ethernet header but before any VLAN tags.
+     * OpenFlow 1.3+ requires this behavior. */
+   OFPACT_MPLS_BEFORE_VLAN,
+
+   /* Add the MPLS LSE after the Ethernet header and any VLAN tags.
+    * OpenFlow 1.1 and 1.2 require this behavior. */
+   OFPACT_MPLS_AFTER_VLAN
+};
+
 /* OFPACT_PUSH_VLAN/MPLS/PBB
  *
  * Used for NXAST_PUSH_MPLS, OFPAT11_PUSH_MPLS. */
 struct ofpact_push_mpls {
     struct ofpact ofpact;
     ovs_be16 ethertype;
+    enum ofpact_mpls_position position;
 };
 
 /* OFPACT_POP_MPLS
@@ -374,6 +391,33 @@ struct ofpact_metadata {
     ovs_be64 mask;
 };
 
+/* OFPACT_METER.
+ *
+ * Used for OFPIT13_METER. */
+struct ofpact_meter {
+    struct ofpact ofpact;
+    uint32_t meter_id;
+};
+
+/* OFPACT_WRITE_ACTIONS.
+ *
+ * Used for OFPIT11_WRITE_ACTIONS. */
+struct ofpact_nest {
+    struct ofpact ofpact;
+    uint8_t pad[OFPACT_ALIGN(sizeof(struct ofpact)) - sizeof(struct ofpact)];
+    struct ofpact actions[];
+};
+BUILD_ASSERT_DECL(offsetof(struct ofpact_nest, actions) == OFPACT_ALIGNTO);
+
+static inline size_t
+ofpact_nest_get_action_len(const struct ofpact_nest *on)
+{
+    return on->ofpact.len - offsetof(struct ofpact_nest, actions);
+}
+
+void ofpacts_execute_action_set(struct ofpbuf *action_list,
+                                const struct ofpbuf *action_set);
+
 /* OFPACT_RESUBMIT.
  *
  * Used for NXAST_RESUBMIT, NXAST_RESUBMIT_TABLE. */
@@ -405,7 +449,7 @@ struct ofpact_learn {
     uint16_t hard_timeout;      /* Max time before discarding (seconds). */
     uint16_t priority;          /* Priority level of flow entry. */
     uint64_t cookie;            /* Cookie for new flow. */
-    uint16_t flags;             /* Either 0 or OFPFF_SEND_FLOW_REM. */
+    enum ofputil_flow_mod_flags flags;
     uint8_t table_id;           /* Table to insert flow entry. */
     uint16_t fin_idle_timeout;  /* Idle timeout after FIN, if nonzero. */
     uint16_t fin_hard_timeout;  /* Hard timeout after FIN, if nonzero. */
@@ -481,19 +525,29 @@ struct ofpact_goto_table {
     uint8_t table_id;
 };
 
+/* OFPACT_GROUP.
+ *
+ * Used for OFPAT11_GROUP. */
+struct ofpact_group {
+    struct ofpact ofpact;
+    uint32_t group_id;
+};
+
 /* Converting OpenFlow to 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,
+                                            enum ofp_version version,
                                             unsigned int actions_len,
                                             struct ofpbuf *ofpacts);
 enum ofperr ofpacts_pull_openflow11_instructions(struct ofpbuf *openflow,
+                                                 enum ofp_version version,
                                                  unsigned int instructions_len,
-                                                 uint8_t table_id,
                                                  struct ofpbuf *ofpacts);
 enum ofperr ofpacts_check(const struct ofpact[], size_t ofpacts_len,
-                          struct flow *, ofp_port_t max_ports);
+                          struct flow *, ofp_port_t max_ports,
+                          uint8_t table_id);
 enum ofperr ofpacts_verify(const struct ofpact ofpacts[], size_t ofpacts_len);
 
 /* Converting ofpacts to OpenFlow. */
@@ -508,8 +562,11 @@ void ofpacts_put_openflow11_instructions(const struct ofpact[],
 /* Working with ofpacts. */
 bool ofpacts_output_to_port(const struct ofpact[], size_t ofpacts_len,
                             ofp_port_t port);
+bool ofpacts_output_to_group(const struct ofpact[], size_t ofpacts_len,
+                             uint32_t group_id);
 bool ofpacts_equal(const struct ofpact a[], size_t a_len,
                    const struct ofpact b[], size_t b_len);
+uint32_t ofpacts_get_meter(const struct ofpact[], size_t ofpacts_len);
 
 /* Formatting ofpacts.
  *
@@ -573,7 +630,7 @@ void *ofpact_put(struct ofpbuf *, enum ofpact_type, size_t len);
     ofpact_get_##ENUM(const struct ofpact *ofpact)                      \
     {                                                                   \
         ovs_assert(ofpact->type == OFPACT_##ENUM);                      \
-        return (struct STRUCT *) ofpact;                                \
+        return ALIGNED_CAST(struct STRUCT *, ofpact);                   \
     }                                                                   \
                                                                         \
     static inline struct STRUCT *                                       \
@@ -601,6 +658,10 @@ void ofpact_pad(struct ofpbuf *);
  * It is enforced on parser from text string.
  */
 #define OVS_INSTRUCTIONS                                    \
+    DEFINE_INST(OFPIT13_METER,                              \
+                ofp13_instruction_meter,          false,    \
+                "meter")                                    \
+                                                            \
     DEFINE_INST(OFPIT11_APPLY_ACTIONS,                      \
                 ofp11_instruction_actions,        true,     \
                 "apply_actions")                            \
@@ -633,20 +694,11 @@ enum {
 #undef DEFINE_INST
 };
 
-
-static inline bool
-ofpact_is_instruction(const struct ofpact *a)
-{
-    /* XXX Write-Actions */
-    return a->type == OFPACT_CLEAR_ACTIONS
-        || a->type == OFPACT_WRITE_METADATA
-        || a->type == OFPACT_GOTO_TABLE;
-}
-
-const char *ofpact_instruction_name_from_type(enum ovs_instruction_type type);
-int ofpact_instruction_type_from_name(const char *name);
+const char *ovs_instruction_name_from_type(enum ovs_instruction_type type);
+int ovs_instruction_type_from_name(const char *name);
+enum ovs_instruction_type ovs_instruction_type_from_ofpact_type(
+    enum ofpact_type);
 
 void ofpact_set_field_init(struct ofpact_reg_load *load,
                            const struct mf_field *mf, const void *src);
-
 #endif /* ofp-actions.h */