Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 715448ff authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'mvrp'



David Ward says:

====================
The Linux kernel currently implements the GARP VLAN Registration
Protocol (GVRP) from IEEE 802.1Q-1998 (applicant-only participant).
When the GVRP flag is set for a VLAN interface on a Linux host, the
host advertises its membership in the VLAN to the attached bridge/
switch, so that it is not necessary to manually configure the bridge/
switch port to participate in the VLAN.

GVRP has been superseded by the Multiple VLAN Registration Protocol
(MVRP) in IEEE 802.1Q-2011, which addresses scalability concerns about
the earlier protocol.  The following patches add support for MVRP to
the Linux kernel and iproute2 utility. They are based largely off of
the existing implementation of GVRP, but have been modified for the
new PDU structure and state machine.

This implementation was tested with two Juniper EX4200 switches.
====================

Signed-off-by: default avatarDavid Ward <david.ward@ll.mit.edu>
Acked-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5b815b52 86fbe9bb
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1290,6 +1290,8 @@ struct net_device {
	};
	/* GARP */
	struct garp_port __rcu	*garp_port;
	/* MRP */
	struct mrp_port __rcu	*mrp_port;

	/* class/net/name entry */
	struct device		dev;

include/net/mrp.h

0 → 100644
+143 −0
Original line number Diff line number Diff line
#ifndef _NET_MRP_H
#define _NET_MRP_H

#define MRP_END_MARK		0x0

struct mrp_pdu_hdr {
	u8	version;
};

struct mrp_msg_hdr {
	u8	attrtype;
	u8	attrlen;
};

struct mrp_vecattr_hdr {
	__be16	lenflags;
	unsigned char	firstattrvalue[];
#define MRP_VECATTR_HDR_LEN_MASK cpu_to_be16(0x1FFF)
#define MRP_VECATTR_HDR_FLAG_LA cpu_to_be16(0x2000)
};

enum mrp_vecattr_event {
	MRP_VECATTR_EVENT_NEW,
	MRP_VECATTR_EVENT_JOIN_IN,
	MRP_VECATTR_EVENT_IN,
	MRP_VECATTR_EVENT_JOIN_MT,
	MRP_VECATTR_EVENT_MT,
	MRP_VECATTR_EVENT_LV,
	__MRP_VECATTR_EVENT_MAX
};

struct mrp_skb_cb {
	struct mrp_msg_hdr	*mh;
	struct mrp_vecattr_hdr	*vah;
	unsigned char		attrvalue[];
};

static inline struct mrp_skb_cb *mrp_cb(struct sk_buff *skb)
{
	BUILD_BUG_ON(sizeof(struct mrp_skb_cb) >
		     FIELD_SIZEOF(struct sk_buff, cb));
	return (struct mrp_skb_cb *)skb->cb;
}

enum mrp_applicant_state {
	MRP_APPLICANT_INVALID,
	MRP_APPLICANT_VO,
	MRP_APPLICANT_VP,
	MRP_APPLICANT_VN,
	MRP_APPLICANT_AN,
	MRP_APPLICANT_AA,
	MRP_APPLICANT_QA,
	MRP_APPLICANT_LA,
	MRP_APPLICANT_AO,
	MRP_APPLICANT_QO,
	MRP_APPLICANT_AP,
	MRP_APPLICANT_QP,
	__MRP_APPLICANT_MAX
};
#define MRP_APPLICANT_MAX	(__MRP_APPLICANT_MAX - 1)

enum mrp_event {
	MRP_EVENT_NEW,
	MRP_EVENT_JOIN,
	MRP_EVENT_LV,
	MRP_EVENT_TX,
	MRP_EVENT_R_NEW,
	MRP_EVENT_R_JOIN_IN,
	MRP_EVENT_R_IN,
	MRP_EVENT_R_JOIN_MT,
	MRP_EVENT_R_MT,
	MRP_EVENT_R_LV,
	MRP_EVENT_R_LA,
	MRP_EVENT_REDECLARE,
	MRP_EVENT_PERIODIC,
	__MRP_EVENT_MAX
};
#define MRP_EVENT_MAX		(__MRP_EVENT_MAX - 1)

enum mrp_tx_action {
	MRP_TX_ACTION_NONE,
	MRP_TX_ACTION_S_NEW,
	MRP_TX_ACTION_S_JOIN_IN,
	MRP_TX_ACTION_S_JOIN_IN_OPTIONAL,
	MRP_TX_ACTION_S_IN_OPTIONAL,
	MRP_TX_ACTION_S_LV,
};

struct mrp_attr {
	struct rb_node			node;
	enum mrp_applicant_state	state;
	u8				type;
	u8				len;
	unsigned char			value[];
};

enum mrp_applications {
	MRP_APPLICATION_MVRP,
	__MRP_APPLICATION_MAX
};
#define MRP_APPLICATION_MAX	(__MRP_APPLICATION_MAX - 1)

struct mrp_application {
	enum mrp_applications	type;
	unsigned int		maxattr;
	struct packet_type	pkttype;
	unsigned char		group_address[ETH_ALEN];
	u8			version;
};

struct mrp_applicant {
	struct mrp_application	*app;
	struct net_device	*dev;
	struct timer_list	join_timer;

	spinlock_t		lock;
	struct sk_buff_head	queue;
	struct sk_buff		*pdu;
	struct rb_root		mad;
	struct rcu_head		rcu;
};

struct mrp_port {
	struct mrp_applicant __rcu	*applicants[MRP_APPLICATION_MAX + 1];
	struct rcu_head			rcu;
};

extern int	mrp_register_application(struct mrp_application *app);
extern void	mrp_unregister_application(struct mrp_application *app);

extern int	mrp_init_applicant(struct net_device *dev,
				    struct mrp_application *app);
extern void	mrp_uninit_applicant(struct net_device *dev,
				      struct mrp_application *app);

extern int	mrp_request_join(const struct net_device *dev,
				  const struct mrp_application *app,
				  const void *value, u8 len, u8 type);
extern void	mrp_request_leave(const struct net_device *dev,
				   const struct mrp_application *app,
				   const void *value, u8 len, u8 type);

#endif /* _NET_MRP_H */
+1 −0
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@
#define ETH_P_802_EX1	0x88B5		/* 802.1 Local Experimental 1.  */
#define ETH_P_TIPC	0x88CA		/* TIPC 			*/
#define ETH_P_8021AH	0x88E7          /* 802.1ah Backbone Service Tag */
#define ETH_P_MVRP	0x88F5          /* 802.1Q MVRP                  */
#define ETH_P_1588	0x88F7		/* IEEE 1588 Timesync */
#define ETH_P_FCOE	0x8906		/* Fibre Channel over Ethernet  */
#define ETH_P_TDLS	0x890D          /* TDLS */
+1 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ enum vlan_flags {
	VLAN_FLAG_REORDER_HDR	= 0x1,
	VLAN_FLAG_GVRP		= 0x2,
	VLAN_FLAG_LOOSE_BINDING	= 0x4,
	VLAN_FLAG_MVRP		= 0x8,
};

enum vlan_name_types {
+3 −0
Original line number Diff line number Diff line
@@ -5,3 +5,6 @@ config STP
config GARP
	tristate
	select STP

config MRP
	tristate
Loading