Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *	STP SAP demux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *	Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/llc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <net/llc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <net/llc_pdu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <net/stp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) /* 01:80:c2:00:00:20 - 01:80:c2:00:00:2F */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define GARP_ADDR_MIN	0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define GARP_ADDR_MAX	0x2F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define GARP_ADDR_RANGE	(GARP_ADDR_MAX - GARP_ADDR_MIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) static const struct stp_proto __rcu *garp_protos[GARP_ADDR_RANGE + 1] __read_mostly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) static const struct stp_proto __rcu *stp_proto __read_mostly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) static struct llc_sap *sap __read_mostly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) static unsigned int sap_registered;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) static DEFINE_MUTEX(stp_proto_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) /* Called under rcu_read_lock from LLC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) static int stp_pdu_rcv(struct sk_buff *skb, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 		       struct packet_type *pt, struct net_device *orig_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	const struct ethhdr *eh = eth_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	const struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	const struct stp_proto *proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	if (pdu->ssap != LLC_SAP_BSPAN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	    pdu->dsap != LLC_SAP_BSPAN ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	    pdu->ctrl_1 != LLC_PDU_TYPE_U)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	if (eh->h_dest[5] >= GARP_ADDR_MIN && eh->h_dest[5] <= GARP_ADDR_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		proto = rcu_dereference(garp_protos[eh->h_dest[5] -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 						    GARP_ADDR_MIN]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 		if (proto &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		    !ether_addr_equal(eh->h_dest, proto->group_address))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		proto = rcu_dereference(stp_proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	if (!proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	proto->rcv(proto, skb, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) int stp_proto_register(const struct stp_proto *proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	mutex_lock(&stp_proto_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	if (sap_registered++ == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		sap = llc_sap_open(LLC_SAP_BSPAN, stp_pdu_rcv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		if (!sap) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 			err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	if (is_zero_ether_addr(proto->group_address))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		rcu_assign_pointer(stp_proto, proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		rcu_assign_pointer(garp_protos[proto->group_address[5] -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 					       GARP_ADDR_MIN], proto);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	mutex_unlock(&stp_proto_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) EXPORT_SYMBOL_GPL(stp_proto_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) void stp_proto_unregister(const struct stp_proto *proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	mutex_lock(&stp_proto_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	if (is_zero_ether_addr(proto->group_address))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		RCU_INIT_POINTER(stp_proto, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		RCU_INIT_POINTER(garp_protos[proto->group_address[5] -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 					       GARP_ADDR_MIN], NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	synchronize_rcu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	if (--sap_registered == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		llc_sap_put(sap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	mutex_unlock(&stp_proto_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) EXPORT_SYMBOL_GPL(stp_proto_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) MODULE_LICENSE("GPL");