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_PORT_BRIDGE_FLAGS_SUPPORT,
  50        SWITCHDEV_ATTR_ID_PORT_MROUTER,
  51        SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME,
  52        SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING,
  53        SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED,
  54        SWITCHDEV_ATTR_ID_BRIDGE_MROUTER,
  55};
  56
  57struct switchdev_attr {
  58        struct net_device *orig_dev;
  59        enum switchdev_attr_id id;
  60        u32 flags;
  61        void *complete_priv;
  62        void (*complete)(struct net_device *dev, int err, void *priv);
  63        union {
  64                struct netdev_phys_item_id ppid;        /* PORT_PARENT_ID */
  65                u8 stp_state;                           /* PORT_STP_STATE */
  66                unsigned long brport_flags;             /* PORT_BRIDGE_FLAGS */
  67                unsigned long brport_flags_support;     /* PORT_BRIDGE_FLAGS_SUPPORT */
  68                bool mrouter;                           /* PORT_MROUTER */
  69                clock_t ageing_time;                    /* BRIDGE_AGEING_TIME */
  70                bool vlan_filtering;                    /* BRIDGE_VLAN_FILTERING */
  71                bool mc_disabled;                       /* MC_DISABLED */
  72        } u;
  73};
  74
  75enum switchdev_obj_id {
  76        SWITCHDEV_OBJ_ID_UNDEFINED,
  77        SWITCHDEV_OBJ_ID_PORT_VLAN,
  78        SWITCHDEV_OBJ_ID_PORT_MDB,
  79        SWITCHDEV_OBJ_ID_HOST_MDB,
  80};
  81
  82struct switchdev_obj {
  83        struct net_device *orig_dev;
  84        enum switchdev_obj_id id;
  85        u32 flags;
  86        void *complete_priv;
  87        void (*complete)(struct net_device *dev, int err, void *priv);
  88};
  89
  90/* SWITCHDEV_OBJ_ID_PORT_VLAN */
  91struct switchdev_obj_port_vlan {
  92        struct switchdev_obj obj;
  93        u16 flags;
  94        u16 vid_begin;
  95        u16 vid_end;
  96};
  97
  98#define SWITCHDEV_OBJ_PORT_VLAN(obj) \
  99        container_of(obj, struct switchdev_obj_port_vlan, obj)
 100
 101/* SWITCHDEV_OBJ_ID_PORT_MDB */
 102struct switchdev_obj_port_mdb {
 103        struct switchdev_obj obj;
 104        unsigned char addr[ETH_ALEN];
 105        u16 vid;
 106};
 107
 108#define SWITCHDEV_OBJ_PORT_MDB(obj) \
 109        container_of(obj, struct switchdev_obj_port_mdb, obj)
 110
 111void switchdev_trans_item_enqueue(struct switchdev_trans *trans,
 112                                  void *data, void (*destructor)(void const *),
 113                                  struct switchdev_trans_item *tritem);
 114void *switchdev_trans_item_dequeue(struct switchdev_trans *trans);
 115
 116typedef int switchdev_obj_dump_cb_t(struct switchdev_obj *obj);
 117
 118/**
 119 * struct switchdev_ops - switchdev operations
 120 *
 121 * @switchdev_port_attr_get: Get a port attribute (see switchdev_attr).
 122 *
 123 * @switchdev_port_attr_set: Set a port attribute (see switchdev_attr).
 124 *
 125 * @switchdev_port_obj_add: Add an object to port (see switchdev_obj_*).
 126 *
 127 * @switchdev_port_obj_del: Delete an object from port (see switchdev_obj_*).
 128 */
 129struct switchdev_ops {
 130        int     (*switchdev_port_attr_get)(struct net_device *dev,
 131                                           struct switchdev_attr *attr);
 132        int     (*switchdev_port_attr_set)(struct net_device *dev,
 133                                           const struct switchdev_attr *attr,
 134                                           struct switchdev_trans *trans);
 135        int     (*switchdev_port_obj_add)(struct net_device *dev,
 136                                          const struct switchdev_obj *obj,
 137                                          struct switchdev_trans *trans);
 138        int     (*switchdev_port_obj_del)(struct net_device *dev,
 139                                          const struct switchdev_obj *obj);
 140};
 141
 142enum switchdev_notifier_type {
 143        SWITCHDEV_FDB_ADD_TO_BRIDGE = 1,
 144        SWITCHDEV_FDB_DEL_TO_BRIDGE,
 145        SWITCHDEV_FDB_ADD_TO_DEVICE,
 146        SWITCHDEV_FDB_DEL_TO_DEVICE,
 147        SWITCHDEV_FDB_OFFLOADED,
 148};
 149
 150struct switchdev_notifier_info {
 151        struct net_device *dev;
 152};
 153
 154struct switchdev_notifier_fdb_info {
 155        struct switchdev_notifier_info info; /* must be first */
 156        const unsigned char *addr;
 157        u16 vid;
 158};
 159
 160static inline struct net_device *
 161switchdev_notifier_info_to_dev(const struct switchdev_notifier_info *info)
 162{
 163        return info->dev;
 164}
 165
 166#ifdef CONFIG_NET_SWITCHDEV
 167
 168void switchdev_deferred_process(void);
 169int switchdev_port_attr_get(struct net_device *dev,
 170                            struct switchdev_attr *attr);
 171int switchdev_port_attr_set(struct net_device *dev,
 172                            const struct switchdev_attr *attr);
 173int switchdev_port_obj_add(struct net_device *dev,
 174                           const struct switchdev_obj *obj);
 175int switchdev_port_obj_del(struct net_device *dev,
 176                           const struct switchdev_obj *obj);
 177int register_switchdev_notifier(struct notifier_block *nb);
 178int unregister_switchdev_notifier(struct notifier_block *nb);
 179int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
 180                             struct switchdev_notifier_info *info);
 181void switchdev_port_fwd_mark_set(struct net_device *dev,
 182                                 struct net_device *group_dev,
 183                                 bool joining);
 184
 185bool switchdev_port_same_parent_id(struct net_device *a,
 186                                   struct net_device *b);
 187
 188#define SWITCHDEV_SET_OPS(netdev, ops) ((netdev)->switchdev_ops = (ops))
 189#else
 190
 191static inline void switchdev_deferred_process(void)
 192{
 193}
 194
 195static inline int switchdev_port_attr_get(struct net_device *dev,
 196                                          struct switchdev_attr *attr)
 197{
 198        return -EOPNOTSUPP;
 199}
 200
 201static inline int switchdev_port_attr_set(struct net_device *dev,
 202                                          const struct switchdev_attr *attr)
 203{
 204        return -EOPNOTSUPP;
 205}
 206
 207static inline int switchdev_port_obj_add(struct net_device *dev,
 208                                         const struct switchdev_obj *obj)
 209{
 210        return -EOPNOTSUPP;
 211}
 212
 213static inline int switchdev_port_obj_del(struct net_device *dev,
 214                                         const struct switchdev_obj *obj)
 215{
 216        return -EOPNOTSUPP;
 217}
 218
 219static inline int register_switchdev_notifier(struct notifier_block *nb)
 220{
 221        return 0;
 222}
 223
 224static inline int unregister_switchdev_notifier(struct notifier_block *nb)
 225{
 226        return 0;
 227}
 228
 229static inline int call_switchdev_notifiers(unsigned long val,
 230                                           struct net_device *dev,
 231                                           struct switchdev_notifier_info *info)
 232{
 233        return NOTIFY_DONE;
 234}
 235
 236static inline bool switchdev_port_same_parent_id(struct net_device *a,
 237                                                 struct net_device *b)
 238{
 239        return false;
 240}
 241
 242#define SWITCHDEV_SET_OPS(netdev, ops) do {} while (0)
 243
 244#endif
 245
 246#endif /* _LINUX_SWITCHDEV_H_ */
 247