at v3.5 277 lines 6.6 kB view raw
1/* 2 * include/linux/if_team.h - Network team device driver header 3 * Copyright (c) 2011 Jiri Pirko <jpirko@redhat.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 */ 10 11#ifndef _LINUX_IF_TEAM_H_ 12#define _LINUX_IF_TEAM_H_ 13 14#ifdef __KERNEL__ 15 16struct team_pcpu_stats { 17 u64 rx_packets; 18 u64 rx_bytes; 19 u64 rx_multicast; 20 u64 tx_packets; 21 u64 tx_bytes; 22 struct u64_stats_sync syncp; 23 u32 rx_dropped; 24 u32 tx_dropped; 25}; 26 27struct team; 28 29struct team_port { 30 struct net_device *dev; 31 struct hlist_node hlist; /* node in enabled ports hash list */ 32 struct list_head list; /* node in ordinary list */ 33 struct team *team; 34 int index; /* index of enabled port. If disabled, it's set to -1 */ 35 36 bool linkup; /* either state.linkup or user.linkup */ 37 38 struct { 39 bool linkup; 40 u32 speed; 41 u8 duplex; 42 } state; 43 44 /* Values set by userspace */ 45 struct { 46 bool linkup; 47 bool linkup_enabled; 48 } user; 49 50 /* Custom gennetlink interface related flags */ 51 bool changed; 52 bool removed; 53 54 /* 55 * A place for storing original values of the device before it 56 * become a port. 57 */ 58 struct { 59 unsigned char dev_addr[MAX_ADDR_LEN]; 60 unsigned int mtu; 61 } orig; 62 63 struct rcu_head rcu; 64}; 65 66struct team_mode_ops { 67 int (*init)(struct team *team); 68 void (*exit)(struct team *team); 69 rx_handler_result_t (*receive)(struct team *team, 70 struct team_port *port, 71 struct sk_buff *skb); 72 bool (*transmit)(struct team *team, struct sk_buff *skb); 73 int (*port_enter)(struct team *team, struct team_port *port); 74 void (*port_leave)(struct team *team, struct team_port *port); 75 void (*port_change_mac)(struct team *team, struct team_port *port); 76}; 77 78enum team_option_type { 79 TEAM_OPTION_TYPE_U32, 80 TEAM_OPTION_TYPE_STRING, 81 TEAM_OPTION_TYPE_BINARY, 82 TEAM_OPTION_TYPE_BOOL, 83}; 84 85struct team_gsetter_ctx { 86 union { 87 u32 u32_val; 88 const char *str_val; 89 struct { 90 const void *ptr; 91 u32 len; 92 } bin_val; 93 bool bool_val; 94 } data; 95 struct team_port *port; 96}; 97 98struct team_option { 99 struct list_head list; 100 const char *name; 101 bool per_port; 102 enum team_option_type type; 103 int (*getter)(struct team *team, struct team_gsetter_ctx *ctx); 104 int (*setter)(struct team *team, struct team_gsetter_ctx *ctx); 105}; 106 107struct team_mode { 108 struct list_head list; 109 const char *kind; 110 struct module *owner; 111 size_t priv_size; 112 const struct team_mode_ops *ops; 113}; 114 115#define TEAM_PORT_HASHBITS 4 116#define TEAM_PORT_HASHENTRIES (1 << TEAM_PORT_HASHBITS) 117 118#define TEAM_MODE_PRIV_LONGS 4 119#define TEAM_MODE_PRIV_SIZE (sizeof(long) * TEAM_MODE_PRIV_LONGS) 120 121struct team { 122 struct net_device *dev; /* associated netdevice */ 123 struct team_pcpu_stats __percpu *pcpu_stats; 124 125 struct mutex lock; /* used for overall locking, e.g. port lists write */ 126 127 /* 128 * List of enabled ports and their count 129 */ 130 int en_port_count; 131 struct hlist_head en_port_hlist[TEAM_PORT_HASHENTRIES]; 132 133 struct list_head port_list; /* list of all ports */ 134 135 struct list_head option_list; 136 struct list_head option_inst_list; /* list of option instances */ 137 138 const struct team_mode *mode; 139 struct team_mode_ops ops; 140 long mode_priv[TEAM_MODE_PRIV_LONGS]; 141}; 142 143static inline struct hlist_head *team_port_index_hash(struct team *team, 144 int port_index) 145{ 146 return &team->en_port_hlist[port_index & (TEAM_PORT_HASHENTRIES - 1)]; 147} 148 149static inline struct team_port *team_get_port_by_index(struct team *team, 150 int port_index) 151{ 152 struct hlist_node *p; 153 struct team_port *port; 154 struct hlist_head *head = team_port_index_hash(team, port_index); 155 156 hlist_for_each_entry(port, p, head, hlist) 157 if (port->index == port_index) 158 return port; 159 return NULL; 160} 161static inline struct team_port *team_get_port_by_index_rcu(struct team *team, 162 int port_index) 163{ 164 struct hlist_node *p; 165 struct team_port *port; 166 struct hlist_head *head = team_port_index_hash(team, port_index); 167 168 hlist_for_each_entry_rcu(port, p, head, hlist) 169 if (port->index == port_index) 170 return port; 171 return NULL; 172} 173 174extern int team_port_set_team_mac(struct team_port *port); 175extern int team_options_register(struct team *team, 176 const struct team_option *option, 177 size_t option_count); 178extern void team_options_unregister(struct team *team, 179 const struct team_option *option, 180 size_t option_count); 181extern int team_mode_register(struct team_mode *mode); 182extern int team_mode_unregister(struct team_mode *mode); 183 184#endif /* __KERNEL__ */ 185 186#define TEAM_STRING_MAX_LEN 32 187 188/********************************** 189 * NETLINK_GENERIC netlink family. 190 **********************************/ 191 192enum { 193 TEAM_CMD_NOOP, 194 TEAM_CMD_OPTIONS_SET, 195 TEAM_CMD_OPTIONS_GET, 196 TEAM_CMD_PORT_LIST_GET, 197 198 __TEAM_CMD_MAX, 199 TEAM_CMD_MAX = (__TEAM_CMD_MAX - 1), 200}; 201 202enum { 203 TEAM_ATTR_UNSPEC, 204 TEAM_ATTR_TEAM_IFINDEX, /* u32 */ 205 TEAM_ATTR_LIST_OPTION, /* nest */ 206 TEAM_ATTR_LIST_PORT, /* nest */ 207 208 __TEAM_ATTR_MAX, 209 TEAM_ATTR_MAX = __TEAM_ATTR_MAX - 1, 210}; 211 212/* Nested layout of get/set msg: 213 * 214 * [TEAM_ATTR_LIST_OPTION] 215 * [TEAM_ATTR_ITEM_OPTION] 216 * [TEAM_ATTR_OPTION_*], ... 217 * [TEAM_ATTR_ITEM_OPTION] 218 * [TEAM_ATTR_OPTION_*], ... 219 * ... 220 * [TEAM_ATTR_LIST_PORT] 221 * [TEAM_ATTR_ITEM_PORT] 222 * [TEAM_ATTR_PORT_*], ... 223 * [TEAM_ATTR_ITEM_PORT] 224 * [TEAM_ATTR_PORT_*], ... 225 * ... 226 */ 227 228enum { 229 TEAM_ATTR_ITEM_OPTION_UNSPEC, 230 TEAM_ATTR_ITEM_OPTION, /* nest */ 231 232 __TEAM_ATTR_ITEM_OPTION_MAX, 233 TEAM_ATTR_ITEM_OPTION_MAX = __TEAM_ATTR_ITEM_OPTION_MAX - 1, 234}; 235 236enum { 237 TEAM_ATTR_OPTION_UNSPEC, 238 TEAM_ATTR_OPTION_NAME, /* string */ 239 TEAM_ATTR_OPTION_CHANGED, /* flag */ 240 TEAM_ATTR_OPTION_TYPE, /* u8 */ 241 TEAM_ATTR_OPTION_DATA, /* dynamic */ 242 TEAM_ATTR_OPTION_REMOVED, /* flag */ 243 TEAM_ATTR_OPTION_PORT_IFINDEX, /* u32 */ /* for per-port options */ 244 245 __TEAM_ATTR_OPTION_MAX, 246 TEAM_ATTR_OPTION_MAX = __TEAM_ATTR_OPTION_MAX - 1, 247}; 248 249enum { 250 TEAM_ATTR_ITEM_PORT_UNSPEC, 251 TEAM_ATTR_ITEM_PORT, /* nest */ 252 253 __TEAM_ATTR_ITEM_PORT_MAX, 254 TEAM_ATTR_ITEM_PORT_MAX = __TEAM_ATTR_ITEM_PORT_MAX - 1, 255}; 256 257enum { 258 TEAM_ATTR_PORT_UNSPEC, 259 TEAM_ATTR_PORT_IFINDEX, /* u32 */ 260 TEAM_ATTR_PORT_CHANGED, /* flag */ 261 TEAM_ATTR_PORT_LINKUP, /* flag */ 262 TEAM_ATTR_PORT_SPEED, /* u32 */ 263 TEAM_ATTR_PORT_DUPLEX, /* u8 */ 264 TEAM_ATTR_PORT_REMOVED, /* flag */ 265 266 __TEAM_ATTR_PORT_MAX, 267 TEAM_ATTR_PORT_MAX = __TEAM_ATTR_PORT_MAX - 1, 268}; 269 270/* 271 * NETLINK_GENERIC related info 272 */ 273#define TEAM_GENL_NAME "team" 274#define TEAM_GENL_VERSION 0x1 275#define TEAM_GENL_CHANGE_EVENT_MC_GRP_NAME "change_event" 276 277#endif /* _LINUX_IF_TEAM_H_ */