/* * Copyright (c) 2008-2017 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef OPENVSWITCH_OFP_TABLE_H #define OPENVSWITCH_OFP_TABLE_H 1 #include #include "openflow/openflow.h" #include "openvswitch/meta-flow.h" #include "openvswitch/ofp-port.h" #ifdef __cplusplus extern "C" { #endif struct ofputil_table_stats; /* Abstract version of OFPTC11_TABLE_MISS_*. * * OpenFlow 1.0 always sends packets that miss to the next flow table, or to * the controller if they miss in the last flow table. * * OpenFlow 1.1 and 1.2 can configure table miss behavior via a "table-mod" * that specifies "send to controller", "miss", or "drop". * * OpenFlow 1.3 and later never sends packets that miss to the controller. */ enum ofputil_table_miss { /* Protocol-specific default behavior. On OpenFlow 1.0 through 1.2 * connections, the packet is sent to the controller, and on OpenFlow 1.3 * and later connections, the packet is dropped. * * This is also used as a result of decoding OpenFlow 1.3+ "config" values * in table-mods, to indicate that no table-miss was specified. */ OFPUTIL_TABLE_MISS_DEFAULT, /* Protocol default behavior. */ /* These constants have the same meanings as those in OpenFlow with the * same names. */ OFPUTIL_TABLE_MISS_CONTROLLER, /* Send to controller. */ OFPUTIL_TABLE_MISS_CONTINUE, /* Go to next table. */ OFPUTIL_TABLE_MISS_DROP, /* Drop the packet. */ }; const char *ofputil_table_miss_to_string(enum ofputil_table_miss); /* Abstract version of OFPTC14_EVICTION. * * OpenFlow 1.0 through 1.3 don't know anything about eviction, so decoding a * message for one of these protocols always yields * OFPUTIL_TABLE_EVICTION_DEFAULT. */ enum ofputil_table_eviction { OFPUTIL_TABLE_EVICTION_DEFAULT, /* No value. */ OFPUTIL_TABLE_EVICTION_ON, /* Enable eviction. */ OFPUTIL_TABLE_EVICTION_OFF /* Disable eviction. */ }; const char *ofputil_table_eviction_to_string(enum ofputil_table_eviction); /* Abstract version of OFPTC14_VACANCY_EVENTS. * * OpenFlow 1.0 through 1.3 don't know anything about vacancy events, so * decoding a message for one of these protocols always yields * OFPUTIL_TABLE_VACANCY_DEFAULT. */ enum ofputil_table_vacancy { OFPUTIL_TABLE_VACANCY_DEFAULT, /* No value. */ OFPUTIL_TABLE_VACANCY_ON, /* Enable vacancy events. */ OFPUTIL_TABLE_VACANCY_OFF /* Disable vacancy events. */ }; const char *ofputil_table_vacancy_to_string(enum ofputil_table_vacancy); /* Abstract version of OFPTMPT_VACANCY. * * Openflow 1.4+ defines vacancy events. * The fields vacancy_down and vacancy_up are the threshold for generating * vacancy events that should be configured on the flow table, expressed as * a percent. * The vacancy field is only used when this property in included in a * OFPMP_TABLE_DESC multipart reply or a OFPT_TABLE_STATUS message and * represent the current vacancy of the table, expressed as a percent. In * OFP_TABLE_MOD requests, this field must be set to 0 */ struct ofputil_table_mod_prop_vacancy { uint8_t vacancy_down; /* Vacancy threshold when space decreases (%). */ uint8_t vacancy_up; /* Vacancy threshold when space increases (%). */ uint8_t vacancy; /* Current vacancy (%). */ }; /* Mapping between table numbers and names. */ struct ofputil_table_map { struct namemap map; }; #define OFPUTIL_TABLE_MAP_INITIALIZER(MAP) { NAMEMAP_INITIALIZER((MAP).map) } void ofputil_table_map_init(struct ofputil_table_map *); const char *ofputil_table_map_get_name(const struct ofputil_table_map *, uint8_t); uint8_t ofputil_table_map_get_number(const struct ofputil_table_map *, const char *name); void ofputil_table_map_put(struct ofputil_table_map *, uint8_t, const char *name); void ofputil_table_map_destroy(struct ofputil_table_map *); /* Table numbers. */ bool ofputil_table_from_string(const char *, const struct ofputil_table_map *, uint8_t *tablep); void ofputil_format_table(uint8_t table, const struct ofputil_table_map *, struct ds *); void ofputil_table_to_string(uint8_t, const struct ofputil_table_map *, char *namebuf, size_t bufsize); /* Abstract ofp_table_mod. */ struct ofputil_table_mod { uint8_t table_id; /* ID of the table, 0xff indicates all tables. */ /* OpenFlow 1.1 and 1.2 only. For other versions, ignored on encoding, * decoded to OFPUTIL_TABLE_MISS_DEFAULT. */ enum ofputil_table_miss miss; /* OpenFlow 1.4+ only. For other versions, ignored on encoding, decoded to * OFPUTIL_TABLE_EVICTION_DEFAULT. */ enum ofputil_table_eviction eviction; /* OpenFlow 1.4+ only and optional even there; UINT32_MAX indicates * absence. For other versions, ignored on encoding, decoded to * UINT32_MAX.*/ uint32_t eviction_flags; /* OFPTMPEF14_*. */ /* OpenFlow 1.4+ only. For other versions, ignored on encoding, decoded to * OFPUTIL_TABLE_VACANCY_DEFAULT. */ enum ofputil_table_vacancy vacancy; /* Openflow 1.4+ only. Defines threshold values of vacancy expressed as * percent, value of current vacancy is set to zero for table-mod. * For other versions, ignored on encoding, all values decoded to * zero. */ struct ofputil_table_mod_prop_vacancy table_vacancy; }; enum ofperr ofputil_decode_table_mod(const struct ofp_header *, struct ofputil_table_mod *); struct ofpbuf *ofputil_encode_table_mod(const struct ofputil_table_mod *, enum ofputil_protocol); void ofputil_table_mod_format(struct ds *, const struct ofputil_table_mod *, const struct ofputil_table_map *); char *parse_ofp_table_mod(struct ofputil_table_mod *, const char **namep, const char *table_id, const char *flow_miss_handling, const struct ofputil_table_map *, uint32_t *usable_versions) OVS_WARN_UNUSED_RESULT; /* Abstract ofp14_table_desc. */ struct ofputil_table_desc { uint8_t table_id; /* ID of the table. */ enum ofputil_table_eviction eviction; uint32_t eviction_flags; /* UINT32_MAX if not present. */ enum ofputil_table_vacancy vacancy; struct ofputil_table_mod_prop_vacancy table_vacancy; }; int ofputil_decode_table_desc(struct ofpbuf *, struct ofputil_table_desc *, enum ofp_version); void ofputil_append_table_desc_reply(const struct ofputil_table_desc *td, struct ovs_list *replies, enum ofp_version); void ofputil_table_desc_format(struct ds *, const struct ofputil_table_desc *, const struct ofputil_table_map *); /* Abstract ofp_table_features. * * This is used for all versions of OpenFlow, even though ofp_table_features * was only introduced in OpenFlow 1.3, because earlier versions of OpenFlow * include support for a subset of ofp_table_features through OFPST_TABLE (aka * OFPMP_TABLE). */ struct ofputil_table_features { /* Only for OFPT_TABLE_FEATURES requests and only the first table_features * in such a request. */ enum ofp15_table_features_command command; /* The following are always present in table features requests and * replies. */ uint8_t table_id; char name[OFP_MAX_TABLE_NAME_LEN]; ovs_be64 metadata_match; /* Bits of metadata table can match. */ ovs_be64 metadata_write; /* Bits of metadata table can write. */ uint32_t max_entries; /* Max number of entries supported. */ /* True if the message included any properties. This is important for * OFPT_TABLE_FEATURES requests, which change table properties only if any * are included. */ bool any_properties; /* Flags. * * 'miss_config' is relevant for OpenFlow 1.1 and 1.2 only, because those * versions include OFPTC_MISS_* flags in OFPST_TABLE. For other versions, * it is decoded to OFPUTIL_TABLE_MISS_DEFAULT and ignored for encoding. * * 'supports_eviction' and 'supports_vacancy_events' are relevant only for * OpenFlow 1.4 and later only. For OF1.4, they are boolean: 1 if * supported, otherwise 0. For other versions, they are decoded as -1 and * ignored for encoding. * * Search for "OFPTC_* Table Configuration" in the documentation for more * details of how OpenFlow has changed in this area. */ enum ofputil_table_miss miss_config; /* OF1.1 and 1.2 only. */ int supports_eviction; /* OF1.4+ only. */ int supports_vacancy_events; /* OF1.4+ only. */ /* Table features related to instructions. There are two instances: * * - 'miss' reports features available in the table miss flow. * * - 'nonmiss' reports features available in other flows. */ struct ofputil_table_instruction_features { /* Tables that "goto-table" may jump to. */ unsigned long int next[BITMAP_N_LONGS(255)]; /* Bitmap of OVSINST_* for supported instructions. */ uint32_t instructions; /* Table features related to actions. There are two instances: * * - 'write' reports features available in a "write_actions" * instruction. * * - 'apply' reports features available in an "apply_actions" * instruction. */ struct ofputil_table_action_features { uint64_t ofpacts; /* Bitmap of supported OFPACT_*. */ struct mf_bitmap set_fields; /* Fields for "set-field". */ } write, apply; } nonmiss, miss; /* MFF_* bitmaps. * * For any given field the following combinations are valid: * * - match=0, wildcard=0, mask=0: Flows in this table cannot match on * this field. * * - match=1, wildcard=0, mask=0: Flows in this table must match on all * the bits in this field. * * - match=1, wildcard=1, mask=0: Flows in this table must either match * on all the bits in the field or wildcard the field entirely. * * - match=1, wildcard=1, mask=1: Flows in this table may arbitrarily * mask this field (as special cases, they may match on all the bits * or wildcard it entirely). * * Other combinations do not make sense. */ struct mf_bitmap match; /* Fields that may be matched. */ struct mf_bitmap mask; /* Subset of 'match' that may have masks. */ struct mf_bitmap wildcard; /* Subset of 'match' that may be wildcarded. */ }; int ofputil_decode_table_features( struct ofpbuf *, struct ofputil_table_features *, struct ofpbuf *raw_properties); struct ofpbuf *ofputil_encode_table_features_request(enum ofp_version); struct ofpbuf *ofputil_encode_table_desc_request(enum ofp_version); void ofputil_append_table_features( const struct ofputil_table_features *tf, const struct ofpbuf *raw_properties, struct ovs_list *msgs); void ofputil_table_features_format( struct ds *, const struct ofputil_table_features *features, const struct ofputil_table_features *prev_features, const struct ofputil_table_stats *stats, const struct ofputil_table_stats *prev_stats, int *first_ditto, int *last_ditto); void ofputil_table_features_format_finish(struct ds *, int first_ditto, int last_ditto); bool ofputil_table_features_are_superset( const struct ofputil_table_features *super, const struct ofputil_table_features *sub); /* Abstract table stats. * * This corresponds to the OpenFlow 1.3 table statistics structure, which only * includes actual statistics. In earlier versions of OpenFlow, several * members describe table features, so this structure has to be paired with * struct ofputil_table_features to get all information. */ struct ofputil_table_stats { uint8_t table_id; /* Identifier of table. */ uint32_t active_count; /* Number of active entries. */ uint64_t lookup_count; /* Number of packets looked up in table. */ uint64_t matched_count; /* Number of packets that hit table. */ }; struct ofpbuf *ofputil_encode_table_stats_reply(const struct ofp_header *rq); struct ofpbuf *ofputil_encode_table_desc_reply(const struct ofp_header *rq); void ofputil_append_table_stats_reply(struct ofpbuf *reply, const struct ofputil_table_stats *, const struct ofputil_table_features *); int ofputil_decode_table_stats_reply(struct ofpbuf *reply, struct ofputil_table_stats *, struct ofputil_table_features *); /* Abstract ofp14_table_status. */ struct ofputil_table_status { enum ofp14_table_reason reason; /* One of OFPTR_*. */ struct ofputil_table_desc desc; /* New table config. */ }; const char *ofp_table_reason_to_string(enum ofp14_table_reason, char *reasonbuf, size_t bufsize); enum ofperr ofputil_decode_table_status(const struct ofp_header *, struct ofputil_table_status *); struct ofpbuf *ofputil_encode_table_status(const struct ofputil_table_status *, enum ofputil_protocol); void ofputil_format_table_status(struct ds *, const struct ofputil_table_status *, const struct ofputil_table_map *); #ifdef __cplusplus } #endif #endif /* ofp-table.h */