blob: adef8acd85d33993d7797b17989a9419d5b5c64f [file] [log] [blame]
#ifndef __FP_DEVICE_H__
#define __FP_DEVICE_H__
#define FP_DEV_MASK_GB6_SET 0
#define FP_DEV_MASK_LL6_SET 1
#define FP_DEV_MASK_MTU_SET 2
struct fp_dev_list {
struct list_head devices_list;
spinlock_t list_lock;
wait_queue_head_t wq;
atomic_t dev_count;
struct workqueue_struct *dev_put_wq;
};
struct fp_dev_work {
struct list_head list;
struct fp_dev_list *fpdl;
struct delayed_work work;
struct fp_net_device *fpdev;
};
struct fp_net_device_stats {
unsigned long rx_packets;
unsigned long tx_packets;
unsigned long rx_bytes;
unsigned long tx_bytes;
unsigned long rx_errors;
unsigned long tx_errors;
unsigned long rx_dropped;
unsigned long tx_dropped;
unsigned long queue_stopped;
};
struct fp_net_device {
struct kobject kobj;
struct rcu_head rcu;
struct list_head list;
struct work_struct free_work;
struct net_device *dev; /* associated net_device */
struct net_device *br; /* bridge to which this device is attached */
atomic_t refcnt;
unsigned long flags;
bool forward; /* fastpath forwarding enabled/disabled */
struct fp_net_device_stats stats;
struct in6_addr ll6addr;
struct in6_addr gb6addr;
u8 prefixlen;
u32 mtu;
};
int fpdev_add_if(struct net_device *dev);
int fpdev_del_if(struct net_device *dev);
struct fp_net_device *fpdev_get_if(struct net_device *dev);
struct fp_net_device *fpdev_get_ccinet(void);
void destroy_fpdev_rcu(struct rcu_head *rcu);
static inline int fpdev_cmp_if(struct fp_net_device *fdev, struct net_device *dev)
{
return (fdev->dev == dev);
}
/* increment reference to a fastpath device */
static inline struct fp_net_device *fpdev_hold(struct fp_net_device *fpdev)
{
if (fpdev && !atomic_inc_not_zero(&fpdev->refcnt))
return NULL;
return fpdev;
}
/* decrement reference to a fastpath device */
static inline void fpdev_put(struct fp_net_device *fpdev)
{
if (fpdev && atomic_dec_and_test(&fpdev->refcnt))
call_rcu(&fpdev->rcu, destroy_fpdev_rcu);
}
static inline void fpdev_set_gb6(struct fp_net_device *fpdev)
{
set_bit(FP_DEV_MASK_GB6_SET, &fpdev->flags);
}
static inline int fpdev_is_gb6_set(struct fp_net_device *fpdev)
{
return test_bit(FP_DEV_MASK_GB6_SET, &fpdev->flags);
}
static inline void fpdev_clear_gb6(struct fp_net_device *fpdev)
{
clear_bit(FP_DEV_MASK_GB6_SET, &fpdev->flags);
}
static inline void fpdev_set_ll6(struct fp_net_device *fpdev)
{
set_bit(FP_DEV_MASK_LL6_SET, &fpdev->flags);
}
static inline int fpdev_is_ll6_set(struct fp_net_device *fpdev)
{
return test_bit(FP_DEV_MASK_LL6_SET, &fpdev->flags);
}
static inline void fpdev_clear_mtu(struct fp_net_device *fpdev)
{
clear_bit(FP_DEV_MASK_MTU_SET, &fpdev->flags);
}
static inline void fpdev_set_mtu(struct fp_net_device *fpdev)
{
set_bit(FP_DEV_MASK_MTU_SET, &fpdev->flags);
}
static inline int fpdev_is_mtu_set(struct fp_net_device *fpdev)
{
return test_bit(FP_DEV_MASK_MTU_SET, &fpdev->flags);
}
static inline void fpdev_clear_ll6(struct fp_net_device *fpdev)
{
clear_bit(FP_DEV_MASK_LL6_SET, &fpdev->flags);
}
#endif