forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add small STP demux layer for demuxing STP PDUs based on MAC address. This is needed to run both GARP and STP in parallel (or even load the modules) since both use LLC_SAP_BSPAN. Signed-off-by: Patrick McHardy <[email protected]> Signed-off-by: David S. Miller <[email protected]>
- Loading branch information
Showing
5 changed files
with
121 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#ifndef _NET_STP_H | ||
#define _NET_STP_H | ||
|
||
struct stp_proto { | ||
unsigned char group_address[ETH_ALEN]; | ||
void (*rcv)(const struct stp_proto *, struct sk_buff *, | ||
struct net_device *); | ||
void *data; | ||
}; | ||
|
||
extern int stp_proto_register(const struct stp_proto *proto); | ||
extern void stp_proto_unregister(const struct stp_proto *proto); | ||
|
||
#endif /* _NET_STP_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
config STP | ||
tristate | ||
select LLC |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/* | ||
* STP SAP demux | ||
* | ||
* Copyright (c) 2008 Patrick McHardy <[email protected]> | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* version 2 as published by the Free Software Foundation. | ||
*/ | ||
#include <linux/mutex.h> | ||
#include <linux/skbuff.h> | ||
#include <linux/etherdevice.h> | ||
#include <linux/llc.h> | ||
#include <net/llc.h> | ||
#include <net/llc_pdu.h> | ||
#include <net/stp.h> | ||
|
||
/* 01:80:c2:00:00:20 - 01:80:c2:00:00:2F */ | ||
#define GARP_ADDR_MIN 0x20 | ||
#define GARP_ADDR_MAX 0x2F | ||
#define GARP_ADDR_RANGE (GARP_ADDR_MAX - GARP_ADDR_MIN) | ||
|
||
static const struct stp_proto *garp_protos[GARP_ADDR_RANGE + 1] __read_mostly; | ||
static const struct stp_proto *stp_proto __read_mostly; | ||
|
||
static struct llc_sap *sap __read_mostly; | ||
static unsigned int sap_registered; | ||
static DEFINE_MUTEX(stp_proto_mutex); | ||
|
||
/* Called under rcu_read_lock from LLC */ | ||
static int stp_pdu_rcv(struct sk_buff *skb, struct net_device *dev, | ||
struct packet_type *pt, struct net_device *orig_dev) | ||
{ | ||
const struct ethhdr *eh = eth_hdr(skb); | ||
const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb); | ||
const struct stp_proto *proto; | ||
|
||
if (pdu->ssap != LLC_SAP_BSPAN || | ||
pdu->dsap != LLC_SAP_BSPAN || | ||
pdu->ctrl_1 != LLC_PDU_TYPE_U) | ||
goto err; | ||
|
||
if (eh->h_dest[5] >= GARP_ADDR_MIN && eh->h_dest[5] <= GARP_ADDR_MAX) { | ||
proto = rcu_dereference(garp_protos[eh->h_dest[5] - | ||
GARP_ADDR_MIN]); | ||
if (proto && | ||
compare_ether_addr(eh->h_dest, proto->group_address)) | ||
goto err; | ||
} else | ||
proto = rcu_dereference(stp_proto); | ||
|
||
if (!proto) | ||
goto err; | ||
|
||
proto->rcv(proto, skb, dev); | ||
return 0; | ||
|
||
err: | ||
kfree_skb(skb); | ||
return 0; | ||
} | ||
|
||
int stp_proto_register(const struct stp_proto *proto) | ||
{ | ||
int err = 0; | ||
|
||
mutex_lock(&stp_proto_mutex); | ||
if (sap_registered++ == 0) { | ||
sap = llc_sap_open(LLC_SAP_BSPAN, stp_pdu_rcv); | ||
if (!sap) { | ||
err = -ENOMEM; | ||
goto out; | ||
} | ||
} | ||
if (is_zero_ether_addr(proto->group_address)) | ||
rcu_assign_pointer(stp_proto, proto); | ||
else | ||
rcu_assign_pointer(garp_protos[proto->group_address[5] - | ||
GARP_ADDR_MIN], proto); | ||
out: | ||
mutex_unlock(&stp_proto_mutex); | ||
return err; | ||
} | ||
EXPORT_SYMBOL_GPL(stp_proto_register); | ||
|
||
void stp_proto_unregister(const struct stp_proto *proto) | ||
{ | ||
mutex_lock(&stp_proto_mutex); | ||
if (is_zero_ether_addr(proto->group_address)) | ||
rcu_assign_pointer(stp_proto, NULL); | ||
else | ||
rcu_assign_pointer(garp_protos[proto->group_address[5] - | ||
GARP_ADDR_MIN], NULL); | ||
synchronize_rcu(); | ||
|
||
if (--sap_registered == 0) | ||
llc_sap_put(sap); | ||
mutex_unlock(&stp_proto_mutex); | ||
} | ||
EXPORT_SYMBOL_GPL(stp_proto_unregister); | ||
|
||
MODULE_LICENSE("GPL"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters