Blame view

drivers/net/macvlan.c 45 KB
2874c5fd2   Thomas Gleixner   treewide: Replace...
1
  // SPDX-License-Identifier: GPL-2.0-or-later
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
2
3
4
  /*
   * Copyright (c) 2007 Patrick McHardy <kaber@trash.net>
   *
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
5
6
7
8
9
10
11
12
13
14
15
16
17
18
   * The code this is based on carried the following copyright notice:
   * ---
   * (C) Copyright 2001-2006
   * Alex Zeffertt, Cambridge Broadband Ltd, ajz@cambridgebroadband.com
   * Re-worked by Ben Greear <greearb@candelatech.com>
   * ---
   */
  #include <linux/kernel.h>
  #include <linux/types.h>
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/errno.h>
  #include <linux/slab.h>
  #include <linux/string.h>
82524746c   Franck Bui-Huu   rcu: split list.h...
19
  #include <linux/rculist.h>
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
20
21
22
  #include <linux/notifier.h>
  #include <linux/netdevice.h>
  #include <linux/etherdevice.h>
254c0a2bf   Hangbin Liu   macvlan: pass get...
23
  #include <linux/net_tstamp.h>
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
24
25
  #include <linux/ethtool.h>
  #include <linux/if_arp.h>
87002b03b   Jiri Pirko   net: introduce vl...
26
  #include <linux/if_vlan.h>
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
27
28
  #include <linux/if_link.h>
  #include <linux/if_macvlan.h>
cd431e738   Eric Dumazet   macvlan: add mult...
29
  #include <linux/hash.h>
412ca1550   Herbert Xu   macvlan: Move bro...
30
  #include <linux/workqueue.h>
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
31
  #include <net/rtnetlink.h>
618e1b748   Arnd Bergmann   macvlan: implemen...
32
  #include <net/xfrm.h>
688cea83f   dingtianhong   macvlan: add netp...
33
  #include <linux/netpoll.h>
254c0a2bf   Hangbin Liu   macvlan: pass get...
34
  #include <linux/phy.h>
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
35

79cf79abc   Michael Braun   macvlan: add sour...
36
37
  #define MACVLAN_HASH_BITS	8
  #define MACVLAN_HASH_SIZE	(1<<MACVLAN_HASH_BITS)
07d92d5cc   Nicolas Dichtel   macvlan: allow to...
38
  #define MACVLAN_BC_QUEUE_LEN	1000
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
39

43c2d578a   Vlad Yasevich   macvlan: convert ...
40
  #define MACVLAN_F_PASSTHRU	1
18c8c54de   Vlad Yasevich   macvlan: Let pass...
41
  #define MACVLAN_F_ADDRCHANGE	2
43c2d578a   Vlad Yasevich   macvlan: convert ...
42

b863ceb7d   Patrick McHardy   [NET]: Add macvla...
43
44
45
46
  struct macvlan_port {
  	struct net_device	*dev;
  	struct hlist_head	vlan_hash[MACVLAN_HASH_SIZE];
  	struct list_head	vlans;
412ca1550   Herbert Xu   macvlan: Move bro...
47
48
  	struct sk_buff_head	bc_queue;
  	struct work_struct	bc_work;
43c2d578a   Vlad Yasevich   macvlan: convert ...
49
  	u32			flags;
5e3c516b5   David S. Miller   Revert "macvlan: ...
50
  	int			count;
79cf79abc   Michael Braun   macvlan: add sour...
51
  	struct hlist_head	vlan_source_hash[MACVLAN_HASH_SIZE];
9c127a016   Herbert Xu   macvlan: Avoid un...
52
  	DECLARE_BITMAP(mc_filter, MACVLAN_MC_FILTER_SZ);
18c8c54de   Vlad Yasevich   macvlan: Let pass...
53
  	unsigned char           perm_addr[ETH_ALEN];
79cf79abc   Michael Braun   macvlan: add sour...
54
55
56
57
58
59
60
  };
  
  struct macvlan_source_entry {
  	struct hlist_node	hlist;
  	struct macvlan_dev	*vlan;
  	unsigned char		addr[6+2] __aligned(sizeof(u16));
  	struct rcu_head		rcu;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
61
  };
412ca1550   Herbert Xu   macvlan: Move bro...
62
63
64
65
66
  struct macvlan_skb_cb {
  	const struct macvlan_dev *src;
  };
  
  #define MACVLAN_SKB_CB(__skb) ((struct macvlan_skb_cb *)&((__skb)->cb[0]))
d5cd92448   Eric W. Biederman   macvlan: Fix use ...
67
  static void macvlan_port_destroy(struct net_device *dev);
43c2d578a   Vlad Yasevich   macvlan: convert ...
68
69
70
71
72
73
74
75
76
  static inline bool macvlan_passthru(const struct macvlan_port *port)
  {
  	return port->flags & MACVLAN_F_PASSTHRU;
  }
  
  static inline void macvlan_set_passthru(struct macvlan_port *port)
  {
  	port->flags |= MACVLAN_F_PASSTHRU;
  }
18c8c54de   Vlad Yasevich   macvlan: Let pass...
77
78
79
80
81
82
83
84
85
86
87
88
89
90
  static inline bool macvlan_addr_change(const struct macvlan_port *port)
  {
  	return port->flags & MACVLAN_F_ADDRCHANGE;
  }
  
  static inline void macvlan_set_addr_change(struct macvlan_port *port)
  {
  	port->flags |= MACVLAN_F_ADDRCHANGE;
  }
  
  static inline void macvlan_clear_addr_change(struct macvlan_port *port)
  {
  	port->flags &= ~MACVLAN_F_ADDRCHANGE;
  }
79cf79abc   Michael Braun   macvlan: add sour...
91
92
93
94
95
96
97
98
99
100
101
102
103
  /* Hash Ethernet address */
  static u32 macvlan_eth_hash(const unsigned char *addr)
  {
  	u64 value = get_unaligned((u64 *)addr);
  
  	/* only want 6 bytes */
  #ifdef __BIG_ENDIAN
  	value >>= 16;
  #else
  	value <<= 16;
  #endif
  	return hash_64(value, MACVLAN_HASH_BITS);
  }
e052f7e64   Eric Dumazet   macvlan: use the ...
104
105
106
107
108
109
110
111
112
  static struct macvlan_port *macvlan_port_get_rcu(const struct net_device *dev)
  {
  	return rcu_dereference(dev->rx_handler_data);
  }
  
  static struct macvlan_port *macvlan_port_get_rtnl(const struct net_device *dev)
  {
  	return rtnl_dereference(dev->rx_handler_data);
  }
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
113
114
115
116
  static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port,
  					       const unsigned char *addr)
  {
  	struct macvlan_dev *vlan;
79cf79abc   Michael Braun   macvlan: add sour...
117
  	u32 idx = macvlan_eth_hash(addr);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
118

58e64a312   Wei Yongjun   macvlan: silence ...
119
120
  	hlist_for_each_entry_rcu(vlan, &port->vlan_hash[idx], hlist,
  				 lockdep_rtnl_is_held()) {
a6700db17   Joe Perches   net, drivers/net:...
121
  		if (ether_addr_equal_64bits(vlan->dev->dev_addr, addr))
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
122
123
124
125
  			return vlan;
  	}
  	return NULL;
  }
79cf79abc   Michael Braun   macvlan: add sour...
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
  static struct macvlan_source_entry *macvlan_hash_lookup_source(
  	const struct macvlan_dev *vlan,
  	const unsigned char *addr)
  {
  	struct macvlan_source_entry *entry;
  	u32 idx = macvlan_eth_hash(addr);
  	struct hlist_head *h = &vlan->port->vlan_source_hash[idx];
  
  	hlist_for_each_entry_rcu(entry, h, hlist) {
  		if (ether_addr_equal_64bits(entry->addr, addr) &&
  		    entry->vlan == vlan)
  			return entry;
  	}
  	return NULL;
  }
  
  static int macvlan_hash_add_source(struct macvlan_dev *vlan,
  				   const unsigned char *addr)
  {
  	struct macvlan_port *port = vlan->port;
  	struct macvlan_source_entry *entry;
  	struct hlist_head *h;
  
  	entry = macvlan_hash_lookup_source(vlan, addr);
  	if (entry)
  		return 0;
  
  	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
  	if (!entry)
  		return -ENOMEM;
  
  	ether_addr_copy(entry->addr, addr);
  	entry->vlan = vlan;
  	h = &port->vlan_source_hash[macvlan_eth_hash(addr)];
  	hlist_add_head_rcu(&entry->hlist, h);
  	vlan->macaddr_count++;
  
  	return 0;
  }
f9ac30f08   Eric Biederman   macvlan: Determin...
165
166
167
168
  static void macvlan_hash_add(struct macvlan_dev *vlan)
  {
  	struct macvlan_port *port = vlan->port;
  	const unsigned char *addr = vlan->dev->dev_addr;
79cf79abc   Michael Braun   macvlan: add sour...
169
  	u32 idx = macvlan_eth_hash(addr);
f9ac30f08   Eric Biederman   macvlan: Determin...
170

79cf79abc   Michael Braun   macvlan: add sour...
171
172
173
174
175
176
177
  	hlist_add_head_rcu(&vlan->hlist, &port->vlan_hash[idx]);
  }
  
  static void macvlan_hash_del_source(struct macvlan_source_entry *entry)
  {
  	hlist_del_rcu(&entry->hlist);
  	kfree_rcu(entry, rcu);
f9ac30f08   Eric Biederman   macvlan: Determin...
178
  }
449f45442   Eric Dumazet   macvlan: remove o...
179
  static void macvlan_hash_del(struct macvlan_dev *vlan, bool sync)
f9ac30f08   Eric Biederman   macvlan: Determin...
180
181
  {
  	hlist_del_rcu(&vlan->hlist);
449f45442   Eric Dumazet   macvlan: remove o...
182
183
  	if (sync)
  		synchronize_rcu();
f9ac30f08   Eric Biederman   macvlan: Determin...
184
185
186
187
188
  }
  
  static void macvlan_hash_change_addr(struct macvlan_dev *vlan,
  					const unsigned char *addr)
  {
449f45442   Eric Dumazet   macvlan: remove o...
189
  	macvlan_hash_del(vlan, true);
f9ac30f08   Eric Biederman   macvlan: Determin...
190
191
192
193
194
195
  	/* Now that we are unhashed it is safe to change the device
  	 * address without confusing packet delivery.
  	 */
  	memcpy(vlan->dev->dev_addr, addr, ETH_ALEN);
  	macvlan_hash_add(vlan);
  }
d94d02547   Gao Feng   driver: macvlan: ...
196
197
  static bool macvlan_addr_busy(const struct macvlan_port *port,
  			      const unsigned char *addr)
f9ac30f08   Eric Biederman   macvlan: Determin...
198
  {
18c8c54de   Vlad Yasevich   macvlan: Let pass...
199
  	/* Test to see if the specified address is
f9ac30f08   Eric Biederman   macvlan: Determin...
200
201
202
  	 * currently in use by the underlying device or
  	 * another macvlan.
  	 */
18c8c54de   Vlad Yasevich   macvlan: Let pass...
203
  	if (!macvlan_passthru(port) && !macvlan_addr_change(port) &&
e696cda7b   Vlad Yasevich   macvlan: Fix pass...
204
  	    ether_addr_equal_64bits(port->dev->dev_addr, addr))
d94d02547   Gao Feng   driver: macvlan: ...
205
  		return true;
f9ac30f08   Eric Biederman   macvlan: Determin...
206
207
  
  	if (macvlan_hash_lookup(port, addr))
d94d02547   Gao Feng   driver: macvlan: ...
208
  		return true;
f9ac30f08   Eric Biederman   macvlan: Determin...
209

d94d02547   Gao Feng   driver: macvlan: ...
210
  	return false;
f9ac30f08   Eric Biederman   macvlan: Determin...
211
  }
a1e514c5d   Arnd Bergmann   macvlan: cleanup ...
212

fc0663d6b   Arnd Bergmann   macvlan: allow mu...
213
214
  static int macvlan_broadcast_one(struct sk_buff *skb,
  				 const struct macvlan_dev *vlan,
618e1b748   Arnd Bergmann   macvlan: implemen...
215
  				 const struct ethhdr *eth, bool local)
a1e514c5d   Arnd Bergmann   macvlan: cleanup ...
216
  {
fc0663d6b   Arnd Bergmann   macvlan: allow mu...
217
  	struct net_device *dev = vlan->dev;
a1e514c5d   Arnd Bergmann   macvlan: cleanup ...
218

618e1b748   Arnd Bergmann   macvlan: implemen...
219
  	if (local)
412ca1550   Herbert Xu   macvlan: Move bro...
220
  		return __dev_forward_skb(dev, skb);
618e1b748   Arnd Bergmann   macvlan: implemen...
221

a1e514c5d   Arnd Bergmann   macvlan: cleanup ...
222
  	skb->dev = dev;
a6700db17   Joe Perches   net, drivers/net:...
223
  	if (ether_addr_equal_64bits(eth->h_dest, dev->broadcast))
a1e514c5d   Arnd Bergmann   macvlan: cleanup ...
224
225
226
  		skb->pkt_type = PACKET_BROADCAST;
  	else
  		skb->pkt_type = PACKET_MULTICAST;
412ca1550   Herbert Xu   macvlan: Move bro...
227
  	return 0;
a1e514c5d   Arnd Bergmann   macvlan: cleanup ...
228
  }
3807ff589   Eric Dumazet   macvlan: add a sa...
229
230
231
232
233
234
235
236
  static u32 macvlan_hash_mix(const struct macvlan_dev *vlan)
  {
  	return (u32)(((unsigned long)vlan) >> L1_CACHE_SHIFT);
  }
  
  
  static unsigned int mc_hash(const struct macvlan_dev *vlan,
  			    const unsigned char *addr)
cd431e738   Eric Dumazet   macvlan: add mult...
237
238
  {
  	u32 val = __get_unaligned_cpu32(addr + 2);
3807ff589   Eric Dumazet   macvlan: add a sa...
239
  	val ^= macvlan_hash_mix(vlan);
cd431e738   Eric Dumazet   macvlan: add mult...
240
241
  	return hash_32(val, MACVLAN_MC_FILTER_BITS);
  }
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
242
  static void macvlan_broadcast(struct sk_buff *skb,
618e1b748   Arnd Bergmann   macvlan: implemen...
243
244
245
  			      const struct macvlan_port *port,
  			      struct net_device *src,
  			      enum macvlan_mode mode)
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
246
  {
1712b2fff   Eric Dumazet   macvlan: use skb_...
247
  	const struct ethhdr *eth = eth_hdr(skb);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
248
  	const struct macvlan_dev *vlan;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
249
250
  	struct sk_buff *nskb;
  	unsigned int i;
a1e514c5d   Arnd Bergmann   macvlan: cleanup ...
251
  	int err;
3807ff589   Eric Dumazet   macvlan: add a sa...
252
  	unsigned int hash;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
253

efbbced36   Patrick McHardy   macvlan: don't br...
254
255
  	if (skb->protocol == htons(ETH_P_PAUSE))
  		return;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
256
  	for (i = 0; i < MACVLAN_HASH_SIZE; i++) {
b67bfe0d4   Sasha Levin   hlist: drop the n...
257
  		hlist_for_each_entry_rcu(vlan, &port->vlan_hash[i], hlist) {
618e1b748   Arnd Bergmann   macvlan: implemen...
258
259
  			if (vlan->dev == src || !(vlan->mode & mode))
  				continue;
3807ff589   Eric Dumazet   macvlan: add a sa...
260
  			hash = mc_hash(vlan, eth->h_dest);
cd431e738   Eric Dumazet   macvlan: add mult...
261
262
  			if (!test_bit(hash, vlan->mc_filter))
  				continue;
de9e8f3f4   Herbert Xu   macvlan: Move skb...
263
264
  
  			err = NET_RX_DROP;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
265
  			nskb = skb_clone(skb, GFP_ATOMIC);
de9e8f3f4   Herbert Xu   macvlan: Move skb...
266
267
268
  			if (likely(nskb))
  				err = macvlan_broadcast_one(
  					nskb, vlan, eth,
412ca1550   Herbert Xu   macvlan: Move bro...
269
270
  					mode == MACVLAN_MODE_BRIDGE) ?:
  				      netif_rx_ni(nskb);
a1e514c5d   Arnd Bergmann   macvlan: cleanup ...
271
  			macvlan_count_rx(vlan, skb->len + ETH_HLEN,
4c9799359   jbaron@akamai.com   macvlan: pass 'bo...
272
  					 err == NET_RX_SUCCESS, true);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
273
274
275
  		}
  	}
  }
412ca1550   Herbert Xu   macvlan: Move bro...
276
  static void macvlan_process_broadcast(struct work_struct *w)
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
277
  {
412ca1550   Herbert Xu   macvlan: Move bro...
278
279
280
281
  	struct macvlan_port *port = container_of(w, struct macvlan_port,
  						 bc_work);
  	struct sk_buff *skb;
  	struct sk_buff_head list;
fe0ca7328   Eric Dumazet   macvlan: fix a ra...
282
  	__skb_queue_head_init(&list);
412ca1550   Herbert Xu   macvlan: Move bro...
283
284
285
286
287
288
289
290
291
  
  	spin_lock_bh(&port->bc_queue.lock);
  	skb_queue_splice_tail_init(&port->bc_queue, &list);
  	spin_unlock_bh(&port->bc_queue.lock);
  
  	while ((skb = __skb_dequeue(&list))) {
  		const struct macvlan_dev *src = MACVLAN_SKB_CB(skb)->src;
  
  		rcu_read_lock();
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
292

618e1b748   Arnd Bergmann   macvlan: implemen...
293
294
295
296
297
  		if (!src)
  			/* frame comes from an external address */
  			macvlan_broadcast(skb, port, NULL,
  					  MACVLAN_MODE_PRIVATE |
  					  MACVLAN_MODE_VEPA    |
eb06acdc8   Sridhar Samudrala   macvlan: Introduc...
298
  					  MACVLAN_MODE_PASSTHRU|
618e1b748   Arnd Bergmann   macvlan: implemen...
299
300
301
302
303
304
  					  MACVLAN_MODE_BRIDGE);
  		else if (src->mode == MACVLAN_MODE_VEPA)
  			/* flood to everyone except source */
  			macvlan_broadcast(skb, port, src->dev,
  					  MACVLAN_MODE_VEPA |
  					  MACVLAN_MODE_BRIDGE);
412ca1550   Herbert Xu   macvlan: Move bro...
305
  		else
618e1b748   Arnd Bergmann   macvlan: implemen...
306
307
308
309
310
311
  			/*
  			 * flood only to VEPA ports, bridge ports
  			 * already saw the frame on the way out.
  			 */
  			macvlan_broadcast(skb, port, src->dev,
  					  MACVLAN_MODE_VEPA);
412ca1550   Herbert Xu   macvlan: Move bro...
312
313
  
  		rcu_read_unlock();
260916dfb   Herbert Xu   macvlan: Fix pote...
314
315
  		if (src)
  			dev_put(src->dev);
bf97403ac   Yang Wei   macvlan: replace ...
316
  		consume_skb(skb);
ce9a4186f   Mahesh Bandewar   macvlan: add cond...
317
318
  
  		cond_resched();
412ca1550   Herbert Xu   macvlan: Move bro...
319
320
321
322
  	}
  }
  
  static void macvlan_broadcast_enqueue(struct macvlan_port *port,
260916dfb   Herbert Xu   macvlan: Fix pote...
323
  				      const struct macvlan_dev *src,
412ca1550   Herbert Xu   macvlan: Move bro...
324
325
  				      struct sk_buff *skb)
  {
e676f197a   Herbert Xu   macvlan: Fix leak...
326
  	struct sk_buff *nskb;
412ca1550   Herbert Xu   macvlan: Move bro...
327
  	int err = -ENOMEM;
e676f197a   Herbert Xu   macvlan: Fix leak...
328
329
  	nskb = skb_clone(skb, GFP_ATOMIC);
  	if (!nskb)
412ca1550   Herbert Xu   macvlan: Move bro...
330
  		goto err;
260916dfb   Herbert Xu   macvlan: Fix pote...
331
  	MACVLAN_SKB_CB(nskb)->src = src;
412ca1550   Herbert Xu   macvlan: Move bro...
332
  	spin_lock(&port->bc_queue.lock);
07d92d5cc   Nicolas Dichtel   macvlan: allow to...
333
  	if (skb_queue_len(&port->bc_queue) < MACVLAN_BC_QUEUE_LEN) {
260916dfb   Herbert Xu   macvlan: Fix pote...
334
335
  		if (src)
  			dev_hold(src->dev);
e676f197a   Herbert Xu   macvlan: Fix leak...
336
  		__skb_queue_tail(&port->bc_queue, nskb);
412ca1550   Herbert Xu   macvlan: Move bro...
337
338
339
  		err = 0;
  	}
  	spin_unlock(&port->bc_queue.lock);
1d7ea5566   Menglong Dong   macvlan: schedule...
340
  	schedule_work(&port->bc_work);
412ca1550   Herbert Xu   macvlan: Move bro...
341
  	if (err)
e676f197a   Herbert Xu   macvlan: Fix leak...
342
  		goto free_nskb;
412ca1550   Herbert Xu   macvlan: Move bro...
343

412ca1550   Herbert Xu   macvlan: Move bro...
344
  	return;
e676f197a   Herbert Xu   macvlan: Fix leak...
345
346
  free_nskb:
  	kfree_skb(nskb);
412ca1550   Herbert Xu   macvlan: Move bro...
347
348
349
  err:
  	atomic_long_inc(&skb->dev->rx_dropped);
  }
79cf79abc   Michael Braun   macvlan: add sour...
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
  static void macvlan_flush_sources(struct macvlan_port *port,
  				  struct macvlan_dev *vlan)
  {
  	int i;
  
  	for (i = 0; i < MACVLAN_HASH_SIZE; i++) {
  		struct hlist_node *h, *n;
  
  		hlist_for_each_safe(h, n, &port->vlan_source_hash[i]) {
  			struct macvlan_source_entry *entry;
  
  			entry = hlist_entry(h, struct macvlan_source_entry,
  					    hlist);
  			if (entry->vlan == vlan)
  				macvlan_hash_del_source(entry);
  		}
  	}
  	vlan->macaddr_count = 0;
  }
  
  static void macvlan_forward_source_one(struct sk_buff *skb,
  				       struct macvlan_dev *vlan)
  {
  	struct sk_buff *nskb;
  	struct net_device *dev;
  	int len;
  	int ret;
  
  	dev = vlan->dev;
  	if (unlikely(!(dev->flags & IFF_UP)))
  		return;
  
  	nskb = skb_clone(skb, GFP_ATOMIC);
  	if (!nskb)
  		return;
  
  	len = nskb->len + ETH_HLEN;
  	nskb->dev = dev;
c8c41ea1b   Alexander Duyck   macvlan: Only upd...
388
389
390
  
  	if (ether_addr_equal_64bits(eth_hdr(skb)->h_dest, dev->dev_addr))
  		nskb->pkt_type = PACKET_HOST;
79cf79abc   Michael Braun   macvlan: add sour...
391
392
  
  	ret = netif_rx(nskb);
4c9799359   jbaron@akamai.com   macvlan: pass 'bo...
393
  	macvlan_count_rx(vlan, len, ret == NET_RX_SUCCESS, false);
79cf79abc   Michael Braun   macvlan: add sour...
394
395
396
397
398
399
400
401
402
403
404
405
  }
  
  static void macvlan_forward_source(struct sk_buff *skb,
  				   struct macvlan_port *port,
  				   const unsigned char *addr)
  {
  	struct macvlan_source_entry *entry;
  	u32 idx = macvlan_eth_hash(addr);
  	struct hlist_head *h = &port->vlan_source_hash[idx];
  
  	hlist_for_each_entry_rcu(entry, h, hlist) {
  		if (ether_addr_equal_64bits(entry->addr, addr))
fc51f2b7e   Gao Feng   driver: macvlan: ...
406
  			macvlan_forward_source_one(skb, entry->vlan);
79cf79abc   Michael Braun   macvlan: add sour...
407
408
  	}
  }
412ca1550   Herbert Xu   macvlan: Move bro...
409
410
411
412
413
414
415
416
417
418
  /* called under rcu_read_lock() from netif_receive_skb */
  static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
  {
  	struct macvlan_port *port;
  	struct sk_buff *skb = *pskb;
  	const struct ethhdr *eth = eth_hdr(skb);
  	const struct macvlan_dev *vlan;
  	const struct macvlan_dev *src;
  	struct net_device *dev;
  	unsigned int len = 0;
d1dd91193   jbaron@akamai.com   macvlan: optimize...
419
420
  	int ret;
  	rx_handler_result_t handle_res;
412ca1550   Herbert Xu   macvlan: Move bro...
421

81f3dc934   Alexander Sverdlin   macvlan: Skip loo...
422
423
424
  	/* Packets from dev_loopback_xmit() do not have L2 header, bail out */
  	if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
  		return RX_HANDLER_PASS;
412ca1550   Herbert Xu   macvlan: Move bro...
425
426
  	port = macvlan_port_get_rcu(skb->dev);
  	if (is_multicast_ether_addr(eth->h_dest)) {
9c127a016   Herbert Xu   macvlan: Avoid un...
427
  		unsigned int hash;
19bcf9f20   Eric W. Biederman   ipv4: Pass struct...
428
  		skb = ip_check_defrag(dev_net(skb->dev), skb, IP_DEFRAG_MACVLAN);
412ca1550   Herbert Xu   macvlan: Move bro...
429
430
  		if (!skb)
  			return RX_HANDLER_CONSUMED;
e639b8d8a   Sabrina Dubroca   macvlan: fix leak...
431
  		*pskb = skb;
412ca1550   Herbert Xu   macvlan: Move bro...
432
  		eth = eth_hdr(skb);
79cf79abc   Michael Braun   macvlan: add sour...
433
  		macvlan_forward_source(skb, port, eth->h_source);
412ca1550   Herbert Xu   macvlan: Move bro...
434
435
436
  		src = macvlan_hash_lookup(port, eth->h_source);
  		if (src && src->mode != MACVLAN_MODE_VEPA &&
  		    src->mode != MACVLAN_MODE_BRIDGE) {
729e72a10   stephen hemminger   macvlan: receive ...
437
438
  			/* forward to original port. */
  			vlan = src;
412ca1550   Herbert Xu   macvlan: Move bro...
439
440
  			ret = macvlan_broadcast_one(skb, vlan, eth, 0) ?:
  			      netif_rx(skb);
d1dd91193   jbaron@akamai.com   macvlan: optimize...
441
  			handle_res = RX_HANDLER_CONSUMED;
729e72a10   stephen hemminger   macvlan: receive ...
442
443
  			goto out;
  		}
9c127a016   Herbert Xu   macvlan: Avoid un...
444
445
446
  		hash = mc_hash(NULL, eth->h_dest);
  		if (test_bit(hash, port->mc_filter))
  			macvlan_broadcast_enqueue(port, src, skb);
412ca1550   Herbert Xu   macvlan: Move bro...
447

8a4eb5734   Jiri Pirko   net: introduce rx...
448
  		return RX_HANDLER_PASS;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
449
  	}
79cf79abc   Michael Braun   macvlan: add sour...
450
  	macvlan_forward_source(skb, port, eth->h_source);
43c2d578a   Vlad Yasevich   macvlan: convert ...
451
  	if (macvlan_passthru(port))
233c7df08   Jiri Pirko   macvlan: fix pass...
452
453
  		vlan = list_first_or_null_rcu(&port->vlans,
  					      struct macvlan_dev, list);
eb06acdc8   Sridhar Samudrala   macvlan: Introduc...
454
455
  	else
  		vlan = macvlan_hash_lookup(port, eth->h_dest);
dd6b9c2c3   Alexander Duyck   macvlan: Only del...
456
  	if (!vlan || vlan->mode == MACVLAN_MODE_SOURCE)
8a4eb5734   Jiri Pirko   net: introduce rx...
457
  		return RX_HANDLER_PASS;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
458
459
460
461
  
  	dev = vlan->dev;
  	if (unlikely(!(dev->flags & IFF_UP))) {
  		kfree_skb(skb);
8a4eb5734   Jiri Pirko   net: introduce rx...
462
  		return RX_HANDLER_CONSUMED;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
463
  	}
a1e514c5d   Arnd Bergmann   macvlan: cleanup ...
464
  	len = skb->len + ETH_HLEN;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
465
  	skb = skb_share_check(skb, GFP_ATOMIC);
d1dd91193   jbaron@akamai.com   macvlan: optimize...
466
467
468
  	if (!skb) {
  		ret = NET_RX_DROP;
  		handle_res = RX_HANDLER_CONSUMED;
ba01877f5   Sridhar Samudrala   macvlan: Fix rx c...
469
  		goto out;
d1dd91193   jbaron@akamai.com   macvlan: optimize...
470
  	}
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
471

e639b8d8a   Sabrina Dubroca   macvlan: fix leak...
472
  	*pskb = skb;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
473
474
  	skb->dev = dev;
  	skb->pkt_type = PACKET_HOST;
d1dd91193   jbaron@akamai.com   macvlan: optimize...
475
476
  	ret = NET_RX_SUCCESS;
  	handle_res = RX_HANDLER_ANOTHER;
ba01877f5   Sridhar Samudrala   macvlan: Fix rx c...
477
  out:
4c9799359   jbaron@akamai.com   macvlan: pass 'bo...
478
  	macvlan_count_rx(vlan, len, ret == NET_RX_SUCCESS, false);
d1dd91193   jbaron@akamai.com   macvlan: optimize...
479
  	return handle_res;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
480
  }
618e1b748   Arnd Bergmann   macvlan: implemen...
481
482
483
484
485
486
487
  static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
  {
  	const struct macvlan_dev *vlan = netdev_priv(dev);
  	const struct macvlan_port *port = vlan->port;
  	const struct macvlan_dev *dest;
  
  	if (vlan->mode == MACVLAN_MODE_BRIDGE) {
1712b2fff   Eric Dumazet   macvlan: use skb_...
488
  		const struct ethhdr *eth = skb_eth_hdr(skb);
618e1b748   Arnd Bergmann   macvlan: implemen...
489
490
491
  
  		/* send to other bridge ports directly */
  		if (is_multicast_ether_addr(eth->h_dest)) {
1712b2fff   Eric Dumazet   macvlan: use skb_...
492
  			skb_reset_mac_header(skb);
618e1b748   Arnd Bergmann   macvlan: implemen...
493
494
495
496
497
498
  			macvlan_broadcast(skb, port, dev, MACVLAN_MODE_BRIDGE);
  			goto xmit_world;
  		}
  
  		dest = macvlan_hash_lookup(port, eth->h_dest);
  		if (dest && dest->mode == MACVLAN_MODE_BRIDGE) {
a37dd3332   David Ward   macvlan: Forward ...
499
  			/* send to lowerdev first for its network taps */
cb2d0f3e9   David Ward   macvlan/macvtap: ...
500
  			dev_forward_skb(vlan->lowerdev, skb);
618e1b748   Arnd Bergmann   macvlan: implemen...
501
502
503
504
  
  			return NET_XMIT_SUCCESS;
  		}
  	}
618e1b748   Arnd Bergmann   macvlan: implemen...
505
  xmit_world:
59b9997ba   David S. Miller   Revert "net: main...
506
  	skb->dev = vlan->lowerdev;
eadec877c   Alexander Duyck   net: Add support ...
507
508
  	return dev_queue_xmit_accel(skb,
  				    netdev_get_sb_channel(dev) ? dev : NULL);
618e1b748   Arnd Bergmann   macvlan: implemen...
509
  }
688cea83f   dingtianhong   macvlan: add netp...
510
511
512
  static inline netdev_tx_t macvlan_netpoll_send_skb(struct macvlan_dev *vlan, struct sk_buff *skb)
  {
  #ifdef CONFIG_NET_POLL_CONTROLLER
f78ed2204   Eric Dumazet   netpoll: accept N...
513
  	return netpoll_send_skb(vlan->netpoll, skb);
688cea83f   dingtianhong   macvlan: add netp...
514
515
  #else
  	BUG();
688cea83f   dingtianhong   macvlan: add netp...
516
  	return NETDEV_TX_OK;
f78ed2204   Eric Dumazet   netpoll: accept N...
517
  #endif
688cea83f   dingtianhong   macvlan: add netp...
518
  }
0db901bd3   stephen hemminger   macvlan: make sta...
519
520
  static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
  				      struct net_device *dev)
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
521
  {
81d4e91cd   Alexander Duyck   macvlan: Use soft...
522
  	struct macvlan_dev *vlan = netdev_priv(dev);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
523
524
  	unsigned int len = skb->len;
  	int ret;
688cea83f   dingtianhong   macvlan: add netp...
525
526
527
  
  	if (unlikely(netpoll_tx_running(dev)))
  		return macvlan_netpoll_send_skb(vlan, skb);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
528

81d4e91cd   Alexander Duyck   macvlan: Use soft...
529
  	ret = macvlan_queue_xmit(skb, dev);
a6cc0cfa7   John Fastabend   net: Add layer 2 ...
530

2d6c9ffcc   Eric Dumazet   net: congestion n...
531
  	if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {
cdf3e274c   Li RongQing   macvlan: unify ma...
532
  		struct vlan_pcpu_stats *pcpu_stats;
2c1145532   Eric Dumazet   macvlan: add mult...
533

8ffab51b3   Eric Dumazet   macvlan: lockless...
534
535
536
537
538
539
540
541
  		pcpu_stats = this_cpu_ptr(vlan->pcpu_stats);
  		u64_stats_update_begin(&pcpu_stats->syncp);
  		pcpu_stats->tx_packets++;
  		pcpu_stats->tx_bytes += len;
  		u64_stats_update_end(&pcpu_stats->syncp);
  	} else {
  		this_cpu_inc(vlan->pcpu_stats->tx_dropped);
  	}
cbbef5e18   Patrick McHardy   vlan/macvlan: pro...
542
  	return ret;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
543
544
545
  }
  
  static int macvlan_hard_header(struct sk_buff *skb, struct net_device *dev,
3b04ddde0   Stephen Hemminger   [NET]: Move hardw...
546
547
  			       unsigned short type, const void *daddr,
  			       const void *saddr, unsigned len)
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
548
549
550
  {
  	const struct macvlan_dev *vlan = netdev_priv(dev);
  	struct net_device *lowerdev = vlan->lowerdev;
0c4e85813   Stephen Hemminger   [NET]: Wrap netde...
551
552
  	return dev_hard_header(skb, lowerdev, type, daddr,
  			       saddr ? : dev->dev_addr, len);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
553
  }
3b04ddde0   Stephen Hemminger   [NET]: Move hardw...
554
555
  static const struct header_ops macvlan_hard_header_ops = {
  	.create  	= macvlan_hard_header,
3b04ddde0   Stephen Hemminger   [NET]: Move hardw...
556
  	.parse		= eth_header_parse,
3b04ddde0   Stephen Hemminger   [NET]: Move hardw...
557
558
559
  	.cache		= eth_header_cache,
  	.cache_update	= eth_header_cache_update,
  };
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
560
561
562
  static int macvlan_open(struct net_device *dev)
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
563
564
  	struct net_device *lowerdev = vlan->lowerdev;
  	int err;
43c2d578a   Vlad Yasevich   macvlan: convert ...
565
  	if (macvlan_passthru(vlan->port)) {
787381415   Michael S. Tsirkin   macvlan: handle s...
566
567
568
569
570
  		if (!(vlan->flags & MACVLAN_FLAG_NOPROMISC)) {
  			err = dev_set_promiscuity(lowerdev, 1);
  			if (err < 0)
  				goto out;
  		}
eb06acdc8   Sridhar Samudrala   macvlan: Introduc...
571
572
  		goto hash_add;
  	}
59f997b08   Matteo Croce   macvlan: return c...
573
  	err = -EADDRINUSE;
7d775f634   Alexander Duyck   macvlan: Rename f...
574
575
576
577
578
579
  	if (macvlan_addr_busy(vlan->port, dev->dev_addr))
  		goto out;
  
  	/* Attempt to populate accel_priv which is used to offload the L2
  	 * forwarding requests for unicast packets.
  	 */
81d4e91cd   Alexander Duyck   macvlan: Use soft...
580
  	if (lowerdev->features & NETIF_F_HW_L2FW_DOFFLOAD)
7d775f634   Alexander Duyck   macvlan: Rename f...
581
  		vlan->accel_priv =
a6cc0cfa7   John Fastabend   net: Add layer 2 ...
582
  		      lowerdev->netdev_ops->ndo_dfwd_add_station(lowerdev, dev);
81d4e91cd   Alexander Duyck   macvlan: Use soft...
583
584
585
586
587
588
589
590
  	/* If earlier attempt to offload failed, or accel_priv is not
  	 * populated we must add the unicast address to the lower device.
  	 */
  	if (IS_ERR_OR_NULL(vlan->accel_priv)) {
  		vlan->accel_priv = NULL;
  		err = dev_uc_add(lowerdev, dev->dev_addr);
  		if (err < 0)
  			goto out;
a6cc0cfa7   John Fastabend   net: Add layer 2 ...
591
  	}
b89fb7da2   Wang Chen   macvlan: Check re...
592
593
594
595
596
  	if (dev->flags & IFF_ALLMULTI) {
  		err = dev_set_allmulti(lowerdev, 1);
  		if (err < 0)
  			goto del_unicast;
  	}
eb06acdc8   Sridhar Samudrala   macvlan: Introduc...
597

efdbd2b30   Vlad Yasevich   macvlan: Propagat...
598
599
600
601
602
  	if (dev->flags & IFF_PROMISC) {
  		err = dev_set_promiscuity(lowerdev, 1);
  		if (err < 0)
  			goto clear_multi;
  	}
eb06acdc8   Sridhar Samudrala   macvlan: Introduc...
603
  hash_add:
f9ac30f08   Eric Biederman   macvlan: Determin...
604
  	macvlan_hash_add(vlan);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
605
  	return 0;
b89fb7da2   Wang Chen   macvlan: Check re...
606

efdbd2b30   Vlad Yasevich   macvlan: Propagat...
607
  clear_multi:
c3891fa25   Gao Feng   driver: macvlan: ...
608
609
  	if (dev->flags & IFF_ALLMULTI)
  		dev_set_allmulti(lowerdev, -1);
b89fb7da2   Wang Chen   macvlan: Check re...
610
  del_unicast:
7d775f634   Alexander Duyck   macvlan: Rename f...
611
  	if (vlan->accel_priv) {
a6cc0cfa7   John Fastabend   net: Add layer 2 ...
612
  		lowerdev->netdev_ops->ndo_dfwd_del_station(lowerdev,
7d775f634   Alexander Duyck   macvlan: Rename f...
613
614
  							   vlan->accel_priv);
  		vlan->accel_priv = NULL;
81d4e91cd   Alexander Duyck   macvlan: Use soft...
615
616
  	} else {
  		dev_uc_del(lowerdev, dev->dev_addr);
a6cc0cfa7   John Fastabend   net: Add layer 2 ...
617
  	}
81d4e91cd   Alexander Duyck   macvlan: Use soft...
618
  out:
b89fb7da2   Wang Chen   macvlan: Check re...
619
  	return err;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
620
621
622
623
624
625
  }
  
  static int macvlan_stop(struct net_device *dev)
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
  	struct net_device *lowerdev = vlan->lowerdev;
7d775f634   Alexander Duyck   macvlan: Rename f...
626
  	if (vlan->accel_priv) {
a6cc0cfa7   John Fastabend   net: Add layer 2 ...
627
  		lowerdev->netdev_ops->ndo_dfwd_del_station(lowerdev,
7d775f634   Alexander Duyck   macvlan: Rename f...
628
629
  							   vlan->accel_priv);
  		vlan->accel_priv = NULL;
a6cc0cfa7   John Fastabend   net: Add layer 2 ...
630
  	}
df8ef8f3a   John Fastabend   macvlan: add FDB ...
631
632
  	dev_uc_unsync(lowerdev, dev);
  	dev_mc_unsync(lowerdev, dev);
43c2d578a   Vlad Yasevich   macvlan: convert ...
633
  	if (macvlan_passthru(vlan->port)) {
df8ef8f3a   John Fastabend   macvlan: add FDB ...
634
635
  		if (!(vlan->flags & MACVLAN_FLAG_NOPROMISC))
  			dev_set_promiscuity(lowerdev, -1);
eb06acdc8   Sridhar Samudrala   macvlan: Introduc...
636
637
  		goto hash_del;
  	}
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
638
639
  	if (dev->flags & IFF_ALLMULTI)
  		dev_set_allmulti(lowerdev, -1);
efdbd2b30   Vlad Yasevich   macvlan: Propagat...
640
641
  	if (dev->flags & IFF_PROMISC)
  		dev_set_promiscuity(lowerdev, -1);
a748ee242   Jiri Pirko   net: move address...
642
  	dev_uc_del(lowerdev, dev->dev_addr);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
643

eb06acdc8   Sridhar Samudrala   macvlan: Introduc...
644
  hash_del:
449f45442   Eric Dumazet   macvlan: remove o...
645
  	macvlan_hash_del(vlan, !dev->dismantle);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
646
647
  	return 0;
  }
e289fd281   dingtianhong   macvlan: fix the ...
648
  static int macvlan_sync_address(struct net_device *dev, unsigned char *addr)
ad5d20a63   Patrick McHardy   [MACVLAN]: Allow ...
649
650
651
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
  	struct net_device *lowerdev = vlan->lowerdev;
18c8c54de   Vlad Yasevich   macvlan: Let pass...
652
  	struct macvlan_port *port = vlan->port;
ad5d20a63   Patrick McHardy   [MACVLAN]: Allow ...
653
  	int err;
f9ac30f08   Eric Biederman   macvlan: Determin...
654
655
  	if (!(dev->flags & IFF_UP)) {
  		/* Just copy in the new address */
e289fd281   dingtianhong   macvlan: fix the ...
656
  		ether_addr_copy(dev->dev_addr, addr);
f9ac30f08   Eric Biederman   macvlan: Determin...
657
658
  	} else {
  		/* Rehash and update the device filters */
e289fd281   dingtianhong   macvlan: fix the ...
659
  		if (macvlan_addr_busy(vlan->port, addr))
59f997b08   Matteo Croce   macvlan: return c...
660
  			return -EADDRINUSE;
ad5d20a63   Patrick McHardy   [MACVLAN]: Allow ...
661

18c8c54de   Vlad Yasevich   macvlan: Let pass...
662
  		if (!macvlan_passthru(port)) {
e289fd281   dingtianhong   macvlan: fix the ...
663
664
665
  			err = dev_uc_add(lowerdev, addr);
  			if (err)
  				return err;
ad5d20a63   Patrick McHardy   [MACVLAN]: Allow ...
666

e289fd281   dingtianhong   macvlan: fix the ...
667
668
  			dev_uc_del(lowerdev, dev->dev_addr);
  		}
f9ac30f08   Eric Biederman   macvlan: Determin...
669

e289fd281   dingtianhong   macvlan: fix the ...
670
  		macvlan_hash_change_addr(vlan, addr);
f9ac30f08   Eric Biederman   macvlan: Determin...
671
  	}
18c8c54de   Vlad Yasevich   macvlan: Let pass...
672
673
674
675
676
677
678
679
680
  	if (macvlan_passthru(port) && !macvlan_addr_change(port)) {
  		/* Since addr_change isn't set, we are here due to lower
  		 * device change.  Save the lower-dev address so we can
  		 * restore it later.
  		 */
  		ether_addr_copy(vlan->port->perm_addr,
  				lowerdev->dev_addr);
  	}
  	macvlan_clear_addr_change(port);
ad5d20a63   Patrick McHardy   [MACVLAN]: Allow ...
681
682
  	return 0;
  }
e289fd281   dingtianhong   macvlan: fix the ...
683
684
685
686
687
688
689
  static int macvlan_set_mac_address(struct net_device *dev, void *p)
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
  	struct sockaddr *addr = p;
  
  	if (!is_valid_ether_addr(addr->sa_data))
  		return -EADDRNOTAVAIL;
e26f43faa   Vlad Yasevich   macvlan: Do not r...
690
691
692
  	/* If the addresses are the same, this is a no-op */
  	if (ether_addr_equal(dev->dev_addr, addr->sa_data))
  		return 0;
e289fd281   dingtianhong   macvlan: fix the ...
693
  	if (vlan->mode == MACVLAN_MODE_PASSTHRU) {
18c8c54de   Vlad Yasevich   macvlan: Let pass...
694
  		macvlan_set_addr_change(vlan->port);
3a37a9636   Petr Machata   net: dev: Add ext...
695
  		return dev_set_mac_address(vlan->lowerdev, addr, NULL);
e289fd281   dingtianhong   macvlan: fix the ...
696
  	}
59f997b08   Matteo Croce   macvlan: return c...
697
698
  	if (macvlan_addr_busy(vlan->port, addr->sa_data))
  		return -EADDRINUSE;
e289fd281   dingtianhong   macvlan: fix the ...
699
700
  	return macvlan_sync_address(dev, addr->sa_data);
  }
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
701
702
703
704
  static void macvlan_change_rx_flags(struct net_device *dev, int change)
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
  	struct net_device *lowerdev = vlan->lowerdev;
bbeb0eadc   Peter Christensen   macvlan: Don't pr...
705
706
707
  	if (dev->flags & IFF_UP) {
  		if (change & IFF_ALLMULTI)
  			dev_set_allmulti(lowerdev, dev->flags & IFF_ALLMULTI ? 1 : -1);
efdbd2b30   Vlad Yasevich   macvlan: Propagat...
708
709
710
  		if (change & IFF_PROMISC)
  			dev_set_promiscuity(lowerdev,
  					    dev->flags & IFF_PROMISC ? 1 : -1);
bbeb0eadc   Peter Christensen   macvlan: Don't pr...
711
  	}
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
712
  }
9c127a016   Herbert Xu   macvlan: Avoid un...
713
714
715
  static void macvlan_compute_filter(unsigned long *mc_filter,
  				   struct net_device *dev,
  				   struct macvlan_dev *vlan)
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
716
  {
cd431e738   Eric Dumazet   macvlan: add mult...
717
  	if (dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) {
9c127a016   Herbert Xu   macvlan: Avoid un...
718
  		bitmap_fill(mc_filter, MACVLAN_MC_FILTER_SZ);
cd431e738   Eric Dumazet   macvlan: add mult...
719
720
721
722
723
724
  	} else {
  		struct netdev_hw_addr *ha;
  		DECLARE_BITMAP(filter, MACVLAN_MC_FILTER_SZ);
  
  		bitmap_zero(filter, MACVLAN_MC_FILTER_SZ);
  		netdev_for_each_mc_addr(ha, dev) {
3807ff589   Eric Dumazet   macvlan: add a sa...
725
  			__set_bit(mc_hash(vlan, ha->addr), filter);
cd431e738   Eric Dumazet   macvlan: add mult...
726
  		}
d52704304   Eric Dumazet   macvlan: broadcas...
727

3807ff589   Eric Dumazet   macvlan: add a sa...
728
  		__set_bit(mc_hash(vlan, dev->broadcast), filter);
d52704304   Eric Dumazet   macvlan: broadcas...
729

9c127a016   Herbert Xu   macvlan: Avoid un...
730
  		bitmap_copy(mc_filter, filter, MACVLAN_MC_FILTER_SZ);
cd431e738   Eric Dumazet   macvlan: add mult...
731
  	}
9c127a016   Herbert Xu   macvlan: Avoid un...
732
733
734
735
736
737
738
  }
  
  static void macvlan_set_mac_lists(struct net_device *dev)
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
  
  	macvlan_compute_filter(vlan->mc_filter, dev, vlan);
df8ef8f3a   John Fastabend   macvlan: add FDB ...
739
  	dev_uc_sync(vlan->lowerdev, dev);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
740
  	dev_mc_sync(vlan->lowerdev, dev);
9c127a016   Herbert Xu   macvlan: Avoid un...
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
  
  	/* This is slightly inaccurate as we're including the subscription
  	 * list of vlan->lowerdev too.
  	 *
  	 * Bug alert: This only works if everyone has the same broadcast
  	 * address as lowerdev.  As soon as someone changes theirs this
  	 * will break.
  	 *
  	 * However, this is already broken as when you change your broadcast
  	 * address we don't get called.
  	 *
  	 * The solution is to maintain a list of broadcast addresses like
  	 * we do for uc/mc, if you care.
  	 */
  	macvlan_compute_filter(vlan->port->mc_filter, vlan->lowerdev, NULL);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
756
757
758
759
760
  }
  
  static int macvlan_change_mtu(struct net_device *dev, int new_mtu)
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
91572088e   Jarod Wilson   net: use core MTU...
761
  	if (vlan->lowerdev->mtu < new_mtu)
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
762
763
764
765
  		return -EINVAL;
  	dev->mtu = new_mtu;
  	return 0;
  }
254c0a2bf   Hangbin Liu   macvlan: pass get...
766
767
768
769
770
771
  static int macvlan_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
  {
  	struct net_device *real_dev = macvlan_dev_real_dev(dev);
  	const struct net_device_ops *ops = real_dev->netdev_ops;
  	struct ifreq ifrr;
  	int err = -EOPNOTSUPP;
36f18439e   Gustavo A. R. Silva   macvlan: Replace ...
772
  	strscpy(ifrr.ifr_name, real_dev->name, IFNAMSIZ);
254c0a2bf   Hangbin Liu   macvlan: pass get...
773
774
775
776
  	ifrr.ifr_ifru = ifr->ifr_ifru;
  
  	switch (cmd) {
  	case SIOCSHWTSTAMP:
6c2ea9eba   Hangbin Liu   macvlan: disable ...
777
778
  		if (!net_eq(dev_net(dev), &init_net))
  			break;
df561f668   Gustavo A. R. Silva   treewide: Use fal...
779
  		fallthrough;
254c0a2bf   Hangbin Liu   macvlan: pass get...
780
781
782
783
784
785
786
787
788
789
790
  	case SIOCGHWTSTAMP:
  		if (netif_device_present(real_dev) && ops->ndo_do_ioctl)
  			err = ops->ndo_do_ioctl(real_dev, &ifrr, cmd);
  		break;
  	}
  
  	if (!err)
  		ifr->ifr_ifru = ifrr.ifr_ifru;
  
  	return err;
  }
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
791
792
793
794
795
  /*
   * macvlan network devices have devices nesting below it and are a special
   * "super class" of normal network devices; split their locks off into a
   * separate class since they always nest.
   */
845e0ebb4   Cong Wang   net: change addr_...
796
  static struct lock_class_key macvlan_netdev_addr_lock_key;
70957eaec   Vlad Yasevich   macvlan: Fix perf...
797
798
  #define ALWAYS_ON_OFFLOADS \
  	(NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_GSO_SOFTWARE | \
f21e50770   Dimitris Michailidis   macvlan: add offl...
799
  	 NETIF_F_GSO_ROBUST | NETIF_F_GSO_ENCAP_ALL)
8b4703e9b   Vlad Yasevich   macvlan: Add supp...
800

70957eaec   Vlad Yasevich   macvlan: Fix perf...
801
  #define ALWAYS_ON_FEATURES (ALWAYS_ON_OFFLOADS | NETIF_F_LLTX)
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
802
  #define MACVLAN_FEATURES \
a188222b6   Tom Herbert   net: Rename NETIF...
803
  	(NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST | \
fb652fdfe   David S. Miller   macvlan/macvtap: ...
804
  	 NETIF_F_GSO | NETIF_F_TSO | NETIF_F_LRO | \
8d13e670d   John Fastabend   macvlan: add VLAN...
805
  	 NETIF_F_TSO_ECN | NETIF_F_TSO6 | NETIF_F_GRO | NETIF_F_RXCSUM | \
28d2b136c   Patrick McHardy   net: vlan: announ...
806
  	 NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_STAG_FILTER)
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
807
808
809
  
  #define MACVLAN_STATE_MASK \
  	((1<<__LINK_STATE_NOCARRIER) | (1<<__LINK_STATE_DORMANT))
845e0ebb4   Cong Wang   net: change addr_...
810
811
812
  static void macvlan_set_lockdep_class(struct net_device *dev)
  {
  	netdev_lockdep_set_classes(dev);
be74294ff   Cong Wang   net: get rid of l...
813
814
  	lockdep_set_class(&dev->addr_list_lock,
  			  &macvlan_netdev_addr_lock_key);
845e0ebb4   Cong Wang   net: change addr_...
815
  }
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
816
817
818
819
  static int macvlan_init(struct net_device *dev)
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
  	const struct net_device *lowerdev = vlan->lowerdev;
308379607   Francesco Ruggeri   macvlan: fix fail...
820
  	struct macvlan_port *port = vlan->port;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
821
822
823
824
  
  	dev->state		= (dev->state & ~MACVLAN_STATE_MASK) |
  				  (lowerdev->state & MACVLAN_STATE_MASK);
  	dev->features 		= lowerdev->features & MACVLAN_FEATURES;
8b4703e9b   Vlad Yasevich   macvlan: Add supp...
825
  	dev->features		|= ALWAYS_ON_FEATURES;
62dbe8301   Michal Kubeček   macvlan: allow se...
826
  	dev->hw_features	|= NETIF_F_LRO;
081e83a78   Vlad Yasevich   macvlan: Initiali...
827
  	dev->vlan_features	= lowerdev->vlan_features & MACVLAN_FEATURES;
70957eaec   Vlad Yasevich   macvlan: Fix perf...
828
  	dev->vlan_features	|= ALWAYS_ON_OFFLOADS;
f21e50770   Dimitris Michailidis   macvlan: add offl...
829
  	dev->hw_enc_features    |= dev->features;
8c2acc53f   Patrick McHardy   macvlan: fix gso_...
830
  	dev->gso_max_size	= lowerdev->gso_max_size;
f6773c5e9   Eric Dumazet   vlan: propagate g...
831
  	dev->gso_max_segs	= lowerdev->gso_max_segs;
ef5c89967   sg.tweak@gmail.com   drivers/net/macvl...
832
  	dev->hard_header_len	= lowerdev->hard_header_len;
845e0ebb4   Cong Wang   net: change addr_...
833
  	macvlan_set_lockdep_class(dev);
1a33e10e4   Cong Wang   net: partially re...
834

1c213bd24   WANG Cong   net: introduce ne...
835
  	vlan->pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats);
8ffab51b3   Eric Dumazet   macvlan: lockless...
836
  	if (!vlan->pcpu_stats)
fccaf7101   Eric Dumazet   macvlan: Precise ...
837
  		return -ENOMEM;
308379607   Francesco Ruggeri   macvlan: fix fail...
838
  	port->count += 1;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
839
840
  	return 0;
  }
fccaf7101   Eric Dumazet   macvlan: Precise ...
841
842
843
  static void macvlan_uninit(struct net_device *dev)
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
d5cd92448   Eric W. Biederman   macvlan: Fix use ...
844
  	struct macvlan_port *port = vlan->port;
fccaf7101   Eric Dumazet   macvlan: Precise ...
845

8ffab51b3   Eric Dumazet   macvlan: lockless...
846
  	free_percpu(vlan->pcpu_stats);
d5cd92448   Eric W. Biederman   macvlan: Fix use ...
847

79cf79abc   Michael Braun   macvlan: add sour...
848
  	macvlan_flush_sources(port, vlan);
5e3c516b5   David S. Miller   Revert "macvlan: ...
849
850
  	port->count -= 1;
  	if (!port->count)
d5cd92448   Eric W. Biederman   macvlan: Fix use ...
851
  		macvlan_port_destroy(port->dev);
fccaf7101   Eric Dumazet   macvlan: Precise ...
852
  }
bc1f44709   stephen hemminger   net: make ndo_get...
853
854
  static void macvlan_dev_get_stats64(struct net_device *dev,
  				    struct rtnl_link_stats64 *stats)
fccaf7101   Eric Dumazet   macvlan: Precise ...
855
  {
fccaf7101   Eric Dumazet   macvlan: Precise ...
856
  	struct macvlan_dev *vlan = netdev_priv(dev);
8ffab51b3   Eric Dumazet   macvlan: lockless...
857
  	if (vlan->pcpu_stats) {
cdf3e274c   Li RongQing   macvlan: unify ma...
858
  		struct vlan_pcpu_stats *p;
8ffab51b3   Eric Dumazet   macvlan: lockless...
859
860
  		u64 rx_packets, rx_bytes, rx_multicast, tx_packets, tx_bytes;
  		u32 rx_errors = 0, tx_dropped = 0;
bc66154ef   Eric Dumazet   macvlan: 64 bit r...
861
  		unsigned int start;
fccaf7101   Eric Dumazet   macvlan: Precise ...
862
863
864
  		int i;
  
  		for_each_possible_cpu(i) {
8ffab51b3   Eric Dumazet   macvlan: lockless...
865
  			p = per_cpu_ptr(vlan->pcpu_stats, i);
bc66154ef   Eric Dumazet   macvlan: 64 bit r...
866
  			do {
57a7744e0   Eric W. Biederman   net: Replace u64_...
867
  				start = u64_stats_fetch_begin_irq(&p->syncp);
bc66154ef   Eric Dumazet   macvlan: 64 bit r...
868
869
870
  				rx_packets	= p->rx_packets;
  				rx_bytes	= p->rx_bytes;
  				rx_multicast	= p->rx_multicast;
8ffab51b3   Eric Dumazet   macvlan: lockless...
871
872
  				tx_packets	= p->tx_packets;
  				tx_bytes	= p->tx_bytes;
57a7744e0   Eric W. Biederman   net: Replace u64_...
873
  			} while (u64_stats_fetch_retry_irq(&p->syncp, start));
8ffab51b3   Eric Dumazet   macvlan: lockless...
874
875
876
877
878
879
880
881
882
883
884
  
  			stats->rx_packets	+= rx_packets;
  			stats->rx_bytes		+= rx_bytes;
  			stats->multicast	+= rx_multicast;
  			stats->tx_packets	+= tx_packets;
  			stats->tx_bytes		+= tx_bytes;
  			/* rx_errors & tx_dropped are u32, updated
  			 * without syncp protection.
  			 */
  			rx_errors	+= p->rx_errors;
  			tx_dropped	+= p->tx_dropped;
fccaf7101   Eric Dumazet   macvlan: Precise ...
885
  		}
8ffab51b3   Eric Dumazet   macvlan: lockless...
886
887
888
  		stats->rx_errors	= rx_errors;
  		stats->rx_dropped	= rx_errors;
  		stats->tx_dropped	= tx_dropped;
fccaf7101   Eric Dumazet   macvlan: Precise ...
889
  	}
fccaf7101   Eric Dumazet   macvlan: Precise ...
890
  }
8e586137e   Jiri Pirko   net: make vlan nd...
891
  static int macvlan_vlan_rx_add_vid(struct net_device *dev,
80d5c3689   Patrick McHardy   net: vlan: prepar...
892
  				   __be16 proto, u16 vid)
8d13e670d   John Fastabend   macvlan: add VLAN...
893
894
895
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
  	struct net_device *lowerdev = vlan->lowerdev;
8d13e670d   John Fastabend   macvlan: add VLAN...
896

80d5c3689   Patrick McHardy   net: vlan: prepar...
897
  	return vlan_vid_add(lowerdev, proto, vid);
8d13e670d   John Fastabend   macvlan: add VLAN...
898
  }
8e586137e   Jiri Pirko   net: make vlan nd...
899
  static int macvlan_vlan_rx_kill_vid(struct net_device *dev,
80d5c3689   Patrick McHardy   net: vlan: prepar...
900
  				    __be16 proto, u16 vid)
8d13e670d   John Fastabend   macvlan: add VLAN...
901
902
903
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
  	struct net_device *lowerdev = vlan->lowerdev;
8d13e670d   John Fastabend   macvlan: add VLAN...
904

80d5c3689   Patrick McHardy   net: vlan: prepar...
905
  	vlan_vid_del(lowerdev, proto, vid);
8e586137e   Jiri Pirko   net: make vlan nd...
906
  	return 0;
8d13e670d   John Fastabend   macvlan: add VLAN...
907
  }
edc7d5732   stephen hemminger   netlink: add attr...
908
  static int macvlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
df8ef8f3a   John Fastabend   macvlan: add FDB ...
909
  			   struct net_device *dev,
f6f6424ba   Jiri Pirko   net: make vid as ...
910
  			   const unsigned char *addr, u16 vid,
87b0984eb   Petr Machata   net: Add extack a...
911
912
  			   u16 flags,
  			   struct netlink_ext_ack *extack)
df8ef8f3a   John Fastabend   macvlan: add FDB ...
913
914
915
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
  	int err = -EINVAL;
8a50f11c3   Vlad Yasevich   macvlan: Allow se...
916
917
918
  	/* Support unicast filter only on passthru devices.
  	 * Multicast filter should be allowed on all devices.
  	 */
43c2d578a   Vlad Yasevich   macvlan: convert ...
919
  	if (!macvlan_passthru(vlan->port) && is_unicast_ether_addr(addr))
df8ef8f3a   John Fastabend   macvlan: add FDB ...
920
  		return -EOPNOTSUPP;
ab2cfbb2b   Thomas Richter   macvlan fdb repla...
921
922
  	if (flags & NLM_F_REPLACE)
  		return -EOPNOTSUPP;
df8ef8f3a   John Fastabend   macvlan: add FDB ...
923
924
925
926
927
928
929
  	if (is_unicast_ether_addr(addr))
  		err = dev_uc_add_excl(dev, addr);
  	else if (is_multicast_ether_addr(addr))
  		err = dev_mc_add_excl(dev, addr);
  
  	return err;
  }
1690be63a   Vlad Yasevich   bridge: Add vlan ...
930
  static int macvlan_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
df8ef8f3a   John Fastabend   macvlan: add FDB ...
931
  			   struct net_device *dev,
f6f6424ba   Jiri Pirko   net: make vid as ...
932
  			   const unsigned char *addr, u16 vid)
df8ef8f3a   John Fastabend   macvlan: add FDB ...
933
934
935
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
  	int err = -EINVAL;
8a50f11c3   Vlad Yasevich   macvlan: Allow se...
936
937
938
  	/* Support unicast filter only on passthru devices.
  	 * Multicast filter should be allowed on all devices.
  	 */
43c2d578a   Vlad Yasevich   macvlan: convert ...
939
  	if (!macvlan_passthru(vlan->port) && is_unicast_ether_addr(addr))
df8ef8f3a   John Fastabend   macvlan: add FDB ...
940
941
942
943
944
945
946
947
948
  		return -EOPNOTSUPP;
  
  	if (is_unicast_ether_addr(addr))
  		err = dev_uc_del(dev, addr);
  	else if (is_multicast_ether_addr(addr))
  		err = dev_mc_del(dev, addr);
  
  	return err;
  }
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
949
950
951
  static void macvlan_ethtool_get_drvinfo(struct net_device *dev,
  					struct ethtool_drvinfo *drvinfo)
  {
7826d43f2   Jiri Pirko   ethtool: fix drvi...
952
953
  	strlcpy(drvinfo->driver, "macvlan", sizeof(drvinfo->driver));
  	strlcpy(drvinfo->version, "0.1", sizeof(drvinfo->version));
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
954
  }
85f958197   David Decotigny   net: macvlan: use...
955
956
  static int macvlan_ethtool_get_link_ksettings(struct net_device *dev,
  					      struct ethtool_link_ksettings *cmd)
9edb8bb68   Stephen Hemminger   macvlan: add supp...
957
958
  {
  	const struct macvlan_dev *vlan = netdev_priv(dev);
4bc71cb98   Jiri Pirko   net: consolidate ...
959

85f958197   David Decotigny   net: macvlan: use...
960
  	return __ethtool_get_link_ksettings(vlan->lowerdev, cmd);
9edb8bb68   Stephen Hemminger   macvlan: add supp...
961
  }
254c0a2bf   Hangbin Liu   macvlan: pass get...
962
963
964
965
966
967
  static int macvlan_ethtool_get_ts_info(struct net_device *dev,
  				       struct ethtool_ts_info *info)
  {
  	struct net_device *real_dev = macvlan_dev_real_dev(dev);
  	const struct ethtool_ops *ops = real_dev->ethtool_ops;
  	struct phy_device *phydev = real_dev->phydev;
d25de984a   Richard Cochran   net: macvlan: Use...
968
969
  	if (phy_has_tsinfo(phydev)) {
  		return phy_ts_info(phydev, info);
254c0a2bf   Hangbin Liu   macvlan: pass get...
970
971
972
973
974
975
976
977
978
979
  	} else if (ops->get_ts_info) {
  		return ops->get_ts_info(real_dev, info);
  	} else {
  		info->so_timestamping = SOF_TIMESTAMPING_RX_SOFTWARE |
  			SOF_TIMESTAMPING_SOFTWARE;
  		info->phc_index = -1;
  	}
  
  	return 0;
  }
2be5c7679   Vlad Yasevich   macvtap: Let TUNS...
980
981
982
983
  static netdev_features_t macvlan_fix_features(struct net_device *dev,
  					      netdev_features_t features)
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
62dbe8301   Michal Kubeček   macvlan: allow se...
984
  	netdev_features_t lowerdev_features = vlan->lowerdev->features;
797f87f83   Florian Westphal   macvlan: fix netd...
985
  	netdev_features_t mask;
2be5c7679   Vlad Yasevich   macvtap: Let TUNS...
986

797f87f83   Florian Westphal   macvlan: fix netd...
987
988
989
  	features |= NETIF_F_ALL_FOR_ALL;
  	features &= (vlan->set_features | ~MACVLAN_FEATURES);
  	mask = features;
62dbe8301   Michal Kubeček   macvlan: allow se...
990
991
  	lowerdev_features &= (features | ~NETIF_F_LRO);
  	features = netdev_increment_features(lowerdev_features, features, mask);
8b4703e9b   Vlad Yasevich   macvlan: Add supp...
992
  	features |= ALWAYS_ON_FEATURES;
13fbcc8dc   Shannon Nelson   macvlan: filter o...
993
  	features &= (ALWAYS_ON_FEATURES | MACVLAN_FEATURES);
797f87f83   Florian Westphal   macvlan: fix netd...
994
995
  
  	return features;
2be5c7679   Vlad Yasevich   macvtap: Let TUNS...
996
  }
688cea83f   dingtianhong   macvlan: add netp...
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
  #ifdef CONFIG_NET_POLL_CONTROLLER
  static void macvlan_dev_poll_controller(struct net_device *dev)
  {
  	return;
  }
  
  static int macvlan_dev_netpoll_setup(struct net_device *dev, struct netpoll_info *npinfo)
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
  	struct net_device *real_dev = vlan->lowerdev;
  	struct netpoll *netpoll;
  	int err = 0;
  
  	netpoll = kzalloc(sizeof(*netpoll), GFP_KERNEL);
  	err = -ENOMEM;
  	if (!netpoll)
  		goto out;
  
  	err = __netpoll_setup(netpoll, real_dev);
  	if (err) {
  		kfree(netpoll);
  		goto out;
  	}
  
  	vlan->netpoll = netpoll;
  
  out:
  	return err;
  }
  
  static void macvlan_dev_netpoll_cleanup(struct net_device *dev)
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
  	struct netpoll *netpoll = vlan->netpoll;
  
  	if (!netpoll)
  		return;
  
  	vlan->netpoll = NULL;
c9fbd71f7   Debabrata Banerjee   netpoll: allow cl...
1036
  	__netpoll_free(netpoll);
688cea83f   dingtianhong   macvlan: add netp...
1037
1038
  }
  #endif	/* CONFIG_NET_POLL_CONTROLLER */
ef5fa6bc4   Nicolas Dichtel   macvlan: implemen...
1039
1040
1041
1042
1043
1044
  static int macvlan_dev_get_iflink(const struct net_device *dev)
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
  
  	return vlan->lowerdev->ifindex;
  }
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1045
1046
  static const struct ethtool_ops macvlan_ethtool_ops = {
  	.get_link		= ethtool_op_get_link,
85f958197   David Decotigny   net: macvlan: use...
1047
  	.get_link_ksettings	= macvlan_ethtool_get_link_ksettings,
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1048
  	.get_drvinfo		= macvlan_ethtool_get_drvinfo,
254c0a2bf   Hangbin Liu   macvlan: pass get...
1049
  	.get_ts_info		= macvlan_ethtool_get_ts_info,
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1050
  };
54a30c975   Stephen Hemminger   macvlan: convert ...
1051
1052
  static const struct net_device_ops macvlan_netdev_ops = {
  	.ndo_init		= macvlan_init,
fccaf7101   Eric Dumazet   macvlan: Precise ...
1053
  	.ndo_uninit		= macvlan_uninit,
54a30c975   Stephen Hemminger   macvlan: convert ...
1054
1055
  	.ndo_open		= macvlan_open,
  	.ndo_stop		= macvlan_stop,
008298231   Stephen Hemminger   netdev: add more ...
1056
  	.ndo_start_xmit		= macvlan_start_xmit,
54a30c975   Stephen Hemminger   macvlan: convert ...
1057
  	.ndo_change_mtu		= macvlan_change_mtu,
254c0a2bf   Hangbin Liu   macvlan: pass get...
1058
  	.ndo_do_ioctl		= macvlan_do_ioctl,
2be5c7679   Vlad Yasevich   macvtap: Let TUNS...
1059
  	.ndo_fix_features	= macvlan_fix_features,
54a30c975   Stephen Hemminger   macvlan: convert ...
1060
1061
  	.ndo_change_rx_flags	= macvlan_change_rx_flags,
  	.ndo_set_mac_address	= macvlan_set_mac_address,
df8ef8f3a   John Fastabend   macvlan: add FDB ...
1062
  	.ndo_set_rx_mode	= macvlan_set_mac_lists,
bc66154ef   Eric Dumazet   macvlan: 64 bit r...
1063
  	.ndo_get_stats64	= macvlan_dev_get_stats64,
54a30c975   Stephen Hemminger   macvlan: convert ...
1064
  	.ndo_validate_addr	= eth_validate_addr,
8d13e670d   John Fastabend   macvlan: add VLAN...
1065
1066
  	.ndo_vlan_rx_add_vid	= macvlan_vlan_rx_add_vid,
  	.ndo_vlan_rx_kill_vid	= macvlan_vlan_rx_kill_vid,
df8ef8f3a   John Fastabend   macvlan: add FDB ...
1067
1068
1069
  	.ndo_fdb_add		= macvlan_fdb_add,
  	.ndo_fdb_del		= macvlan_fdb_del,
  	.ndo_fdb_dump		= ndo_dflt_fdb_dump,
688cea83f   dingtianhong   macvlan: add netp...
1070
1071
1072
1073
1074
  #ifdef CONFIG_NET_POLL_CONTROLLER
  	.ndo_poll_controller	= macvlan_dev_poll_controller,
  	.ndo_netpoll_setup	= macvlan_dev_netpoll_setup,
  	.ndo_netpoll_cleanup	= macvlan_dev_netpoll_cleanup,
  #endif
ef5fa6bc4   Nicolas Dichtel   macvlan: implemen...
1075
  	.ndo_get_iflink		= macvlan_dev_get_iflink,
f56e67b51   Toshiaki Makita   macvlan: Don't se...
1076
  	.ndo_features_check	= passthru_features_check,
2e8b4ba64   Andy Roulin   macvlan: add ndo_...
1077
  	.ndo_change_proto_down  = dev_change_proto_down_generic,
54a30c975   Stephen Hemminger   macvlan: convert ...
1078
  };
8a35747a5   Herbert Xu   macvtap: Limit pa...
1079
  void macvlan_common_setup(struct net_device *dev)
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1080
1081
  {
  	ether_setup(dev);
91572088e   Jarod Wilson   net: use core MTU...
1082
1083
  	dev->min_mtu		= 0;
  	dev->max_mtu		= ETH_MAX_MTU;
028758788   Eric Dumazet   net: better IFF_X...
1084
1085
  	dev->priv_flags	       &= ~IFF_TX_SKB_SHARING;
  	netif_keep_dst(dev);
87ab7f6f2   Vlad Yasevich   macvlan: Set IFF_...
1086
  	dev->priv_flags	       |= IFF_UNICAST_FLT;
54a30c975   Stephen Hemminger   macvlan: convert ...
1087
  	dev->netdev_ops		= &macvlan_netdev_ops;
cf124db56   David S. Miller   net: Fix inconsis...
1088
  	dev->needs_free_netdev	= true;
717401295   Lutz Jaenicke   macvlan: fix typo...
1089
  	dev->header_ops		= &macvlan_hard_header_ops;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1090
  	dev->ethtool_ops	= &macvlan_ethtool_ops;
8a35747a5   Herbert Xu   macvtap: Limit pa...
1091
1092
1093
1094
1095
1096
  }
  EXPORT_SYMBOL_GPL(macvlan_common_setup);
  
  static void macvlan_setup(struct net_device *dev)
  {
  	macvlan_common_setup(dev);
7009212b1   Zhang Shengju   macvlan: convert ...
1097
  	dev->priv_flags |= IFF_NO_QUEUE;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1098
1099
1100
1101
1102
1103
  }
  
  static int macvlan_port_create(struct net_device *dev)
  {
  	struct macvlan_port *port;
  	unsigned int i;
ab95bfe01   Jiri Pirko   net: replace hook...
1104
  	int err;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1105
1106
1107
  
  	if (dev->type != ARPHRD_ETHER || dev->flags & IFF_LOOPBACK)
  		return -EINVAL;
322dc6e06   Mahesh Bandewar   macvlan: use netd...
1108
  	if (netdev_is_rx_handler_busy(dev))
d6b00fec5   Mahesh Bandewar   macvlan: play wel...
1109
  		return -EBUSY;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1110
1111
1112
1113
1114
  	port = kzalloc(sizeof(*port), GFP_KERNEL);
  	if (port == NULL)
  		return -ENOMEM;
  
  	port->dev = dev;
18c8c54de   Vlad Yasevich   macvlan: Let pass...
1115
  	ether_addr_copy(port->perm_addr, dev->dev_addr);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1116
1117
1118
  	INIT_LIST_HEAD(&port->vlans);
  	for (i = 0; i < MACVLAN_HASH_SIZE; i++)
  		INIT_HLIST_HEAD(&port->vlan_hash[i]);
79cf79abc   Michael Braun   macvlan: add sour...
1119
1120
  	for (i = 0; i < MACVLAN_HASH_SIZE; i++)
  		INIT_HLIST_HEAD(&port->vlan_source_hash[i]);
ab95bfe01   Jiri Pirko   net: replace hook...
1121

412ca1550   Herbert Xu   macvlan: Move bro...
1122
1123
  	skb_queue_head_init(&port->bc_queue);
  	INIT_WORK(&port->bc_work, macvlan_process_broadcast);
a35e2c1b6   Jiri Pirko   macvlan: use rx_h...
1124
1125
  	err = netdev_rx_handler_register(dev, macvlan_handle_frame, port);
  	if (err)
ab95bfe01   Jiri Pirko   net: replace hook...
1126
  		kfree(port);
d93515611   Eric Dumazet   macvlan: fix pani...
1127
1128
  	else
  		dev->priv_flags |= IFF_MACVLAN_PORT;
ab95bfe01   Jiri Pirko   net: replace hook...
1129
  	return err;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1130
1131
1132
1133
  }
  
  static void macvlan_port_destroy(struct net_device *dev)
  {
e052f7e64   Eric Dumazet   macvlan: use the ...
1134
  	struct macvlan_port *port = macvlan_port_get_rtnl(dev);
f6478218e   Herbert Xu   macvlan: Fix devi...
1135
  	struct sk_buff *skb;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1136

a35e2c1b6   Jiri Pirko   macvlan: use rx_h...
1137
  	dev->priv_flags &= ~IFF_MACVLAN_PORT;
ab95bfe01   Jiri Pirko   net: replace hook...
1138
  	netdev_rx_handler_unregister(dev);
fe0ca7328   Eric Dumazet   macvlan: fix a ra...
1139
1140
1141
1142
1143
  
  	/* After this point, no packet can schedule bc_work anymore,
  	 * but we need to cancel it and purge left skbs if any.
  	 */
  	cancel_work_sync(&port->bc_work);
f6478218e   Herbert Xu   macvlan: Fix devi...
1144
1145
1146
1147
1148
1149
1150
1151
1152
  
  	while ((skb = __skb_dequeue(&port->bc_queue))) {
  		const struct macvlan_dev *src = MACVLAN_SKB_CB(skb)->src;
  
  		if (src)
  			dev_put(src->dev);
  
  		kfree_skb(skb);
  	}
fe0ca7328   Eric Dumazet   macvlan: fix a ra...
1153

18c8c54de   Vlad Yasevich   macvlan: Let pass...
1154
1155
1156
1157
1158
1159
1160
1161
1162
  	/* If the lower device address has been changed by passthru
  	 * macvlan, put it back.
  	 */
  	if (macvlan_passthru(port) &&
  	    !ether_addr_equal(port->dev->dev_addr, port->perm_addr)) {
  		struct sockaddr sa;
  
  		sa.sa_family = port->dev->type;
  		memcpy(&sa.sa_data, port->perm_addr, port->dev->addr_len);
3a37a9636   Petr Machata   net: dev: Add ext...
1163
  		dev_set_mac_address(port->dev, &sa, NULL);
18c8c54de   Vlad Yasevich   macvlan: Let pass...
1164
  	}
a1f5315ce   Gao Feng   driver: macvlan: ...
1165
  	kfree(port);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1166
  }
a8b8a889e   Matthias Schiffer   net: add netlink_...
1167
1168
  static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[],
  			    struct netlink_ext_ack *extack)
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1169
  {
8b61fba50   Alvin Šipraga   macvlan: validate...
1170
1171
  	struct nlattr *nla, *head;
  	int rem, len;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1172
1173
1174
1175
1176
1177
  	if (tb[IFLA_ADDRESS]) {
  		if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
  			return -EINVAL;
  		if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
  			return -EADDRNOTAVAIL;
  	}
27c0b1a85   Arnd Bergmann   macvlan: export m...
1178

07850a4f7   Zhang Shengju   macvlan: code ref...
1179
1180
1181
1182
  	if (!data)
  		return 0;
  
  	if (data[IFLA_MACVLAN_FLAGS] &&
151274782   Michael S. Tsirkin   macvlan: validate...
1183
1184
  	    nla_get_u16(data[IFLA_MACVLAN_FLAGS]) & ~MACVLAN_FLAG_NOPROMISC)
  		return -EINVAL;
07850a4f7   Zhang Shengju   macvlan: code ref...
1185
  	if (data[IFLA_MACVLAN_MODE]) {
27c0b1a85   Arnd Bergmann   macvlan: export m...
1186
1187
1188
1189
  		switch (nla_get_u32(data[IFLA_MACVLAN_MODE])) {
  		case MACVLAN_MODE_PRIVATE:
  		case MACVLAN_MODE_VEPA:
  		case MACVLAN_MODE_BRIDGE:
eb06acdc8   Sridhar Samudrala   macvlan: Introduc...
1190
  		case MACVLAN_MODE_PASSTHRU:
79cf79abc   Michael Braun   macvlan: add sour...
1191
1192
1193
1194
1195
1196
  		case MACVLAN_MODE_SOURCE:
  			break;
  		default:
  			return -EINVAL;
  		}
  	}
07850a4f7   Zhang Shengju   macvlan: code ref...
1197
  	if (data[IFLA_MACVLAN_MACADDR_MODE]) {
79cf79abc   Michael Braun   macvlan: add sour...
1198
1199
1200
1201
1202
  		switch (nla_get_u32(data[IFLA_MACVLAN_MACADDR_MODE])) {
  		case MACVLAN_MACADDR_ADD:
  		case MACVLAN_MACADDR_DEL:
  		case MACVLAN_MACADDR_FLUSH:
  		case MACVLAN_MACADDR_SET:
27c0b1a85   Arnd Bergmann   macvlan: export m...
1203
1204
1205
1206
1207
  			break;
  		default:
  			return -EINVAL;
  		}
  	}
79cf79abc   Michael Braun   macvlan: add sour...
1208

07850a4f7   Zhang Shengju   macvlan: code ref...
1209
  	if (data[IFLA_MACVLAN_MACADDR]) {
79cf79abc   Michael Braun   macvlan: add sour...
1210
1211
1212
1213
1214
1215
  		if (nla_len(data[IFLA_MACVLAN_MACADDR]) != ETH_ALEN)
  			return -EINVAL;
  
  		if (!is_valid_ether_addr(nla_data(data[IFLA_MACVLAN_MACADDR])))
  			return -EADDRNOTAVAIL;
  	}
8b61fba50   Alvin Šipraga   macvlan: validate...
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
  	if (data[IFLA_MACVLAN_MACADDR_DATA]) {
  		head = nla_data(data[IFLA_MACVLAN_MACADDR_DATA]);
  		len = nla_len(data[IFLA_MACVLAN_MACADDR_DATA]);
  
  		nla_for_each_attr(nla, head, len, rem) {
  			if (nla_type(nla) != IFLA_MACVLAN_MACADDR ||
  			    nla_len(nla) != ETH_ALEN)
  				return -EINVAL;
  
  			if (!is_valid_ether_addr(nla_data(nla)))
  				return -EADDRNOTAVAIL;
  		}
  	}
07850a4f7   Zhang Shengju   macvlan: code ref...
1229
  	if (data[IFLA_MACVLAN_MACADDR_COUNT])
79cf79abc   Michael Braun   macvlan: add sour...
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
  		return -EINVAL;
  
  	return 0;
  }
  
  /**
   * reconfigure list of remote source mac address
   * (only for macvlan devices in source mode)
   * Note regarding alignment: all netlink data is aligned to 4 Byte, which
   * suffices for both ether_addr_copy and ether_addr_equal_64bits usage.
   */
  static int macvlan_changelink_sources(struct macvlan_dev *vlan, u32 mode,
  				      struct nlattr *data[])
  {
  	char *addr = NULL;
  	int ret, rem, len;
  	struct nlattr *nla, *head;
  	struct macvlan_source_entry *entry;
  
  	if (data[IFLA_MACVLAN_MACADDR])
  		addr = nla_data(data[IFLA_MACVLAN_MACADDR]);
  
  	if (mode == MACVLAN_MACADDR_ADD) {
  		if (!addr)
  			return -EINVAL;
  
  		return macvlan_hash_add_source(vlan, addr);
  
  	} else if (mode == MACVLAN_MACADDR_DEL) {
  		if (!addr)
  			return -EINVAL;
  
  		entry = macvlan_hash_lookup_source(vlan, addr);
  		if (entry) {
  			macvlan_hash_del_source(entry);
  			vlan->macaddr_count--;
  		}
  	} else if (mode == MACVLAN_MACADDR_FLUSH) {
  		macvlan_flush_sources(vlan->port, vlan);
  	} else if (mode == MACVLAN_MACADDR_SET) {
  		macvlan_flush_sources(vlan->port, vlan);
  
  		if (addr) {
  			ret = macvlan_hash_add_source(vlan, addr);
  			if (ret)
  				return ret;
  		}
  
  		if (!data || !data[IFLA_MACVLAN_MACADDR_DATA])
  			return 0;
  
  		head = nla_data(data[IFLA_MACVLAN_MACADDR_DATA]);
  		len = nla_len(data[IFLA_MACVLAN_MACADDR_DATA]);
  
  		nla_for_each_attr(nla, head, len, rem) {
79cf79abc   Michael Braun   macvlan: add sour...
1285
1286
1287
1288
1289
1290
1291
1292
  			addr = nla_data(nla);
  			ret = macvlan_hash_add_source(vlan, addr);
  			if (ret)
  				return ret;
  		}
  	} else {
  		return -EINVAL;
  	}
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1293
1294
  	return 0;
  }
fc0663d6b   Arnd Bergmann   macvlan: allow mu...
1295
  int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
42ab19ee9   David Ahern   net: Add extack t...
1296
1297
  			   struct nlattr *tb[], struct nlattr *data[],
  			   struct netlink_ext_ack *extack)
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1298
1299
1300
1301
1302
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
  	struct macvlan_port *port;
  	struct net_device *lowerdev;
  	int err;
79cf79abc   Michael Braun   macvlan: add sour...
1303
  	int macmode;
aa5fd0fb7   Gao Feng   driver: macvlan: ...
1304
  	bool create = false;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1305
1306
1307
  
  	if (!tb[IFLA_LINK])
  		return -EINVAL;
81adee47d   Eric W. Biederman   net: Support spec...
1308
  	lowerdev = __dev_get_by_index(src_net, nla_get_u32(tb[IFLA_LINK]));
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1309
1310
  	if (lowerdev == NULL)
  		return -ENODEV;
d70f2cf52   Kevin Wallace   macvlan: Support ...
1311
  	/* When creating macvlans or macvtaps on top of other macvlans - use
b0832a296   Eric Biederman   macvlan: Support ...
1312
  	 * the real device as the lowerdev.
a6ca5f1db   Patrick McHardy   [MACVLAN]: Preven...
1313
  	 */
d70f2cf52   Kevin Wallace   macvlan: Support ...
1314
1315
  	if (netif_is_macvlan(lowerdev))
  		lowerdev = macvlan_dev_real_dev(lowerdev);
a6ca5f1db   Patrick McHardy   [MACVLAN]: Preven...
1316

b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1317
1318
1319
1320
  	if (!tb[IFLA_MTU])
  		dev->mtu = lowerdev->mtu;
  	else if (dev->mtu > lowerdev->mtu)
  		return -EINVAL;
91572088e   Jarod Wilson   net: use core MTU...
1321
1322
1323
  	/* MTU range: 68 - lowerdev->max_mtu */
  	dev->min_mtu = ETH_MIN_MTU;
  	dev->max_mtu = lowerdev->max_mtu;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1324
  	if (!tb[IFLA_ADDRESS])
7ce5d2221   Danny Kukawka   net: use eth_hw_a...
1325
  		eth_hw_addr_random(dev);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1326

913564fbc   Julian Wiedmann   macvlan: use neti...
1327
  	if (!netif_is_macvlan_port(lowerdev)) {
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1328
1329
1330
  		err = macvlan_port_create(lowerdev);
  		if (err < 0)
  			return err;
aa5fd0fb7   Gao Feng   driver: macvlan: ...
1331
  		create = true;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1332
  	}
e052f7e64   Eric Dumazet   macvlan: use the ...
1333
  	port = macvlan_port_get_rtnl(lowerdev);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1334

eb06acdc8   Sridhar Samudrala   macvlan: Introduc...
1335
  	/* Only 1 macvlan device can be created in passthru mode */
43c2d578a   Vlad Yasevich   macvlan: convert ...
1336
  	if (macvlan_passthru(port)) {
aa5fd0fb7   Gao Feng   driver: macvlan: ...
1337
1338
1339
1340
1341
1342
  		/* The macvlan port must be not created this time,
  		 * still goto destroy_macvlan_port for readability.
  		 */
  		err = -EINVAL;
  		goto destroy_macvlan_port;
  	}
eb06acdc8   Sridhar Samudrala   macvlan: Introduc...
1343

b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1344
1345
1346
  	vlan->lowerdev = lowerdev;
  	vlan->dev      = dev;
  	vlan->port     = port;
2be5c7679   Vlad Yasevich   macvtap: Let TUNS...
1347
  	vlan->set_features = MACVLAN_FEATURES;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1348

27c0b1a85   Arnd Bergmann   macvlan: export m...
1349
1350
1351
  	vlan->mode     = MACVLAN_MODE_VEPA;
  	if (data && data[IFLA_MACVLAN_MODE])
  		vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
df8ef8f3a   John Fastabend   macvlan: add FDB ...
1352
1353
  	if (data && data[IFLA_MACVLAN_FLAGS])
  		vlan->flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]);
eb06acdc8   Sridhar Samudrala   macvlan: Introduc...
1354
  	if (vlan->mode == MACVLAN_MODE_PASSTHRU) {
aa5fd0fb7   Gao Feng   driver: macvlan: ...
1355
1356
1357
1358
  		if (port->count) {
  			err = -EINVAL;
  			goto destroy_macvlan_port;
  		}
43c2d578a   Vlad Yasevich   macvlan: convert ...
1359
  		macvlan_set_passthru(port);
8b98604e3   Bjørn Mork   net: macvlan: inh...
1360
  		eth_hw_addr_inherit(dev, lowerdev);
eb06acdc8   Sridhar Samudrala   macvlan: Introduc...
1361
  	}
79cf79abc   Michael Braun   macvlan: add sour...
1362
  	if (data && data[IFLA_MACVLAN_MACADDR_MODE]) {
aa5fd0fb7   Gao Feng   driver: macvlan: ...
1363
1364
1365
1366
  		if (vlan->mode != MACVLAN_MODE_SOURCE) {
  			err = -EINVAL;
  			goto destroy_macvlan_port;
  		}
79cf79abc   Michael Braun   macvlan: add sour...
1367
1368
1369
  		macmode = nla_get_u32(data[IFLA_MACVLAN_MACADDR_MODE]);
  		err = macvlan_changelink_sources(vlan, macmode, data);
  		if (err)
aa5fd0fb7   Gao Feng   driver: macvlan: ...
1370
  			goto destroy_macvlan_port;
79cf79abc   Michael Braun   macvlan: add sour...
1371
  	}
47d4ab91e   John Fastabend   macvlan: resolve ...
1372
1373
  	err = register_netdevice(dev);
  	if (err < 0)
aa5fd0fb7   Gao Feng   driver: macvlan: ...
1374
  		goto destroy_macvlan_port;
47d4ab91e   John Fastabend   macvlan: resolve ...
1375

a6cc0cfa7   John Fastabend   net: Add layer 2 ...
1376
  	dev->priv_flags |= IFF_MACVLAN;
42ab19ee9   David Ahern   net: Add extack t...
1377
  	err = netdev_upper_dev_link(lowerdev, dev, extack);
7cd43db77   Jiri Pirko   macvlan: add link...
1378
  	if (err)
da37705ce   Cong Wang   macvlan: unregist...
1379
  		goto unregister_netdev;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1380

233c7df08   Jiri Pirko   macvlan: fix pass...
1381
  	list_add_tail_rcu(&vlan->list, &port->vlans);
fc4a74896   Patrick Mullaney   netdevice: provid...
1382
  	netif_stacked_transfer_operstate(lowerdev, dev);
de7d244d0   Nikolay Aleksandrov   macvlan: make ope...
1383
  	linkwatch_fire_event(dev);
f16d3d574   Jiri Pirko   macvlan: do prope...
1384

b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1385
  	return 0;
f16d3d574   Jiri Pirko   macvlan: do prope...
1386

da37705ce   Cong Wang   macvlan: unregist...
1387
  unregister_netdev:
d02fd6e7d   Gao Feng   macvlan: Fix one ...
1388
  	/* macvlan_uninit would free the macvlan port */
da37705ce   Cong Wang   macvlan: unregist...
1389
  	unregister_netdevice(dev);
d02fd6e7d   Gao Feng   macvlan: Fix one ...
1390
  	return err;
aa5fd0fb7   Gao Feng   driver: macvlan: ...
1391
  destroy_macvlan_port:
d02fd6e7d   Gao Feng   macvlan: Fix one ...
1392
1393
1394
  	/* the macvlan port may be freed by macvlan_uninit when fail to register.
  	 * so we destroy the macvlan port only when it's valid.
  	 */
4e14bf423   Alexey Kodanev   macvlan: fix use-...
1395
  	if (create && macvlan_port_get_rtnl(lowerdev))
aa5fd0fb7   Gao Feng   driver: macvlan: ...
1396
  		macvlan_port_destroy(port->dev);
f16d3d574   Jiri Pirko   macvlan: do prope...
1397
  	return err;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1398
  }
fc0663d6b   Arnd Bergmann   macvlan: allow mu...
1399
  EXPORT_SYMBOL_GPL(macvlan_common_newlink);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1400

fc0663d6b   Arnd Bergmann   macvlan: allow mu...
1401
  static int macvlan_newlink(struct net *src_net, struct net_device *dev,
7a3f4a185   Matthias Schiffer   net: add netlink_...
1402
1403
  			   struct nlattr *tb[], struct nlattr *data[],
  			   struct netlink_ext_ack *extack)
fc0663d6b   Arnd Bergmann   macvlan: allow mu...
1404
  {
42ab19ee9   David Ahern   net: Add extack t...
1405
  	return macvlan_common_newlink(src_net, dev, tb, data, extack);
fc0663d6b   Arnd Bergmann   macvlan: allow mu...
1406
1407
1408
  }
  
  void macvlan_dellink(struct net_device *dev, struct list_head *head)
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1409
1410
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1411

79cf79abc   Michael Braun   macvlan: add sour...
1412
1413
  	if (vlan->mode == MACVLAN_MODE_SOURCE)
  		macvlan_flush_sources(vlan->port, vlan);
233c7df08   Jiri Pirko   macvlan: fix pass...
1414
  	list_del_rcu(&vlan->list);
23289a37e   Eric Dumazet   net: add a list_h...
1415
  	unregister_netdevice_queue(dev, head);
7cd43db77   Jiri Pirko   macvlan: add link...
1416
  	netdev_upper_dev_unlink(vlan->lowerdev, dev);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1417
  }
fc0663d6b   Arnd Bergmann   macvlan: allow mu...
1418
  EXPORT_SYMBOL_GPL(macvlan_dellink);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1419

27c0b1a85   Arnd Bergmann   macvlan: export m...
1420
  static int macvlan_changelink(struct net_device *dev,
ad744b223   Matthias Schiffer   net: add netlink_...
1421
1422
  			      struct nlattr *tb[], struct nlattr *data[],
  			      struct netlink_ext_ack *extack)
27c0b1a85   Arnd Bergmann   macvlan: export m...
1423
1424
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
266e83474   Michael S. Tsirkin   macvlan: better m...
1425
1426
  	enum macvlan_mode mode;
  	bool set_mode = false;
79cf79abc   Michael Braun   macvlan: add sour...
1427
1428
  	enum macvlan_macaddr_mode macmode;
  	int ret;
266e83474   Michael S. Tsirkin   macvlan: better m...
1429
1430
1431
1432
1433
1434
1435
1436
1437
  
  	/* Validate mode, but don't set yet: setting flags may fail. */
  	if (data && data[IFLA_MACVLAN_MODE]) {
  		set_mode = true;
  		mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
  		/* Passthrough mode can't be set or cleared dynamically */
  		if ((mode == MACVLAN_MODE_PASSTHRU) !=
  		    (vlan->mode == MACVLAN_MODE_PASSTHRU))
  			return -EINVAL;
79cf79abc   Michael Braun   macvlan: add sour...
1438
1439
1440
  		if (vlan->mode == MACVLAN_MODE_SOURCE &&
  		    vlan->mode != mode)
  			macvlan_flush_sources(vlan->port, vlan);
266e83474   Michael S. Tsirkin   macvlan: better m...
1441
  	}
99ffc3e74   Michael S. Tsirkin   macvlan: don't to...
1442

df8ef8f3a   John Fastabend   macvlan: add FDB ...
1443
1444
1445
  	if (data && data[IFLA_MACVLAN_FLAGS]) {
  		__u16 flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]);
  		bool promisc = (flags ^ vlan->flags) & MACVLAN_FLAG_NOPROMISC;
43c2d578a   Vlad Yasevich   macvlan: convert ...
1446
  		if (macvlan_passthru(vlan->port) && promisc) {
99ffc3e74   Michael S. Tsirkin   macvlan: don't to...
1447
1448
1449
1450
1451
1452
1453
1454
1455
  			int err;
  
  			if (flags & MACVLAN_FLAG_NOPROMISC)
  				err = dev_set_promiscuity(vlan->lowerdev, -1);
  			else
  				err = dev_set_promiscuity(vlan->lowerdev, 1);
  			if (err < 0)
  				return err;
  		}
df8ef8f3a   John Fastabend   macvlan: add FDB ...
1456
1457
  		vlan->flags = flags;
  	}
266e83474   Michael S. Tsirkin   macvlan: better m...
1458
1459
  	if (set_mode)
  		vlan->mode = mode;
79cf79abc   Michael Braun   macvlan: add sour...
1460
1461
1462
1463
1464
1465
1466
1467
  	if (data && data[IFLA_MACVLAN_MACADDR_MODE]) {
  		if (vlan->mode != MACVLAN_MODE_SOURCE)
  			return -EINVAL;
  		macmode = nla_get_u32(data[IFLA_MACVLAN_MACADDR_MODE]);
  		ret = macvlan_changelink_sources(vlan, macmode, data);
  		if (ret)
  			return ret;
  	}
27c0b1a85   Arnd Bergmann   macvlan: export m...
1468
1469
  	return 0;
  }
79cf79abc   Michael Braun   macvlan: add sour...
1470
1471
1472
1473
1474
1475
1476
  static size_t macvlan_get_size_mac(const struct macvlan_dev *vlan)
  {
  	if (vlan->macaddr_count == 0)
  		return 0;
  	return nla_total_size(0) /* IFLA_MACVLAN_MACADDR_DATA */
  		+ vlan->macaddr_count * nla_total_size(sizeof(u8) * ETH_ALEN);
  }
27c0b1a85   Arnd Bergmann   macvlan: export m...
1477
1478
  static size_t macvlan_get_size(const struct net_device *dev)
  {
79cf79abc   Michael Braun   macvlan: add sour...
1479
  	struct macvlan_dev *vlan = netdev_priv(dev);
01fe944f1   Eric Dumazet   macvlan: fix macv...
1480
1481
1482
  	return (0
  		+ nla_total_size(4) /* IFLA_MACVLAN_MODE */
  		+ nla_total_size(2) /* IFLA_MACVLAN_FLAGS */
79cf79abc   Michael Braun   macvlan: add sour...
1483
1484
  		+ nla_total_size(4) /* IFLA_MACVLAN_MACADDR_COUNT */
  		+ macvlan_get_size_mac(vlan) /* IFLA_MACVLAN_MACADDR */
01fe944f1   Eric Dumazet   macvlan: fix macv...
1485
  		);
27c0b1a85   Arnd Bergmann   macvlan: export m...
1486
  }
79cf79abc   Michael Braun   macvlan: add sour...
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
  static int macvlan_fill_info_macaddr(struct sk_buff *skb,
  				     const struct macvlan_dev *vlan,
  				     const int i)
  {
  	struct hlist_head *h = &vlan->port->vlan_source_hash[i];
  	struct macvlan_source_entry *entry;
  
  	hlist_for_each_entry_rcu(entry, h, hlist) {
  		if (entry->vlan != vlan)
  			continue;
  		if (nla_put(skb, IFLA_MACVLAN_MACADDR, ETH_ALEN, entry->addr))
  			return 1;
  	}
  	return 0;
  }
27c0b1a85   Arnd Bergmann   macvlan: export m...
1502
1503
1504
1505
  static int macvlan_fill_info(struct sk_buff *skb,
  				const struct net_device *dev)
  {
  	struct macvlan_dev *vlan = netdev_priv(dev);
79cf79abc   Michael Braun   macvlan: add sour...
1506
1507
  	int i;
  	struct nlattr *nest;
27c0b1a85   Arnd Bergmann   macvlan: export m...
1508

ead9a76ce   David S. Miller   macvlan: Stop usi...
1509
1510
  	if (nla_put_u32(skb, IFLA_MACVLAN_MODE, vlan->mode))
  		goto nla_put_failure;
df8ef8f3a   John Fastabend   macvlan: add FDB ...
1511
1512
  	if (nla_put_u16(skb, IFLA_MACVLAN_FLAGS, vlan->flags))
  		goto nla_put_failure;
79cf79abc   Michael Braun   macvlan: add sour...
1513
1514
1515
  	if (nla_put_u32(skb, IFLA_MACVLAN_MACADDR_COUNT, vlan->macaddr_count))
  		goto nla_put_failure;
  	if (vlan->macaddr_count > 0) {
ae0be8de9   Michal Kubecek   netlink: make nla...
1516
  		nest = nla_nest_start_noflag(skb, IFLA_MACVLAN_MACADDR_DATA);
79cf79abc   Michael Braun   macvlan: add sour...
1517
1518
1519
1520
1521
1522
1523
1524
1525
  		if (nest == NULL)
  			goto nla_put_failure;
  
  		for (i = 0; i < MACVLAN_HASH_SIZE; i++) {
  			if (macvlan_fill_info_macaddr(skb, vlan, i))
  				goto nla_put_failure;
  		}
  		nla_nest_end(skb, nest);
  	}
27c0b1a85   Arnd Bergmann   macvlan: export m...
1526
1527
1528
1529
1530
1531
1532
  	return 0;
  
  nla_put_failure:
  	return -EMSGSIZE;
  }
  
  static const struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX + 1] = {
df8ef8f3a   John Fastabend   macvlan: add FDB ...
1533
1534
  	[IFLA_MACVLAN_MODE]  = { .type = NLA_U32 },
  	[IFLA_MACVLAN_FLAGS] = { .type = NLA_U16 },
79cf79abc   Michael Braun   macvlan: add sour...
1535
1536
1537
1538
  	[IFLA_MACVLAN_MACADDR_MODE] = { .type = NLA_U32 },
  	[IFLA_MACVLAN_MACADDR] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
  	[IFLA_MACVLAN_MACADDR_DATA] = { .type = NLA_NESTED },
  	[IFLA_MACVLAN_MACADDR_COUNT] = { .type = NLA_U32 },
27c0b1a85   Arnd Bergmann   macvlan: export m...
1539
  };
fc0663d6b   Arnd Bergmann   macvlan: allow mu...
1540
1541
1542
  int macvlan_link_register(struct rtnl_link_ops *ops)
  {
  	/* common fields */
fc0663d6b   Arnd Bergmann   macvlan: allow mu...
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
  	ops->validate		= macvlan_validate;
  	ops->maxtype		= IFLA_MACVLAN_MAX;
  	ops->policy		= macvlan_policy;
  	ops->changelink		= macvlan_changelink;
  	ops->get_size		= macvlan_get_size;
  	ops->fill_info		= macvlan_fill_info;
  
  	return rtnl_link_register(ops);
  };
  EXPORT_SYMBOL_GPL(macvlan_link_register);
eaca400f1   Nicolas Dichtel   macvlan: advertis...
1553
1554
1555
1556
  static struct net *macvlan_get_link_net(const struct net_device *dev)
  {
  	return dev_net(macvlan_dev_real_dev(dev));
  }
fc0663d6b   Arnd Bergmann   macvlan: allow mu...
1557
  static struct rtnl_link_ops macvlan_link_ops = {
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1558
  	.kind		= "macvlan",
8a35747a5   Herbert Xu   macvtap: Limit pa...
1559
  	.setup		= macvlan_setup,
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1560
1561
  	.newlink	= macvlan_newlink,
  	.dellink	= macvlan_dellink,
eaca400f1   Nicolas Dichtel   macvlan: advertis...
1562
  	.get_link_net	= macvlan_get_link_net,
6fe3faf86   Sainath Grandhi   tap: Abstract typ...
1563
  	.priv_size      = sizeof(struct macvlan_dev),
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1564
1565
1566
1567
1568
  };
  
  static int macvlan_device_event(struct notifier_block *unused,
  				unsigned long event, void *ptr)
  {
351638e7d   Jiri Pirko   net: pass info st...
1569
  	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1570
1571
  	struct macvlan_dev *vlan, *next;
  	struct macvlan_port *port;
226bd3411   Eric Dumazet   net: use batched ...
1572
  	LIST_HEAD(list_kill);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1573

913564fbc   Julian Wiedmann   macvlan: use neti...
1574
  	if (!netif_is_macvlan_port(dev))
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1575
  		return NOTIFY_DONE;
e052f7e64   Eric Dumazet   macvlan: use the ...
1576
  	port = macvlan_port_get_rtnl(dev);
a35e2c1b6   Jiri Pirko   macvlan: use rx_h...
1577

b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1578
  	switch (event) {
de7d244d0   Nikolay Aleksandrov   macvlan: make ope...
1579
  	case NETDEV_UP:
80fd2d6ca   Travis Brown   macvlan: Change s...
1580
  	case NETDEV_DOWN:
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1581
1582
  	case NETDEV_CHANGE:
  		list_for_each_entry(vlan, &port->vlans, list)
fc4a74896   Patrick Mullaney   netdevice: provid...
1583
1584
  			netif_stacked_transfer_operstate(vlan->lowerdev,
  							 vlan->dev);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1585
1586
1587
  		break;
  	case NETDEV_FEAT_CHANGE:
  		list_for_each_entry(vlan, &port->vlans, list) {
8c2acc53f   Patrick McHardy   macvlan: fix gso_...
1588
  			vlan->dev->gso_max_size = dev->gso_max_size;
f6773c5e9   Eric Dumazet   vlan: propagate g...
1589
  			vlan->dev->gso_max_segs = dev->gso_max_segs;
797f87f83   Florian Westphal   macvlan: fix netd...
1590
  			netdev_update_features(vlan->dev);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1591
1592
  		}
  		break;
3763e7ef1   dingtianhong   macvlan: Propagat...
1593
1594
1595
1596
1597
1598
1599
  	case NETDEV_CHANGEMTU:
  		list_for_each_entry(vlan, &port->vlans, list) {
  			if (vlan->dev->mtu <= dev->mtu)
  				continue;
  			dev_set_mtu(vlan->dev, dev->mtu);
  		}
  		break;
e289fd281   dingtianhong   macvlan: fix the ...
1600
  	case NETDEV_CHANGEADDR:
43c2d578a   Vlad Yasevich   macvlan: convert ...
1601
  		if (!macvlan_passthru(port))
e289fd281   dingtianhong   macvlan: fix the ...
1602
1603
1604
1605
1606
  			return NOTIFY_DONE;
  
  		vlan = list_first_entry_or_null(&port->vlans,
  						struct macvlan_dev,
  						list);
4dee15b4f   Taehee Yoo   macvlan: fix null...
1607
  		if (vlan && macvlan_sync_address(vlan->dev, dev->dev_addr))
e289fd281   dingtianhong   macvlan: fix the ...
1608
1609
1610
  			return NOTIFY_BAD;
  
  		break;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1611
  	case NETDEV_UNREGISTER:
3b27e1055   David Lamparter   netns: keep vlan ...
1612
1613
1614
  		/* twiddle thumbs on netns device moves */
  		if (dev->reg_state != NETREG_UNREGISTERING)
  			break;
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1615
  		list_for_each_entry_safe(vlan, next, &port->vlans, list)
226bd3411   Eric Dumazet   net: use batched ...
1616
1617
  			vlan->dev->rtnl_link_ops->dellink(vlan->dev, &list_kill);
  		unregister_netdevice_many(&list_kill);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1618
  		break;
1c01fe14a   Jiri Pirko   net: forbid under...
1619
1620
1621
  	case NETDEV_PRE_TYPE_CHANGE:
  		/* Forbid underlaying device to change its type. */
  		return NOTIFY_BAD;
4c9912556   Vlad Yasevich   macvlan: Support ...
1622
1623
1624
1625
1626
1627
1628
  
  	case NETDEV_NOTIFY_PEERS:
  	case NETDEV_BONDING_FAILOVER:
  	case NETDEV_RESEND_IGMP:
  		/* Propagate to all vlans */
  		list_for_each_entry(vlan, &port->vlans, list)
  			call_netdevice_notifiers(event, vlan->dev);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
  	}
  	return NOTIFY_DONE;
  }
  
  static struct notifier_block macvlan_notifier_block __read_mostly = {
  	.notifier_call	= macvlan_device_event,
  };
  
  static int __init macvlan_init_module(void)
  {
  	int err;
  
  	register_netdevice_notifier(&macvlan_notifier_block);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1642

fc0663d6b   Arnd Bergmann   macvlan: allow mu...
1643
  	err = macvlan_link_register(&macvlan_link_ops);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1644
1645
1646
1647
  	if (err < 0)
  		goto err1;
  	return 0;
  err1:
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1648
1649
1650
1651
1652
1653
1654
  	unregister_netdevice_notifier(&macvlan_notifier_block);
  	return err;
  }
  
  static void __exit macvlan_cleanup_module(void)
  {
  	rtnl_link_unregister(&macvlan_link_ops);
b863ceb7d   Patrick McHardy   [NET]: Add macvla...
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
  	unregister_netdevice_notifier(&macvlan_notifier_block);
  }
  
  module_init(macvlan_init_module);
  module_exit(macvlan_cleanup_module);
  
  MODULE_LICENSE("GPL");
  MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
  MODULE_DESCRIPTION("Driver for MAC address based VLANs");
  MODULE_ALIAS_RTNL_LINK("macvlan");