br_private.h 21 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
 *	Linux ethernet bridge
 *
 *	Authors:
 *	Lennert Buytenhek		<buytenh@gnu.org>
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License
 *	as published by the Free Software Foundation; either version
 *	2 of the License, or (at your option) any later version.
 */

#ifndef _BR_PRIVATE_H
#define _BR_PRIVATE_H

#include <linux/netdevice.h>
#include <linux/if_bridge.h>
Herbert Xu's avatar
Herbert Xu committed
18
#include <linux/netpoll.h>
Eric Dumazet's avatar
Eric Dumazet committed
19
#include <linux/u64_stats_sync.h>
20
#include <net/route.h>
21
#include <linux/if_vlan.h>
Linus Torvalds's avatar
Linus Torvalds committed
22
23
24
25
26
27
28
29

#define BR_HASH_BITS 8
#define BR_HASH_SIZE (1 << BR_HASH_BITS)

#define BR_HOLD_TIME (1*HZ)

#define BR_PORT_BITS	10
#define BR_MAX_PORTS	(1<<BR_PORT_BITS)
30
#define BR_VLAN_BITMAP_LEN	BITS_TO_LONGS(VLAN_N_VID)
Linus Torvalds's avatar
Linus Torvalds committed
31

32
33
#define BR_VERSION	"2.3"

34
35
36
37
38
/* Control of forwarding link local multicast */
#define BR_GROUPFWD_DEFAULT	0
/* Don't allow forwarding control protocols like STP and LLDP */
#define BR_GROUPFWD_RESTRICTED	0x4007u

39
40
/* Path to usermode spanning tree program */
#define BR_STP_PROG	"/sbin/bridge-stp"
41

Linus Torvalds's avatar
Linus Torvalds committed
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
typedef struct bridge_id bridge_id;
typedef struct mac_addr mac_addr;
typedef __u16 port_id;

struct bridge_id
{
	unsigned char	prio[2];
	unsigned char	addr[6];
};

struct mac_addr
{
	unsigned char	addr[6];
};

57
58
59
60
struct br_ip
{
	union {
		__be32	ip4;
61
#if IS_ENABLED(CONFIG_IPV6)
62
63
		struct in6_addr ip6;
#endif
64
65
66
67
	} u;
	__be16		proto;
};

68
69
struct net_port_vlans {
	u16				port_idx;
70
	u16				pvid;
71
72
73
74
75
76
	union {
		struct net_bridge_port		*port;
		struct net_bridge		*br;
	}				parent;
	struct rcu_head			rcu;
	unsigned long			vlan_bitmap[BR_VLAN_BITMAP_LEN];
77
	u16				num_vlans;
78
79
};

Linus Torvalds's avatar
Linus Torvalds committed
80
81
82
83
84
85
struct net_bridge_fdb_entry
{
	struct hlist_node		hlist;
	struct net_bridge_port		*dst;

	struct rcu_head			rcu;
86
87
	unsigned long			updated;
	unsigned long			used;
Linus Torvalds's avatar
Linus Torvalds committed
88
89
90
91
92
	mac_addr			addr;
	unsigned char			is_local;
	unsigned char			is_static;
};

93
94
struct net_bridge_port_group {
	struct net_bridge_port		*port;
95
	struct net_bridge_port_group __rcu *next;
96
97
98
	struct hlist_node		mglist;
	struct rcu_head			rcu;
	struct timer_list		timer;
99
	struct br_ip			addr;
100
	unsigned char			state;
101
102
103
104
105
106
};

struct net_bridge_mdb_entry
{
	struct hlist_node		hlist[2];
	struct net_bridge		*br;
107
	struct net_bridge_port_group __rcu *ports;
108
109
	struct rcu_head			rcu;
	struct timer_list		timer;
110
	struct br_ip			addr;
111
	bool				mglist;
112
113
114
115
116
117
118
119
120
121
122
123
124
};

struct net_bridge_mdb_htable
{
	struct hlist_head		*mhash;
	struct rcu_head			rcu;
	struct net_bridge_mdb_htable	*old;
	u32				size;
	u32				max;
	u32				secret;
	u32				ver;
};

Linus Torvalds's avatar
Linus Torvalds committed
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
struct net_bridge_port
{
	struct net_bridge		*br;
	struct net_device		*dev;
	struct list_head		list;

	/* STP */
	u8				priority;
	u8				state;
	u16				port_no;
	unsigned char			topology_change_ack;
	unsigned char			config_pending;
	port_id				port_id;
	port_id				designated_port;
	bridge_id			designated_root;
	bridge_id			designated_bridge;
	u32				path_cost;
	u32				designated_cost;
143
	unsigned long			designated_age;
Linus Torvalds's avatar
Linus Torvalds committed
144
145
146
147
148
149

	struct timer_list		forward_delay_timer;
	struct timer_list		hold_timer;
	struct timer_list		message_age_timer;
	struct kobject			kobj;
	struct rcu_head			rcu;
150
151
152

	unsigned long 			flags;
#define BR_HAIRPIN_MODE		0x00000001
153
#define BR_BPDU_GUARD           0x00000002
154
#define BR_ROOT_BLOCK		0x00000004
155
#define BR_MULTICAST_FAST_LEAVE	0x00000008
156
157
158
159
160
161
162
163
164

#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
	u32				multicast_startup_queries_sent;
	unsigned char			multicast_router;
	struct timer_list		multicast_router_timer;
	struct timer_list		multicast_query_timer;
	struct hlist_head		mglist;
	struct hlist_node		rlist;
#endif
165
166
167
168

#ifdef CONFIG_SYSFS
	char				sysfs_name[IFNAMSIZ];
#endif
Herbert Xu's avatar
Herbert Xu committed
169
170
171
172

#ifdef CONFIG_NET_POLL_CONTROLLER
	struct netpoll			*np;
#endif
173
174
175
#ifdef CONFIG_BRIDGE_VLAN_FILTERING
	struct net_port_vlans __rcu	*vlan_info;
#endif
Linus Torvalds's avatar
Linus Torvalds committed
176
177
};

178
179
#define br_port_exists(dev) (dev->priv_flags & IFF_BRIDGE_PORT)

180
181
static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev)
{
182
183
184
	struct net_bridge_port *port =
			rcu_dereference_rtnl(dev->rx_handler_data);

185
186
187
	return br_port_exists(dev) ? port : NULL;
}

188
static inline struct net_bridge_port *br_port_get_rtnl(struct net_device *dev)
189
{
190
191
	return br_port_exists(dev) ?
		rtnl_dereference(dev->rx_handler_data) : NULL;
192
193
}

194
struct br_cpu_netstats {
Eric Dumazet's avatar
Eric Dumazet committed
195
196
197
198
199
	u64			rx_packets;
	u64			rx_bytes;
	u64			tx_packets;
	u64			tx_bytes;
	struct u64_stats_sync	syncp;
200
201
};

Linus Torvalds's avatar
Linus Torvalds committed
202
203
204
205
206
struct net_bridge
{
	spinlock_t			lock;
	struct list_head		port_list;
	struct net_device		*dev;
207

208
	struct br_cpu_netstats __percpu *stats;
Linus Torvalds's avatar
Linus Torvalds committed
209
210
	spinlock_t			hash_lock;
	struct hlist_head		hash[BR_HASH_SIZE];
211
212
#ifdef CONFIG_BRIDGE_NETFILTER
	struct rtable 			fake_rtable;
213
214
215
	bool				nf_call_iptables;
	bool				nf_call_ip6tables;
	bool				nf_call_arptables;
216
#endif
217
218
	u16				group_fwd_mask;

Linus Torvalds's avatar
Linus Torvalds committed
219
220
221
222
223
224
225
226
227
228
229
230
	/* STP */
	bridge_id			designated_root;
	bridge_id			bridge_id;
	u32				root_path_cost;
	unsigned long			max_age;
	unsigned long			hello_time;
	unsigned long			forward_delay;
	unsigned long			bridge_max_age;
	unsigned long			ageing_time;
	unsigned long			bridge_hello_time;
	unsigned long			bridge_forward_delay;

231
	u8				group_addr[ETH_ALEN];
Linus Torvalds's avatar
Linus Torvalds committed
232
	u16				root_port;
233
234
235
236
237
238
239

	enum {
		BR_NO_STP, 		/* no spanning tree */
		BR_KERNEL_STP,		/* old STP in kernel */
		BR_USER_STP,		/* new RSTP in userspace */
	} stp_enabled;

Linus Torvalds's avatar
Linus Torvalds committed
240
241
242
	unsigned char			topology_change;
	unsigned char			topology_change_detected;

243
244
245
246
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
	unsigned char			multicast_router;

	u8				multicast_disabled:1;
247
	u8				multicast_querier:1;
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

	u32				hash_elasticity;
	u32				hash_max;

	u32				multicast_last_member_count;
	u32				multicast_startup_queries_sent;
	u32				multicast_startup_query_count;

	unsigned long			multicast_last_member_interval;
	unsigned long			multicast_membership_interval;
	unsigned long			multicast_querier_interval;
	unsigned long			multicast_query_interval;
	unsigned long			multicast_query_response_interval;
	unsigned long			multicast_startup_query_interval;

	spinlock_t			multicast_lock;
264
	struct net_bridge_mdb_htable __rcu *mdb;
265
266
267
268
269
270
271
	struct hlist_head		router_list;

	struct timer_list		multicast_router_timer;
	struct timer_list		multicast_querier_timer;
	struct timer_list		multicast_query_timer;
#endif

Linus Torvalds's avatar
Linus Torvalds committed
272
273
274
275
	struct timer_list		hello_timer;
	struct timer_list		tcn_timer;
	struct timer_list		topology_change_timer;
	struct timer_list		gc_timer;
276
	struct kobject			*ifobj;
277
278
279
280
#ifdef CONFIG_BRIDGE_VLAN_FILTERING
	u8				vlan_enabled;
	struct net_port_vlans __rcu	*vlan_info;
#endif
Linus Torvalds's avatar
Linus Torvalds committed
281
282
};

283
284
struct br_input_skb_cb {
	struct net_device *brdev;
285
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
286
287
	int igmp;
	int mrouters_only;
288
#endif
289
290
291
292
};

#define BR_INPUT_SKB_CB(__skb)	((struct br_input_skb_cb *)(__skb)->cb)

293
294
295
296
297
298
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
# define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb)	(BR_INPUT_SKB_CB(__skb)->mrouters_only)
#else
# define BR_INPUT_SKB_CB_MROUTERS_ONLY(__skb)	(0)
#endif

299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
#define br_printk(level, br, format, args...)	\
	printk(level "%s: " format, (br)->dev->name, ##args)

#define br_err(__br, format, args...)			\
	br_printk(KERN_ERR, __br, format, ##args)
#define br_warn(__br, format, args...)			\
	br_printk(KERN_WARNING, __br, format, ##args)
#define br_notice(__br, format, args...)		\
	br_printk(KERN_NOTICE, __br, format, ##args)
#define br_info(__br, format, args...)			\
	br_printk(KERN_INFO, __br, format, ##args)

#define br_debug(br, format, args...)			\
	pr_debug("%s: " format,  (br)->dev->name, ##args)

Linus Torvalds's avatar
Linus Torvalds committed
314
315
316
317
318
319
320
321
322
323
extern struct notifier_block br_device_notifier;

/* called under bridge lock */
static inline int br_is_root_bridge(const struct net_bridge *br)
{
	return !memcmp(&br->bridge_id, &br->designated_root, 8);
}

/* br_device.c */
extern void br_dev_setup(struct net_device *dev);
324
extern void br_dev_delete(struct net_device *dev, struct list_head *list);
325
326
extern netdev_tx_t br_dev_xmit(struct sk_buff *skb,
			       struct net_device *dev);
stephen hemminger's avatar
stephen hemminger committed
327
#ifdef CONFIG_NET_POLL_CONTROLLER
Herbert Xu's avatar
Herbert Xu committed
328
329
330
331
332
333
334
335
336
337
338
339
340
341
static inline struct netpoll_info *br_netpoll_info(struct net_bridge *br)
{
	return br->dev->npinfo;
}

static inline void br_netpoll_send_skb(const struct net_bridge_port *p,
				       struct sk_buff *skb)
{
	struct netpoll *np = p->np;

	if (np)
		netpoll_send_skb(np, skb);
}

342
extern int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp);
Herbert Xu's avatar
Herbert Xu committed
343
extern void br_netpoll_disable(struct net_bridge_port *p);
stephen hemminger's avatar
stephen hemminger committed
344
#else
Herbert Xu's avatar
Herbert Xu committed
345
346
347
348
349
static inline struct netpoll_info *br_netpoll_info(struct net_bridge *br)
{
	return NULL;
}

350
static inline void br_netpoll_send_skb(const struct net_bridge_port *p,
Herbert Xu's avatar
Herbert Xu committed
351
352
353
				       struct sk_buff *skb)
{
}
stephen hemminger's avatar
stephen hemminger committed
354

355
static inline int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp)
Herbert Xu's avatar
Herbert Xu committed
356
357
358
359
360
361
362
{
	return 0;
}

static inline void br_netpoll_disable(struct net_bridge_port *p)
{
}
stephen hemminger's avatar
stephen hemminger committed
363
#endif
Linus Torvalds's avatar
Linus Torvalds committed
364
365

/* br_fdb.c */
366
extern int br_fdb_init(void);
Linus Torvalds's avatar
Linus Torvalds committed
367
extern void br_fdb_fini(void);
368
extern void br_fdb_flush(struct net_bridge *br);
Linus Torvalds's avatar
Linus Torvalds committed
369
370
extern void br_fdb_changeaddr(struct net_bridge_port *p,
			      const unsigned char *newaddr);
371
extern void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr);
Linus Torvalds's avatar
Linus Torvalds committed
372
373
extern void br_fdb_cleanup(unsigned long arg);
extern void br_fdb_delete_by_port(struct net_bridge *br,
374
				  const struct net_bridge_port *p, int do_all);
Linus Torvalds's avatar
Linus Torvalds committed
375
376
extern struct net_bridge_fdb_entry *__br_fdb_get(struct net_bridge *br,
						 const unsigned char *addr);
377
extern int br_fdb_test_addr(struct net_device *dev, unsigned char *addr);
378
extern int br_fdb_fillbuf(struct net_bridge *br, void *buf,
Linus Torvalds's avatar
Linus Torvalds committed
379
380
381
382
383
384
385
			  unsigned long count, unsigned long off);
extern int br_fdb_insert(struct net_bridge *br,
			 struct net_bridge_port *source,
			 const unsigned char *addr);
extern void br_fdb_update(struct net_bridge *br,
			  struct net_bridge_port *source,
			  const unsigned char *addr);
386
387
388

extern int br_fdb_delete(struct ndmsg *ndm,
			 struct net_device *dev,
389
			 const unsigned char *addr);
390
extern int br_fdb_add(struct ndmsg *nlh, struct nlattr *tb[],
391
		      struct net_device *dev,
392
		      const unsigned char *addr,
393
394
395
396
397
		      u16 nlh_flags);
extern int br_fdb_dump(struct sk_buff *skb,
		       struct netlink_callback *cb,
		       struct net_device *dev,
		       int idx);
Linus Torvalds's avatar
Linus Torvalds committed
398
399
400
401
402
403

/* br_forward.c */
extern void br_deliver(const struct net_bridge_port *to,
		struct sk_buff *skb);
extern int br_dev_queue_push_xmit(struct sk_buff *skb);
extern void br_forward(const struct net_bridge_port *to,
404
		struct sk_buff *skb, struct sk_buff *skb0);
Linus Torvalds's avatar
Linus Torvalds committed
405
extern int br_forward_finish(struct sk_buff *skb);
406
extern void br_flood_deliver(struct net_bridge *br, struct sk_buff *skb);
407
408
extern void br_flood_forward(struct net_bridge *br, struct sk_buff *skb,
			     struct sk_buff *skb2);
Linus Torvalds's avatar
Linus Torvalds committed
409
410

/* br_if.c */
411
extern void br_port_carrier_check(struct net_bridge_port *p);
412
413
extern int br_add_bridge(struct net *net, const char *name);
extern int br_del_bridge(struct net *net, const char *name);
414
extern void br_net_exit(struct net *net);
Linus Torvalds's avatar
Linus Torvalds committed
415
416
417
418
419
extern int br_add_if(struct net_bridge *br,
	      struct net_device *dev);
extern int br_del_if(struct net_bridge *br,
	      struct net_device *dev);
extern int br_min_mtu(const struct net_bridge *br);
420
421
extern netdev_features_t br_features_recompute(struct net_bridge *br,
	netdev_features_t features);
Linus Torvalds's avatar
Linus Torvalds committed
422
423
424

/* br_input.c */
extern int br_handle_frame_finish(struct sk_buff *skb);
425
extern rx_handler_result_t br_handle_frame(struct sk_buff **pskb);
Linus Torvalds's avatar
Linus Torvalds committed
426
427
428

/* br_ioctl.c */
extern int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
429
extern int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *arg);
Linus Torvalds's avatar
Linus Torvalds committed
430

431
432
/* br_multicast.c */
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
433
extern unsigned int br_mdb_rehash_seq;
434
435
436
437
438
439
440
441
442
443
444
445
extern int br_multicast_rcv(struct net_bridge *br,
			    struct net_bridge_port *port,
			    struct sk_buff *skb);
extern struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
					       struct sk_buff *skb);
extern void br_multicast_add_port(struct net_bridge_port *port);
extern void br_multicast_del_port(struct net_bridge_port *port);
extern void br_multicast_enable_port(struct net_bridge_port *port);
extern void br_multicast_disable_port(struct net_bridge_port *port);
extern void br_multicast_init(struct net_bridge *br);
extern void br_multicast_open(struct net_bridge *br);
extern void br_multicast_stop(struct net_bridge *br);
446
447
448
449
extern void br_multicast_deliver(struct net_bridge_mdb_entry *mdst,
				 struct sk_buff *skb);
extern void br_multicast_forward(struct net_bridge_mdb_entry *mdst,
				 struct sk_buff *skb, struct sk_buff *skb2);
450
451
452
extern int br_multicast_set_router(struct net_bridge *br, unsigned long val);
extern int br_multicast_set_port_router(struct net_bridge_port *p,
					unsigned long val);
453
extern int br_multicast_toggle(struct net_bridge *br, unsigned long val);
454
extern int br_multicast_set_querier(struct net_bridge *br, unsigned long val);
455
extern int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val);
456
457
458
459
460
461
462
463
464
extern struct net_bridge_mdb_entry *br_mdb_ip_get(
				struct net_bridge_mdb_htable *mdb,
				struct br_ip *dst);
extern struct net_bridge_mdb_entry *br_multicast_new_group(struct net_bridge *br,
				struct net_bridge_port *port, struct br_ip *group);
extern void br_multicast_free_pg(struct rcu_head *head);
extern struct net_bridge_port_group *br_multicast_new_port_group(
				struct net_bridge_port *port,
				struct br_ip *group,
465
466
				struct net_bridge_port_group *next,
				unsigned char state);
467
extern void br_mdb_init(void);
468
extern void br_mdb_uninit(void);
469
470
extern void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port,
			  struct br_ip *group, int type);
471

472
473
474
475
476
477
478
479
480
481
482
483
484
#define mlock_dereference(X, br) \
	rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock))

#if IS_ENABLED(CONFIG_IPV6)
#include <net/addrconf.h>
static inline int ipv6_is_transient_multicast(const struct in6_addr *addr)
{
	if (ipv6_addr_is_multicast(addr) && IPV6_ADDR_MC_FLAG_TRANSIENT(addr))
		return 1;
	return 0;
}
#endif

485
486
487
488
489
490
static inline bool br_multicast_is_router(struct net_bridge *br)
{
	return br->multicast_router == 2 ||
	       (br->multicast_router == 1 &&
		timer_pending(&br->multicast_router_timer));
}
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
#else
static inline int br_multicast_rcv(struct net_bridge *br,
				   struct net_bridge_port *port,
				   struct sk_buff *skb)
{
	return 0;
}

static inline struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
						      struct sk_buff *skb)
{
	return NULL;
}

static inline void br_multicast_add_port(struct net_bridge_port *port)
{
}

static inline void br_multicast_del_port(struct net_bridge_port *port)
{
}

static inline void br_multicast_enable_port(struct net_bridge_port *port)
{
}

static inline void br_multicast_disable_port(struct net_bridge_port *port)
{
}

static inline void br_multicast_init(struct net_bridge *br)
{
}

static inline void br_multicast_open(struct net_bridge *br)
{
}

static inline void br_multicast_stop(struct net_bridge *br)
{
}
532
533
534
535
536
537
538
539
540
541
542

static inline void br_multicast_deliver(struct net_bridge_mdb_entry *mdst,
					struct sk_buff *skb)
{
}

static inline void br_multicast_forward(struct net_bridge_mdb_entry *mdst,
					struct sk_buff *skb,
					struct sk_buff *skb2)
{
}
543
544
static inline bool br_multicast_is_router(struct net_bridge *br)
{
545
	return 0;
546
}
547
548
549
550
551
552
static inline void br_mdb_init(void)
{
}
static inline void br_mdb_uninit(void)
{
}
553
#endif
554

555
556
/* br_vlan.c */
#ifdef CONFIG_BRIDGE_VLAN_FILTERING
557
extern bool br_allowed_ingress(struct net_bridge *br, struct net_port_vlans *v,
558
			       struct sk_buff *skb, u16 *vid);
559
560
561
extern bool br_allowed_egress(struct net_bridge *br,
			      const struct net_port_vlans *v,
			      const struct sk_buff *skb);
562
563
564
extern struct sk_buff *br_handle_vlan(struct net_bridge *br,
				      const struct net_port_vlans *v,
				      struct sk_buff *skb);
565
566
567
568
569
570
571
extern int br_vlan_add(struct net_bridge *br, u16 vid);
extern int br_vlan_delete(struct net_bridge *br, u16 vid);
extern void br_vlan_flush(struct net_bridge *br);
extern int br_vlan_filter_toggle(struct net_bridge *br, unsigned long val);
extern int nbp_vlan_add(struct net_bridge_port *port, u16 vid);
extern int nbp_vlan_delete(struct net_bridge_port *port, u16 vid);
extern void nbp_vlan_flush(struct net_bridge_port *port);
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600

static inline struct net_port_vlans *br_get_vlan_info(
						const struct net_bridge *br)
{
	return rcu_dereference(br->vlan_info);
}

static inline struct net_port_vlans *nbp_get_vlan_info(
						const struct net_bridge_port *p)
{
	return rcu_dereference(p->vlan_info);
}

/* Since bridge now depends on 8021Q module, but the time bridge sees the
 * skb, the vlan tag will always be present if the frame was tagged.
 */
static inline int br_vlan_get_tag(const struct sk_buff *skb, u16 *vid)
{
	int err = 0;

	if (vlan_tx_tag_present(skb))
		*vid = vlan_tx_tag_get(skb) & VLAN_VID_MASK;
	else {
		*vid = 0;
		err = -EINVAL;
	}

	return err;
}
601
602
603
604
605
606
607
608
609
610
611
612

static inline u16 br_get_pvid(const struct net_port_vlans *v)
{
	/* Return just the VID if it is set, or VLAN_N_VID (invalid vid) if
	 * vid wasn't set
	 */
	smp_rmb();
	return (v->pvid & VLAN_TAG_PRESENT) ?
			(v->pvid & ~VLAN_TAG_PRESENT) :
			VLAN_N_VID;
}

613
#else
614
615
static inline bool br_allowed_ingress(struct net_bridge *br,
				      struct net_port_vlans *v,
616
617
				      struct sk_buff *skb,
				      u16 *vid)
618
619
620
621
{
	return true;
}

622
623
624
625
626
627
628
static inline bool br_allowed_egress(struct net_bridge *br,
				     const struct net_port_vlans *v,
				     const struct sk_buff *skb)
{
	return true;
}

629
630
631
632
633
634
635
static inline struct sk_buff *br_handle_vlan(struct net_bridge *br,
					     const struct net_port_vlans *v,
					     struct sk_buff *skb)
{
	return skb;
}

636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
static inline int br_vlan_add(struct net_bridge *br, u16 vid)
{
	return -EOPNOTSUPP;
}

static inline int br_vlan_delete(struct net_bridge *br, u16 vid)
{
	return -EOPNOTSUPP;
}

static inline void br_vlan_flush(struct net_bridge *br)
{
}

static inline int nbp_vlan_add(struct net_bridge_port *port, u16 vid)
{
	return -EOPNOTSUPP;
}

static inline int nbp_vlan_delete(struct net_bridge_port *port, u16 vid)
{
	return -EOPNOTSUPP;
}

static inline void nbp_vlan_flush(struct net_bridge_port *port)
{
}

664
665
666
667
668
669
670
671
672
673
674
static inline struct net_port_vlans *br_get_vlan_info(
						const struct net_bridge *br)
{
	return NULL;
}
static inline struct net_port_vlans *nbp_get_vlan_info(
						const struct net_bridge_port *p)
{
	return NULL;
}

675
static inline u16 br_vlan_get_tag(const struct sk_buff *skb, u16 *tag)
676
677
678
{
	return 0;
}
679
680
681
682
static inline u16 br_get_pvid(const struct net_port_vlans *v)
{
	return VLAN_N_VID;	/* Returns invalid vid */
}
683
684
#endif

Linus Torvalds's avatar
Linus Torvalds committed
685
/* br_netfilter.c */
686
#ifdef CONFIG_BRIDGE_NETFILTER
Linus Torvalds's avatar
Linus Torvalds committed
687
688
extern int br_netfilter_init(void);
extern void br_netfilter_fini(void);
689
extern void br_netfilter_rtable_init(struct net_bridge *);
690
691
692
#else
#define br_netfilter_init()	(0)
#define br_netfilter_fini()	do { } while(0)
693
#define br_netfilter_rtable_init(x)
694
#endif
Linus Torvalds's avatar
Linus Torvalds committed
695
696
697
698

/* br_stp.c */
extern void br_log_state(const struct net_bridge_port *p);
extern struct net_bridge_port *br_get_port(struct net_bridge *br,
699
					   u16 port_no);
Linus Torvalds's avatar
Linus Torvalds committed
700
701
702
extern void br_init_port(struct net_bridge_port *p);
extern void br_become_designated_port(struct net_bridge_port *p);

703
704
705
706
707
extern int br_set_forward_delay(struct net_bridge *br, unsigned long x);
extern int br_set_hello_time(struct net_bridge *br, unsigned long x);
extern int br_set_max_age(struct net_bridge *br, unsigned long x);


Linus Torvalds's avatar
Linus Torvalds committed
708
709
710
/* br_stp_if.c */
extern void br_stp_enable_bridge(struct net_bridge *br);
extern void br_stp_disable_bridge(struct net_bridge *br);
711
extern void br_stp_set_enabled(struct net_bridge *br, unsigned long val);
Linus Torvalds's avatar
Linus Torvalds committed
712
713
extern void br_stp_enable_port(struct net_bridge_port *p);
extern void br_stp_disable_port(struct net_bridge_port *p);
714
extern bool br_stp_recalculate_bridge_id(struct net_bridge *br);
715
extern void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a);
Linus Torvalds's avatar
Linus Torvalds committed
716
717
extern void br_stp_set_bridge_priority(struct net_bridge *br,
				       u16 newprio);
718
719
720
721
extern int br_stp_set_port_priority(struct net_bridge_port *p,
				    unsigned long newprio);
extern int br_stp_set_path_cost(struct net_bridge_port *p,
				unsigned long path_cost);
Linus Torvalds's avatar
Linus Torvalds committed
722
723
724
extern ssize_t br_show_bridge_id(char *buf, const struct bridge_id *id);

/* br_stp_bpdu.c */
Patrick McHardy's avatar
Patrick McHardy committed
725
726
727
struct stp_proto;
extern void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
		       struct net_device *dev);
Linus Torvalds's avatar
Linus Torvalds committed
728
729
730
731
732
733
734

/* br_stp_timer.c */
extern void br_stp_timer_init(struct net_bridge *br);
extern void br_stp_port_timer_init(struct net_bridge_port *p);
extern unsigned long br_timer_value(const struct timer_list *timer);

/* br.c */
Igor Maravić's avatar
Igor Maravić committed
735
#if IS_ENABLED(CONFIG_ATM_LANE)
736
737
extern int (*br_fdb_test_addr_hook)(struct net_device *dev, unsigned char *addr);
#endif
Linus Torvalds's avatar
Linus Torvalds committed
738

739
/* br_netlink.c */
740
extern struct rtnl_link_ops br_link_ops;
741
extern int br_netlink_init(void);
742
743
extern void br_netlink_fini(void);
extern void br_ifinfo_notify(int event, struct net_bridge_port *port);
744
extern int br_setlink(struct net_device *dev, struct nlmsghdr *nlmsg);
745
extern int br_dellink(struct net_device *dev, struct nlmsghdr *nlmsg);
746
extern int br_getlink(struct sk_buff *skb, u32 pid, u32 seq,
747
		      struct net_device *dev, u32 filter_mask);
748

Linus Torvalds's avatar
Linus Torvalds committed
749
750
#ifdef CONFIG_SYSFS
/* br_sysfs_if.c */
751
extern const struct sysfs_ops brport_sysfs_ops;
Linus Torvalds's avatar
Linus Torvalds committed
752
extern int br_sysfs_addif(struct net_bridge_port *p);
753
extern int br_sysfs_renameif(struct net_bridge_port *p);
Linus Torvalds's avatar
Linus Torvalds committed
754
755
756
757
758
759
760

/* br_sysfs_br.c */
extern int br_sysfs_addbr(struct net_device *dev);
extern void br_sysfs_delbr(struct net_device *dev);

#else

761
762
763
764
static inline int br_sysfs_addif(struct net_bridge_port *p) { return 0; }
static inline int br_sysfs_renameif(struct net_bridge_port *p) { return 0; }
static inline int br_sysfs_addbr(struct net_device *dev) { return 0; }
static inline void br_sysfs_delbr(struct net_device *dev) { return; }
Linus Torvalds's avatar
Linus Torvalds committed
765
766
767
#endif /* CONFIG_SYSFS */

#endif