18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * NET3: Support for 802.2 demultiplexing off Ethernet 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Demultiplex 802.2 encoded protocols. We match the entry by the 68c2ecf20Sopenharmony_ci * SSAP/DSAP pair and then deliver to the registered datalink that 78c2ecf20Sopenharmony_ci * matches. The control byte is ignored and handling of such items 88c2ecf20Sopenharmony_ci * is up to the routine passed the frame. 98c2ecf20Sopenharmony_ci * 108c2ecf20Sopenharmony_ci * Unlike the 802.3 datalink we have a list of 802.2 entries as 118c2ecf20Sopenharmony_ci * there are multiple protocols to demux. The list is currently 128c2ecf20Sopenharmony_ci * short (3 or 4 entries at most). The current demux assumes this. 138c2ecf20Sopenharmony_ci */ 148c2ecf20Sopenharmony_ci#include <linux/module.h> 158c2ecf20Sopenharmony_ci#include <linux/netdevice.h> 168c2ecf20Sopenharmony_ci#include <linux/skbuff.h> 178c2ecf20Sopenharmony_ci#include <linux/slab.h> 188c2ecf20Sopenharmony_ci#include <net/datalink.h> 198c2ecf20Sopenharmony_ci#include <linux/mm.h> 208c2ecf20Sopenharmony_ci#include <linux/in.h> 218c2ecf20Sopenharmony_ci#include <linux/init.h> 228c2ecf20Sopenharmony_ci#include <net/llc.h> 238c2ecf20Sopenharmony_ci#include <net/p8022.h> 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_cistatic int p8022_request(struct datalink_proto *dl, struct sk_buff *skb, 268c2ecf20Sopenharmony_ci unsigned char *dest) 278c2ecf20Sopenharmony_ci{ 288c2ecf20Sopenharmony_ci llc_build_and_send_ui_pkt(dl->sap, skb, dest, dl->sap->laddr.lsap); 298c2ecf20Sopenharmony_ci return 0; 308c2ecf20Sopenharmony_ci} 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_cistruct datalink_proto *register_8022_client(unsigned char type, 338c2ecf20Sopenharmony_ci int (*func)(struct sk_buff *skb, 348c2ecf20Sopenharmony_ci struct net_device *dev, 358c2ecf20Sopenharmony_ci struct packet_type *pt, 368c2ecf20Sopenharmony_ci struct net_device *orig_dev)) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci struct datalink_proto *proto; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci proto = kmalloc(sizeof(*proto), GFP_ATOMIC); 418c2ecf20Sopenharmony_ci if (proto) { 428c2ecf20Sopenharmony_ci proto->type[0] = type; 438c2ecf20Sopenharmony_ci proto->header_length = 3; 448c2ecf20Sopenharmony_ci proto->request = p8022_request; 458c2ecf20Sopenharmony_ci proto->sap = llc_sap_open(type, func); 468c2ecf20Sopenharmony_ci if (!proto->sap) { 478c2ecf20Sopenharmony_ci kfree(proto); 488c2ecf20Sopenharmony_ci proto = NULL; 498c2ecf20Sopenharmony_ci } 508c2ecf20Sopenharmony_ci } 518c2ecf20Sopenharmony_ci return proto; 528c2ecf20Sopenharmony_ci} 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_civoid unregister_8022_client(struct datalink_proto *proto) 558c2ecf20Sopenharmony_ci{ 568c2ecf20Sopenharmony_ci llc_sap_put(proto->sap); 578c2ecf20Sopenharmony_ci kfree(proto); 588c2ecf20Sopenharmony_ci} 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ciEXPORT_SYMBOL(register_8022_client); 618c2ecf20Sopenharmony_ciEXPORT_SYMBOL(unregister_8022_client); 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 64