summaryrefslogtreecommitdiff
path: root/net/llc
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2026-09-28 12:07:59 -0700
committerPaolo Abeni <pabeni@redhat.com>2026-10-01 10:07:32 +0200
commit6c1f58d7d5dfdcf6d06bbe9f5cd4adfd22a7268a (patch)
tree14bb8a6223c4a7c6726e8bc317724e527b1c21a4 /net/llc
parent003f21868b2b0b4d09eb6b1f4abe0a8fbc03e859 (diff)
llc: strip the leftovers of the llc2 removal
Nothing in tree registers the type 1 / type 2 packet handlers or the station handler any more, and nothing looks at the socket hashes hanging off struct llc_sap. The two SAPs opened in tree - SNAP, and STP for the bridge's BPDUs and GARP's PDUs - receive through the per-SAP rcv_func(), so llc_rcv() boils down to a SAP lookup and a call. llc_sap_list becomes static and five exports go away with all this; the llc2 module out of tree has been reworked to open its own SAPs. Frames with a NULL DSAP used to be handed to the station handler before the SAP lookup. They take the normal path now, meaning they get dropped unless something registers SAP 0. struct llc_sap is down to 48 bytes on 64-bit from over a kilobyte, which also moves its GFP_ATOMIC allocation from kmalloc-2k to kmalloc-64. The two 64-entry socket hashes are the bulk of it, and the address it carried is now just the SAP number - nothing has read the MAC half since the socket layer left. llc_pdu.h keeps only what its remaining users need, plus LLC_PDU_RSP to document the one argument which can take it. That takes out the type 2 (I and S format, FRMR) definitions, the XID and TEST builders with their constants - the kernel neither sends nor answers either any more - the SAP address defines, the field accessors, and the prototypes of the llc_pdu.c helpers which went out of tree with the rest of LLC2. With the I and S formats gone llc_pdu_header_init() has one PDU type left, so drop the argument. Signed-off-by: Jakub Kicinski <kuba@kernel.org> Link: https://patch.msgid.link/20260928190800.2521749-3-kuba@kernel.org Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Diffstat (limited to 'net/llc')
-rw-r--r--net/llc/llc_core.c27
-rw-r--r--net/llc/llc_input.c125
-rw-r--r--net/llc/llc_output.c3
3 files changed, 17 insertions, 138 deletions
diff --git a/net/llc/llc_core.c b/net/llc/llc_core.c
index 5b0f1986bddc..cde6a0b1509e 100644
--- a/net/llc/llc_core.c
+++ b/net/llc/llc_core.c
@@ -16,7 +16,7 @@
#include <net/net_namespace.h>
#include <net/llc.h>
-LIST_HEAD(llc_sap_list);
+static LIST_HEAD(llc_sap_list);
static DEFINE_SPINLOCK(llc_sap_list_lock);
/**
@@ -27,16 +27,9 @@ static DEFINE_SPINLOCK(llc_sap_list_lock);
static struct llc_sap *llc_sap_alloc(void)
{
struct llc_sap *sap = kzalloc_obj(*sap, GFP_ATOMIC);
- int i;
-
- if (sap) {
- /* sap->laddr.mac - leave as a null, it's filled by bind */
- sap->state = LLC_SAP_STATE_ACTIVE;
- spin_lock_init(&sap->sk_lock);
- for (i = 0; i < LLC_SK_LADDR_HASH_ENTRIES; i++)
- INIT_HLIST_NULLS_HEAD(&sap->sk_laddr_hash[i], i);
+
+ if (sap)
refcount_set(&sap->refcnt, 1);
- }
return sap;
}
@@ -45,7 +38,7 @@ static struct llc_sap *__llc_sap_find(unsigned char sap_value)
struct llc_sap *sap;
list_for_each_entry(sap, &llc_sap_list, node)
- if (sap->laddr.lsap == sap_value)
+ if (sap->lsap == sap_value)
goto out;
sap = NULL;
out:
@@ -53,10 +46,9 @@ out:
}
/**
- * llc_sap_find - searches a SAP in station
+ * llc_sap_find - searches for a SAP by its number
* @sap_value: sap to be found
*
- * Searches for a sap in the sap list of the LLC's station upon the sap ID.
* If the sap is found it will be refcounted and the user will have to do
* a llc_sap_put after use.
* Returns the sap or %NULL if not found.
@@ -96,7 +88,7 @@ struct llc_sap *llc_sap_open(unsigned char lsap,
sap = llc_sap_alloc();
if (!sap)
goto out;
- sap->laddr.lsap = lsap;
+ sap->lsap = lsap;
sap->rcv_func = func;
list_add_tail_rcu(&sap->node, &llc_sap_list);
out:
@@ -110,13 +102,10 @@ out:
*
* Close interface function to upper layer. Each one who wants to
* close an open SAP (for example NetBEUI) should call this function.
- * Removes this sap from the list of saps in the station and then
- * frees the memory for this sap.
+ * Removes this sap from the SAP list and then frees the memory for it.
*/
void llc_sap_close(struct llc_sap *sap)
{
- WARN_ON(sap->sk_count);
-
spin_lock_bh(&llc_sap_list_lock);
list_del_rcu(&sap->node);
spin_unlock_bh(&llc_sap_list_lock);
@@ -143,8 +132,6 @@ static void __exit llc_exit(void)
module_init(llc_init);
module_exit(llc_exit);
-EXPORT_SYMBOL(llc_sap_list);
-EXPORT_SYMBOL(llc_sap_find);
EXPORT_SYMBOL(llc_sap_open);
EXPORT_SYMBOL(llc_sap_close);
diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c
index 78426ae7c73f..a8730c54b5c2 100644
--- a/net/llc/llc_input.c
+++ b/net/llc/llc_input.c
@@ -7,7 +7,6 @@
*/
#include <linux/netdevice.h>
#include <linux/slab.h>
-#include <linux/export.h>
#include <net/net_namespace.h>
#include <net/llc.h>
#include <net/llc_pdu.h>
@@ -18,80 +17,6 @@
#define dprintk(args...)
#endif
-/*
- * Packet handler for the station, registerable because in the minimal
- * LLC core that is taking shape only the very minimal subset of LLC that
- * is needed for things like IPX, Appletalk, etc will stay, with all the
- * rest in the llc1 and llc2 modules.
- */
-static void (*llc_station_handler)(struct sk_buff *skb);
-
-/*
- * Packet handlers for LLC_DEST_SAP and LLC_DEST_CONN.
- */
-static void (*llc_type_handlers[2])(struct llc_sap *sap,
- struct sk_buff *skb);
-
-void llc_add_pack(int type, void (*handler)(struct llc_sap *sap,
- struct sk_buff *skb))
-{
- smp_wmb(); /* ensure initialisation is complete before it's called */
- if (type == LLC_DEST_SAP || type == LLC_DEST_CONN)
- llc_type_handlers[type - 1] = handler;
-}
-
-void llc_remove_pack(int type)
-{
- if (type == LLC_DEST_SAP || type == LLC_DEST_CONN)
- llc_type_handlers[type - 1] = NULL;
- synchronize_net();
-}
-
-void llc_set_station_handler(void (*handler)(struct sk_buff *skb))
-{
- /* Ensure initialisation is complete before it's called */
- if (handler)
- smp_wmb();
-
- llc_station_handler = handler;
-
- if (!handler)
- synchronize_net();
-}
-
-/**
- * llc_pdu_type - returns which LLC component must handle for PDU
- * @skb: input skb
- *
- * This function returns which LLC component must handle this PDU.
- */
-static __inline__ int llc_pdu_type(struct sk_buff *skb)
-{
- int type = LLC_DEST_CONN; /* I-PDU or S-PDU type */
- struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
-
- if ((pdu->ctrl_1 & LLC_PDU_TYPE_MASK) != LLC_PDU_TYPE_U)
- goto out;
- switch (LLC_U_PDU_CMD(pdu)) {
- case LLC_1_PDU_CMD_XID:
- case LLC_1_PDU_CMD_UI:
- case LLC_1_PDU_CMD_TEST:
- type = LLC_DEST_SAP;
- break;
- case LLC_2_PDU_CMD_SABME:
- case LLC_2_PDU_CMD_DISC:
- case LLC_2_PDU_RSP_UA:
- case LLC_2_PDU_RSP_DM:
- case LLC_2_PDU_RSP_FRMR:
- break;
- default:
- type = LLC_DEST_INVALID;
- break;
- }
-out:
- return type;
-}
-
/**
* llc_fixup_skb - initializes skb pointers
* @skb: This argument points to incoming skb
@@ -146,21 +71,16 @@ static inline int llc_fixup_skb(struct sk_buff *skb)
* @orig_dev: the original receive net device
*
* When the system receives a 802.2 frame this function is called. It
- * checks SAP and connection of received pdu and passes frame to
- * llc_{station,sap,conn}_rcv for sending to proper state machine. If
- * the frame is related to a busy connection (a connection is sending
- * data now), it queues this frame in the connection's backlog.
+ * looks up the SAP the pdu is addressed to and passes the frame to its
+ * handler, dropping it if the SAP is unknown or has no handler.
*/
int llc_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev)
{
- struct llc_sap *sap;
- struct llc_pdu_sn *pdu;
- int dest;
int (*rcv)(struct sk_buff *, struct net_device *,
struct packet_type *, struct net_device *);
- void (*sta_handler)(struct sk_buff *skb);
- void (*sap_handler)(struct llc_sap *sap, struct sk_buff *skb);
+ struct llc_pdu_un *pdu;
+ struct llc_sap *sap;
/*
* When the interface is in promisc. mode, drop all the crap that it
@@ -175,49 +95,22 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev,
goto out;
if (unlikely(!llc_fixup_skb(skb)))
goto drop;
- pdu = llc_pdu_sn_hdr(skb);
- if (unlikely(!pdu->dsap)) /* NULL DSAP, refer to station */
- goto handle_station;
+ pdu = llc_pdu_un_hdr(skb);
sap = llc_sap_find(pdu->dsap);
if (unlikely(!sap)) {/* unknown SAP */
dprintk("%s: llc_sap_find(%02X) failed!\n", __func__,
pdu->dsap);
goto drop;
}
- /*
- * First the upper layer protocols that don't need the full
- * LLC functionality
- */
rcv = rcu_dereference(sap->rcv_func);
- dest = llc_pdu_type(skb);
- sap_handler = dest ? READ_ONCE(llc_type_handlers[dest - 1]) : NULL;
- if (unlikely(!sap_handler)) {
- if (rcv)
- rcv(skb, dev, pt, orig_dev);
- else
- kfree_skb(skb);
- } else {
- if (rcv) {
- struct sk_buff *cskb = skb_clone(skb, GFP_ATOMIC);
- if (cskb)
- rcv(cskb, dev, pt, orig_dev);
- }
- sap_handler(sap, skb);
- }
+ if (likely(rcv))
+ rcv(skb, dev, pt, orig_dev);
+ else
+ kfree_skb(skb);
llc_sap_put(sap);
out:
return 0;
drop:
kfree_skb(skb);
goto out;
-handle_station:
- sta_handler = READ_ONCE(llc_station_handler);
- if (!sta_handler)
- goto drop;
- sta_handler(skb);
- goto out;
}
-
-EXPORT_SYMBOL(llc_add_pack);
-EXPORT_SYMBOL(llc_remove_pack);
-EXPORT_SYMBOL(llc_set_station_handler);
diff --git a/net/llc/llc_output.c b/net/llc/llc_output.c
index 5a6466fc626a..8324f1cad4ca 100644
--- a/net/llc/llc_output.c
+++ b/net/llc/llc_output.c
@@ -59,8 +59,7 @@ int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
const unsigned char *dmac, unsigned char dsap)
{
int rc;
- llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
- dsap, LLC_PDU_CMD);
+ llc_pdu_header_init(skb, sap->lsap, dsap, LLC_PDU_CMD);
llc_pdu_init_as_ui_cmd(skb);
rc = llc_mac_hdr_init(skb, skb->dev->dev_addr, dmac);
if (likely(!rc))