2014-11-24 10:07:46 +03:00
/*
* Copyright ( c ) 2014 Mahesh Bandewar < maheshb @ google . com >
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation ; either version 2 of
* the License , or ( at your option ) any later version .
*
*/
# ifndef __IPVLAN_H
# define __IPVLAN_H
# include <linux/kernel.h>
# include <linux/types.h>
# include <linux/module.h>
# include <linux/init.h>
# include <linux/rculist.h>
# include <linux/notifier.h>
# include <linux/netdevice.h>
# include <linux/etherdevice.h>
# include <linux/if_arp.h>
# include <linux/if_link.h>
# include <linux/if_vlan.h>
# include <linux/ip.h>
# include <linux/inetdevice.h>
2016-09-16 22:59:19 +03:00
# include <linux/netfilter.h>
2014-11-27 08:13:45 +03:00
# include <net/ip.h>
# include <net/ip6_route.h>
2017-04-20 19:08:15 +03:00
# include <net/netns/generic.h>
2014-11-24 10:07:46 +03:00
# include <net/rtnetlink.h>
# include <net/route.h>
# include <net/addrconf.h>
2016-09-16 22:59:19 +03:00
# include <net/l3mdev.h>
2014-11-24 10:07:46 +03:00
# define IPVLAN_DRV "ipvlan"
# define IPV_DRV_VER "0.1"
# define IPVLAN_HASH_SIZE (1 << BITS_PER_BYTE)
# define IPVLAN_HASH_MASK (IPVLAN_HASH_SIZE - 1)
# define IPVLAN_MAC_FILTER_BITS 8
# define IPVLAN_MAC_FILTER_SIZE (1 << IPVLAN_MAC_FILTER_BITS)
# define IPVLAN_MAC_FILTER_MASK (IPVLAN_MAC_FILTER_SIZE - 1)
2015-05-05 03:06:03 +03:00
# define IPVLAN_QBACKLOG_LIMIT 1000
2014-11-24 10:07:46 +03:00
typedef enum {
IPVL_IPV6 = 0 ,
IPVL_ICMPV6 ,
IPVL_IPV4 ,
IPVL_ARP ,
} ipvl_hdr_type ;
struct ipvl_pcpu_stats {
u64 rx_pkts ;
u64 rx_bytes ;
u64 rx_mcast ;
u64 tx_pkts ;
u64 tx_bytes ;
struct u64_stats_sync syncp ;
u32 rx_errs ;
u32 tx_drps ;
} ;
struct ipvl_port ;
struct ipvl_dev {
struct net_device * dev ;
struct list_head pnode ;
struct ipvl_port * port ;
struct net_device * phy_dev ;
struct list_head addrs ;
2015-02-12 06:51:46 +03:00
struct ipvl_pcpu_stats __percpu * pcpu_stats ;
2014-11-24 10:07:46 +03:00
DECLARE_BITMAP ( mac_filters , IPVLAN_MAC_FILTER_SIZE ) ;
netdev_features_t sfeatures ;
u32 msg_enable ;
} ;
struct ipvl_addr {
struct ipvl_dev * master ; /* Back pointer to master */
union {
struct in6_addr ip6 ; /* IPv6 address on logical interface */
struct in_addr ip4 ; /* IPv4 address on logical interface */
} ipu ;
# define ip6addr ipu.ip6
# define ip4addr ipu.ip4
struct hlist_node hlnode ; /* Hash-table linkage */
struct list_head anode ; /* logical-interface linkage */
ipvl_hdr_type atype ;
2016-02-21 06:31:41 +03:00
struct rcu_head rcu ;
2014-11-24 10:07:46 +03:00
} ;
struct ipvl_port {
struct net_device * dev ;
2017-04-20 19:08:15 +03:00
possible_net_t pnet ;
2014-11-24 10:07:46 +03:00
struct hlist_head hlhead [ IPVLAN_HASH_SIZE ] ;
struct list_head ipvlans ;
2016-02-21 06:31:41 +03:00
u16 mode ;
2017-10-27 01:09:21 +03:00
u16 flags ;
2017-01-10 02:05:54 +03:00
u16 dev_id_start ;
2015-05-05 03:06:03 +03:00
struct work_struct wq ;
struct sk_buff_head backlog ;
2014-11-24 10:07:46 +03:00
int count ;
2017-01-03 23:47:16 +03:00
struct ida ida ;
2014-11-24 10:07:46 +03:00
} ;
2016-12-22 04:30:16 +03:00
struct ipvl_skb_cb {
bool tx_pkt ;
} ;
# define IPVL_SKB_CB(_skb) ((struct ipvl_skb_cb *)&((_skb)->cb[0]))
2014-11-24 10:07:46 +03:00
static inline struct ipvl_port * ipvlan_port_get_rcu ( const struct net_device * d )
{
return rcu_dereference ( d - > rx_handler_data ) ;
}
2015-07-14 16:35:54 +03:00
static inline struct ipvl_port * ipvlan_port_get_rcu_bh ( const struct net_device * d )
{
return rcu_dereference_bh ( d - > rx_handler_data ) ;
}
2014-11-24 10:07:46 +03:00
static inline struct ipvl_port * ipvlan_port_get_rtnl ( const struct net_device * d )
{
return rtnl_dereference ( d - > rx_handler_data ) ;
}
2017-10-27 01:09:21 +03:00
static inline bool ipvlan_is_private ( const struct ipvl_port * port )
{
return ! ! ( port - > flags & IPVLAN_F_PRIVATE ) ;
}
static inline void ipvlan_mark_private ( struct ipvl_port * port )
{
port - > flags | = IPVLAN_F_PRIVATE ;
}
static inline void ipvlan_clear_private ( struct ipvl_port * port )
{
port - > flags & = ~ IPVLAN_F_PRIVATE ;
}
2017-10-27 01:09:25 +03:00
static inline bool ipvlan_is_vepa ( const struct ipvl_port * port )
{
return ! ! ( port - > flags & IPVLAN_F_VEPA ) ;
}
static inline void ipvlan_mark_vepa ( struct ipvl_port * port )
{
port - > flags | = IPVLAN_F_VEPA ;
}
static inline void ipvlan_clear_vepa ( struct ipvl_port * port )
{
port - > flags & = ~ IPVLAN_F_VEPA ;
}
2014-11-24 10:07:46 +03:00
void ipvlan_init_secret ( void ) ;
unsigned int ipvlan_mac_hash ( const unsigned char * addr ) ;
rx_handler_result_t ipvlan_handle_frame ( struct sk_buff * * pskb ) ;
2015-05-05 03:06:03 +03:00
void ipvlan_process_multicast ( struct work_struct * work ) ;
2014-11-24 10:07:46 +03:00
int ipvlan_queue_xmit ( struct sk_buff * skb , struct net_device * dev ) ;
void ipvlan_ht_addr_add ( struct ipvl_dev * ipvlan , struct ipvl_addr * addr ) ;
2015-03-28 21:13:25 +03:00
struct ipvl_addr * ipvlan_find_addr ( const struct ipvl_dev * ipvlan ,
const void * iaddr , bool is_v6 ) ;
bool ipvlan_addr_busy ( struct ipvl_port * port , void * iaddr , bool is_v6 ) ;
2015-07-14 16:35:53 +03:00
void ipvlan_ht_addr_del ( struct ipvl_addr * addr ) ;
2016-09-16 22:59:19 +03:00
struct sk_buff * ipvlan_l3_rcv ( struct net_device * dev , struct sk_buff * skb ,
u16 proto ) ;
unsigned int ipvlan_nf_input ( void * priv , struct sk_buff * skb ,
const struct nf_hook_state * state ) ;
2017-02-11 03:03:52 +03:00
void ipvlan_count_rx ( const struct ipvl_dev * ipvlan ,
unsigned int len , bool success , bool mcast ) ;
int ipvlan_link_new ( struct net * src_net , struct net_device * dev ,
2017-06-26 00:55:59 +03:00
struct nlattr * tb [ ] , struct nlattr * data [ ] ,
struct netlink_ext_ack * extack ) ;
2017-02-11 03:03:52 +03:00
void ipvlan_link_delete ( struct net_device * dev , struct list_head * head ) ;
void ipvlan_link_setup ( struct net_device * dev ) ;
int ipvlan_link_register ( struct rtnl_link_ops * ops ) ;
2014-11-24 10:07:46 +03:00
# endif /* __IPVLAN_H */