#include <stddef.h>
#include <stdint.h>
#include "classifier.h"
+#include "compiler.h"
#include "flow.h"
#include "netdev.h"
#include "openflow/nicira-ext.h"
uint32_t buffer_id;
uint16_t out_port;
uint16_t flags;
- union ofp_action *actions;
- size_t n_actions;
+ struct ofpact *ofpacts; /* Series of "struct ofpact"s. */
+ size_t ofpacts_len; /* Length of ofpacts, in bytes. */
};
enum ofperr ofputil_decode_flow_mod(struct ofputil_flow_mod *,
const struct ofp_header *,
- enum ofputil_protocol);
+ enum ofputil_protocol,
+ struct ofpbuf *ofpacts);
struct ofpbuf *ofputil_encode_flow_mod(const struct ofputil_flow_mod *,
enum ofputil_protocol);
int hard_age; /* Seconds since last change, -1 if unknown. */
uint64_t packet_count; /* Packet count, UINT64_MAX if unknown. */
uint64_t byte_count; /* Byte count, UINT64_MAX if unknown. */
- union ofp_action *actions;
- size_t n_actions;
+ struct ofpact *ofpacts;
+ size_t ofpacts_len;
};
int ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *,
struct ofpbuf *msg,
- bool flow_age_extension);
+ bool flow_age_extension,
+ struct ofpbuf *ofpacts);
void ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *,
struct list *replies);
struct flow_metadata fmd; /* Metadata at creation time. */
};
-int ofputil_decode_packet_in(struct ofputil_packet_in *,
- const struct ofp_header *);
+enum ofperr ofputil_decode_packet_in(struct ofputil_packet_in *,
+ const struct ofp_header *);
struct ofpbuf *ofputil_encode_packet_in(const struct ofputil_packet_in *,
enum nx_packet_in_format);
size_t packet_len; /* Length of packet data in bytes. */
uint32_t buffer_id; /* Buffer id or UINT32_MAX if no buffer. */
uint16_t in_port; /* Packet's input port. */
- union ofp_action *actions; /* Actions. */
- size_t n_actions; /* Number of elements in 'actions' array. */
+ struct ofpact *ofpacts; /* Actions. */
+ size_t ofpacts_len; /* Size of ofpacts in bytes. */
};
enum ofperr ofputil_decode_packet_out(struct ofputil_packet_out *,
- const struct ofp_packet_out *);
+ const struct ofp_packet_out *,
+ struct ofpbuf *ofpacts);
struct ofpbuf *ofputil_encode_packet_out(const struct ofputil_packet_out *);
enum ofputil_port_config {
const struct ofp_stats_msg *request,
struct ofpbuf **);
+void ofputil_put_stats_header(ovs_be32 xid, uint8_t ofp_type,
+ ovs_be16 ofpst_type, ovs_be32 nxst_subtype,
+ struct ofpbuf *);
+
void ofputil_start_stats_reply(const struct ofp_stats_msg *request,
struct list *);
struct ofpbuf *ofputil_reserve_stats_reply(size_t len, struct list *);
void *ofputil_append_stats_reply(size_t len, struct list *);
+void ofputil_postappend_stats_reply(size_t start_ofs, struct list *);
void ofputil_append_port_desc_stats_reply(uint8_t ofp_version,
const struct ofputil_phy_port *pp,
const void *ofputil_nxstats_body(const struct ofp_header *);
size_t ofputil_nxstats_body_len(const struct ofp_header *);
-struct ofpbuf *make_flow_mod(uint16_t command, const struct cls_rule *,
- size_t actions_len);
-struct ofpbuf *make_add_flow(const struct cls_rule *, uint32_t buffer_id,
- uint16_t max_idle, size_t actions_len);
-struct ofpbuf *make_del_flow(const struct cls_rule *);
-struct ofpbuf *make_add_simple_flow(const struct cls_rule *,
- uint32_t buffer_id, uint16_t out_port,
- uint16_t max_idle);
-struct ofpbuf *make_packet_in(uint32_t buffer_id, uint16_t in_port,
- uint8_t reason,
- const struct ofpbuf *payload, int max_send_len);
+/* */
struct ofpbuf *make_echo_request(void);
struct ofpbuf *make_echo_reply(const struct ofp_header *rq);
*
* (The above list helps developers who want to "grep" for these definitions.)
*/
-enum ofputil_action_code {
-#define OFPAT10_ACTION(ENUM, STRUCT, NAME) OFPUTIL_##ENUM,
+enum OVS_PACKED_ENUM ofputil_action_code {
+ OFPUTIL_ACTION_INVALID,
+#define OFPAT10_ACTION(ENUM, STRUCT, NAME) OFPUTIL_##ENUM,
+#define OFPAT11_ACTION(ENUM, STRUCT, NAME) OFPUTIL_##ENUM,
#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) OFPUTIL_##ENUM,
#include "ofp-util.def"
};
/* The number of values of "enum ofputil_action_code". */
enum {
-#define OFPAT10_ACTION(ENUM, STRUCT, NAME) + 1
+#define OFPAT10_ACTION(ENUM, STRUCT, NAME) + 1
+#define OFPAT11_ACTION(ENUM, STRUCT, NAME) + 1
#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) + 1
- OFPUTIL_N_ACTIONS = 0
+ OFPUTIL_N_ACTIONS = 1
#include "ofp-util.def"
};
-int ofputil_decode_action(const union ofp_action *);
-enum ofputil_action_code ofputil_decode_action_unsafe(
- const union ofp_action *);
-
int ofputil_action_code_from_name(const char *);
void *ofputil_put_action(enum ofputil_action_code, struct ofpbuf *buf);
#define OFPAT10_ACTION(ENUM, STRUCT, NAME) \
void ofputil_init_##ENUM(struct STRUCT *); \
struct STRUCT *ofputil_put_##ENUM(struct ofpbuf *);
+#define OFPAT11_ACTION(ENUM, STRUCT, NAME) \
+ void ofputil_init_##ENUM(struct STRUCT *); \
+ struct STRUCT *ofputil_put_##ENUM(struct ofpbuf *);
#define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \
void ofputil_init_##ENUM(struct STRUCT *); \
struct STRUCT *ofputil_put_##ENUM(struct ofpbuf *);
#define OFP_ACTION_ALIGN 8 /* Alignment of ofp_actions. */
-static inline union ofp_action *
-ofputil_action_next(const union ofp_action *a)
-{
- return ((union ofp_action *) (void *)
- ((uint8_t *) a + ntohs(a->header.len)));
-}
-
-static inline bool
-ofputil_action_is_valid(const union ofp_action *a, size_t n_actions)
-{
- uint16_t len = ntohs(a->header.len);
- return (!(len % OFP_ACTION_ALIGN)
- && len >= sizeof *a
- && len / sizeof *a <= n_actions);
-}
-
-/* This macro is careful to check for actions with bad lengths. */
-#define OFPUTIL_ACTION_FOR_EACH(ITER, LEFT, ACTIONS, N_ACTIONS) \
- for ((ITER) = (ACTIONS), (LEFT) = (N_ACTIONS); \
- (LEFT) > 0 && ofputil_action_is_valid(ITER, LEFT); \
- ((LEFT) -= ntohs((ITER)->header.len) / sizeof(union ofp_action), \
- (ITER) = ofputil_action_next(ITER)))
-
-/* This macro does not check for actions with bad lengths. It should only be
- * used with actions from trusted sources or with actions that have already
- * been validated (e.g. with OFPUTIL_ACTION_FOR_EACH). */
-#define OFPUTIL_ACTION_FOR_EACH_UNSAFE(ITER, LEFT, ACTIONS, N_ACTIONS) \
- for ((ITER) = (ACTIONS), (LEFT) = (N_ACTIONS); \
- (LEFT) > 0; \
- ((LEFT) -= ntohs((ITER)->header.len) / sizeof(union ofp_action), \
- (ITER) = ofputil_action_next(ITER)))
-
enum ofperr validate_actions(const union ofp_action *, size_t n_actions,
const struct flow *, int max_ports);
bool action_outputs_to_port(const union ofp_action *, ovs_be16 port);