Files
linux-apfs/include/linux/if_team.h
T

254 lines
6.4 KiB
C
Raw Normal View History

2011-11-11 22:16:48 +00:00
/*
* include/linux/if_team.h - Network team device driver header
* Copyright (c) 2011 Jiri Pirko <jpirko@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef _LINUX_IF_TEAM_H_
#define _LINUX_IF_TEAM_H_
2012-07-17 05:22:36 +00:00
#include <linux/netpoll.h>
2012-07-20 02:28:51 +00:00
#include <net/sch_generic.h>
2012-10-13 10:46:48 +01:00
#include <uapi/linux/if_team.h>
2012-07-17 05:22:36 +00:00
2011-11-11 22:16:48 +00:00
struct team_pcpu_stats {
u64 rx_packets;
u64 rx_bytes;
u64 rx_multicast;
u64 tx_packets;
u64 tx_bytes;
struct u64_stats_sync syncp;
u32 rx_dropped;
u32 tx_dropped;
};
struct team;
struct team_port {
struct net_device *dev;
2012-04-20 04:42:05 +00:00
struct hlist_node hlist; /* node in enabled ports hash list */
2011-11-11 22:16:48 +00:00
struct list_head list; /* node in ordinary list */
struct team *team;
2012-04-20 04:42:05 +00:00
int index; /* index of enabled port. If disabled, it's set to -1 */
2011-11-11 22:16:48 +00:00
bool linkup; /* either state.linkup or user.linkup */
struct {
bool linkup;
u32 speed;
u8 duplex;
} state;
/* Values set by userspace */
struct {
bool linkup;
bool linkup_enabled;
} user;
/* Custom gennetlink interface related flags */
bool changed;
bool removed;
2011-11-11 22:16:48 +00:00
/*
* A place for storing original values of the device before it
* become a port.
*/
struct {
unsigned char dev_addr[MAX_ADDR_LEN];
unsigned int mtu;
} orig;
2012-07-17 05:22:36 +00:00
#ifdef CONFIG_NET_POLL_CONTROLLER
struct netpoll *np;
#endif
2012-07-27 06:28:54 +00:00
s32 priority; /* lower number ~ higher priority */
u16 queue_id;
struct list_head qom_list; /* node in queue override mapping list */
2012-06-19 05:54:05 +00:00
long mode_priv[0];
2011-11-11 22:16:48 +00:00
};
static inline bool team_port_enabled(struct team_port *port)
{
return port->index != -1;
}
static inline bool team_port_txable(struct team_port *port)
{
return port->linkup && team_port_enabled(port);
}
2012-06-26 06:52:46 +00:00
2012-07-17 05:22:36 +00:00
#ifdef CONFIG_NET_POLL_CONTROLLER
static inline void team_netpoll_send_skb(struct team_port *port,
struct sk_buff *skb)
{
struct netpoll *np = port->np;
if (np)
netpoll_send_skb(np, skb);
}
#else
static inline void team_netpoll_send_skb(struct team_port *port,
struct sk_buff *skb)
{
}
#endif
2011-11-11 22:16:48 +00:00
struct team_mode_ops {
int (*init)(struct team *team);
void (*exit)(struct team *team);
rx_handler_result_t (*receive)(struct team *team,
struct team_port *port,
struct sk_buff *skb);
bool (*transmit)(struct team *team, struct sk_buff *skb);
int (*port_enter)(struct team *team, struct team_port *port);
void (*port_leave)(struct team *team, struct team_port *port);
2012-08-17 04:00:48 +00:00
void (*port_change_dev_addr)(struct team *team, struct team_port *port);
void (*port_enabled)(struct team *team, struct team_port *port);
void (*port_disabled)(struct team *team, struct team_port *port);
2011-11-11 22:16:48 +00:00
};
enum team_option_type {
TEAM_OPTION_TYPE_U32,
TEAM_OPTION_TYPE_STRING,
2012-04-04 12:16:26 +00:00
TEAM_OPTION_TYPE_BINARY,
2012-04-10 05:15:43 +00:00
TEAM_OPTION_TYPE_BOOL,
2012-07-27 06:28:53 +00:00
TEAM_OPTION_TYPE_S32,
2011-11-11 22:16:48 +00:00
};
struct team_option_inst_info {
u32 array_index;
struct team_port *port; /* != NULL if per-port */
};
2012-04-10 05:15:42 +00:00
struct team_gsetter_ctx {
union {
u32 u32_val;
const char *str_val;
struct {
const void *ptr;
u32 len;
} bin_val;
2012-04-10 05:15:43 +00:00
bool bool_val;
2012-07-27 06:28:53 +00:00
s32 s32_val;
2012-04-10 05:15:42 +00:00
} data;
struct team_option_inst_info *info;
2012-04-10 05:15:42 +00:00
};
2011-11-11 22:16:48 +00:00
struct team_option {
struct list_head list;
const char *name;
2012-04-10 05:15:42 +00:00
bool per_port;
2012-06-19 05:54:08 +00:00
unsigned int array_size; /* != 0 means the option is array */
2011-11-11 22:16:48 +00:00
enum team_option_type type;
int (*init)(struct team *team, struct team_option_inst_info *info);
2012-04-10 05:15:42 +00:00
int (*getter)(struct team *team, struct team_gsetter_ctx *ctx);
int (*setter)(struct team *team, struct team_gsetter_ctx *ctx);
2011-11-11 22:16:48 +00:00
};
2012-06-19 05:54:11 +00:00
extern void team_option_inst_set_change(struct team_option_inst_info *opt_inst_info);
extern void team_options_change_check(struct team *team);
2011-11-11 22:16:48 +00:00
struct team_mode {
const char *kind;
struct module *owner;
size_t priv_size;
2012-06-19 05:54:05 +00:00
size_t port_priv_size;
2011-11-11 22:16:48 +00:00
const struct team_mode_ops *ops;
};
#define TEAM_PORT_HASHBITS 4
#define TEAM_PORT_HASHENTRIES (1 << TEAM_PORT_HASHBITS)
#define TEAM_MODE_PRIV_LONGS 4
#define TEAM_MODE_PRIV_SIZE (sizeof(long) * TEAM_MODE_PRIV_LONGS)
struct team {
struct net_device *dev; /* associated netdevice */
struct team_pcpu_stats __percpu *pcpu_stats;
2011-11-16 11:09:08 +00:00
struct mutex lock; /* used for overall locking, e.g. port lists write */
2011-11-11 22:16:48 +00:00
/*
2012-04-20 04:42:05 +00:00
* List of enabled ports and their count
2011-11-11 22:16:48 +00:00
*/
2012-04-20 04:42:05 +00:00
int en_port_count;
struct hlist_head en_port_hlist[TEAM_PORT_HASHENTRIES];
struct list_head port_list; /* list of all ports */
2011-11-11 22:16:48 +00:00
struct list_head option_list;
2012-04-10 05:15:42 +00:00
struct list_head option_inst_list; /* list of option instances */
2011-11-11 22:16:48 +00:00
const struct team_mode *mode;
struct team_mode_ops ops;
bool queue_override_enabled;
struct list_head *qom_lists; /* array of queue override mapping lists */
2011-11-11 22:16:48 +00:00
long mode_priv[TEAM_MODE_PRIV_LONGS];
};
static inline int team_dev_queue_xmit(struct team *team, struct team_port *port,
struct sk_buff *skb)
{
BUILD_BUG_ON(sizeof(skb->queue_mapping) !=
sizeof(qdisc_skb_cb(skb)->slave_dev_queue_mapping));
skb_set_queue_mapping(skb, qdisc_skb_cb(skb)->slave_dev_queue_mapping);
skb->dev = port->dev;
if (unlikely(netpoll_tx_running(team->dev))) {
team_netpoll_send_skb(port, skb);
return 0;
}
return dev_queue_xmit(skb);
}
2011-11-11 22:16:48 +00:00
static inline struct hlist_head *team_port_index_hash(struct team *team,
int port_index)
{
2012-04-20 04:42:05 +00:00
return &team->en_port_hlist[port_index & (TEAM_PORT_HASHENTRIES - 1)];
2011-11-11 22:16:48 +00:00
}
static inline struct team_port *team_get_port_by_index(struct team *team,
int port_index)
{
struct hlist_node *p;
struct team_port *port;
struct hlist_head *head = team_port_index_hash(team, port_index);
hlist_for_each_entry(port, p, head, hlist)
if (port->index == port_index)
return port;
return NULL;
}
static inline struct team_port *team_get_port_by_index_rcu(struct team *team,
int port_index)
{
struct hlist_node *p;
struct team_port *port;
struct hlist_head *head = team_port_index_hash(team, port_index);
hlist_for_each_entry_rcu(port, p, head, hlist)
if (port->index == port_index)
return port;
return NULL;
}
2012-08-17 04:00:48 +00:00
extern int team_port_set_team_dev_addr(struct team_port *port);
2011-11-16 11:09:09 +00:00
extern int team_options_register(struct team *team,
const struct team_option *option,
size_t option_count);
2011-11-11 22:16:48 +00:00
extern void team_options_unregister(struct team *team,
2011-11-16 11:09:09 +00:00
const struct team_option *option,
2011-11-11 22:16:48 +00:00
size_t option_count);
2012-06-19 05:54:03 +00:00
extern int team_mode_register(const struct team_mode *mode);
extern void team_mode_unregister(const struct team_mode *mode);
2011-11-11 22:16:48 +00:00
2012-07-20 02:28:51 +00:00
#define TEAM_DEFAULT_NUM_TX_QUEUES 16
#define TEAM_DEFAULT_NUM_RX_QUEUES 16
2011-11-11 22:16:48 +00:00
#endif /* _LINUX_IF_TEAM_H_ */