X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fofp-actions.h;h=1db3bdee23e85e960b6554638a43d061504c8989;hb=ea96b766c2092609fe850e9d5f6392252a2f5fa2;hp=c62020de19dadaec586d4e11c8b76f604de2b62e;hpb=b19e8793390f788a4e394d049ea64ce0161ad923;p=sliver-openvswitch.git diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h index c62020de1..1db3bdee2 100644 --- a/lib/ofp-actions.h +++ b/lib/ofp-actions.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012 Nicira, Inc. + * Copyright (c) 2012, 2013, 2014 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,7 @@ #ifndef OFP_ACTIONS_H #define OFP_ACTIONS_H 1 +#include #include #include "meta-flow.h" #include "ofp-errors.h" @@ -51,25 +52,38 @@ #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) \ DEFINE_OFPACT(BUNDLE, ofpact_bundle, slaves) \ \ /* Header changes. */ \ + DEFINE_OFPACT(SET_FIELD, ofpact_set_field, ofpact) \ DEFINE_OFPACT(SET_VLAN_VID, ofpact_vlan_vid, ofpact) \ DEFINE_OFPACT(SET_VLAN_PCP, ofpact_vlan_pcp, ofpact) \ DEFINE_OFPACT(STRIP_VLAN, ofpact_null, ofpact) \ + DEFINE_OFPACT(PUSH_VLAN, ofpact_null, ofpact) \ DEFINE_OFPACT(SET_ETH_SRC, ofpact_mac, ofpact) \ 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_IP_ECN, ofpact_ecn, ofpact) \ + DEFINE_OFPACT(SET_IP_TTL, ofpact_ip_ttl, 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(REG_LOAD, ofpact_reg_load, ofpact) \ + DEFINE_OFPACT(STACK_PUSH, ofpact_stack, ofpact) \ + DEFINE_OFPACT(STACK_POP, ofpact_stack, ofpact) \ DEFINE_OFPACT(DEC_TTL, ofpact_cnt_ids, cnt_ids) \ + DEFINE_OFPACT(SET_MPLS_LABEL, ofpact_mpls_label, ofpact) \ + DEFINE_OFPACT(SET_MPLS_TC, ofpact_mpls_tc, ofpact) \ + DEFINE_OFPACT(SET_MPLS_TTL, ofpact_mpls_ttl, ofpact) \ + DEFINE_OFPACT(DEC_MPLS_TTL, ofpact_null, ofpact) \ + DEFINE_OFPACT(PUSH_MPLS, ofpact_push_mpls, ofpact) \ + DEFINE_OFPACT(POP_MPLS, ofpact_pop_mpls, ofpact) \ \ /* Metadata. */ \ DEFINE_OFPACT(SET_TUNNEL, ofpact_tunnel, ofpact) \ @@ -83,15 +97,17 @@ \ /* Arithmetic. */ \ DEFINE_OFPACT(MULTIPATH, ofpact_multipath, ofpact) \ - DEFINE_OFPACT(AUTOPATH, ofpact_autopath, ofpact) \ \ /* Other. */ \ DEFINE_OFPACT(NOTE, ofpact_note, data) \ DEFINE_OFPACT(EXIT, ofpact_null, ofpact) \ + DEFINE_OFPACT(SAMPLE, ofpact_sample, ofpact) \ \ /* Instructions */ \ - /* TODO:XXX Write-Actions, Write-Metadata */ \ + 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_ for each action. */ @@ -176,8 +192,8 @@ ofpact_end(const struct ofpact *ofpacts, size_t ofpacts_len) /* OFPACT_STRIP_VLAN, OFPACT_POP_QUEUE, OFPACT_EXIT, OFPACT_CLEAR_ACTIONS. * - * Used for OFPAT10_STRIP_VLAN, NXAST_DEC_TTL, NXAST_POP_QUEUE, NXAST_EXIT, - * OFPIT11_CLEAR_ACTIONS. + * Used for OFPAT10_STRIP_VLAN, NXAST_POP_QUEUE, NXAST_EXIT, + * OFPAT11_POP_VLAN, OFPIT11_CLEAR_ACTIONS. * * Action structure for actions that do not have any extra data beyond the * action type. */ @@ -190,7 +206,7 @@ struct ofpact_null { * Used for OFPAT10_OUTPUT. */ struct ofpact_output { struct ofpact ofpact; - uint16_t port; /* Output port. */ + ofp_port_t port; /* Output port. */ uint16_t max_len; /* Max send len, for port OFPP_CONTROLLER. */ }; @@ -209,7 +225,7 @@ struct ofpact_controller { * Used for OFPAT10_ENQUEUE. */ struct ofpact_enqueue { struct ofpact ofpact; - uint16_t port; + ofp_port_t port; uint32_t queue; }; @@ -239,23 +255,37 @@ struct ofpact_bundle { /* Slaves for output. */ unsigned int n_slaves; - uint16_t slaves[]; + ofp_port_t slaves[]; }; /* OFPACT_SET_VLAN_VID. * - * Used for OFPAT10_SET_VLAN_VID. */ + * We keep track if vlan was present at action validation time to avoid a + * PUSH_VLAN when translating to OpenFlow 1.1+. + * + * We also keep the originating OFPUTIL action code in ofpact.compat. + * + * Used for OFPAT10_SET_VLAN_VID and OFPAT11_SET_VLAN_VID. */ struct ofpact_vlan_vid { struct ofpact ofpact; uint16_t vlan_vid; /* VLAN VID in low 12 bits, 0 in other bits. */ + bool push_vlan_if_needed; /* OF 1.0 semantics if true. */ + bool flow_has_vlan; /* VLAN present at action validation time? */ }; /* OFPACT_SET_VLAN_PCP. * - * Used for OFPAT10_SET_VLAN_PCP. */ + * We keep track if vlan was present at action validation time to avoid a + * PUSH_VLAN when translating to OpenFlow 1.1+. + * + * We also keep the originating OFPUTIL action code in ofpact.compat. + * + * Used for OFPAT10_SET_VLAN_PCP and OFPAT11_SET_VLAN_PCP. */ struct ofpact_vlan_pcp { struct ofpact ofpact; uint8_t vlan_pcp; /* VLAN PCP in low 3 bits, 0 in other bits. */ + bool push_vlan_if_needed; /* OF 1.0 semantics if true. */ + bool flow_has_vlan; /* VLAN present at action validation time? */ }; /* OFPACT_SET_ETH_SRC, OFPACT_SET_ETH_DST. @@ -274,7 +304,7 @@ struct ofpact_ipv4 { ovs_be32 ipv4; }; -/* OFPACT_SET_IPV4_DSCP. +/* OFPACT_SET_IP_DSCP. * * Used for OFPAT10_SET_NW_TOS. */ struct ofpact_dscp { @@ -282,12 +312,29 @@ struct ofpact_dscp { uint8_t dscp; /* DSCP in high 6 bits, rest ignored. */ }; +/* OFPACT_SET_IP_ECN. + * + * Used for OFPAT11_SET_NW_ECN. */ +struct ofpact_ecn { + struct ofpact ofpact; + uint8_t ecn; /* ECN in low 2 bits, rest ignored. */ +}; + +/* OFPACT_SET_IP_TTL. + * + * Used for OFPAT11_SET_NW_TTL. */ +struct ofpact_ip_ttl { + struct ofpact ofpact; + uint8_t ttl; +}; + /* OFPACT_SET_L4_SRC_PORT, OFPACT_SET_L4_DST_PORT. * * Used for OFPAT10_SET_TP_SRC, OFPAT10_SET_TP_DST. */ struct ofpact_l4_port { struct ofpact ofpact; - uint16_t port; /* TCP or UDP port number. */ + uint16_t port; /* TCP, UDP or SCTP port number. */ + uint8_t flow_ip_proto; /* IP proto from corresponding match, or 0 */ }; /* OFPACT_REG_MOVE. @@ -299,15 +346,49 @@ struct ofpact_reg_move { struct mf_subfield dst; }; +/* OFPACT_STACK_PUSH. + * + * Used for NXAST_STACK_PUSH and NXAST_STACK_POP. */ +struct ofpact_stack { + struct ofpact ofpact; + struct mf_subfield subfield; +}; + /* OFPACT_REG_LOAD. * - * Used for NXAST_REG_LOAD, OFPAT12_SET_FIELD. */ + * Used for NXAST_REG_LOAD. */ struct ofpact_reg_load { struct ofpact ofpact; struct mf_subfield dst; union mf_subvalue subvalue; /* Least-significant bits are used. */ }; +/* OFPACT_SET_FIELD. + * + * Used for OFPAT12_SET_FIELD. */ +struct ofpact_set_field { + struct ofpact ofpact; + const struct mf_field *field; + bool flow_has_vlan; /* VLAN present at action validation time. */ + union mf_value value; +}; + +/* OFPACT_PUSH_VLAN/MPLS/PBB + * + * Used for NXAST_PUSH_MPLS, OFPAT11_PUSH_MPLS. */ +struct ofpact_push_mpls { + struct ofpact ofpact; + ovs_be16 ethertype; +}; + +/* OFPACT_POP_MPLS + * + * Used for NXAST_POP_MPLS, OFPAT11_POP_MPLS.. */ +struct ofpact_pop_mpls { + struct ofpact ofpact; + ovs_be16 ethertype; +}; + /* OFPACT_SET_TUNNEL. * * Used for NXAST_SET_TUNNEL, NXAST_SET_TUNNEL64. */ @@ -333,25 +414,61 @@ struct ofpact_fin_timeout { uint16_t fin_hard_timeout; }; +/* OFPACT_WRITE_METADATA. + * + * Used for NXAST_WRITE_METADATA. */ +struct ofpact_metadata { + struct ofpact ofpact; + ovs_be64 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[PAD_SIZE(sizeof(struct ofpact), OFPACT_ALIGNTO)]; + struct ofpact actions[]; +}; +BUILD_ASSERT_DECL(offsetof(struct ofpact_nest, actions) % OFPACT_ALIGNTO == 0); + +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. */ struct ofpact_resubmit { struct ofpact ofpact; - uint16_t in_port; + ofp_port_t in_port; uint8_t table_id; }; /* Part of struct ofpact_learn, below. */ struct ofpact_learn_spec { - int n_bits; + int n_bits; /* Number of bits in source and dest. */ - int src_type; - struct mf_subfield src; - union mf_subvalue src_imm; + int src_type; /* One of NX_LEARN_SRC_*. */ + struct mf_subfield src; /* NX_LEARN_SRC_FIELD only. */ + union mf_subvalue src_imm; /* NX_LEARN_SRC_IMMEDIATE only. */ - int dst_type; - struct mf_subfield dst; + int dst_type; /* One of NX_LEARN_DST_*. */ + struct mf_subfield dst; /* NX_LEARN_DST_MATCH, NX_LEARN_DST_LOAD only. */ }; /* OFPACT_LEARN. @@ -363,9 +480,9 @@ struct ofpact_learn { uint16_t idle_timeout; /* Idle time before discarding (seconds). */ 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. */ uint8_t table_id; /* Table to insert flow entry. */ + uint64_t cookie; /* Cookie for new flow. */ + enum ofputil_flow_mod_flags flags; uint16_t fin_idle_timeout; /* Idle timeout after FIN, if nonzero. */ uint16_t fin_hard_timeout; /* Hard timeout after FIN, if nonzero. */ @@ -392,15 +509,6 @@ struct ofpact_multipath { struct mf_subfield dst; }; -/* OFPACT_AUTOPATH. - * - * Used for NXAST_AUTOPATH. */ -struct ofpact_autopath { - struct ofpact ofpact; - struct mf_subfield dst; - uint32_t port; -}; - /* OFPACT_NOTE. * * Used for NXAST_NOTE. */ @@ -410,9 +518,20 @@ struct ofpact_note { uint8_t data[]; }; +/* OFPACT_SAMPLE. + * + * Used for NXAST_SAMPLE. */ +struct ofpact_sample { + struct ofpact ofpact; + uint16_t probability; // Always >0. + uint32_t collector_set_id; + uint32_t obs_domain_id; + uint32_t obs_point_id; +}; + /* OFPACT_DEC_TTL. * - * Used for NXAST_DEC_TTL and NXAST_DEC_TTL_CNT_IDS. */ + * Used for OFPAT11_DEC_NW_TTL, NXAST_DEC_TTL and NXAST_DEC_TTL_CNT_IDS. */ struct ofpact_cnt_ids { struct ofpact ofpact; @@ -421,6 +540,33 @@ struct ofpact_cnt_ids { uint16_t cnt_ids[]; }; +/* OFPACT_SET_MPLS_LABEL. + * + * Used for OFPAT11_SET_MPLS_LABEL and NXAST_SET_MPLS_LABEL */ +struct ofpact_mpls_label { + struct ofpact ofpact; + + ovs_be32 label; +}; + +/* OFPACT_SET_MPLS_TC. + * + * Used for OFPAT11_SET_MPLS_TC and NXAST_SET_MPLS_TC */ +struct ofpact_mpls_tc { + struct ofpact ofpact; + + uint8_t tc; +}; + +/* OFPACT_SET_MPLS_TTL. + * + * Used for OFPAT11_SET_MPLS_TTL and NXAST_SET_MPLS_TTL */ +struct ofpact_mpls_ttl { + struct ofpact ofpact; + + uint8_t ttl; +}; + /* OFPACT_GOTO_TABLE * * Used for OFPIT11_GOTO_TABLE */ @@ -429,33 +575,50 @@ 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, - 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); +enum ofperr ofpacts_pull_openflow_actions(struct ofpbuf *openflow, + unsigned int actions_len, + enum ofp_version version, + struct ofpbuf *ofpacts); +enum ofperr ofpacts_pull_openflow_instructions(struct ofpbuf *openflow, + unsigned int instructions_len, + enum ofp_version version, + struct ofpbuf *ofpacts); +enum ofperr ofpacts_check(struct ofpact[], size_t ofpacts_len, + struct flow *, ofp_port_t max_ports, + uint8_t table_id, uint8_t n_tables, + enum ofputil_protocol *usable_protocols); +enum ofperr ofpacts_check_consistency(struct ofpact[], size_t ofpacts_len, + struct flow *, ofp_port_t max_ports, + uint8_t table_id, uint8_t n_tables, + enum ofputil_protocol usable_protocols); +enum ofperr ofpacts_verify(const struct ofpact ofpacts[], size_t ofpacts_len); +enum ofperr ofpact_check_output_port(ofp_port_t port, ofp_port_t max_ports); /* Converting ofpacts to 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); +size_t ofpacts_put_openflow_actions(const struct ofpact[], size_t ofpacts_len, + struct ofpbuf *openflow, enum ofp_version); +void ofpacts_put_openflow_instructions(const struct ofpact[], + size_t ofpacts_len, + struct ofpbuf *openflow, + enum ofp_version ofp_version); /* Working with ofpacts. */ bool ofpacts_output_to_port(const struct ofpact[], size_t ofpacts_len, - uint16_t port); + 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. * @@ -478,8 +641,8 @@ void *ofpact_put(struct ofpbuf *, enum ofpact_type, size_t len); * After using this function to add a variable-length action, add the * elements of the flexible array (e.g. with ofpbuf_put()), then use * ofpact_update_len() to update the length embedded into the action. - * (Keep in mind the need to refresh the structure from 'ofpacts->l2' after - * adding data to 'ofpacts'.) + * (Keep in mind the need to refresh the structure from 'ofpacts->frame' + * after adding data to 'ofpacts'.) * * struct *ofpact_get_(const struct ofpact *ofpact); * @@ -518,8 +681,8 @@ void *ofpact_put(struct ofpbuf *, enum ofpact_type, size_t len); static inline struct STRUCT * \ ofpact_get_##ENUM(const struct ofpact *ofpact) \ { \ - assert(ofpact->type == OFPACT_##ENUM); \ - return (struct STRUCT *) ofpact; \ + ovs_assert(ofpact->type == OFPACT_##ENUM); \ + return ALIGNED_CAST(struct STRUCT *, ofpact); \ } \ \ static inline struct STRUCT * \ @@ -547,6 +710,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") \ @@ -579,19 +746,11 @@ enum { #undef DEFINE_INST }; - -static inline bool -ofpact_is_instruction(const struct ofpact *a) -{ - /* TODO:XXX Write-Actions, Write-Metadata */ - return a->type == OFPACT_CLEAR_ACTIONS - || 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); - -void ofpact_set_field_init(struct ofpact_reg_load *load, - const struct mf_field *mf, const void *src); +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); +enum ofperr ovs_instruction_type_from_inst_type( + enum ovs_instruction_type *instruction_type, const uint16_t inst_type); #endif /* ofp-actions.h */