X-Git-Url: http://git.cascardo.eti.br/?a=blobdiff_plain;f=ofproto%2Fofproto-dpif.h;h=61a28ea08f452bc4f02405c55396524ffb1d1b9a;hb=7e7e8dbb6749034d5229ed17ebdc5fe5a3ad98b0;hp=493ee4cb40b95d7a8811ddd9dc03c9f421402ab1;hpb=ca6fa6fb38d2e33c329593d122acf66fcfb92e0d;p=cascardo%2Fovs.git diff --git a/ofproto/ofproto-dpif.h b/ofproto/ofproto-dpif.h index 493ee4cb4..61a28ea08 100644 --- a/ofproto/ofproto-dpif.h +++ b/ofproto/ofproto-dpif.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2009, 2010, 2011, 2012, 2013 Nicira, Inc. +/* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015 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,258 +17,218 @@ #include +#include "fail-open.h" #include "hmapx.h" -#include "ofproto/ofproto-provider.h" -#include "tag.h" +#include "odp-util.h" +#include "ofp-util.h" +#include "ovs-thread.h" +#include "ofproto-provider.h" #include "timer.h" #include "util.h" +#include "ovs-thread.h" -union user_action_cookie; +/* Priority for internal rules created to handle recirculation */ +#define RECIRC_RULE_PRIORITY 20 -#define MAX_MIRRORS 32 -typedef uint32_t mirror_mask_t; -#define MIRROR_MASK_C(X) UINT32_C(X) -BUILD_ASSERT_DECL(sizeof(mirror_mask_t) * CHAR_BIT >= MAX_MIRRORS); +union user_action_cookie; +struct dpif_flow_stats; +struct ofproto; +struct ofproto_async_msg; +struct ofproto_dpif; +struct ofport_dpif; +struct dpif_backer; +struct OVS_LOCKABLE rule_dpif; +struct OVS_LOCKABLE group_dpif; /* Number of implemented OpenFlow tables. */ enum { N_TABLES = 255 }; enum { TBL_INTERNAL = N_TABLES - 1 }; /* Used for internal hidden rules. */ BUILD_ASSERT_DECL(N_TABLES >= 2 && N_TABLES <= 255); -struct rule_dpif { - struct rule up; - - /* These statistics: - * - * - Do include packets and bytes from facets that have been deleted or - * whose own statistics have been folded into the rule. - * - * - Do include packets and bytes sent "by hand" that were accounted to - * the rule without any facet being involved (this is a rare corner - * case in rule_execute()). - * - * - Do not include packet or bytes that can be obtained from any facet's - * packet_count or byte_count member or that can be obtained from the - * datapath by, e.g., dpif_flow_get() for any subfacet. - */ - uint64_t packet_count; /* Number of packets received. */ - uint64_t byte_count; /* Number of bytes received. */ - - tag_type tag; /* Caches rule_calculate_tag() result. */ - - struct list facets; /* List of "struct facet"s. */ -}; +/* Ofproto-dpif -- DPIF based ofproto implementation. + * + * Ofproto-dpif provides an ofproto implementation for those platforms which + * implement the netdev and dpif interface defined in netdev.h and dpif.h. The + * most important of which is the Linux Kernel Module (dpif-linux), but + * alternatives are supported such as a userspace only implementation + * (dpif-netdev), and a dummy implementation used for unit testing. + * + * Ofproto-dpif is divided into three major chunks. + * + * - ofproto-dpif.c + * The main ofproto-dpif module is responsible for implementing the + * provider interface, installing and removing datapath flows, maintaining + * packet statistics, running protocols (BFD, LACP, STP, etc), and + * configuring relevant submodules. + * + * - ofproto-dpif-upcall.c + * Ofproto-dpif-upcall is responsible for retrieving upcalls from the kernel, + * processing miss upcalls, and handing more complex ones up to the main + * ofproto-dpif module. Miss upcall processing boils down to figuring out + * what each packet's actions are, executing them (i.e. asking the kernel to + * forward it), and handing it up to ofproto-dpif to decided whether or not + * to install a kernel flow. + * + * - ofproto-dpif-xlate.c + * Ofproto-dpif-xlate is responsible for translating OpenFlow actions into + * datapath actions. */ -/* Extra information about a classifier table. - * Currently used just for optimized flow revalidation. */ -struct table_dpif { - /* If either of these is nonnull, then this table has a form that allows - * flows to be tagged to avoid revalidating most flows for the most common - * kinds of flow table changes. */ - struct cls_table *catchall_table; /* Table that wildcards all fields. */ - struct cls_table *other_table; /* Table with any other wildcard set. */ - uint32_t basis; /* Keeps each table's tags separate. */ -}; +/* Stores the various features which the corresponding backer supports. */ +struct dpif_backer_support { + /* True if the datapath supports variable-length + * OVS_USERSPACE_ATTR_USERDATA in OVS_ACTION_ATTR_USERSPACE actions. + * False if the datapath supports only 8-byte (or shorter) userdata. */ + bool variable_length_userdata; -struct ofproto_dpif { - struct hmap_node all_ofproto_dpifs_node; /* In 'all_ofproto_dpifs'. */ - struct ofproto up; - struct dpif_backer *backer; - - /* Special OpenFlow rules. */ - struct rule_dpif *miss_rule; /* Sends flow table misses to controller. */ - struct rule_dpif *no_packet_in_rule; /* Drops flow table misses. */ - struct rule_dpif *drop_frags_rule; /* Used in OFPC_FRAG_DROP mode. */ - - /* Bridging. */ - struct netflow *netflow; - struct dpif_sflow *sflow; - struct dpif_ipfix *ipfix; - struct hmap bundles; /* Contains "struct ofbundle"s. */ - struct mac_learning *ml; - struct ofmirror *mirrors[MAX_MIRRORS]; - bool has_mirrors; - bool has_bonded_bundles; - - /* Facets. */ - struct classifier facets; /* Contains 'struct facet's. */ - long long int consistency_rl; - - /* Revalidation. */ - struct table_dpif tables[N_TABLES]; - - /* Support for debugging async flow mods. */ - struct list completions; - - struct netdev_stats stats; /* To account packets generated and consumed in - * userspace. */ - - /* Spanning tree. */ - struct stp *stp; - long long int stp_last_tick; - - /* VLAN splinters. */ - struct hmap realdev_vid_map; /* (realdev,vid) -> vlandev. */ - struct hmap vlandev_map; /* vlandev -> (realdev,vid). */ - - /* Ports. */ - struct sset ports; /* Set of standard port names. */ - struct sset ghost_ports; /* Ports with no datapath port. */ - struct sset port_poll_set; /* Queued names for port_poll() reply. */ - int port_poll_errno; /* Last errno for port_poll() reply. */ - - /* Per ofproto's dpif stats. */ - uint64_t n_hit; - uint64_t n_missed; -}; + /* True if the datapath supports masked data in OVS_ACTION_ATTR_SET + * actions. */ + bool masked_set_action; -struct ofport_dpif { - struct hmap_node odp_port_node; /* In dpif_backer's "odp_to_ofport_map". */ - struct ofport up; - - odp_port_t odp_port; - struct ofbundle *bundle; /* Bundle that contains this port, if any. */ - struct list bundle_node; /* In struct ofbundle's "ports" list. */ - struct cfm *cfm; /* Connectivity Fault Management, if any. */ - struct bfd *bfd; /* BFD, if any. */ - tag_type tag; /* Tag associated with this port. */ - bool may_enable; /* May be enabled in bonds. */ - long long int carrier_seq; /* Carrier status changes. */ - struct tnl_port *tnl_port; /* Tunnel handle, or null. */ - struct ofport_dpif *peer; /* Peer if patch port. */ - - /* Spanning tree. */ - struct stp_port *stp_port; /* Spanning Tree Protocol, if any. */ - enum stp_state stp_state; /* Always STP_DISABLED if STP not in use. */ - long long int stp_state_entered; - - struct hmap priorities; /* Map of attached 'priority_to_dscp's. */ - - /* Linux VLAN device support (e.g. "eth0.10" for VLAN 10.) - * - * This is deprecated. It is only for compatibility with broken device - * drivers in old versions of Linux that do not properly support VLANs when - * VLAN devices are not used. When broken device drivers are no longer in - * widespread use, we will delete these interfaces. */ - ofp_port_t realdev_ofp_port; - int vlandev_vid; -}; + /* True if the datapath supports tnl_push and pop actions. */ + bool tnl_push_pop; -struct ofbundle { - struct hmap_node hmap_node; /* In struct ofproto's "bundles" hmap. */ - struct ofproto_dpif *ofproto; /* Owning ofproto. */ - void *aux; /* Key supplied by ofproto's client. */ - char *name; /* Identifier for log messages. */ - - /* Configuration. */ - struct list ports; /* Contains "struct ofport"s. */ - enum port_vlan_mode vlan_mode; /* VLAN mode */ - int vlan; /* -1=trunk port, else a 12-bit VLAN ID. */ - unsigned long *trunks; /* Bitmap of trunked VLANs, if 'vlan' == -1. - * NULL if all VLANs are trunked. */ - struct lacp *lacp; /* LACP if LACP is enabled, otherwise NULL. */ - struct bond *bond; /* Nonnull iff more than one port. */ - bool use_priority_tags; /* Use 802.1p tag for frames in VLAN 0? */ - - /* Status. */ - bool floodable; /* True if no port has OFPUTIL_PC_NO_FLOOD set. */ - - /* Port mirroring info. */ - mirror_mask_t src_mirrors; /* Mirrors triggered when packet received. */ - mirror_mask_t dst_mirrors; /* Mirrors triggered when packet sent. */ - mirror_mask_t mirror_out; /* Mirrors that output to this bundle. */ -}; + /* True if the datapath supports OVS_FLOW_ATTR_UFID. */ + bool ufid; -struct ofmirror { - struct ofproto_dpif *ofproto; /* Owning ofproto. */ - size_t idx; /* In ofproto's "mirrors" array. */ - void *aux; /* Key supplied by ofproto's client. */ - char *name; /* Identifier for log messages. */ - - /* Selection criteria. */ - struct hmapx srcs; /* Contains "struct ofbundle *"s. */ - struct hmapx dsts; /* Contains "struct ofbundle *"s. */ - unsigned long *vlans; /* Bitmap of chosen VLANs, NULL selects all. */ - - /* Output (exactly one of out == NULL and out_vlan == -1 is true). */ - struct ofbundle *out; /* Output port or NULL. */ - int out_vlan; /* Output VLAN or -1. */ - mirror_mask_t dup_mirrors; /* Bitmap of mirrors with the same output. */ - - /* Counters. */ - int64_t packet_count; /* Number of packets sent. */ - int64_t byte_count; /* Number of bytes sent. */ + /* Each member represents support for related OVS_KEY_ATTR_* fields. */ + struct odp_support odp; }; -static inline struct rule_dpif *rule_dpif_cast(const struct rule *rule) -{ - return rule ? CONTAINER_OF(rule, struct rule_dpif, up) : NULL; -} - -static inline struct ofproto_dpif * -ofproto_dpif_cast(const struct ofproto *ofproto) -{ - ovs_assert(ofproto->ofproto_class == &ofproto_dpif_class); - return CONTAINER_OF(ofproto, struct ofproto_dpif, up); -} +bool ofproto_dpif_get_enable_ufid(const struct dpif_backer *backer); +struct dpif_backer_support *ofproto_dpif_get_support(const struct ofproto_dpif *); -static inline struct ofport_dpif * -ofbundle_get_a_port(const struct ofbundle *bundle) -{ - return CONTAINER_OF(list_front(&bundle->ports), struct ofport_dpif, - bundle_node); -} +cls_version_t ofproto_dpif_get_tables_version(struct ofproto_dpif *); -static inline int -mirror_mask_ffs(mirror_mask_t mask) -{ - BUILD_ASSERT_DECL(sizeof(unsigned int) >= sizeof(mask)); - return ffs(mask); -} +struct rule_dpif *rule_dpif_lookup_from_table(struct ofproto_dpif *, + cls_version_t, struct flow *, + struct flow_wildcards *, + const struct dpif_flow_stats *, + uint8_t *table_id, + ofp_port_t in_port, + bool may_packet_in, + bool honor_table_miss); -struct ofport_dpif *get_ofp_port(const struct ofproto_dpif *, - ofp_port_t ofp_port); +static inline void rule_dpif_ref(struct rule_dpif *); +static inline void rule_dpif_unref(struct rule_dpif *); -struct ofport_dpif *get_odp_port(const struct ofproto_dpif *, - odp_port_t odp_port); +void rule_dpif_credit_stats(struct rule_dpif *rule , + const struct dpif_flow_stats *); -odp_port_t ofp_port_to_odp_port(const struct ofproto_dpif *, - ofp_port_t ofp_port); +static inline bool rule_dpif_is_fail_open(const struct rule_dpif *); +static inline bool rule_dpif_is_table_miss(const struct rule_dpif *); +static inline bool rule_dpif_is_internal(const struct rule_dpif *); -struct rule_dpif *rule_dpif_lookup_in_table(struct ofproto_dpif *, - const struct flow *, - struct flow_wildcards *, - uint8_t table_id); +uint8_t rule_dpif_get_table(const struct rule_dpif *); -tag_type rule_calculate_tag(const struct flow *flow, const struct minimask *, - uint32_t secret); +bool table_is_internal(uint8_t table_id); -struct rule_dpif *rule_dpif_miss_rule(struct ofproto_dpif *ofproto, - const struct flow *); +const struct rule_actions *rule_dpif_get_actions(const struct rule_dpif *); +void rule_set_recirc_id(struct rule *, uint32_t id); -void rule_credit_stats(struct rule_dpif *, const struct dpif_flow_stats *); +ovs_be64 rule_dpif_get_flow_cookie(const struct rule_dpif *rule); -void ofproto_trace(struct ofproto_dpif *, const struct flow *, - const struct ofpbuf *packet, struct ds *); +void rule_dpif_reduce_timeouts(struct rule_dpif *rule, uint16_t idle_timeout, + uint16_t hard_timeout); -size_t put_userspace_action(const struct ofproto_dpif *, - struct ofpbuf *odp_actions, const struct flow *, - const union user_action_cookie *, - const size_t cookie_size); +void group_dpif_credit_stats(struct group_dpif *, + struct ofputil_bucket *, + const struct dpif_flow_stats *); +bool group_dpif_lookup(struct ofproto_dpif *ofproto, uint32_t group_id, + struct group_dpif **group); -bool stp_should_process_flow(const struct flow *, struct flow_wildcards *); -void stp_process_packet(const struct ofport_dpif *, - const struct ofpbuf *packet); +void group_dpif_get_buckets(const struct group_dpif *group, + const struct ovs_list **buckets); +enum ofp11_group_type group_dpif_get_type(const struct group_dpif *group); +const char *group_dpif_get_selection_method(const struct group_dpif *group); +uint64_t group_dpif_get_selection_method_param(const struct group_dpif *group); +const struct field_array *group_dpif_get_fields(const struct group_dpif *group); +bool ofproto_has_vlan_splinters(const struct ofproto_dpif *); ofp_port_t vsp_realdev_to_vlandev(const struct ofproto_dpif *, ofp_port_t realdev_ofp_port, ovs_be16 vlan_tci); +bool vsp_adjust_flow(const struct ofproto_dpif *, struct flow *, + struct dp_packet *packet); + +int ofproto_dpif_execute_actions(struct ofproto_dpif *, const struct flow *, + struct rule_dpif *, const struct ofpact *, + size_t ofpacts_len, struct dp_packet *); +int ofproto_dpif_execute_actions__(struct ofproto_dpif *, const struct flow *, + struct rule_dpif *, const struct ofpact *, + size_t ofpacts_len, int recurse, + int resubmits, struct dp_packet *); +void ofproto_dpif_send_async_msg(struct ofproto_dpif *, + struct ofproto_async_msg *); +bool ofproto_dpif_wants_packet_in_on_miss(struct ofproto_dpif *); +int ofproto_dpif_send_packet(const struct ofport_dpif *, struct dp_packet *); +void ofproto_dpif_flow_mod(struct ofproto_dpif *, + const struct ofputil_flow_mod *); +struct rule_dpif *ofproto_dpif_refresh_rule(struct rule_dpif *); + +struct ofport_dpif *odp_port_to_ofport(const struct dpif_backer *, odp_port_t); +struct ofport_dpif *ofp_port_to_ofport(const struct ofproto_dpif *, + ofp_port_t); + +bool ofproto_dpif_backer_enabled(struct dpif_backer* backer); + +int ofproto_dpif_add_internal_flow(struct ofproto_dpif *, + const struct match *, int priority, + uint16_t idle_timeout, + const struct ofpbuf *ofpacts, + struct rule **rulep); +int ofproto_dpif_delete_internal_flow(struct ofproto_dpif *, struct match *, + int priority); + +/* struct rule_dpif has struct rule as it's first member. */ +#define RULE_CAST(RULE) ((struct rule *)RULE) +#define GROUP_CAST(GROUP) ((struct ofgroup *)GROUP) + +static inline struct group_dpif* group_dpif_ref(struct group_dpif *group) +{ + if (group) { + ofproto_group_ref(GROUP_CAST(group)); + } + return group; +} + +static inline void group_dpif_unref(struct group_dpif *group) +{ + if (group) { + ofproto_group_unref(GROUP_CAST(group)); + } +} + +static inline void rule_dpif_ref(struct rule_dpif *rule) +{ + if (rule) { + ofproto_rule_ref(RULE_CAST(rule)); + } +} + +static inline void rule_dpif_unref(struct rule_dpif *rule) +{ + if (rule) { + ofproto_rule_unref(RULE_CAST(rule)); + } +} + +static inline bool rule_dpif_is_fail_open(const struct rule_dpif *rule) +{ + return is_fail_open_rule(RULE_CAST(rule)); +} + +static inline bool rule_dpif_is_table_miss(const struct rule_dpif *rule) +{ + return rule_is_table_miss(RULE_CAST(rule)); +} + +/* Returns true if 'rule' is an internal rule, false otherwise. */ +static inline bool rule_dpif_is_internal(const struct rule_dpif *rule) +{ + return RULE_CAST(rule)->table_id == TBL_INTERNAL; +} -bool ofproto_dpif_dscp_from_priority(const struct ofport_dpif *, - uint32_t priority, uint8_t *dscp); -int ofproto_dpif_queue_to_priority(const struct ofproto_dpif *, - uint32_t queue_id, uint32_t *priority); -tag_type calculate_flow_tag(struct ofproto_dpif *, const struct flow *, - uint8_t table_id, struct rule_dpif *); +#undef RULE_CAST +bool ovs_native_tunneling_is_on(struct ofproto_dpif *ofproto); #endif /* ofproto-dpif.h */