mac_flow_impl.h revision 0dc2366f7b9f9f36e10909b1e95edbf2a261c2ac
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2010 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _MAC_FLOW_IMPL_H
#define _MAC_FLOW_IMPL_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/mac_flow.h>
/*
*/
#define FLOW_REFHOLD(flent) { \
}
/*
* Data paths must not attempt to use a flow entry if it is marked INCIPIENT
* or QUIESCE. In the former case the set up is not yet complete and the
* data path could stumble on inconsistent data structures. In the latter
* case a control operation is waiting for quiescence so that it can
* change callbacks or other structures without the use of locks.
*/
(err) = 0; \
(err) = -1; \
else \
}
#define FLOW_REFRELE(flent) { \
} else { \
} \
}
#define FLOW_USER_REFHOLD(flent) { \
(flent)->fe_user_refcnt++; \
}
#define FLOW_USER_REFRELE(flent) { \
if (--(flent)->fe_user_refcnt == 0 && \
}
#define FLOW_FINAL_REFRELE(flent) { \
FLOW_REFRELE(flent); \
}
/*
* Mark or unmark the flent with a bit flag
*/
}
}
#define FLENT_TO_MIP(flent) \
/* Convert a bandwidth expressed in bps to a number of bytes per tick. */
/*
* Given an underlying range and a priority level, obtain the minimum for the
* new range.
*/
/*
* Given an underlying range and a minimum level (base), obtain the maximum
* for the new range.
*/
/*
* Given an underlying range and a priority level, get the absolute
* priority value. For now there are just 3 values, high, low and
* medium so we can just return max, min or min + (max - min) / 2.
* If there are more than three we need to change this computation.
*/
#define MAC_FLOW_TAB_SIZE 500
typedef struct flow_entry_s flow_entry_t;
typedef struct flow_tab_s flow_tab_t;
typedef struct flow_state_s flow_state_t;
struct mac_impl_s;
struct mac_client_impl_s;
/*
* Classification flags used to lookup the flow.
*/
#define FLOW_INBOUND 0x01
#define FLOW_OUTBOUND 0x02
/* Don't compare VID when classifying the packets, see mac_rx_classify() */
#define FLOW_IGNORE_VLAN 0x04
/* Generic flow client function signature */
/* Flow state */
typedef enum {
/* Matches a flow_entry_t using the extracted flow_state_t info */
flow_state_t *);
/* fe_flags */
/* fe_type */
#define FLOW_VNIC FLOW_VNIC_MAC
/*
* Shared Bandwidth control counters between the soft ring set and its
* has a group of Rx rings assigned to it, we have the same
* number of soft ring sets as we have the Rx ring in the group
* and each individual SRS (and its soft rings) decide when to
* poll their Rx ring independently. But if there is a B/W limit
* shared across all the SRS in the group and their associated
* soft rings.
*
* There is a many to 1 mapping between the SRS and
* mac_bw_ctl if the flow has a group of Rx rings associated with
* it.
*/
typedef struct mac_bw_ctl_s {
} mac_bw_ctl_t;
struct flow_entry_s { /* Protected by */
/* Properties as specified for this flow */
/* Properties actually effective at run time for this flow */
/*
* Initial flow ref is 1 on creation. A thread that lookups the
* flent typically by a mac_flow_lookup() dynamically holds a ref.
* If the ref is 1, it means there arent' any upcalls from the driver
* or downcalls from the stack using this flent. Structures pointing
* to the flent or flent inserted in lists don't count towards this
* refcnt. Instead they are tracked using fe_flags. Only a control
* thread doing a teardown operation deletes the flent, after waiting
* for upcalls to finish synchronously. The fe_refcnt tracks
* the number of upcall refs
*/
/*
* This tracks lookups done using the global hash list for user
* generated flows. This refcnt only protects the flent itself
* from disappearing and helps walkers to read the flent info such
* as flow spec. However the flent may be quiesced and the SRS could
* be deleted. The fe_user_refcnt tracks the number of global flow
* has refs.
*/
/*
* Only the function ff_fn may be changed dynamically and atomically.
* The ff_arg1 and ff_arg2 are set at creation time and may not
* be changed.
*/
void *fe_cb_arg1; /* fe_lock */
void *fe_cb_arg2; /* fe_lock */
void *fe_client_cookie; /* WO */
void *fe_rx_ring_group; /* SL */
int fe_rx_srs_cnt; /* fe_lock */
void *fe_tx_ring_group;
void *fe_tx_srs; /* WO */
int fe_tx_ring_cnt;
/*
* This is a unicast flow, and is a mac_client_impl_t
*/
void *fe_mcip; /* WO */
/*
* Used by mci_flent_list of mac_client_impl_t to track flows sharing
* the same mac_client_impl_t.
*/
struct flow_entry_s *fe_client_next;
/*
* This is a broadcast or multicast flow and is a mac_bcast_grp_t
*/
void *fe_mbg; /* WO */
/*
* BW control info.
*/
/*
* Used by flow table lookup code
*/
/*
* Used by mac_flow_remove().
*/
int fe_index;
};
/*
* Various structures used by the flows framework for keeping track
* of packet state information.
*/
/* Layer 2 */
typedef struct flow_l2info_s {
/* Layer 3 */
typedef struct flow_l3info_s {
/* Layer 4 */
typedef struct flow_l4info_s {
/*
* Combined state structure.
* Holds flow direction and an mblk_t pointer.
*/
struct flow_state_s {
};
/*
* Flow ops vector.
* There are two groups of functions. The ones ending with _fe are
* called when a flow is being added. The others (hash, accept) are
* called at flow lookup time.
*/
#define FLOW_MAX_ACCEPT 16
typedef struct flow_ops_s {
/*
* fo_accept_fe():
* Validates the contents of the flow and checks whether
* it's compatible with the flow table. sets the fe_match
* function of the flow.
*/
/*
* fo_hash_fe():
* Generates a hash index to the flow table. This function
* must use the same algorithm as fo_hash(), which is used
* by the flow lookup code path.
*/
/*
* fo_match_fe():
* This is used for finding identical flows.
*/
flow_entry_t *);
/*
* fo_insert_fe():
* Used for inserting a flow to a flow chain.
* Protocols that have special ordering requirements would
* need to implement this. For those that don't,
* flow_generic_insert_fe() may be used.
*/
flow_entry_t *);
/*
* Calculates the flow hash index based on the accumulated
* state in flow_state_t. Must use the same algorithm as
* fo_hash_fe().
*/
/*
* Array of accept fuctions.
* Each function in the array will accumulate enough state
* (header length, protocol) to allow the next function to
* proceed. We support up to FLOW_MAX_ACCEPT functions which
* should be sufficient for all practical purposes.
*/
flow_state_t *);
} flow_ops_t;
/*
* Generic flow table.
*/
struct flow_tab_s {
/*
* Contains a list of functions (described above)
* specific to this table type.
*/
/*
* Indicates what types of flows are supported.
*/
/*
* An array of flow_entry_t * of size ft_size.
* Each element is the beginning of a hash chain.
*/
/*
* The number of flows inserted into ft_table.
*/
struct mac_impl_s *ft_mip;
struct mac_client_impl_s *ft_mcip;
};
/*
* This is used for describing what type of flow table can be created.
* mac_flow.c contains a list of these structures.
*/
typedef struct flow_tab_info_s {
#define MCIP_STAT_UPDATE(m, s, c) { \
+= ((uint64_t)(c)); \
}
#define SRS_RX_STAT_UPDATE(m, s, c) { \
+= ((uint64_t)(c)); \
}
#define SRS_TX_STAT_UPDATE(m, s, c) { \
+= ((uint64_t)(c)); \
}
#define SRS_TX_STATS_UPDATE(m, s) { \
}
#define SOFTRING_TX_STAT_UPDATE(m, s, c) { \
}
#define SOFTRING_TX_STATS_UPDATE(m, s) { \
}
extern void mac_flow_init();
extern void mac_flow_fini();
char *, void *, uint_t, flow_entry_t **);
extern int mac_flow_hash_add(flow_entry_t *);
extern int mac_flow_lookup_byname(char *, flow_entry_t **);
flow_entry_t **);
void *);
extern int mac_flow_walk_nolock(flow_tab_t *,
int (*)(flow_entry_t *, void *), void *);
extern void *mac_flow_get_client_cookie(flow_entry_t *);
extern void mac_flow_hash_remove(flow_entry_t *);
extern void mac_flow_quiesce(flow_entry_t *);
extern void mac_flow_restart(flow_entry_t *);
extern void mac_flow_cleanup(flow_entry_t *);
extern void mac_flow_destroy(flow_entry_t *);
struct mac_impl_s *, flow_tab_t **);
extern void mac_flow_tab_destroy(flow_tab_t *);
extern void mac_flow_drop(void *, void *, mblk_t *);
extern void flow_stat_destroy(flow_entry_t *);
#ifdef __cplusplus
}
#endif
#endif /* _MAC_FLOW_IMPL_H */