linux/include/linux/if_team.h
<<
>>
Prefs
   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_ */
 278