xref: /OK3568_Linux_fs/kernel/drivers/net/ipvlan/ipvlan.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (c) 2014 Mahesh Bandewar <maheshb@google.com>
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun #ifndef __IPVLAN_H
6*4882a593Smuzhiyun #define __IPVLAN_H
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <linux/kernel.h>
9*4882a593Smuzhiyun #include <linux/types.h>
10*4882a593Smuzhiyun #include <linux/module.h>
11*4882a593Smuzhiyun #include <linux/init.h>
12*4882a593Smuzhiyun #include <linux/rculist.h>
13*4882a593Smuzhiyun #include <linux/notifier.h>
14*4882a593Smuzhiyun #include <linux/netdevice.h>
15*4882a593Smuzhiyun #include <linux/etherdevice.h>
16*4882a593Smuzhiyun #include <linux/if_arp.h>
17*4882a593Smuzhiyun #include <linux/if_link.h>
18*4882a593Smuzhiyun #include <linux/if_vlan.h>
19*4882a593Smuzhiyun #include <linux/ip.h>
20*4882a593Smuzhiyun #include <linux/inetdevice.h>
21*4882a593Smuzhiyun #include <linux/netfilter.h>
22*4882a593Smuzhiyun #include <net/ip.h>
23*4882a593Smuzhiyun #include <net/ip6_route.h>
24*4882a593Smuzhiyun #include <net/netns/generic.h>
25*4882a593Smuzhiyun #include <net/rtnetlink.h>
26*4882a593Smuzhiyun #include <net/route.h>
27*4882a593Smuzhiyun #include <net/addrconf.h>
28*4882a593Smuzhiyun #include <net/l3mdev.h>
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun #define IPVLAN_DRV	"ipvlan"
31*4882a593Smuzhiyun #define IPV_DRV_VER	"0.1"
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun #define IPVLAN_HASH_SIZE	(1 << BITS_PER_BYTE)
34*4882a593Smuzhiyun #define IPVLAN_HASH_MASK	(IPVLAN_HASH_SIZE - 1)
35*4882a593Smuzhiyun 
36*4882a593Smuzhiyun #define IPVLAN_MAC_FILTER_BITS	8
37*4882a593Smuzhiyun #define IPVLAN_MAC_FILTER_SIZE	(1 << IPVLAN_MAC_FILTER_BITS)
38*4882a593Smuzhiyun #define IPVLAN_MAC_FILTER_MASK	(IPVLAN_MAC_FILTER_SIZE - 1)
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun #define IPVLAN_QBACKLOG_LIMIT	1000
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun typedef enum {
43*4882a593Smuzhiyun 	IPVL_IPV6 = 0,
44*4882a593Smuzhiyun 	IPVL_ICMPV6,
45*4882a593Smuzhiyun 	IPVL_IPV4,
46*4882a593Smuzhiyun 	IPVL_ARP,
47*4882a593Smuzhiyun } ipvl_hdr_type;
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun struct ipvl_pcpu_stats {
50*4882a593Smuzhiyun 	u64			rx_pkts;
51*4882a593Smuzhiyun 	u64			rx_bytes;
52*4882a593Smuzhiyun 	u64			rx_mcast;
53*4882a593Smuzhiyun 	u64			tx_pkts;
54*4882a593Smuzhiyun 	u64			tx_bytes;
55*4882a593Smuzhiyun 	struct u64_stats_sync	syncp;
56*4882a593Smuzhiyun 	u32			rx_errs;
57*4882a593Smuzhiyun 	u32			tx_drps;
58*4882a593Smuzhiyun };
59*4882a593Smuzhiyun 
60*4882a593Smuzhiyun struct ipvl_port;
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun struct ipvl_dev {
63*4882a593Smuzhiyun 	struct net_device	*dev;
64*4882a593Smuzhiyun 	struct list_head	pnode;
65*4882a593Smuzhiyun 	struct ipvl_port	*port;
66*4882a593Smuzhiyun 	struct net_device	*phy_dev;
67*4882a593Smuzhiyun 	struct list_head	addrs;
68*4882a593Smuzhiyun 	struct ipvl_pcpu_stats	__percpu *pcpu_stats;
69*4882a593Smuzhiyun 	DECLARE_BITMAP(mac_filters, IPVLAN_MAC_FILTER_SIZE);
70*4882a593Smuzhiyun 	netdev_features_t	sfeatures;
71*4882a593Smuzhiyun 	u32			msg_enable;
72*4882a593Smuzhiyun 	spinlock_t		addrs_lock;
73*4882a593Smuzhiyun };
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun struct ipvl_addr {
76*4882a593Smuzhiyun 	struct ipvl_dev		*master; /* Back pointer to master */
77*4882a593Smuzhiyun 	union {
78*4882a593Smuzhiyun 		struct in6_addr	ip6;	 /* IPv6 address on logical interface */
79*4882a593Smuzhiyun 		struct in_addr	ip4;	 /* IPv4 address on logical interface */
80*4882a593Smuzhiyun 	} ipu;
81*4882a593Smuzhiyun #define ip6addr	ipu.ip6
82*4882a593Smuzhiyun #define ip4addr ipu.ip4
83*4882a593Smuzhiyun 	struct hlist_node	hlnode;  /* Hash-table linkage */
84*4882a593Smuzhiyun 	struct list_head	anode;   /* logical-interface linkage */
85*4882a593Smuzhiyun 	ipvl_hdr_type		atype;
86*4882a593Smuzhiyun 	struct rcu_head		rcu;
87*4882a593Smuzhiyun };
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun struct ipvl_port {
90*4882a593Smuzhiyun 	struct net_device	*dev;
91*4882a593Smuzhiyun 	possible_net_t		pnet;
92*4882a593Smuzhiyun 	struct hlist_head	hlhead[IPVLAN_HASH_SIZE];
93*4882a593Smuzhiyun 	struct list_head	ipvlans;
94*4882a593Smuzhiyun 	u16			mode;
95*4882a593Smuzhiyun 	u16			flags;
96*4882a593Smuzhiyun 	u16			dev_id_start;
97*4882a593Smuzhiyun 	struct work_struct	wq;
98*4882a593Smuzhiyun 	struct sk_buff_head	backlog;
99*4882a593Smuzhiyun 	int			count;
100*4882a593Smuzhiyun 	struct ida		ida;
101*4882a593Smuzhiyun };
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun struct ipvl_skb_cb {
104*4882a593Smuzhiyun 	bool tx_pkt;
105*4882a593Smuzhiyun };
106*4882a593Smuzhiyun #define IPVL_SKB_CB(_skb) ((struct ipvl_skb_cb *)&((_skb)->cb[0]))
107*4882a593Smuzhiyun 
ipvlan_port_get_rcu(const struct net_device * d)108*4882a593Smuzhiyun static inline struct ipvl_port *ipvlan_port_get_rcu(const struct net_device *d)
109*4882a593Smuzhiyun {
110*4882a593Smuzhiyun 	return rcu_dereference(d->rx_handler_data);
111*4882a593Smuzhiyun }
112*4882a593Smuzhiyun 
ipvlan_port_get_rcu_bh(const struct net_device * d)113*4882a593Smuzhiyun static inline struct ipvl_port *ipvlan_port_get_rcu_bh(const struct net_device *d)
114*4882a593Smuzhiyun {
115*4882a593Smuzhiyun 	return rcu_dereference_bh(d->rx_handler_data);
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun 
ipvlan_port_get_rtnl(const struct net_device * d)118*4882a593Smuzhiyun static inline struct ipvl_port *ipvlan_port_get_rtnl(const struct net_device *d)
119*4882a593Smuzhiyun {
120*4882a593Smuzhiyun 	return rtnl_dereference(d->rx_handler_data);
121*4882a593Smuzhiyun }
122*4882a593Smuzhiyun 
ipvlan_is_private(const struct ipvl_port * port)123*4882a593Smuzhiyun static inline bool ipvlan_is_private(const struct ipvl_port *port)
124*4882a593Smuzhiyun {
125*4882a593Smuzhiyun 	return !!(port->flags & IPVLAN_F_PRIVATE);
126*4882a593Smuzhiyun }
127*4882a593Smuzhiyun 
ipvlan_mark_private(struct ipvl_port * port)128*4882a593Smuzhiyun static inline void ipvlan_mark_private(struct ipvl_port *port)
129*4882a593Smuzhiyun {
130*4882a593Smuzhiyun 	port->flags |= IPVLAN_F_PRIVATE;
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun 
ipvlan_clear_private(struct ipvl_port * port)133*4882a593Smuzhiyun static inline void ipvlan_clear_private(struct ipvl_port *port)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun 	port->flags &= ~IPVLAN_F_PRIVATE;
136*4882a593Smuzhiyun }
137*4882a593Smuzhiyun 
ipvlan_is_vepa(const struct ipvl_port * port)138*4882a593Smuzhiyun static inline bool ipvlan_is_vepa(const struct ipvl_port *port)
139*4882a593Smuzhiyun {
140*4882a593Smuzhiyun 	return !!(port->flags & IPVLAN_F_VEPA);
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun 
ipvlan_mark_vepa(struct ipvl_port * port)143*4882a593Smuzhiyun static inline void ipvlan_mark_vepa(struct ipvl_port *port)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun 	port->flags |= IPVLAN_F_VEPA;
146*4882a593Smuzhiyun }
147*4882a593Smuzhiyun 
ipvlan_clear_vepa(struct ipvl_port * port)148*4882a593Smuzhiyun static inline void ipvlan_clear_vepa(struct ipvl_port *port)
149*4882a593Smuzhiyun {
150*4882a593Smuzhiyun 	port->flags &= ~IPVLAN_F_VEPA;
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun void ipvlan_init_secret(void);
154*4882a593Smuzhiyun unsigned int ipvlan_mac_hash(const unsigned char *addr);
155*4882a593Smuzhiyun rx_handler_result_t ipvlan_handle_frame(struct sk_buff **pskb);
156*4882a593Smuzhiyun void ipvlan_process_multicast(struct work_struct *work);
157*4882a593Smuzhiyun int ipvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev);
158*4882a593Smuzhiyun void ipvlan_ht_addr_add(struct ipvl_dev *ipvlan, struct ipvl_addr *addr);
159*4882a593Smuzhiyun struct ipvl_addr *ipvlan_find_addr(const struct ipvl_dev *ipvlan,
160*4882a593Smuzhiyun 				   const void *iaddr, bool is_v6);
161*4882a593Smuzhiyun bool ipvlan_addr_busy(struct ipvl_port *port, void *iaddr, bool is_v6);
162*4882a593Smuzhiyun void ipvlan_ht_addr_del(struct ipvl_addr *addr);
163*4882a593Smuzhiyun struct ipvl_addr *ipvlan_addr_lookup(struct ipvl_port *port, void *lyr3h,
164*4882a593Smuzhiyun 				     int addr_type, bool use_dest);
165*4882a593Smuzhiyun void *ipvlan_get_L3_hdr(struct ipvl_port *port, struct sk_buff *skb, int *type);
166*4882a593Smuzhiyun void ipvlan_count_rx(const struct ipvl_dev *ipvlan,
167*4882a593Smuzhiyun 		     unsigned int len, bool success, bool mcast);
168*4882a593Smuzhiyun int ipvlan_link_new(struct net *src_net, struct net_device *dev,
169*4882a593Smuzhiyun 		    struct nlattr *tb[], struct nlattr *data[],
170*4882a593Smuzhiyun 		    struct netlink_ext_ack *extack);
171*4882a593Smuzhiyun void ipvlan_link_delete(struct net_device *dev, struct list_head *head);
172*4882a593Smuzhiyun void ipvlan_link_setup(struct net_device *dev);
173*4882a593Smuzhiyun int ipvlan_link_register(struct rtnl_link_ops *ops);
174*4882a593Smuzhiyun #ifdef CONFIG_IPVLAN_L3S
175*4882a593Smuzhiyun int ipvlan_l3s_register(struct ipvl_port *port);
176*4882a593Smuzhiyun void ipvlan_l3s_unregister(struct ipvl_port *port);
177*4882a593Smuzhiyun void ipvlan_migrate_l3s_hook(struct net *oldnet, struct net *newnet);
178*4882a593Smuzhiyun int ipvlan_l3s_init(void);
179*4882a593Smuzhiyun void ipvlan_l3s_cleanup(void);
180*4882a593Smuzhiyun #else
ipvlan_l3s_register(struct ipvl_port * port)181*4882a593Smuzhiyun static inline int ipvlan_l3s_register(struct ipvl_port *port)
182*4882a593Smuzhiyun {
183*4882a593Smuzhiyun 	return -ENOTSUPP;
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun 
ipvlan_l3s_unregister(struct ipvl_port * port)186*4882a593Smuzhiyun static inline void ipvlan_l3s_unregister(struct ipvl_port *port)
187*4882a593Smuzhiyun {
188*4882a593Smuzhiyun }
189*4882a593Smuzhiyun 
ipvlan_migrate_l3s_hook(struct net * oldnet,struct net * newnet)190*4882a593Smuzhiyun static inline void ipvlan_migrate_l3s_hook(struct net *oldnet,
191*4882a593Smuzhiyun 					   struct net *newnet)
192*4882a593Smuzhiyun {
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun 
ipvlan_l3s_init(void)195*4882a593Smuzhiyun static inline int ipvlan_l3s_init(void)
196*4882a593Smuzhiyun {
197*4882a593Smuzhiyun 	return 0;
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun 
ipvlan_l3s_cleanup(void)200*4882a593Smuzhiyun static inline void ipvlan_l3s_cleanup(void)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun #endif /* CONFIG_IPVLAN_L3S */
204*4882a593Smuzhiyun 
netif_is_ipvlan_port(const struct net_device * dev)205*4882a593Smuzhiyun static inline bool netif_is_ipvlan_port(const struct net_device *dev)
206*4882a593Smuzhiyun {
207*4882a593Smuzhiyun 	return rcu_access_pointer(dev->rx_handler) == ipvlan_handle_frame;
208*4882a593Smuzhiyun }
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun #endif /* __IPVLAN_H */
211