X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fofp-actions.h;h=1db3bdee23e85e960b6554638a43d061504c8989;hb=ea96b766c2092609fe850e9d5f6392252a2f5fa2;hp=e097468ba9bb59f0ce6d76b8a6a49f3e314450c1;hpb=8621547cc94ad91018ac0b662427a6fa20165a8d;p=sliver-openvswitch.git diff --git a/lib/ofp-actions.h b/lib/ofp-actions.h index e097468ba..1db3bdee2 100644 --- a/lib/ofp-actions.h +++ b/lib/ofp-actions.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013 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. @@ -59,6 +59,7 @@ 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) \ @@ -77,6 +78,8 @@ 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) \ @@ -257,18 +260,32 @@ struct ofpact_bundle { /* 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. @@ -316,7 +333,8 @@ struct ofpact_ip_ttl { * 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. @@ -338,24 +356,21 @@ struct ofpact_stack { /* 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. */ }; -/* The position in the packet at which to insert an MPLS header. +/* OFPACT_SET_FIELD. * - * 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 + * 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 @@ -364,7 +379,6 @@ enum ofpact_mpls_position { struct ofpact_push_mpls { struct ofpact ofpact; ovs_be16 ethertype; - enum ofpact_mpls_position position; }; /* OFPACT_POP_MPLS @@ -422,10 +436,10 @@ struct ofpact_meter { * Used for OFPIT11_WRITE_ACTIONS. */ struct ofpact_nest { struct ofpact ofpact; - uint8_t pad[OFPACT_ALIGN(sizeof(struct ofpact)) - sizeof(struct ofpact)]; + uint8_t pad[PAD_SIZE(sizeof(struct ofpact), OFPACT_ALIGNTO)]; struct ofpact actions[]; }; -BUILD_ASSERT_DECL(offsetof(struct ofpact_nest, actions) == OFPACT_ALIGNTO); +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) @@ -466,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. */ + uint8_t table_id; /* Table to insert flow entry. */ uint64_t cookie; /* Cookie for new flow. */ 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. */ @@ -526,9 +540,27 @@ 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 NXAST_SET_MPLS_TTL */ + * Used for OFPAT11_SET_MPLS_TTL and NXAST_SET_MPLS_TTL */ struct ofpact_mpls_ttl { struct ofpact ofpact; @@ -552,30 +584,32 @@ struct ofpact_group { }; /* 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, - struct ofpbuf *ofpacts); -enum ofperr ofpacts_check(const struct ofpact[], size_t ofpacts_len, +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, bool enforce_consistency); + 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, @@ -607,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); * @@ -716,7 +750,7 @@ 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); -void ofpact_set_field_init(struct ofpact_reg_load *load, - const struct mf_field *mf, const void *src); #endif /* ofp-actions.h */