linux/include/net/switchdev.h
<<
>>
Prefs
   1/*
   2 * include/net/switchdev.h - Switch device API
   3 * Copyright (c) 2014-2015 Jiri Pirko <jiri@resnulli.us>
   4 * Copyright (c) 2014-2015 Scott Feldman <sfeldma@gmail.com>
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; either version 2 of the License, or
   9 * (at your option) any later version.
  10 */
  11#ifndef _LINUX_SWITCHDEV_H_
  12#define _LINUX_SWITCHDEV_H_
  13
  14#include <linux/netdevice.h>
  15#include <linux/notifier.h>
  16#include <linux/list.h>
  17#include <net/ip_fib.h>
  18
  19#define SWITCHDEV_F_NO_RECURSE          BIT(0)
  20#define SWITCHDEV_F_SKIP_EOPNOTSUPP     BIT(1)
  21#define SWITCHDEV_F_DEFER               BIT(2)
  22
  23struct switchdev_trans_item {
  24        struct list_head list;
  25        void *data;
  26        void (*destructor)(const void *data);
  27};
  28
  29struct switchdev_trans {
  30        struct list_head item_list;
  31        bool ph_prepare;
  32};
  33
  34static inline bool switchdev_trans_ph_prepare(struct switchdev_trans *trans)
  35{
  36        return trans && trans->ph_prepare;
  37}
  38
  39static inline bool switchdev_trans_ph_commit(struct switchdev_trans *trans)
  40{
  41        return trans && !trans->ph_prepare;
  42}
  43
  44enum switchdev_attr_id {
  45        SWITCHDEV_ATTR_ID_UNDEFINED,
  46        SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
  47        SWITCHDEV_ATTR_ID_PORT_STP_STATE,
  48        SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
  49        SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME,
  50        SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING,
  51};
  52
  53struct switchdev_attr {
  54        struct net_device *orig_dev;
  55        enum switchdev_attr_id id;
  56        u32 flags;
  57        void *complete_priv;
  58        void (*complete)(struct net_device *dev, int err, void *priv);
  59        union {
  60                struct netdev_phys_item_id ppid;        /* PORT_PARENT_ID */
  61                u8 stp_state;                           /* PORT_STP_STATE */
  62                unsigned long brport_flags;             /* PORT_BRIDGE_FLAGS */
  63                clock_t ageing_time;                    /* BRIDGE_AGEING_TIME */
  64                bool vlan_filtering;                    /* BRIDGE_VLAN_FILTERING */
  65        } u;
  66};
  67
  68enum switchdev_obj_id {
  69        SWITCHDEV_OBJ_ID_UNDEFINED,
  70        SWITCHDEV_OBJ_ID_PORT_VLAN,
  71        SWITCHDEV_OBJ_ID_PORT_FDB,
  72        SWITCHDEV_OBJ_ID_PORT_MDB,
  73};
  74
  75struct switchdev_obj {
  76        struct net_device *orig_dev;
  77        enum switchdev_obj_id id;
  78        u32 flags;
  79        void *complete_priv;
  80        void (*complete)(struct net_device *dev, int err, void *priv);
  81};
  82
  83/* SWITCHDEV_OBJ_ID_PORT_VLAN */
  84struct switchdev_obj_port_vlan {
  85        struct switchdev_obj obj;
  86        u16 flags;
  87        u16 vid_begin;
  88        u16 vid_end;
  89};
  90
  91#define SWITCHDEV_OBJ_PORT_VLAN(obj) \
  92        container_of(obj, struct switchdev_obj_port_vlan, obj)
  93
  94/* SWITCHDEV_OBJ_ID_PORT_FDB */
  95struct switchdev_obj_port_fdb {
  96        struct switchdev_obj obj;
  97        unsigned char addr[ETH_ALEN];
  98        u16 vid;
  99        u16 ndm_state;
 100};
 101
 102#define SWITCHDEV_OBJ_PORT_FDB(obj) \
 103        container_of(obj, struct switchdev_obj_port_fdb, obj)
 104
 105/* SWITCHDEV_OBJ_ID_PORT_MDB */
 106struct switchdev_obj_port_mdb {
 107        struct switchdev_obj obj;
 108        unsigned char addr[ETH_ALEN];
 109        u16 vid;
 110};
 111
 112#define SWITCHDEV_OBJ_PORT_MDB(obj) \
 113        container_of(obj, struct switchdev_obj_port_mdb, obj)
 114
 115void switchdev_trans_item_enqueue(struct switchdev_trans *trans,
 116                                  void *data, void (*destructor)(void const *),
 117                                  struct switchdev_trans_item *tritem);
 118void *switchdev_trans_item_dequeue(struct switchdev_trans *trans);
 119
 120typedef int switchdev_obj_dump_cb_t(struct switchdev_obj *obj);
 121
 122/**
 123 * struct switchdev_ops - switchdev operations
 124 *
 125 * @switchdev_port_attr_get: Get a port attribute (see switchdev_attr).
 126 *
 127 * @switchdev_port_attr_set: Set a port attribute (see switchdev_attr).
 128 *
 129 * @switchdev_port_obj_add: Add an object to port (see switchdev_obj_*).
 130 *
 131 * @switchdev_port_obj_del: Delete an object from port (see switchdev_obj_*).
 132 *
 133 * @switchdev_port_obj_dump: Dump port objects (see switchdev_obj_*).
 134 */
 135struct switchdev_ops {
 136        int     (*switchdev_port_attr_get)(struct net_device *dev,
 137                                           struct switchdev_attr *attr);
 138        int     (*switchdev_port_attr_set)(struct net_device *dev,
 139                                           const struct switchdev_attr *attr,
 140                                           struct switchdev_trans *trans);
 141        int     (*switchdev_port_obj_add)(struct net_device *dev,
 142                                          const struct switchdev_obj *obj,
 143                                          struct switchdev_trans *trans);
 144        int     (*switchdev_port_obj_del)(struct net_device *dev,
 145                                          const struct switchdev_obj *obj);
 146        int     (*switchdev_port_obj_dump)(struct net_device *dev,
 147                                           struct switchdev_obj *obj,
 148                                           switchdev_obj_dump_cb_t *cb);
 149};
 150
 151enum switchdev_notifier_type {
 152        SWITCHDEV_FDB_ADD = 1,
 153        SWITCHDEV_FDB_DEL,
 154};
 155
 156struct switchdev_notifier_info {
 157        struct net_device *dev;
 158};
 159
 160struct switchdev_notifier_fdb_info {
 161        struct switchdev_notifier_info info; /* must be first */
 162        const unsigned char *addr;
 163        u16 vid;
 164};
 165
 166static inline struct net_device *
 167switchdev_notifier_info_to_dev(const struct switchdev_notifier_info *info)
 168{
 169        return info->dev;
 170}
 171
 172#ifdef CONFIG_NET_SWITCHDEV
 173
 174void switchdev_deferred_process(void);
 175int switchdev_port_attr_get(struct net_device *dev,
 176                            struct switchdev_attr *attr);
 177int switchdev_port_attr_set(struct net_device *dev,
 178                            const struct switchdev_attr *attr);
 179int switchdev_port_obj_add(struct net_device *dev,
 180                           const struct switchdev_obj *obj);
 181int switchdev_port_obj_del(struct net_device *dev,
 182                           const struct switchdev_obj *obj);
 183int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj,
 184                            switchdev_obj_dump_cb_t *cb);
 185int register_switchdev_notifier(struct notifier_block *nb);
 186int unregister_switchdev_notifier(struct notifier_block *nb);
 187int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
 188                             struct switchdev_notifier_info *info);
 189int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
 190                                  struct net_device *dev, u32 filter_mask,
 191                                  int nlflags);
 192int switchdev_port_bridge_setlink(struct net_device *dev,
 193                                  struct nlmsghdr *nlh, u16 flags);
 194int switchdev_port_bridge_dellink(struct net_device *dev,
 195                                  struct nlmsghdr *nlh, u16 flags);
 196int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
 197                           struct net_device *dev, const unsigned char *addr,
 198                           u16 vid, u16 nlm_flags);
 199int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
 200                           struct net_device *dev, const unsigned char *addr,
 201                           u16 vid);
 202int switchdev_port_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
 203                            struct net_device *dev,
 204                            struct net_device *filter_dev, int *idx);
 205void switchdev_port_fwd_mark_set(struct net_device *dev,
 206                                 struct net_device *group_dev,
 207                                 bool joining);
 208
 209bool switchdev_port_same_parent_id(struct net_device *a,
 210                                   struct net_device *b);
 211#else
 212
 213static inline void switchdev_deferred_process(void)
 214{
 215}
 216
 217static inline int switchdev_port_attr_get(struct net_device *dev,
 218                                          struct switchdev_attr *attr)
 219{
 220        return -EOPNOTSUPP;
 221}
 222
 223static inline int switchdev_port_attr_set(struct net_device *dev,
 224                                          const struct switchdev_attr *attr)
 225{
 226        return -EOPNOTSUPP;
 227}
 228
 229static inline int switchdev_port_obj_add(struct net_device *dev,
 230                                         const struct switchdev_obj *obj)
 231{
 232        return -EOPNOTSUPP;
 233}
 234
 235static inline int switchdev_port_obj_del(struct net_device *dev,
 236                                         const struct switchdev_obj *obj)
 237{
 238        return -EOPNOTSUPP;
 239}
 240
 241static inline int switchdev_port_obj_dump(struct net_device *dev,
 242                                          const struct switchdev_obj *obj,
 243                                          switchdev_obj_dump_cb_t *cb)
 244{
 245        return -EOPNOTSUPP;
 246}
 247
 248static inline int register_switchdev_notifier(struct notifier_block *nb)
 249{
 250        return 0;
 251}
 252
 253static inline int unregister_switchdev_notifier(struct notifier_block *nb)
 254{
 255        return 0;
 256}
 257
 258static inline int call_switchdev_notifiers(unsigned long val,
 259                                           struct net_device *dev,
 260                                           struct switchdev_notifier_info *info)
 261{
 262        return NOTIFY_DONE;
 263}
 264
 265static inline int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid,
 266                                            u32 seq, struct net_device *dev,
 267                                            u32 filter_mask, int nlflags)
 268{
 269        return -EOPNOTSUPP;
 270}
 271
 272static inline int switchdev_port_bridge_setlink(struct net_device *dev,
 273                                                struct nlmsghdr *nlh,
 274                                                u16 flags)
 275{
 276        return -EOPNOTSUPP;
 277}
 278
 279static inline int switchdev_port_bridge_dellink(struct net_device *dev,
 280                                                struct nlmsghdr *nlh,
 281                                                u16 flags)
 282{
 283        return -EOPNOTSUPP;
 284}
 285
 286static inline int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
 287                                         struct net_device *dev,
 288                                         const unsigned char *addr,
 289                                         u16 vid, u16 nlm_flags)
 290{
 291        return -EOPNOTSUPP;
 292}
 293
 294static inline int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
 295                                         struct net_device *dev,
 296                                         const unsigned char *addr, u16 vid)
 297{
 298        return -EOPNOTSUPP;
 299}
 300
 301static inline int switchdev_port_fdb_dump(struct sk_buff *skb,
 302                                          struct netlink_callback *cb,
 303                                          struct net_device *dev,
 304                                          struct net_device *filter_dev,
 305                                          int *idx)
 306{
 307       return *idx;
 308}
 309
 310static inline bool switchdev_port_same_parent_id(struct net_device *a,
 311                                                 struct net_device *b)
 312{
 313        return false;
 314}
 315
 316#endif
 317
 318#endif /* _LINUX_SWITCHDEV_H_ */
 319