#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/mutex.h>
#include <linux/notifier.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_bridge.h>
#include <linux/list.h>
#include <linux/workqueue.h>
#include <linux/if_vlan.h>
#include <linux/rtnetlink.h>
#include <net/switchdev.h>
static bool switchdev_obj_eq(const struct switchdev_obj *a,
const struct switchdev_obj *b)
{ … }
static LIST_HEAD(deferred);
static DEFINE_SPINLOCK(deferred_lock);
switchdev_deferred_func_t;
struct switchdev_deferred_item { … };
static struct switchdev_deferred_item *switchdev_deferred_dequeue(void)
{ … }
void switchdev_deferred_process(void)
{ … }
EXPORT_SYMBOL_GPL(…);
static void switchdev_deferred_process_work(struct work_struct *work)
{ … }
static DECLARE_WORK(deferred_process_work, switchdev_deferred_process_work);
static int switchdev_deferred_enqueue(struct net_device *dev,
const void *data, size_t data_len,
switchdev_deferred_func_t *func)
{ … }
static int switchdev_port_attr_notify(enum switchdev_notifier_type nt,
struct net_device *dev,
const struct switchdev_attr *attr,
struct netlink_ext_ack *extack)
{ … }
static int switchdev_port_attr_set_now(struct net_device *dev,
const struct switchdev_attr *attr,
struct netlink_ext_ack *extack)
{ … }
static void switchdev_port_attr_set_deferred(struct net_device *dev,
const void *data)
{ … }
static int switchdev_port_attr_set_defer(struct net_device *dev,
const struct switchdev_attr *attr)
{ … }
int switchdev_port_attr_set(struct net_device *dev,
const struct switchdev_attr *attr,
struct netlink_ext_ack *extack)
{ … }
EXPORT_SYMBOL_GPL(…);
static size_t switchdev_obj_size(const struct switchdev_obj *obj)
{ … }
static int switchdev_port_obj_notify(enum switchdev_notifier_type nt,
struct net_device *dev,
const struct switchdev_obj *obj,
struct netlink_ext_ack *extack)
{ … }
static void switchdev_obj_id_to_helpful_msg(struct net_device *dev,
enum switchdev_obj_id obj_id,
int err, bool add)
{ … }
static void switchdev_port_obj_add_deferred(struct net_device *dev,
const void *data)
{ … }
static int switchdev_port_obj_add_defer(struct net_device *dev,
const struct switchdev_obj *obj)
{ … }
int switchdev_port_obj_add(struct net_device *dev,
const struct switchdev_obj *obj,
struct netlink_ext_ack *extack)
{ … }
EXPORT_SYMBOL_GPL(…);
static int switchdev_port_obj_del_now(struct net_device *dev,
const struct switchdev_obj *obj)
{ … }
static void switchdev_port_obj_del_deferred(struct net_device *dev,
const void *data)
{ … }
static int switchdev_port_obj_del_defer(struct net_device *dev,
const struct switchdev_obj *obj)
{ … }
int switchdev_port_obj_del(struct net_device *dev,
const struct switchdev_obj *obj)
{ … }
EXPORT_SYMBOL_GPL(…);
bool switchdev_port_obj_act_is_deferred(struct net_device *dev,
enum switchdev_notifier_type nt,
const struct switchdev_obj *obj)
{ … }
EXPORT_SYMBOL_GPL(…);
static ATOMIC_NOTIFIER_HEAD(switchdev_notif_chain);
static BLOCKING_NOTIFIER_HEAD(switchdev_blocking_notif_chain);
int register_switchdev_notifier(struct notifier_block *nb)
{ … }
EXPORT_SYMBOL_GPL(…);
int unregister_switchdev_notifier(struct notifier_block *nb)
{ … }
EXPORT_SYMBOL_GPL(…);
int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
struct switchdev_notifier_info *info,
struct netlink_ext_ack *extack)
{ … }
EXPORT_SYMBOL_GPL(…);
int register_switchdev_blocking_notifier(struct notifier_block *nb)
{ … }
EXPORT_SYMBOL_GPL(…);
int unregister_switchdev_blocking_notifier(struct notifier_block *nb)
{ … }
EXPORT_SYMBOL_GPL(…);
int call_switchdev_blocking_notifiers(unsigned long val, struct net_device *dev,
struct switchdev_notifier_info *info,
struct netlink_ext_ack *extack)
{ … }
EXPORT_SYMBOL_GPL(…);
struct switchdev_nested_priv { … };
static int switchdev_lower_dev_walk(struct net_device *lower_dev,
struct netdev_nested_priv *priv)
{ … }
static struct net_device *
switchdev_lower_dev_find_rcu(struct net_device *dev,
bool (*check_cb)(const struct net_device *dev),
bool (*foreign_dev_check_cb)(const struct net_device *dev,
const struct net_device *foreign_dev))
{ … }
static struct net_device *
switchdev_lower_dev_find(struct net_device *dev,
bool (*check_cb)(const struct net_device *dev),
bool (*foreign_dev_check_cb)(const struct net_device *dev,
const struct net_device *foreign_dev))
{ … }
static int __switchdev_handle_fdb_event_to_device(struct net_device *dev,
struct net_device *orig_dev, unsigned long event,
const struct switchdev_notifier_fdb_info *fdb_info,
bool (*check_cb)(const struct net_device *dev),
bool (*foreign_dev_check_cb)(const struct net_device *dev,
const struct net_device *foreign_dev),
int (*mod_cb)(struct net_device *dev, struct net_device *orig_dev,
unsigned long event, const void *ctx,
const struct switchdev_notifier_fdb_info *fdb_info))
{ … }
int switchdev_handle_fdb_event_to_device(struct net_device *dev, unsigned long event,
const struct switchdev_notifier_fdb_info *fdb_info,
bool (*check_cb)(const struct net_device *dev),
bool (*foreign_dev_check_cb)(const struct net_device *dev,
const struct net_device *foreign_dev),
int (*mod_cb)(struct net_device *dev, struct net_device *orig_dev,
unsigned long event, const void *ctx,
const struct switchdev_notifier_fdb_info *fdb_info))
{ … }
EXPORT_SYMBOL_GPL(…);
static int __switchdev_handle_port_obj_add(struct net_device *dev,
struct switchdev_notifier_port_obj_info *port_obj_info,
bool (*check_cb)(const struct net_device *dev),
bool (*foreign_dev_check_cb)(const struct net_device *dev,
const struct net_device *foreign_dev),
int (*add_cb)(struct net_device *dev, const void *ctx,
const struct switchdev_obj *obj,
struct netlink_ext_ack *extack))
{ … }
int switchdev_handle_port_obj_add(struct net_device *dev,
struct switchdev_notifier_port_obj_info *port_obj_info,
bool (*check_cb)(const struct net_device *dev),
int (*add_cb)(struct net_device *dev, const void *ctx,
const struct switchdev_obj *obj,
struct netlink_ext_ack *extack))
{ … }
EXPORT_SYMBOL_GPL(…);
int switchdev_handle_port_obj_add_foreign(struct net_device *dev,
struct switchdev_notifier_port_obj_info *port_obj_info,
bool (*check_cb)(const struct net_device *dev),
bool (*foreign_dev_check_cb)(const struct net_device *dev,
const struct net_device *foreign_dev),
int (*add_cb)(struct net_device *dev, const void *ctx,
const struct switchdev_obj *obj,
struct netlink_ext_ack *extack))
{ … }
EXPORT_SYMBOL_GPL(…);
static int __switchdev_handle_port_obj_del(struct net_device *dev,
struct switchdev_notifier_port_obj_info *port_obj_info,
bool (*check_cb)(const struct net_device *dev),
bool (*foreign_dev_check_cb)(const struct net_device *dev,
const struct net_device *foreign_dev),
int (*del_cb)(struct net_device *dev, const void *ctx,
const struct switchdev_obj *obj))
{ … }
int switchdev_handle_port_obj_del(struct net_device *dev,
struct switchdev_notifier_port_obj_info *port_obj_info,
bool (*check_cb)(const struct net_device *dev),
int (*del_cb)(struct net_device *dev, const void *ctx,
const struct switchdev_obj *obj))
{ … }
EXPORT_SYMBOL_GPL(…);
int switchdev_handle_port_obj_del_foreign(struct net_device *dev,
struct switchdev_notifier_port_obj_info *port_obj_info,
bool (*check_cb)(const struct net_device *dev),
bool (*foreign_dev_check_cb)(const struct net_device *dev,
const struct net_device *foreign_dev),
int (*del_cb)(struct net_device *dev, const void *ctx,
const struct switchdev_obj *obj))
{ … }
EXPORT_SYMBOL_GPL(…);
static int __switchdev_handle_port_attr_set(struct net_device *dev,
struct switchdev_notifier_port_attr_info *port_attr_info,
bool (*check_cb)(const struct net_device *dev),
int (*set_cb)(struct net_device *dev, const void *ctx,
const struct switchdev_attr *attr,
struct netlink_ext_ack *extack))
{ … }
int switchdev_handle_port_attr_set(struct net_device *dev,
struct switchdev_notifier_port_attr_info *port_attr_info,
bool (*check_cb)(const struct net_device *dev),
int (*set_cb)(struct net_device *dev, const void *ctx,
const struct switchdev_attr *attr,
struct netlink_ext_ack *extack))
{ … }
EXPORT_SYMBOL_GPL(…);
int switchdev_bridge_port_offload(struct net_device *brport_dev,
struct net_device *dev, const void *ctx,
struct notifier_block *atomic_nb,
struct notifier_block *blocking_nb,
bool tx_fwd_offload,
struct netlink_ext_ack *extack)
{ … }
EXPORT_SYMBOL_GPL(…);
void switchdev_bridge_port_unoffload(struct net_device *brport_dev,
const void *ctx,
struct notifier_block *atomic_nb,
struct notifier_block *blocking_nb)
{ … }
EXPORT_SYMBOL_GPL(…);
int switchdev_bridge_port_replay(struct net_device *brport_dev,
struct net_device *dev, const void *ctx,
struct notifier_block *atomic_nb,
struct notifier_block *blocking_nb,
struct netlink_ext_ack *extack)
{ … }
EXPORT_SYMBOL_GPL(…);