X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fofp-util.h;h=b110d71667711abf53239bb0be779b0c35719dd0;hb=df2c07f4338faac04f4969f243fe4e8083b309ac;hp=2ab599c84c60c6d6dbfbfa0f035eff3f0191199e;hpb=76c93b227414f893f54c5ec52155471601713fe0;p=openvswitch diff --git a/lib/ofp-util.h b/lib/ofp-util.h index 2ab599c8..b110d716 100644 --- a/lib/ofp-util.h +++ b/lib/ofp-util.h @@ -31,7 +31,7 @@ struct ofpbuf; /* Basic decoding and length validation of OpenFlow messages. */ enum ofputil_msg_code { - OFPUTIL_INVALID, + OFPUTIL_MSG_INVALID, /* OFPT_* messages. */ OFPUTIL_OFPT_HELLO, @@ -92,6 +92,7 @@ int ofputil_decode_msg_type(const struct ofp_header *, const struct ofputil_msg_type **); enum ofputil_msg_code ofputil_msg_type_code(const struct ofputil_msg_type *); const char *ofputil_msg_type_name(const struct ofputil_msg_type *); +int ofputil_check_output_port(uint16_t ofp_port, int max_ports); /* Converting OFPFW_NW_SRC_MASK and OFPFW_NW_DST_MASK wildcard bit counts to * and from IP bitmasks. */ @@ -121,7 +122,7 @@ struct ofpbuf *ofputil_make_set_flow_format(enum nx_flow_format); struct ofpbuf *ofputil_make_flow_mod_table_id(bool flow_mod_table_id); /* Flow format independent flow_mod. */ -struct flow_mod { +struct ofputil_flow_mod { struct cls_rule cr; ovs_be64 cookie; uint8_t table_id; @@ -135,24 +136,24 @@ struct flow_mod { size_t n_actions; }; -int ofputil_decode_flow_mod(struct flow_mod *, const struct ofp_header *, - bool flow_mod_table_id); -struct ofpbuf *ofputil_encode_flow_mod(const struct flow_mod *, +int ofputil_decode_flow_mod(struct ofputil_flow_mod *, + const struct ofp_header *, bool flow_mod_table_id); +struct ofpbuf *ofputil_encode_flow_mod(const struct ofputil_flow_mod *, enum nx_flow_format, bool flow_mod_table_id); /* Flow stats or aggregate stats request, independent of flow format. */ -struct flow_stats_request { +struct ofputil_flow_stats_request { bool aggregate; /* Aggregate results? */ struct cls_rule match; uint16_t out_port; uint8_t table_id; }; -int ofputil_decode_flow_stats_request(struct flow_stats_request *, +int ofputil_decode_flow_stats_request(struct ofputil_flow_stats_request *, const struct ofp_header *); struct ofpbuf *ofputil_encode_flow_stats_request( - const struct flow_stats_request *, enum nx_flow_format); + const struct ofputil_flow_stats_request *, enum nx_flow_format); /* Flow stats reply, independent of flow format. */ struct ofputil_flow_stats { @@ -163,19 +164,21 @@ struct ofputil_flow_stats { uint32_t duration_nsec; uint16_t idle_timeout; uint16_t hard_timeout; - uint64_t packet_count; - uint64_t byte_count; + 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; }; int ofputil_decode_flow_stats_reply(struct ofputil_flow_stats *, struct ofpbuf *msg); +void ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *, + struct list *replies); /* Aggregate stats reply, independent of flow format. */ struct ofputil_aggregate_stats { - uint64_t packet_count; - uint64_t byte_count; + uint64_t packet_count; /* Packet count, UINT64_MAX if unknown. */ + uint64_t byte_count; /* Byte count, UINT64_MAX if unknown. */ uint32_t flow_count; }; @@ -191,8 +194,8 @@ struct ofputil_flow_removed { uint32_t duration_sec; uint32_t duration_nsec; uint16_t idle_timeout; - uint64_t packet_count; - uint64_t byte_count; + uint64_t packet_count; /* Packet count, UINT64_MAX if unknown. */ + uint64_t byte_count; /* Byte count, UINT64_MAX if unknown. */ }; int ofputil_decode_flow_removed(struct ofputil_flow_removed *, @@ -273,15 +276,75 @@ struct ofpbuf *make_echo_reply(const struct ofp_header *rq); /* Actions. */ +enum ofputil_action_code { + /* OFPAT_* actions. */ + OFPUTIL_OFPAT_OUTPUT, + OFPUTIL_OFPAT_SET_VLAN_VID, + OFPUTIL_OFPAT_SET_VLAN_PCP, + OFPUTIL_OFPAT_STRIP_VLAN, + OFPUTIL_OFPAT_SET_DL_SRC, + OFPUTIL_OFPAT_SET_DL_DST, + OFPUTIL_OFPAT_SET_NW_SRC, + OFPUTIL_OFPAT_SET_NW_DST, + OFPUTIL_OFPAT_SET_NW_TOS, + OFPUTIL_OFPAT_SET_TP_SRC, + OFPUTIL_OFPAT_SET_TP_DST, + OFPUTIL_OFPAT_ENQUEUE, + + /* NXAST_* actions. */ + OFPUTIL_NXAST_RESUBMIT, + OFPUTIL_NXAST_SET_TUNNEL, + OFPUTIL_NXAST_SET_QUEUE, + OFPUTIL_NXAST_POP_QUEUE, + OFPUTIL_NXAST_REG_MOVE, + OFPUTIL_NXAST_REG_LOAD, + OFPUTIL_NXAST_NOTE, + OFPUTIL_NXAST_SET_TUNNEL64, + OFPUTIL_NXAST_MULTIPATH, + OFPUTIL_NXAST_AUTOPATH, + OFPUTIL_NXAST_BUNDLE, + OFPUTIL_NXAST_BUNDLE_LOAD, + OFPUTIL_NXAST_RESUBMIT_TABLE, + OFPUTIL_NXAST_OUTPUT_REG +}; + +int ofputil_decode_action(const union ofp_action *); +enum ofputil_action_code ofputil_decode_action_unsafe( + const union ofp_action *); + #define OFP_ACTION_ALIGN 8 /* Alignment of ofp_actions. */ -struct actions_iterator { - const union ofp_action *pos, *end; -}; -const union ofp_action *actions_first(struct actions_iterator *, - const union ofp_action *, - size_t n_actions); -const union ofp_action *actions_next(struct actions_iterator *); +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))) int validate_actions(const union ofp_action *, size_t n_actions, const struct flow *, int max_ports); @@ -289,6 +352,10 @@ bool action_outputs_to_port(const union ofp_action *, ovs_be16 port); int ofputil_pull_actions(struct ofpbuf *, unsigned int actions_len, union ofp_action **, size_t *); + +bool ofputil_actions_equal(const union ofp_action *a, size_t n_a, + const union ofp_action *b, size_t n_b); +union ofp_action *ofputil_actions_clone(const union ofp_action *, size_t n); /* OpenFlow vendors. *