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