/*
* 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>
#include <linux/netpoll.h>
#include <linux/u64_stats_sync.h>
#include <net/route.h>
#include <net/ip6_fib.h>
#include <linux/if_vlan.h>
#include <linux/rhashtable.h>
#include <linux/refcount.h>
#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)
#define BR_VERSION "2.3"
/* Control of forwarding link local multicast */
#define BR_GROUPFWD_DEFAULT 0
/* Don't allow forwarding of control protocols like STP, MAC PAUSE and LACP */
enum {
BR_GROUPFWD_STP = BIT(0),
BR_GROUPFWD_MACPAUSE = BIT(1),
BR_GROUPFWD_LACP = BIT(2),
};
#define BR_GROUPFWD_RESTRICTED (BR_GROUPFWD_STP | BR_GROUPFWD_MACPAUSE | \
BR_GROUPFWD_LACP)
/* The Nearest Customer Bridge Group Address, 01-80-C2-00-00-[00,0B,0C,0D,0F] */
#define BR_GROUPFWD_8021AD 0xB801u
/* Path to usermode spanning tree program */
#define BR_STP_PROG "/sbin/bridge-stp"
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[ETH_ALEN];
};
struct mac_addr
{
unsigned char addr[ETH_ALEN];
};
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
/* our own querier */
struct bridge_mcast_own_query {
struct timer_list timer;
u32 startup_sent;
};
/* other querier */
struct bridge_mcast_other_query {
struct timer_list timer;
unsigned long delay_time;
};
/* selected querier */
struct bridge_mcast_querier {
struct br_ip addr;
struct net_bridge_port __rcu *port;
};
/* IGMP/MLD statistics */
struct bridge_mcast_stats {
struct br_mcast_stats mstats;
struct u64_stats_sync syncp;
};
#endif
struct br_vlan_stats {
u64 rx_bytes;
u64 rx_packets;
u64 tx_bytes;
u64 tx_packets;
struct u64_stats_sync syncp;
};
struct br_tunnel_info {
__be64 tunnel_id;
struct metadata_dst *tunnel_dst;
};
/**
* struct net_bridge_vlan - per-vlan entry
*
* @vnode: rhashtable member
* @vid: VLAN id
* @flags: bridge vlan flags
* @stats: per-cpu VLAN statistics
* @br: if MASTER flag set, this points to a bridge struct
* @port: if MASTER flag unset, this points to a port struct
* @refcnt: if MASTER flag set, this is bumped for each port referencing it
* @brvlan: if MASTER flag unset, this points to the global per-VLAN context
* for this VLAN entry
* @vlist: sorted list of VLAN entries
* @rcu: used for entry destruction
*
* This structure is shared between the global per-VLAN entries contained in
* the bridge rhashtable and the local per-port per-VLAN entries contained in
* the port's rhashtable. The union entries should be interpreted depending on
* the entry flags that are set.
*/
struct net_bridge_vlan {
struct rhash_head vnode;
struct rhash_head tnode;
u16 vid;
u16 flags;
struct br_vlan_stats __percpu *stats;
union {
struct net_bridge *br;
struct net_bridge_port *port;
};
union {
refcount_t refcnt;
struct net_bridge_vlan *brvlan;
};
struct br_tunnel_info tinfo;
struct list_head vlist;
struct rcu_head rcu;
};
/**
* struct net_bridge_vlan_group
*
* @vlan_hash: VLAN entry rhashtable
* @vlan_list: sorted VLAN entry list
* @num_vlans: number of total VLAN entries
* @pvid: PVID VLAN id
*
* IMPORTANT: Be careful when checking if there're VLAN entries using list
* primitives because the bridge can have entries in its list which
* are just for global context but not for filtering, i.e. they have
* the master flag set but not the brentry flag. If you have to check
* if there're "real" entries in the bridge please test @num_vlans
*/
struct net_bridge_vlan_group {
struct rhashtable vlan_hash;
struct rhashtable tunnel_hash;
struct list_head vlan_list;
u16 num_vlans;
u16 pvid;
};
struct net_bridge_fdb_entry {
struct hlist_node hlist;
struct net_bridge_port *dst;
mac_addr addr;
__u16 vlan_id;
unsigned char is_local:1,
is_static:1,
added_by_user:1,
added_by_external_learn:1,
offloaded:1;
/* write-heavy members should not affect lookups */
unsigned long updated ____cacheline_aligned_in_smp;
unsigned long used;
struct rcu_head rcu;
};
#define MDB_PG_FLAGS_PERMANENT BIT(0)
#define MDB_PG_FLAGS_OFFLOAD BIT(1)
struct net_bridge_port_group {
struct net_bridge_port *port;
struct net_bridge_port_group __rcu *next;
struct hlist_node mglist;
struct rcu_head rcu;
struct timer_list timer;
struct br_ip addr;
unsigned char flags;
unsigned char eth_addr[ETH_ALEN];
};
struct net_bridge_mdb_entry
{
struct hlist_node hlist[2];
struct net_bridge *br;
struct net_bridge_port_group __rcu *ports;
struct rcu_head rcu;
struct timer_list timer;
struct br_ip addr;
bool mglist;
};
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;
};
struct net_bridge_port {
struct net_bridge *br;
struct net_device *dev;
struct list_head list;
unsigned