summaryrefslogtreecommitdiff
path: root/include/net
diff options
context:
space:
mode:
Diffstat (limited to 'include/net')
-rw-r--r--include/net/addrconf.h3
-rw-r--r--include/net/af_rxrpc.h5
-rw-r--r--include/net/af_vsock.h1
-rw-r--r--include/net/amt.h4
-rw-r--r--include/net/arp.h26
-rw-r--r--include/net/bluetooth/bluetooth.h4
-rw-r--r--include/net/bluetooth/coredump.h2
-rw-r--r--include/net/bluetooth/hci.h1
-rw-r--r--include/net/bluetooth/hci_core.h74
-rw-r--r--include/net/bluetooth/hci_h4.h60
-rw-r--r--include/net/bluetooth/hci_mon.h2
-rw-r--r--include/net/bluetooth/hci_sync.h1
-rw-r--r--include/net/bluetooth/l2cap.h103
-rw-r--r--include/net/bluetooth/mgmt.h14
-rw-r--r--include/net/bluetooth/rfcomm.h1
-rw-r--r--include/net/bond_3ad.h7
-rw-r--r--include/net/bond_alb.h14
-rw-r--r--include/net/can.h2
-rw-r--r--include/net/cfg80211.h170
-rw-r--r--include/net/cfg802154.h10
-rw-r--r--include/net/codel.h5
-rw-r--r--include/net/codel_impl.h16
-rw-r--r--include/net/dropreason-core.h38
-rw-r--r--include/net/dsa.h2
-rw-r--r--include/net/dst.h3
-rw-r--r--include/net/gso.h15
-rw-r--r--include/net/gue.h19
-rw-r--r--include/net/ieee80211_radiotap.h113
-rw-r--r--include/net/inet_connection_sock.h1
-rw-r--r--include/net/inet_frag.h1
-rw-r--r--include/net/inet_sock.h2
-rw-r--r--include/net/ip.h49
-rw-r--r--include/net/ip6_route.h54
-rw-r--r--include/net/ip6_tunnel.h1
-rw-r--r--include/net/ip_fib.h4
-rw-r--r--include/net/ip_tunnels.h17
-rw-r--r--include/net/ip_vs.h50
-rw-r--r--include/net/llc.h108
-rw-r--r--include/net/llc_c_ac.h180
-rw-r--r--include/net/llc_c_ev.h217
-rw-r--r--include/net/llc_c_st.h46
-rw-r--r--include/net/llc_conn.h114
-rw-r--r--include/net/llc_if.h63
-rw-r--r--include/net/llc_pdu.h379
-rw-r--r--include/net/llc_s_ac.h35
-rw-r--r--include/net/llc_s_ev.h61
-rw-r--r--include/net/llc_s_st.h32
-rw-r--r--include/net/llc_sap.h26
-rw-r--r--include/net/mac80211.h111
-rw-r--r--include/net/mana/gdma.h118
-rw-r--r--include/net/mana/hw_channel.h8
-rw-r--r--include/net/mana/mana.h20
-rw-r--r--include/net/mptcp.h9
-rw-r--r--include/net/ndisc.h39
-rw-r--r--include/net/neighbour.h46
-rw-r--r--include/net/net_namespace.h5
-rw-r--r--include/net/netdev_lock.h20
-rw-r--r--include/net/netdev_queues.h56
-rw-r--r--include/net/netfilter/nf_conntrack.h5
-rw-r--r--include/net/netfilter/nf_conntrack_seqadj.h1
-rw-r--r--include/net/netfilter/nf_flow_table.h3
-rw-r--r--include/net/netfilter/nf_queue.h3
-rw-r--r--include/net/netmem.h88
-rw-r--r--include/net/netns/netfilter.h2
-rw-r--r--include/net/nfc/hci.h2
-rw-r--r--include/net/nfc/nfc.h3
-rw-r--r--include/net/page_pool/helpers.h30
-rw-r--r--include/net/page_pool/memory_provider.h10
-rw-r--r--include/net/page_pool/types.h6
-rw-r--r--include/net/phy/realtek_phy.h7
-rw-r--r--include/net/pkt_cls.h2
-rw-r--r--include/net/psp/functions.h5
-rw-r--r--include/net/psp/types.h4
-rw-r--r--include/net/route.h13
-rw-r--r--include/net/sch_generic.h11
-rw-r--r--include/net/scm.h10
-rw-r--r--include/net/sctp/sm.h1
-rw-r--r--include/net/seg6_hmac.h3
-rw-r--r--include/net/sock.h12
-rw-r--r--include/net/strparser.h19
-rw-r--r--include/net/tcp.h299
-rw-r--r--include/net/udp.h2
-rw-r--r--include/net/vxlan.h12
-rw-r--r--include/net/xdp.h5
-rw-r--r--include/net/xfrm.h17
-rw-r--r--include/net/xsk_buff_pool.h3
86 files changed, 1435 insertions, 1730 deletions
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index e6764245995f..6818057cf727 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -81,6 +81,9 @@ struct ifa6_config {
u8 ifa_proto;
const struct in6_addr *peer_pfx;
+ struct inet6_ifaddr *ifpub;
+ unsigned long cstamp;
+ unsigned long tstamp;
u32 rt_priority;
u32 ifa_flags;
diff --git a/include/net/af_rxrpc.h b/include/net/af_rxrpc.h
index 0fb4c41c9bbf..f3980348ed34 100644
--- a/include/net/af_rxrpc.h
+++ b/include/net/af_rxrpc.h
@@ -64,9 +64,8 @@ struct rxrpc_call *rxrpc_kernel_begin_call(struct socket *sock,
bool upgrade,
enum rxrpc_interruptibility interruptibility,
unsigned int debug_id);
-int rxrpc_kernel_send_data(struct socket *, struct rxrpc_call *,
- struct msghdr *, size_t,
- rxrpc_notify_end_tx_t);
+int rxrpc_kernel_send_data(struct socket *sock, struct rxrpc_call *call,
+ struct msghdr *msg, rxrpc_notify_end_tx_t notify_end_tx);
int rxrpc_kernel_recv_data(struct socket *, struct rxrpc_call *,
struct iov_iter *, size_t *, bool, u32 *, u16 *);
bool rxrpc_kernel_abort_call(struct socket *, struct rxrpc_call *,
diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
index 5549298c1ec6..e8481f12312e 100644
--- a/include/net/af_vsock.h
+++ b/include/net/af_vsock.h
@@ -68,6 +68,7 @@ struct vsock_sock {
u64 buffer_size;
u64 buffer_min_size;
u64 buffer_max_size;
+ bool recvmsg_inq;
/* Private to transport. */
void *trans;
diff --git a/include/net/amt.h b/include/net/amt.h
index a0255491f5b0..2846dde0cadc 100644
--- a/include/net/amt.h
+++ b/include/net/amt.h
@@ -231,10 +231,6 @@ struct amt_relay_headers {
};
} __packed;
-struct amt_skb_cb {
- struct amt_tunnel_list *tunnel;
-};
-
struct amt_tunnel_list {
struct list_head list;
/* Protect All resources under an amt_tunne_list */
diff --git a/include/net/arp.h b/include/net/arp.h
index e8747e0713c7..329a5456987a 100644
--- a/include/net/arp.h
+++ b/include/net/arp.h
@@ -7,8 +7,10 @@
#include <linux/hash.h>
#include <net/neighbour.h>
-
-extern struct neigh_table arp_tbl;
+static inline struct neigh_table *arp_table(struct net *net)
+{
+ return net->neigh_tables[NEIGH_ARP_TABLE];
+}
static inline u32 arp_hashfn(const void *pkey, const struct net_device *dev, u32 *hash_rnd)
{
@@ -21,10 +23,12 @@ static inline u32 arp_hashfn(const void *pkey, const struct net_device *dev, u32
#ifdef CONFIG_INET
static inline struct neighbour *__ipv4_neigh_lookup_noref(struct net_device *dev, u32 key)
{
+ struct neigh_table *tbl = arp_table(dev_net(dev));
+
if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))
key = INADDR_ANY;
- return ___neigh_lookup_noref(&arp_tbl, neigh_key_eq32, arp_hashfn, &key, dev);
+ return ___neigh_lookup_noref(tbl, neigh_key_eq32, arp_hashfn, &key, dev);
}
#else
static inline
@@ -47,6 +51,22 @@ static inline struct neighbour *__ipv4_neigh_lookup(struct net_device *dev, u32
return n;
}
+static inline struct neighbour *ipv4_neigh_lookup(struct net_device *dev,
+ const void *pkey)
+{
+ struct neigh_table *tbl = arp_table(dev_net(dev));
+
+ return neigh_lookup(tbl, pkey, dev);
+}
+
+static inline struct neighbour *ipv4_neigh_create(struct net_device *dev,
+ const void *pkey)
+{
+ struct neigh_table *tbl = arp_table(dev_net(dev));
+
+ return neigh_create(tbl, pkey, dev);
+}
+
static inline void __ipv4_confirm_neigh(struct net_device *dev, u32 key)
{
struct neighbour *n;
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index b624da5026f5..cd9189244566 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -296,9 +296,9 @@ void bt_err_ratelimited(const char *fmt, ...);
BT_DBG("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
#define bt_dev_warn_ratelimited(hdev, fmt, ...) \
- bt_warn_ratelimited("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
+ bt_warn_ratelimited("%s: " fmt "\n", bt_dev_name(hdev), ##__VA_ARGS__)
#define bt_dev_err_ratelimited(hdev, fmt, ...) \
- bt_err_ratelimited("%s: " fmt, bt_dev_name(hdev), ##__VA_ARGS__)
+ bt_err_ratelimited("%s: " fmt "\n", bt_dev_name(hdev), ##__VA_ARGS__)
/* Connection and socket states */
enum bt_sock_state {
diff --git a/include/net/bluetooth/coredump.h b/include/net/bluetooth/coredump.h
index 1f071ab55416..acc1849f66c0 100644
--- a/include/net/bluetooth/coredump.h
+++ b/include/net/bluetooth/coredump.h
@@ -70,6 +70,7 @@ struct hci_devcoredump {
const char *hci_devcd_state_name(enum devcoredump_state state);
void hci_devcd_reset(struct hci_dev *hdev);
+void hci_devcd_shutdown(struct hci_dev *hdev);
void hci_devcd_rx(struct work_struct *work);
void hci_devcd_timeout(struct work_struct *work);
@@ -89,6 +90,7 @@ static inline const char *hci_devcd_state_name(enum devcoredump_state state)
}
static inline void hci_devcd_reset(struct hci_dev *hdev) {}
+static inline void hci_devcd_shutdown(struct hci_dev *hdev) {}
static inline void hci_devcd_rx(struct work_struct *work) {}
static inline void hci_devcd_timeout(struct work_struct *work) {}
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 1641d879dbda..9dc714d9145e 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -2527,6 +2527,7 @@ struct hci_le_conn_interval_group {
struct hci_rp_le_read_conn_interval {
__u8 status;
+ __u8 min;
__u8 num_grps;
struct hci_le_conn_interval_group grps[];
} __packed;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 4105c446ca98..aa04dec45153 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -28,6 +28,7 @@
#include <linux/rculist.h>
#include <linux/spinlock.h>
#include <linux/srcu.h>
+#include <linux/uio.h>
#include <net/bluetooth/hci.h>
#include <net/bluetooth/hci_drv.h>
@@ -62,7 +63,7 @@ struct inquiry_entry {
NAME_PENDING,
NAME_KNOWN,
} name_state;
- __u32 timestamp;
+ unsigned long timestamp;
struct inquiry_data data;
};
@@ -78,7 +79,7 @@ struct discovery_state {
struct list_head all; /* All devices found during inquiry */
struct list_head unknown; /* Name state not known */
struct list_head resolve; /* Name needs to be resolved */
- __u32 timestamp;
+ unsigned long timestamp;
bdaddr_t last_adv_addr;
u8 last_adv_addr_type;
s8 last_adv_rssi;
@@ -562,6 +563,7 @@ struct hci_dev {
struct list_head link_keys;
struct list_head long_term_keys;
struct list_head identity_resolving_keys;
+ struct mutex remote_oob_lock;
struct list_head remote_oob_data;
struct list_head le_accept_list;
struct list_head le_resolv_list;
@@ -599,7 +601,7 @@ struct hci_dev {
struct list_head adv_instances;
unsigned int adv_instance_cnt;
__u8 cur_adv_instance;
- __u16 adv_instance_timeout;
+ bool adv_instance_timeout;
struct delayed_work adv_instance_expire;
struct idr adv_monitors_idr;
@@ -646,6 +648,8 @@ struct hci_dev {
int (*setup)(struct hci_dev *hdev);
int (*shutdown)(struct hci_dev *hdev);
int (*send)(struct hci_dev *hdev, struct sk_buff *skb);
+ /* Receive HCI_VENDOR_PKT */
+ void (*recv_vendor_pkt)(struct hci_dev *hdev, struct sk_buff *skb);
/* Handle HCI_EV_VENDOR; return true if handled, false otherwise */
bool (*handle_ev_vendor)(struct hci_dev *hdev, struct sk_buff *skb);
void (*notify)(struct hci_dev *hdev, unsigned int evt);
@@ -1030,6 +1034,9 @@ static inline bool hci_conn_sc_enabled(struct hci_conn *conn)
static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)
{
struct hci_conn_hash *h = &hdev->conn_hash;
+
+ lockdep_assert_held(&hdev->lock);
+
list_add_tail_rcu(&c->list, &h->list);
switch (c->type) {
case ACL_LINK:
@@ -1060,6 +1067,8 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
{
struct hci_conn_hash *h = &hdev->conn_hash;
+ lockdep_assert_held(&hdev->lock);
+
list_del_rcu(&c->list);
synchronize_rcu();
@@ -1088,6 +1097,15 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)
}
}
+#ifdef CONFIG_PROVE_RCU
+#define HCI_CONN_HASH_LOCKDEP_CHECK(hdev) \
+ RCU_LOCKDEP_WARN(!lockdep_is_held(&(hdev)->lock) && \
+ !rcu_read_lock_held(), \
+ "suspicious hci_conn locking")
+#else
+#define HCI_CONN_HASH_LOCKDEP_CHECK(hdev) do { } while (0 && (hdev))
+#endif
+
static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type)
{
struct hci_conn_hash *h = &hdev->conn_hash;
@@ -1169,6 +1187,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_bis(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1191,6 +1211,8 @@ hci_conn_hash_lookup_create_pa_sync(struct hci_dev *hdev)
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1217,6 +1239,8 @@ hci_conn_hash_lookup_per_adv_bis(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1241,6 +1265,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_handle(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1260,6 +1286,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1281,6 +1309,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_role(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1302,6 +1332,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_le(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1328,6 +1360,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_cis(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1360,6 +1394,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_cig(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1383,6 +1419,8 @@ static inline struct hci_conn *hci_conn_hash_lookup_big(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1407,6 +1445,8 @@ hci_conn_hash_lookup_big_sync_pend(struct hci_dev *hdev,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1431,6 +1471,8 @@ hci_conn_hash_lookup_big_state(struct hci_dev *hdev, __u8 handle, __u16 state,
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1454,6 +1496,8 @@ hci_conn_hash_lookup_pa_sync_big_handle(struct hci_dev *hdev, __u8 big)
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1477,6 +1521,8 @@ hci_conn_hash_lookup_pa_sync_handle(struct hci_dev *hdev, __u16 sync_handle)
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -1546,6 +1592,8 @@ static inline struct hci_conn *hci_lookup_le_connect(struct hci_dev *hdev)
struct hci_conn_hash *h = &hdev->conn_hash;
struct hci_conn *c;
+ HCI_CONN_HASH_LOCKDEP_CHECK(hdev);
+
rcu_read_lock();
list_for_each_entry_rcu(c, &h->list, list) {
@@ -2207,6 +2255,8 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
conn->security_cfm_cb(conn, status);
}
+void mgmt_security_level_changed(struct hci_conn *conn);
+
static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
{
struct hci_cb *cb;
@@ -2229,11 +2279,19 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status)
encrypt = 0x01;
if (!status) {
- if (conn->sec_level == BT_SECURITY_SDP)
+ /* Callers either set conn->sec_level = conn->pending_sec_level
+ * unconditionally before calling this function, or never
+ * reach here with status == 0 (e.g. conn->state == BT_CONFIG
+ * returns early above, or status is actually an error). So
+ * conn->pending_sec_level is never greater than
+ * conn->sec_level at this point; only the initial
+ * BT_SECURITY_SDP -> BT_SECURITY_LOW bump can still happen
+ * here.
+ */
+ if (conn->sec_level == BT_SECURITY_SDP) {
conn->sec_level = BT_SECURITY_LOW;
-
- if (conn->pending_sec_level > conn->sec_level)
- conn->sec_level = conn->pending_sec_level;
+ mgmt_security_level_changed(conn);
+ }
}
mutex_lock(&hci_cb_list_lock);
@@ -2356,6 +2414,8 @@ static inline int hci_check_conn_params(u16 min, u16 max, u16 latency,
int hci_register_cb(struct hci_cb *hcb);
int hci_unregister_cb(struct hci_cb *hcb);
+int hci_send_vendor_frame(struct hci_dev *hdev, struct iov_iter *iter);
+
int __hci_cmd_send(struct hci_dev *hdev, u16 opcode, u32 plen,
const void *param);
diff --git a/include/net/bluetooth/hci_h4.h b/include/net/bluetooth/hci_h4.h
new file mode 100644
index 000000000000..a37e7df8c9ce
--- /dev/null
+++ b/include/net/bluetooth/hci_h4.h
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Bluetooth HCI H:4 packet reassembly
+ *
+ * Copyright (C) 2000-2001 Qualcomm Incorporated
+ * Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
+ * Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
+ */
+
+#ifndef __HCI_H4_H
+#define __HCI_H4_H
+
+#include <linux/skbuff.h>
+#include <linux/types.h>
+
+struct hci_dev;
+
+struct h4_recv_pkt {
+ u8 type; /* Packet type */
+ u8 hlen; /* Header length */
+ u8 loff; /* Data length offset in header */
+ u8 lsize; /* Data length field size */
+ u16 maxlen; /* Max overall packet length */
+ int (*recv)(struct hci_dev *hdev, struct sk_buff *skb);
+};
+
+#define H4_RECV_ACL \
+ .type = HCI_ACLDATA_PKT, \
+ .hlen = HCI_ACL_HDR_SIZE, \
+ .loff = 2, \
+ .lsize = 2, \
+ .maxlen = HCI_MAX_FRAME_SIZE \
+
+#define H4_RECV_SCO \
+ .type = HCI_SCODATA_PKT, \
+ .hlen = HCI_SCO_HDR_SIZE, \
+ .loff = 2, \
+ .lsize = 1, \
+ .maxlen = HCI_MAX_SCO_SIZE
+
+#define H4_RECV_EVENT \
+ .type = HCI_EVENT_PKT, \
+ .hlen = HCI_EVENT_HDR_SIZE, \
+ .loff = 1, \
+ .lsize = 1, \
+ .maxlen = HCI_MAX_EVENT_SIZE
+
+#define H4_RECV_ISO \
+ .type = HCI_ISODATA_PKT, \
+ .hlen = HCI_ISO_HDR_SIZE, \
+ .loff = 2, \
+ .lsize = 2, \
+ .maxlen = HCI_MAX_FRAME_SIZE \
+
+struct sk_buff *h4_recv_skb(struct hci_dev *hdev, u8 *alignment, u8 *padding,
+ struct sk_buff *skb, const unsigned char *buffer,
+ int count, const struct h4_recv_pkt *pkts,
+ int pkts_count);
+
+#endif /* __HCI_H4_H */
diff --git a/include/net/bluetooth/hci_mon.h b/include/net/bluetooth/hci_mon.h
index 4b2a0af4ed58..7710688c0d30 100644
--- a/include/net/bluetooth/hci_mon.h
+++ b/include/net/bluetooth/hci_mon.h
@@ -50,6 +50,8 @@ struct hci_mon_hdr {
#define HCI_MON_ISO_RX_PKT 19
#define HCI_MON_DRV_TX_PKT 20
#define HCI_MON_DRV_RX_PKT 21
+#define HCI_MON_VENDOR_TX_PKT 22
+#define HCI_MON_VENDOR_RX_PKT 23
struct hci_mon_new_index {
__u8 type;
diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h
index a6579a868678..59cb918d1405 100644
--- a/include/net/bluetooth/hci_sync.h
+++ b/include/net/bluetooth/hci_sync.h
@@ -122,6 +122,7 @@ int hci_disable_per_advertising_sync(struct hci_dev *hdev, u8 instance);
int hci_remove_advertising_sync(struct hci_dev *hdev, struct sock *sk,
u8 instance, bool force);
int hci_disable_advertising_sync(struct hci_dev *hdev);
+int hci_disable_ext_adv_legacy_instance_sync(struct hci_dev *hdev);
int hci_clear_adv_instance_sync(struct hci_dev *hdev, struct sock *sk,
u8 instance, bool force);
int hci_update_passive_scan_sync(struct hci_dev *hdev);
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 3d9a32094347..54eddcdd341f 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -614,31 +614,6 @@ struct l2cap_chan {
struct mutex lock;
};
-struct l2cap_ops {
- char *name;
-
- int (*new_connection)(struct l2cap_chan *chan,
- struct l2cap_chan *new_chan);
- int (*recv) (struct l2cap_chan * chan,
- struct sk_buff *skb);
- void (*teardown) (struct l2cap_chan *chan, int err);
- void (*close) (struct l2cap_chan *chan);
- void (*state_change) (struct l2cap_chan *chan,
- int state, int err);
- void (*ready) (struct l2cap_chan *chan);
- void (*defer) (struct l2cap_chan *chan);
- void (*resume) (struct l2cap_chan *chan);
- void (*suspend) (struct l2cap_chan *chan);
- void (*set_shutdown) (struct l2cap_chan *chan);
- long (*get_sndtimeo) (struct l2cap_chan *chan);
- struct pid *(*get_peer_pid) (struct l2cap_chan *chan);
- struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan,
- unsigned long hdr_len,
- unsigned long len, int nb);
- int (*filter) (struct l2cap_chan * chan,
- struct sk_buff *skb);
-};
-
struct l2cap_conn {
struct hci_conn *hcon;
struct hci_chan *hchan;
@@ -668,12 +643,45 @@ struct l2cap_conn {
struct l2cap_chan *smp;
- struct list_head chan_l;
+ struct list_head chan_l __guarded_by(&lock);
struct mutex lock;
struct kref ref;
struct list_head users;
};
+struct l2cap_ops {
+ char *name;
+
+ int (*new_connection)(struct l2cap_chan *chan,
+ struct l2cap_chan *new_chan)
+ __must_hold(&chan->lock)
+ __must_hold(&new_chan->lock);
+ int (*recv) (struct l2cap_chan * chan,
+ struct sk_buff *skb);
+ void (*teardown) (struct l2cap_chan *chan, int err)
+ __must_hold(&chan->lock);
+ void (*close) (struct l2cap_chan *chan)
+ __must_hold(&chan->lock);
+ void (*state_change) (struct l2cap_chan *chan,
+ int state, int err);
+ void (*ready) (struct l2cap_chan *chan)
+ __must_hold(&chan->lock)
+ __must_hold(&chan->conn->lock);
+ void (*defer) (struct l2cap_chan *chan);
+ void (*resume) (struct l2cap_chan *chan)
+ __must_hold(&chan->lock);
+ void (*suspend) (struct l2cap_chan *chan);
+ void (*set_shutdown) (struct l2cap_chan *chan)
+ __must_hold(&chan->lock);
+ long (*get_sndtimeo) (struct l2cap_chan *chan);
+ struct pid *(*get_peer_pid) (struct l2cap_chan *chan);
+ struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan,
+ unsigned long hdr_len,
+ unsigned long len, int nb);
+ int (*filter) (struct l2cap_chan * chan,
+ struct sk_buff *skb);
+};
+
struct l2cap_user {
struct list_head list;
int (*probe) (struct l2cap_conn *conn, struct l2cap_user *user);
@@ -717,7 +725,6 @@ enum {
CONF_CONNECT_PEND,
CONF_RECV_NO_FCS,
CONF_STATE2_DEVICE,
- CONF_EWS_RECV,
CONF_LOC_CONF_PEND,
CONF_REM_CONF_PEND,
CONF_NOT_COMPLETE,
@@ -758,6 +765,10 @@ enum {
* otherwise considers all channels equal and will e.g. complain about a
* connection oriented channel triggering SMP procedures or a listening
* channel creating and locking a child channel.
+ *
+ * Lock nesting of channels at the same nesting level is allowed if the channels
+ * have the same l2cap_chan::conn and l2cap_chan::conn.lock is taken before the
+ * nested locks. l2cap_chan_try_sibling_lock() must be used.
*/
enum {
L2CAP_NESTING_SMP,
@@ -830,11 +841,13 @@ struct l2cap_chan *l2cap_chan_hold_unless_zero(struct l2cap_chan *c);
void l2cap_chan_put(struct l2cap_chan *c);
static inline void l2cap_chan_lock(struct l2cap_chan *chan)
+ __acquires(&chan->lock)
{
mutex_lock_nested(&chan->lock, atomic_read(&chan->nesting));
}
static inline void l2cap_chan_unlock(struct l2cap_chan *chan)
+ __releases(&chan->lock)
{
mutex_unlock(&chan->lock);
}
@@ -845,12 +858,11 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan,
BT_DBG("chan %p state %s timeout %ld", chan,
state_to_string(chan->state), timeout);
- /* If delayed work cancelled do not hold(chan)
- since it is already done with previous set_timer */
- if (!cancel_delayed_work(work))
- l2cap_chan_hold(chan);
+ l2cap_chan_hold(chan);
- schedule_delayed_work(work, timeout);
+ /* put(chan) if timer was already queued so it already has a ref */
+ if (mod_delayed_work(system_percpu_wq, work, timeout))
+ l2cap_chan_put(chan);
}
static inline bool l2cap_clear_timer(struct l2cap_chan *chan,
@@ -952,14 +964,16 @@ void l2cap_cleanup_sockets(void);
bool l2cap_is_socket(struct socket *sock);
void __l2cap_le_connect_rsp_defer(struct l2cap_chan *chan);
-void __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan);
+void __l2cap_ecred_conn_rsp_defer(struct l2cap_chan *chan)
+ __must_hold(&chan->lock) __must_hold(&chan->conn->lock);
void __l2cap_connect_rsp_defer(struct l2cap_chan *chan);
int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm);
int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid);
struct l2cap_chan *l2cap_chan_create(void);
-void l2cap_chan_close(struct l2cap_chan *chan, int reason);
+void l2cap_chan_close_unlocked(struct l2cap_chan *chan, int reason)
+ __must_not_hold(&chan->lock);
int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
bdaddr_t *dst, u8 dst_type, u16 timeout);
int l2cap_chan_reconfigure(struct l2cap_chan *chan, __u16 mtu);
@@ -971,11 +985,13 @@ int l2cap_chan_check_security(struct l2cap_chan *chan, bool initiator);
void l2cap_chan_set_defaults(struct l2cap_chan *chan, struct l2cap_chan *pchan);
int l2cap_ertm_init(struct l2cap_chan *chan);
void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
-void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
+void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
+ __must_hold(&conn->lock) __must_hold(&chan->lock);
typedef void (*l2cap_chan_func_t)(struct l2cap_chan *chan, void *data);
void l2cap_chan_list(struct l2cap_conn *conn, l2cap_chan_func_t func,
void *data);
-void l2cap_chan_del(struct l2cap_chan *chan, int err);
+void l2cap_chan_del(struct l2cap_chan *chan, int err)
+ __must_hold(&chan->lock) __must_hold(&chan->conn->lock);
void l2cap_send_conn_req(struct l2cap_chan *chan);
struct l2cap_conn *l2cap_conn_get(struct l2cap_conn *conn);
@@ -985,4 +1001,19 @@ void l2cap_conn_put(struct l2cap_conn *conn);
int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user);
void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user);
+bool l2cap_chan_lock_conn(struct l2cap_chan *chan)
+ __acquires(&chan->lock) __cond_acquires(true, &chan->conn->lock);
+
+/* Release macro for l2cap_chan_lock_conn, so context analysis understands it */
+#define l2cap_chan_unlock_conn(chan, conn_locked) \
+ ({ \
+ struct l2cap_chan *__chan = (chan); \
+ struct l2cap_conn *__conn = __chan->conn; \
+ l2cap_chan_unlock(__chan); \
+ if (conn_locked) { \
+ mutex_unlock(&__conn->lock); \
+ l2cap_conn_put(__conn); \
+ } \
+ })
+
#endif /* __L2CAP_H */
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 1e22eab1081c..b02e915bb44c 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -1221,3 +1221,17 @@ struct mgmt_ev_conn_subrate {
__le16 cont_num;
__le16 supv_timeout;
} __packed;
+
+#define MGMT_CONN_SEC_ENCRYPT_NONE 0x00
+#define MGMT_CONN_SEC_ENCRYPT_E0 0x01
+#define MGMT_CONN_SEC_ENCRYPT_AES_CCM 0x02
+
+#define MGMT_SEC_LEVEL_CHANGED_PARAM_LEVEL 0x0000
+#define MGMT_SEC_LEVEL_CHANGED_PARAM_ENC_TYPE 0x0001
+
+#define MGMT_EV_SECURITY_LEVEL_CHANGED 0x0034
+struct mgmt_ev_security_level_changed {
+ struct mgmt_addr_info addr;
+ __u8 tlv_length;
+ __u8 tlv_data[] __counted_by(tlv_length);
+} __packed;
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index 102c278e3584..9dc5fd4cb8c8 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -207,6 +207,7 @@ struct rfcomm_dlc {
#define RFCOMM_AUTH_REJECT 7
#define RFCOMM_DEFER_SETUP 8
#define RFCOMM_ENC_DROP 9
+#define RFCOMM_CLOSED 10
/* Scheduling flags and events */
#define RFCOMM_SCHED_WAKEUP 31
diff --git a/include/net/bond_3ad.h b/include/net/bond_3ad.h
index ef667dff2972..9e548d3dca21 100644
--- a/include/net/bond_3ad.h
+++ b/include/net/bond_3ad.h
@@ -60,12 +60,6 @@ typedef enum {
AD_MUX_COLLECTING_DISTRIBUTING /* mux machine */
} mux_states_t;
-/* tx machine states(43.4.15 in the 802.3ad standard) */
-typedef enum {
- AD_TX_DUMMY,
- AD_TRANSMIT /* tx Machine */
-} tx_states_t;
-
/* churn machine states(43.4.17 in the 802.3ad standard) */
typedef enum {
AD_CHURN_MONITOR, /* monitoring for churn */
@@ -231,7 +225,6 @@ typedef struct port {
u16 sm_periodic_timer_counter; /* state machine periodic timer counter */
mux_states_t sm_mux_state; /* state machine mux state */
u16 sm_mux_timer_counter; /* state machine mux timer counter */
- tx_states_t sm_tx_state; /* state machine tx state */
u16 sm_tx_timer_counter; /* state machine tx timer counter
* (always on - enter to transmit
* state 3 time per second)
diff --git a/include/net/bond_alb.h b/include/net/bond_alb.h
index e5945427f38d..32f1981033e4 100644
--- a/include/net/bond_alb.h
+++ b/include/net/bond_alb.h
@@ -57,12 +57,12 @@ struct tlb_client_info {
* packets to a Client that the Hash function
* gave this entry index.
*/
- u32 tx_bytes; /* Each Client accumulates the BytesTx that
+ u64 tx_bytes; /* Each Client accumulates the BytesTx that
* were transmitted to it, and after each
* CallBack the LoadHistory is divided
* by the balance interval
*/
- u32 load_history; /* This field contains the amount of Bytes
+ u64 load_history; /* This field contains the amount of Bytes
* that were transmitted to this client by
* the server on the previous balance
* interval in Bps.
@@ -118,14 +118,20 @@ struct tlb_slave_info {
* are the entries that were assigned to use this
* slave for transmit.
*/
- u32 load; /* Each slave sums the loadHistory of all clients
+ u64 load; /* Each slave sums the loadHistory of all clients
* assigned to it
*/
};
+struct unbalanced_load_stats {
+ u64_stats_t tx_bytes;
+ struct u64_stats_sync syncp;
+};
+
struct alb_bond_info {
struct tlb_client_info *tx_hashtbl; /* Dynamically allocated */
- u32 unbalanced_load;
+ struct unbalanced_load_stats __percpu *unbalanced_load;
+ u64 prev_total_unbalanced;
atomic_t tx_rebalance_counter;
int lp_counter;
/* -------- rlb parameters -------- */
diff --git a/include/net/can.h b/include/net/can.h
index 6db9e826f0e0..2b8af2598732 100644
--- a/include/net/can.h
+++ b/include/net/can.h
@@ -17,12 +17,14 @@
* @can_framelen: cached echo CAN frame length for bql
* @can_gw_hops: can-gw CAN frame time-to-live counter
* @can_ext_flags: CAN skb extensions flags
+ * @can_skb_uid: CAN skb UID for raw_rcv and isotp echo handling
*/
struct can_skb_ext {
int can_iif;
u16 can_framelen;
u8 can_gw_hops;
u8 can_ext_flags;
+ u32 can_skb_uid;
};
#endif /* _NET_CAN_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 97c16d4ff127..f773856c1818 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -21,6 +21,7 @@
#include <linux/nl80211.h>
#include <linux/if_ether.h>
#include <linux/ieee80211.h>
+#include <linux/refcount.h>
#include <linux/net.h>
#include <linux/rfkill.h>
#include <net/regulatory.h>
@@ -576,7 +577,6 @@ struct ieee80211_sta_s1g_cap {
* @vht_cap: VHT capabilities in this band
* @s1g_cap: S1G capabilities in this band
* @edmg_cap: EDMG capabilities in this band
- * @s1g_cap: S1G capabilities in this band (S1G band only, of course)
* @n_iftype_data: number of iftype data entries
* @iftype_data: interface type data entries. Note that the bits in
* @types_mask inside this structure cannot overlap (i.e. only
@@ -901,6 +901,7 @@ struct cfg80211_bitrate_mask {
enum nl80211_eht_gi eht_gi;
enum nl80211_he_ltf he_ltf;
enum nl80211_eht_ltf eht_ltf;
+ bool nonht_dup_6ghz;
} control[NUM_NL80211_BANDS];
};
@@ -1410,7 +1411,7 @@ struct cfg80211_mbssid_config {
/**
* struct cfg80211_mbssid_elems - Multiple BSSID elements
*
- * @cnt: Number of elements in array %elems.
+ * @cnt: Number of elements in array @elem.
*
* @elem: Array of multiple BSSID element(s) to be added into Beacon frames.
* @elem.data: Data for multiple BSSID elements.
@@ -1427,7 +1428,7 @@ struct cfg80211_mbssid_elems {
/**
* struct cfg80211_rnr_elems - Reduced neighbor report (RNR) elements
*
- * @cnt: Number of elements in array %elems.
+ * @cnt: Number of elements in array @elem.
*
* @elem: Array of RNR element(s) to be added into Beacon frames.
* @elem.data: Data for RNR elements.
@@ -1821,6 +1822,8 @@ struct sta_txpwr {
* @s1g_capa: S1G capabilities of station
* @uhr_capa: UHR capabilities of the station
* @uhr_capa_len: the length of the UHR capabilities
+ * @cip_cap_set: If CIP capabilities are present, required for CIP stations
+ * @cip_cap: CIP capabilities of station
*/
struct link_station_parameters {
const u8 *mld_mac;
@@ -1842,6 +1845,8 @@ struct link_station_parameters {
const struct ieee80211_s1g_cap *s1g_capa;
const struct ieee80211_uhr_cap *uhr_capa;
u8 uhr_capa_len;
+ bool cip_cap_set;
+ u8 cip_cap;
};
/**
@@ -2904,7 +2909,7 @@ struct cfg80211_ssid {
* @scan_start_tsf: scan start time in terms of the TSF of the BSS that the
* wireless device that requested the scan is connected to. If this
* information is not available, this field is left zero.
- * @tsf_bssid: the BSSID according to which %scan_start_tsf is set.
+ * @tsf_bssid: the BSSID according to which @scan_start_tsf is set.
* @aborted: set to true if the scan was aborted for any reason,
* userspace will be notified of that
*/
@@ -3164,8 +3169,8 @@ enum cfg80211_signal_type {
* ktime_get_boottime_ns() is likely appropriate.
* @parent_tsf: the time at the start of reception of the first octet of the
* timestamp field of the frame. The time is the TSF of the BSS specified
- * by %parent_bssid.
- * @parent_bssid: the BSS according to which %parent_tsf is set. This is set to
+ * by @parent_bssid.
+ * @parent_bssid: the BSS according to which @parent_tsf is set. This is set to
* the BSS that requested the scan in which the beacon/probe was received.
* @chains: bitmask for filled values in @chain_signal.
* @chain_signal: per-chain signal strength of last received BSS in dBm.
@@ -3402,6 +3407,8 @@ struct cfg80211_ml_reconf_req {
* flag is not set.
* @ASSOC_REQ_SPP_AMSDU: SPP A-MSDUs will be used on this connection (if any)
* @ASSOC_REQ_DISABLE_UHR: Disable UHR
+ * @ASSOC_REQ_CIP: Enable Control Integrity Protocol
+ * @ASSOC_REQ_PROTECTED_TWT: Enable protected TWT
*/
enum cfg80211_assoc_req_flags {
ASSOC_REQ_DISABLE_HT = BIT(0),
@@ -3413,6 +3420,8 @@ enum cfg80211_assoc_req_flags {
CONNECT_REQ_MLO_SUPPORT = BIT(6),
ASSOC_REQ_SPP_AMSDU = BIT(7),
ASSOC_REQ_DISABLE_UHR = BIT(8),
+ ASSOC_REQ_CIP = BIT(9),
+ ASSOC_REQ_PROTECTED_TWT = BIT(10),
};
/**
@@ -4009,6 +4018,7 @@ struct cfg80211_update_ft_ies_params {
* @link_id: for MLO, the link ID to transmit on, -1 if not given; note
* that the link ID isn't validated (much), it's in range but the
* link might not exist (or be used by the receiver STA)
+ * @no_sta: set if the frame should not be transmitted using an existing STA
*/
struct cfg80211_mgmt_tx_params {
struct ieee80211_channel *chan;
@@ -4021,6 +4031,7 @@ struct cfg80211_mgmt_tx_params {
int n_csa_offsets;
const u16 *csa_offsets;
int link_id;
+ bool no_sta;
};
/**
@@ -4183,9 +4194,12 @@ struct cfg80211_nan_band_config {
* that can take a value from 50-6F-9A-01-00-00 to 50-6F-9A-01-FF-FF.
* @scan_period: period (in seconds) between NAN scans.
* @scan_dwell_time: dwell time (in milliseconds) for NAN scans.
- * @discovery_beacon_interval: interval (in TUs) for discovery beacons.
+ * @discovery_beacon_interval: interval (in TUs) for discovery beacons. Must be
+ * greater than 0 when @instant_comm is true.
* @enable_dw_notification: flag to enable/disable discovery window
* notifications.
+ * @instant_comm: if true, start Instant Communication (IC) as defined in
+ * Chapter 13 of the Wi-Fi Aware Specification v4.0.
* @band_cfgs: array of band specific configurations, indexed by
* &enum nl80211_band values.
* @extra_nan_attrs: pointer to additional NAN attributes.
@@ -4201,6 +4215,7 @@ struct cfg80211_nan_conf {
u16 scan_dwell_time;
u8 discovery_beacon_interval;
bool enable_dw_notification;
+ bool instant_comm;
struct cfg80211_nan_band_config band_cfgs[NUM_NL80211_BANDS];
const u8 *extra_nan_attrs;
u16 extra_nan_attrs_len;
@@ -4232,9 +4247,9 @@ struct cfg80211_nan_channel {
*
* This struct defines NAN local schedule parameters
*
- * @schedule: a mapping of time slots to chandef indexes in %nan_channels.
+ * @schedule: a mapping of time slots to chandef indexes in @nan_channels.
* An unscheduled slot will be set to %NL80211_NAN_SCHED_NOT_AVAIL_SLOT.
- * @n_channels: number of channel definitions in %nan_channels.
+ * @n_channels: number of channel definitions in @nan_channels.
* @nan_avail_blob: pointer to NAN Availability attribute blob.
* See %NL80211_ATTR_NAN_AVAIL_BLOB for more details.
* @nan_avail_blob_len: length of the @nan_avail_blob in bytes.
@@ -4257,6 +4272,21 @@ struct cfg80211_nan_local_sched {
};
/**
+ * struct cfg80211_nan_non_evac_channels - NAN non-evacuable channels
+ *
+ * This struct defines the set of NAN local schedule channels that must not
+ * be evacuated for concurrent operations.
+ *
+ * @n_channels: number of channel definitions in @chandefs.
+ * @chandefs: array of channel definitions that must not be evacuated. Each
+ * must match a channel of the current local schedule.
+ */
+struct cfg80211_nan_non_evac_channels {
+ u8 n_channels;
+ struct cfg80211_chan_def chandefs[] __counted_by(n_channels);
+};
+
+/**
* struct cfg80211_nan_peer_map - NAN peer schedule map
*
* This struct defines a single NAN peer schedule map
@@ -4920,6 +4950,9 @@ struct mgmt_frame_regs {
* @start_ap: Start acting in AP mode defined by the parameters.
* @change_beacon: Change the beacon parameters for an access point mode
* interface. This should reject the call when AP mode wasn't started.
+ * @update_beacon: Update the beacon and other templates like @change_beacon,
+ * but called without the wiphy mutex held. May return -EAGAIN to have
+ * it fall back to @change_beacon with the wiphy mutex held.
* @stop_ap: Stop being an AP, including stopping beaconing.
*
* @add_station: Add a new station.
@@ -4930,7 +4963,13 @@ struct mgmt_frame_regs {
* them, also against the existing state! Drivers must call
* cfg80211_check_station_change() to validate the information.
* @get_station: get station information for the station identified by @mac
+ * @get_station_unlocked: Like @get_station, but called without the wiphy
+ * mutex. Return -EAGAIN to get @get_station called with the wiphy mutex
+ * held instead.
* @dump_station: dump station callback -- resume dump at index @idx
+ * @dump_station_unlocked: Like @dump_station, but called without the wiphy
+ * mutex. Return -EAGAIN to get @dump_station called with the wiphy mutex
+ * held instead.
*
* @add_mpath: add a fixed mesh path
* @del_mpath: delete a given mesh path
@@ -5054,6 +5093,13 @@ struct mgmt_frame_regs {
* This allows the operation to be terminated prior to timeout based on
* the duration value.
* @mgmt_tx: Transmit a management frame.
+ * @mgmt_tx_unlocked: Like @mgmt_tx, but called without the wiphy mutex,
+ * currently limited to AP/GO/NAN. The driver may -EAGAIN to get
+ * @mgmt_tx with the wiphy mutex held for the same operation,
+ * although if the device is removed concurrently that might not
+ * happen and userspace sees -ENODEV.
+ * Note this cannot acquire the wiphy mutex or RTNL, that would
+ * deadlock against unregistering the wdev.
* @mgmt_tx_cancel_wait: Cancel the wait time from transmitting a management
* frame on another channel
*
@@ -5109,7 +5155,10 @@ struct mgmt_frame_regs {
*
* @probe_peer: probe a connected peer (AP: STA MAC required; STA: no MAC),
* must use the @cookie as provided which is later passed to
- * cfg80211_probe_status().
+ * cfg80211_probe_status(). Called without the wiphy mutex, so the
+ * interface type may have changed/be changing and the MAC may be
+ * %NULL even in AP mode (if runtime type changes are supported),
+ * drivers must check for that.
*
* @set_noack_map: Set the NoAck Map for the TIDs.
*
@@ -5204,6 +5253,12 @@ struct mgmt_frame_regs {
* schedule, the full new schedule is provided - partial updates are not
* supported, and the new schedule completely replaces the previous one.
*
+ * @nan_set_non_evac_channels: set the list of local schedule channels that
+ * must not be evacuated for concurrent operations. The provided list
+ * replaces the previous set; channels of the current schedule that are
+ * not included become evacuable again. All provided channels are
+ * guaranteed by cfg80211 to belong to the current local schedule.
+ *
* @set_multicast_to_unicast: configure multicast to unicast conversion for BSS
*
* @get_txq_stats: Get TXQ stats for interface or phy. If wdev is %NULL, this
@@ -5222,6 +5277,7 @@ struct mgmt_frame_regs {
* @tx_control_port: TX a control port frame (EAPoL). The noencrypt parameter
* tells the driver that the frame should not be encrypted. A @cookie
* value of 0 means the caller does not want TX status reporting.
+ * Called without the wiphy mutex.
*
* @get_ftm_responder_stats: Retrieve FTM responder statistics, if available.
* Statistics should be cumulative, currently no way to reset is provided.
@@ -5302,14 +5358,17 @@ struct cfg80211_ops {
unsigned int link_id);
int (*add_key)(struct wiphy *wiphy, struct wireless_dev *wdev,
- int link_id, u8 key_index, bool pairwise,
+ int link_id, u8 key_index,
+ enum nl80211_key_type type,
const u8 *mac_addr, struct key_params *params);
int (*get_key)(struct wiphy *wiphy, struct wireless_dev *wdev,
- int link_id, u8 key_index, bool pairwise,
+ int link_id, u8 key_index,
+ enum nl80211_key_type type,
const u8 *mac_addr, void *cookie,
void (*callback)(void *cookie, struct key_params*));
int (*del_key)(struct wiphy *wiphy, struct wireless_dev *wdev,
- int link_id, u8 key_index, bool pairwise,
+ int link_id, u8 key_index,
+ enum nl80211_key_type type,
const u8 *mac_addr);
int (*set_default_key)(struct wiphy *wiphy,
struct net_device *netdev, int link_id,
@@ -5326,6 +5385,8 @@ struct cfg80211_ops {
struct cfg80211_ap_settings *settings);
int (*change_beacon)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_ap_update *info);
+ int (*update_beacon)(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_ap_update *info);
int (*stop_ap)(struct wiphy *wiphy, struct net_device *dev,
unsigned int link_id);
@@ -5340,8 +5401,16 @@ struct cfg80211_ops {
struct station_parameters *params);
int (*get_station)(struct wiphy *wiphy, struct wireless_dev *wdev,
const u8 *mac, struct station_info *sinfo);
+ int (*get_station_unlocked)(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const u8 *mac,
+ struct station_info *sinfo);
int (*dump_station)(struct wiphy *wiphy, struct wireless_dev *wdev,
int idx, u8 *mac, struct station_info *sinfo);
+ int (*dump_station_unlocked)(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ int idx, u8 *mac,
+ struct station_info *sinfo);
int (*add_mpath)(struct wiphy *wiphy, struct net_device *dev,
const u8 *dst, const u8 *next_hop);
@@ -5466,6 +5535,10 @@ struct cfg80211_ops {
int (*mgmt_tx)(struct wiphy *wiphy, struct wireless_dev *wdev,
struct cfg80211_mgmt_tx_params *params,
u64 cookie);
+ int (*mgmt_tx_unlocked)(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ struct cfg80211_mgmt_tx_params *params,
+ u64 cookie);
int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy,
struct wireless_dev *wdev,
u64 cookie);
@@ -5590,6 +5663,9 @@ struct cfg80211_ops {
int (*nan_set_peer_sched)(struct wiphy *wiphy,
struct wireless_dev *wdev,
struct cfg80211_nan_peer_sched *sched);
+ int (*nan_set_non_evac_channels)(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ struct cfg80211_nan_non_evac_channels *channels);
int (*set_multicast_to_unicast)(struct wiphy *wiphy,
struct net_device *dev,
const bool enabled);
@@ -6043,6 +6119,8 @@ struct wiphy_vendor_command {
* @eml_capabilities: EML capabilities (for MLO)
* @mld_capa_and_ops: MLD capabilities and operations (for MLO)
* @ext_mld_capa_and_ops: Extended MLD capabilities and operations (for MLO)
+ * @cip_supported: CIP is supported and the capabilities are valid
+ * @cip_capabilities: CIP Capabilities element containing the MIC padding delay
*/
struct wiphy_iftype_ext_capab {
enum nl80211_iftype iftype;
@@ -6052,6 +6130,8 @@ struct wiphy_iftype_ext_capab {
u16 eml_capabilities;
u16 mld_capa_and_ops;
u16 ext_mld_capa_and_ops;
+ bool cip_supported;
+ u8 cip_capabilities;
};
/**
@@ -6266,10 +6346,13 @@ struct wiphy_radio {
* @WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC: Device supports NAN configurable
* synchronization.
* @WIPHY_NAN_FLAGS_USERSPACE_DE: Device doesn't support DE offload.
+ * @WIPHY_NAN_FLAGS_INSTANT_COMM: Device can switch to Instant Communication
+ * (IC) mode. Can only be set along with %WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC.
*/
enum wiphy_nan_flags {
WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC = BIT(0),
WIPHY_NAN_FLAGS_USERSPACE_DE = BIT(1),
+ WIPHY_NAN_FLAGS_INSTANT_COMM = BIT(2),
};
/**
@@ -6314,7 +6397,8 @@ struct wiphy_nan_capa {
* @mtx: mutex for the data (structures) of this device
* @reg_notifier: the driver's regulatory notification callback,
* note that if your driver uses wiphy_apply_custom_regulatory()
- * the reg_notifier's request can be passed as NULL
+ * the reg_notifier's request can be passed as NULL.
+ * This is called under wiphy mutex.
* @regd: the driver's regulatory domain, if one was requested via
* the regulatory_hint() API. This can be used by the driver
* on the reg_notifier() if it chooses to ignore future
@@ -7172,6 +7256,9 @@ enum ieee80211_ap_reg_power {
* @netdev: (private) Used to reference back to the netdev, may be %NULL
* @identifier: (private) Identifier used in nl80211 to identify this
* wireless device if it has no netdev
+ * @refcnt: (private) references held by nl80211 if there's no netdev,
+ * to ensure cfg80211_unregister_wdev() cannot return while
+ * unlocked ops are running
* @u: union containing data specific to @iftype
* @connected: indicates if connected or not (STA mode)
* @wext: (private) Used by the internal wireless extensions compat code
@@ -7194,8 +7281,9 @@ enum ieee80211_ap_reg_power {
* @mgmt_registrations_need_update: mgmt registrations were updated,
* need to propagate the update to the driver
* @address: The address for this device, valid only if @netdev is %NULL
- * @is_running: true if this is a non-netdev device that has been started, e.g.
- * the P2P Device.
+ * @is_running: true if the device has been started, e.g. the P2P Device;
+ * for netdevs, tracked under the wiphy mutex from NETDEV_UP until
+ * NETDEV_GOING_DOWN
* @ps: powersave mode is enabled
* @ps_timeout: dynamic powersave timeout
* @unexpected_nlportid: (private) netlink port ID of application
@@ -7236,6 +7324,7 @@ struct wireless_dev {
struct net_device *netdev;
u32 identifier;
+ refcount_t refcnt;
struct list_head mgmt_registrations;
u8 mgmt_registrations_need_update:1;
@@ -7332,6 +7421,8 @@ struct wireless_dev {
union {
struct {
unsigned int beacon_interval;
+ enum ieee80211_ap_reg_power reg_power;
+ enum ieee80211_ap_reg_power csa_reg_power;
struct cfg80211_chan_def chandef;
} ap;
struct {
@@ -7357,8 +7448,6 @@ static inline const u8 *wdev_address(struct wireless_dev *wdev)
static inline bool wdev_running(struct wireless_dev *wdev)
{
- if (wdev->netdev)
- return netif_running(wdev->netdev);
return wdev->is_running;
}
@@ -7817,7 +7906,8 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb,
* byte array to match.
*/
const struct element *
-cfg80211_find_elem_match(u8 eid, const u8 *ies, unsigned int len,
+cfg80211_find_elem_match(enum ieee80211_eid eid,
+ const u8 *ies, unsigned int len,
const u8 *match, unsigned int match_len,
unsigned int match_offset);
@@ -7846,7 +7936,7 @@ cfg80211_find_elem_match(u8 eid, const u8 *ies, unsigned int len,
* byte array to match.
*/
static inline const u8 *
-cfg80211_find_ie_match(u8 eid, const u8 *ies, unsigned int len,
+cfg80211_find_ie_match(enum ieee80211_eid eid, const u8 *ies, unsigned int len,
const u8 *match, unsigned int match_len,
unsigned int match_offset)
{
@@ -7879,7 +7969,7 @@ cfg80211_find_ie_match(u8 eid, const u8 *ies, unsigned int len,
* having to fit into the given data.
*/
static inline const struct element *
-cfg80211_find_elem(u8 eid, const u8 *ies, int len)
+cfg80211_find_elem(enum ieee80211_eid eid, const u8 *ies, int len)
{
return cfg80211_find_elem_match(eid, ies, len, NULL, 0, 0);
}
@@ -7899,7 +7989,8 @@ cfg80211_find_elem(u8 eid, const u8 *ies, int len)
* Note: There are no checks on the element length other than
* having to fit into the given data.
*/
-static inline const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len)
+static inline const u8 *cfg80211_find_ie(enum ieee80211_eid eid,
+ const u8 *ies, int len)
{
return cfg80211_find_ie_match(eid, ies, len, NULL, 0, 0);
}
@@ -7920,10 +8011,13 @@ static inline const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len)
* having to fit into the given data.
*/
static inline const struct element *
-cfg80211_find_ext_elem(u8 ext_eid, const u8 *ies, int len)
+cfg80211_find_ext_elem(enum ieee80211_eid_ext ext_eid,
+ const u8 *ies, int len)
{
+ u8 _ext_eid = ext_eid;
+
return cfg80211_find_elem_match(WLAN_EID_EXTENSION, ies, len,
- &ext_eid, 1, 0);
+ &_ext_eid, 1, 0);
}
/**
@@ -8106,9 +8200,9 @@ int regulatory_set_wiphy_regd(struct wiphy *wiphy,
* @wiphy: the wireless device we want to process the regulatory domain on
* @rd: the regulatory domain information to use for this wiphy
*
- * This functions requires the RTNL and the wiphy mutex to be held and
- * applies the new regdomain synchronously to this wiphy. For more details
- * see regulatory_set_wiphy_regd().
+ * This functions requires the wiphy mutex to be held and applies the new
+ * regdomain synchronously to this wiphy. For more details see
+ * regulatory_set_wiphy_regd().
*
* Return: 0 on success. -EINVAL, -EPERM
*/
@@ -8143,6 +8237,8 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
* it wants to follow we respect that unless a country IE has been received
* and processed already.
*
+ * Must be called within an RCU read-side critical section.
+ *
* Return: A valid pointer, or, when an error occurs, for example if no rule
* can be found, the return value is encoded using ERR_PTR(). Use IS_ERR() to
* check and PTR_ERR() to obtain the numeric return value. The numeric return
@@ -8181,20 +8277,20 @@ bool regulatory_pre_cac_allowed(struct wiphy *wiphy);
*/
/**
- * reg_query_regdb_wmm - Query internal regulatory db for wmm rule
- * Regulatory self-managed driver can use it to proactively
- *
+ * reg_query_regdb_wmm - Query internal regulatory db for WMM rules
* @alpha2: the ISO/IEC 3166 alpha2 wmm rule to be queried.
* @freq: the frequency (in MHz) to be queried.
- * @rule: pointer to store the wmm rule from the regulatory db.
+ * @rule: pointer to store the WMM rule from the regulatory db.
*
- * Self-managed wireless drivers can use this function to query
+ * Self-managed wireless drivers can use this function to query
* the internal regulatory database to check whether the given
- * ISO/IEC 3166 alpha2 country and freq have wmm rule limitations.
+ * ISO/IEC 3166 alpha2 country and freq have WMM rule limitations.
*
* Drivers should check the return value, its possible you can get
* an -ENODATA.
*
+ * This uses RCU internally so can be called in just about any context.
+ *
* Return: 0 on success. -ENODATA.
*/
int reg_query_regdb_wmm(char *alpha2, int freq,
@@ -9501,6 +9597,7 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
* @flags: flags, as defined in &enum nl80211_rxmgmt_flags
* @rx_tstamp: Hardware timestamp of frame RX in nanoseconds
* @ack_tstamp: Hardware timestamp of ack TX in nanoseconds
+ * @no_sta: set if no station is known for the frame (relevant for MLD)
*/
struct cfg80211_rx_info {
int freq;
@@ -9512,6 +9609,7 @@ struct cfg80211_rx_info {
u32 flags;
u64 rx_tstamp;
u64 ack_tstamp;
+ bool no_sta;
};
/**
@@ -9752,6 +9850,7 @@ void cfg80211_cqm_beacon_loss_notify(struct net_device *dev, gfp_t gfp);
* @gfp: context flags
*
* This function is called when a radar is detected on the current chanenl.
+ * Must be called with the wiphy mutex held.
*/
void __cfg80211_radar_event(struct wiphy *wiphy,
struct cfg80211_chan_def *chandef,
@@ -9797,7 +9896,7 @@ void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
*
* This function is called when a Channel availability check (CAC) is finished
* or aborted. This must be called to notify the completion of a CAC process,
- * also by full-MAC drivers.
+ * also by full-MAC drivers. Must be called with the wiphy mutex held.
*/
void cfg80211_cac_event(struct net_device *netdev,
const struct cfg80211_chan_def *chandef,
@@ -10109,6 +10208,9 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate);
* when the driver wishes to unregister the wdev, e.g. when the hardware device
* is unbound from the driver.
*
+ * Note that unlocked operations can run concurrently until this returns, so be
+ * careful about ordering.
+ *
* Context: Requires the RTNL and wiphy mutex to be held.
*/
void cfg80211_unregister_wdev(struct wireless_dev *wdev);
diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h
index 76d2cd2e2b30..2c5dcf6a106f 100644
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -376,6 +376,7 @@ struct cfg802154_mac_pkt {
struct list_head node;
struct sk_buff *skb;
struct ieee802154_sub_if_data *sdata;
+ netdevice_tracker dev_tracker;
u8 page;
u8 channel;
};
@@ -457,15 +458,16 @@ struct ieee802154_llsec_device_key {
u32 frame_counter;
};
-struct wpan_dev_header_ops {
+struct wpan_dev_ops {
/* TODO create callback currently assumes ieee802154_mac_cb inside
* skb->cb. This should be changed to give these information as
* parameter.
*/
- int (*create)(struct sk_buff *skb, struct net_device *dev,
+ int (*header_create)(struct sk_buff *skb, struct net_device *dev,
const struct ieee802154_addr *daddr,
const struct ieee802154_addr *saddr,
unsigned int len);
+ int (*ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd);
};
struct wpan_dev {
@@ -476,7 +478,7 @@ struct wpan_dev {
struct list_head list;
struct net_device *netdev;
- const struct wpan_dev_header_ops *header_ops;
+ const struct wpan_dev_ops *ops;
/* lowpan interface, set when the wpan_dev belongs to one lowpan_dev */
struct net_device *lowpan_dev;
@@ -522,7 +524,7 @@ wpan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
{
struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
- return wpan_dev->header_ops->create(skb, dev, daddr, saddr, len);
+ return wpan_dev->ops->header_create(skb, dev, daddr, saddr, len);
}
#endif
diff --git a/include/net/codel.h b/include/net/codel.h
index aa80f744826c..183d43c2bd43 100644
--- a/include/net/codel.h
+++ b/include/net/codel.h
@@ -140,6 +140,11 @@ struct codel_vars {
/* needed shift to get a Q0.32 number from rec_inv_sqrt */
#define REC_INV_SQRT_SHIFT (32 - REC_INV_SQRT_BITS)
+/* Cap on drops per codel_dequeue() call: the loop's work depends on the
+ * idle gap and backlog, both outside our control; resync when exceeded.
+ */
+#define CODEL_MAX_DROPS_PER_DEQUEUE 256
+
/**
* struct codel_stats - contains codel shared variables and stats
* @maxpacket: largest packet we've seen so far
diff --git a/include/net/codel_impl.h b/include/net/codel_impl.h
index 2c1f0ec309e9..8f26132d45b7 100644
--- a/include/net/codel_impl.h
+++ b/include/net/codel_impl.h
@@ -93,12 +93,17 @@ static void codel_Newton_step(struct codel_vars *vars)
* CoDel control_law is t + interval/sqrt(count)
* We maintain in rec_inv_sqrt the reciprocal value of sqrt(count) to avoid
* both sqrt() and divide operation.
+ *
+ * Clamp the increment to at least 1 tick: a very small interval (or a
+ * large count) can truncate it to zero, stalling the dropping loop.
*/
static codel_time_t codel_control_law(codel_time_t t,
codel_time_t interval,
u32 rec_inv_sqrt)
{
- return t + reciprocal_scale(interval, rec_inv_sqrt << REC_INV_SQRT_SHIFT);
+ return t + max_t(u32, 1,
+ reciprocal_scale(interval,
+ rec_inv_sqrt << REC_INV_SQRT_SHIFT));
}
static bool codel_should_drop(const struct sk_buff *skb,
@@ -154,6 +159,7 @@ static struct sk_buff *codel_dequeue(void *ctx,
codel_skb_dequeue_t dequeue_func)
{
struct sk_buff *skb = dequeue_func(vars, ctx);
+ unsigned int drops = 0;
codel_time_t now;
bool drop;
@@ -180,6 +186,14 @@ static struct sk_buff *codel_dequeue(void *ctx,
*/
while (vars->dropping &&
codel_time_after_eq(now, vars->drop_next)) {
+ if (++drops > CODEL_MAX_DROPS_PER_DEQUEUE) {
+ /* fell far behind the schedule */
+ WRITE_ONCE(vars->drop_next,
+ codel_control_law(now,
+ params->interval,
+ vars->rec_inv_sqrt));
+ break;
+ }
/* dont care of possible wrap
* since there is no more divide.
*/
diff --git a/include/net/dropreason-core.h b/include/net/dropreason-core.h
index 2f312d1f67d6..fa2fe8990557 100644
--- a/include/net/dropreason-core.h
+++ b/include/net/dropreason-core.h
@@ -82,7 +82,6 @@
FN(DEV_READY) \
FN(FULL_RING) \
FN(NOMEM) \
- FN(HDR_TRUNC) \
FN(TAP_FILTER) \
FN(TAP_TXFILTER) \
FN(ICMP_CSUM) \
@@ -93,6 +92,7 @@
FN(IP_INVALID_SOURCE) \
FN(IP_LOCALNET) \
FN(IP_INVALID_DEST) \
+ FN(IP_TTL_EXCEEDED) \
FN(PKT_TOO_BIG) \
FN(DUP_FRAG) \
FN(FRAG_REASM_TIMEOUT) \
@@ -110,8 +110,8 @@
FN(PACKET_SOCK_ERROR) \
FN(TC_CHAIN_NOTFOUND) \
FN(TC_RECLASSIFY_LOOP) \
- FN(VXLAN_INVALID_HDR) \
- FN(VXLAN_VNI_NOT_FOUND) \
+ FN(TUNNEL_INVALID_HDR) \
+ FN(TUNNEL_NOT_FOUND) \
FN(MAC_INVALID_SOURCE) \
FN(VXLAN_ENTRY_EXISTS) \
FN(NO_TX_TARGET) \
@@ -427,12 +427,6 @@ enum skb_drop_reason {
/** @SKB_DROP_REASON_NOMEM: error due to OOM */
SKB_DROP_REASON_NOMEM,
/**
- * @SKB_DROP_REASON_HDR_TRUNC: failed to trunc/extract the header from
- * networking data, e.g., failed to pull the protocol header from
- * frags via pskb_may_pull()
- */
- SKB_DROP_REASON_HDR_TRUNC,
- /**
* @SKB_DROP_REASON_TAP_FILTER: dropped by (ebpf) filter directly attached
* to tun/tap, e.g., via TUNSETFILTEREBPF
*/
@@ -475,6 +469,11 @@ enum skb_drop_reason {
*/
SKB_DROP_REASON_IP_INVALID_DEST,
/**
+ * @SKB_DROP_REASON_IP_TTL_EXCEEDED: IPv4 TTL or IPv6 hop limit <= 1
+ * (see IPSTATS_MIB_INHDRERRORS)
+ */
+ SKB_DROP_REASON_IP_TTL_EXCEEDED,
+ /**
* @SKB_DROP_REASON_PKT_TOO_BIG: packet size is too big (maybe exceed the
* MTU)
*/
@@ -533,13 +532,16 @@ enum skb_drop_reason {
*/
SKB_DROP_REASON_TC_RECLASSIFY_LOOP,
/**
- * @SKB_DROP_REASON_VXLAN_INVALID_HDR: VXLAN header is invalid. E.g.:
- * 1) reserved fields are not zero
- * 2) "I" flag is not set
+ * @SKB_DROP_REASON_TUNNEL_INVALID_HDR: tunnel header is invalid. E.g.:
+ * 1) VXLAN reserved fields are not zero
+ * 2) VXLAN "I" flag is not set
*/
- SKB_DROP_REASON_VXLAN_INVALID_HDR,
- /** @SKB_DROP_REASON_VXLAN_VNI_NOT_FOUND: no VXLAN device found for VNI */
- SKB_DROP_REASON_VXLAN_VNI_NOT_FOUND,
+ SKB_DROP_REASON_TUNNEL_INVALID_HDR,
+ /**
+ * @SKB_DROP_REASON_TUNNEL_NOT_FOUND: no tunnel device found for the
+ * packet, e.g. no VXLAN device for its VNI
+ */
+ SKB_DROP_REASON_TUNNEL_NOT_FOUND,
/** @SKB_DROP_REASON_MAC_INVALID_SOURCE: source mac is invalid */
SKB_DROP_REASON_MAC_INVALID_SOURCE,
/**
@@ -604,7 +606,11 @@ enum skb_drop_reason {
SKB_DROP_REASON_PSP_INPUT,
/** @SKB_DROP_REASON_PSP_OUTPUT: PSP output checks failed */
SKB_DROP_REASON_PSP_OUTPUT,
- /** @SKB_DROP_REASON_RECURSION_LIMIT: Dead loop on virtual device. */
+ /**
+ * @SKB_DROP_REASON_RECURSION_LIMIT: Dead loop on virtual device, e.g. a
+ * tunnel whose route to its remote end goes out of the tunnel device
+ * itself.
+ */
SKB_DROP_REASON_RECURSION_LIMIT,
/**
* @SKB_DROP_REASON_MAX: the maximum of core drop reasons, which
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 7507d632e7c6..5d12191b6f6f 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -61,6 +61,7 @@ struct tc_action;
#define DSA_TAG_PROTO_NETC_VALUE 33
#define DSA_TAG_PROTO_KSZ8463_VALUE 34
#define DSA_TAG_PROTO_MT7628_VALUE 35
+#define DSA_TAG_PROTO_KS8995_VALUE 36
enum dsa_tag_protocol {
DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE,
@@ -99,6 +100,7 @@ enum dsa_tag_protocol {
DSA_TAG_PROTO_NETC = DSA_TAG_PROTO_NETC_VALUE,
DSA_TAG_PROTO_KSZ8463 = DSA_TAG_PROTO_KSZ8463_VALUE,
DSA_TAG_PROTO_MT7628 = DSA_TAG_PROTO_MT7628_VALUE,
+ DSA_TAG_PROTO_KS8995 = DSA_TAG_PROTO_KS8995_VALUE,
};
struct dsa_switch;
diff --git a/include/net/dst.h b/include/net/dst.h
index 307073eae7f8..dbedfe72e1fd 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -455,7 +455,8 @@ static inline unsigned int dst_dev_overhead(struct dst_entry *dst,
struct sk_buff *skb)
{
if (likely(dst))
- return LL_RESERVED_SPACE(dst->dev);
+ return max_t(unsigned int, skb->mac_len,
+ LL_RESERVED_SPACE(dst->dev));
return skb->mac_len;
}
diff --git a/include/net/gso.h b/include/net/gso.h
index 29975440cad5..fe3260b381d4 100644
--- a/include/net/gso.h
+++ b/include/net/gso.h
@@ -19,10 +19,20 @@ struct skb_gso_cb {
int encap_level;
__wsum csum;
__u16 csum_start;
+ /* Number of IPv4/IPv6 GSO handler entries for this packet. */
+ u8 recursion_counter;
+ /* Max MSS segs per output skb, 0 = no limit */
+ u8 max_segs;
};
#define SKB_GSO_CB_OFFSET 32
#define SKB_GSO_CB(skb) ((struct skb_gso_cb *)((skb)->cb + SKB_GSO_CB_OFFSET))
+static inline bool gso_recursion_inc_test(struct sk_buff *skb,
+ unsigned int limit)
+{
+ return ++SKB_GSO_CB(skb)->recursion_counter > limit;
+}
+
static inline int skb_tnl_header_len(const struct sk_buff *inner_skb)
{
return (skb_mac_header(inner_skb) - inner_skb->head) -
@@ -75,12 +85,13 @@ static inline __sum16 gso_make_checksum(struct sk_buff *skb, __wsum res)
}
struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
- netdev_features_t features, bool tx_path);
+ netdev_features_t features, bool tx_path,
+ unsigned int max_segs);
static inline struct sk_buff *skb_gso_segment(struct sk_buff *skb,
netdev_features_t features)
{
- return __skb_gso_segment(skb, features, true);
+ return __skb_gso_segment(skb, features, true, 0);
}
struct sk_buff *skb_eth_gso_segment(struct sk_buff *skb,
diff --git a/include/net/gue.h b/include/net/gue.h
index caefd6da8693..d377155fd0b3 100644
--- a/include/net/gue.h
+++ b/include/net/gue.h
@@ -84,8 +84,9 @@ static inline size_t guehdr_priv_flags_len(__be32 flags)
}
/* Validate standard and private flags. Returns non-zero (meaning invalid)
- * if there is an unknown standard or private flags, or the options length for
- * the flags exceeds the options length specific in hlen of the GUE header.
+ * if there is an unknown standard or private flags, if the options length for
+ * the flags exceeds the options length specified in hlen of the GUE header, or
+ * if a private option contains invalid data.
*/
static inline int validate_gue_flags(struct guehdr *guehdr, size_t optlen)
{
@@ -103,8 +104,8 @@ static inline int validate_gue_flags(struct guehdr *guehdr, size_t optlen)
/* Private flags are last four bytes accounted in
* guehdr_flags_len
*/
- __be32 pflags = *(__be32 *)((void *)&guehdr[1] +
- len - GUE_LEN_PRIV);
+ void *data = (void *)&guehdr[1] + len;
+ __be32 pflags = *(__be32 *)(data - GUE_LEN_PRIV);
if (pflags & ~GUE_PFLAGS_ALL)
return 1;
@@ -112,6 +113,16 @@ static inline int validate_gue_flags(struct guehdr *guehdr, size_t optlen)
len += guehdr_priv_flags_len(pflags);
if (len > optlen)
return 1;
+
+ if (pflags & GUE_PFLAG_REMCSUM) {
+ __be16 *pd = data;
+
+ /* The field offset pd[1] must not be less
+ * than the start pd[0].
+ */
+ if (ntohs(pd[1]) < ntohs(pd[0]))
+ return 1;
+ }
}
return 0;
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
index 8bbaf77da7cf..782c3dcd8b52 100644
--- a/include/net/ieee80211_radiotap.h
+++ b/include/net/ieee80211_radiotap.h
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2017 Intel Deutschland GmbH
- * Copyright (c) 2018-2019, 2021-2022, 2025 Intel Corporation
+ * Copyright (c) 2018-2019, 2021-2022, 2025-2026 Intel Corporation
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -93,6 +93,7 @@ enum ieee80211_radiotap_presence {
IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE = 29,
IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30,
IEEE80211_RADIOTAP_EXT = 31,
+ IEEE80211_RADIOTAP_S1G = 32,
IEEE80211_RADIOTAP_EHT_USIG = 33,
IEEE80211_RADIOTAP_EHT = 34,
IEEE80211_RADIOTAP_UHR_ELR = 37,
@@ -112,6 +113,9 @@ enum ieee80211_radiotap_flags {
/* for IEEE80211_RADIOTAP_CHANNEL */
enum ieee80211_radiotap_channel_flags {
+ IEEE80211_CHAN_700MHZ = 0x0001,
+ IEEE80211_CHAN_800MHZ = 0x0002,
+ IEEE80211_CHAN_900MHZ = 0x0004,
IEEE80211_CHAN_CCK = 0x0020,
IEEE80211_CHAN_OFDM = 0x0040,
IEEE80211_CHAN_2GHZ = 0x0080,
@@ -592,7 +596,7 @@ enum ieee80211_radiotap_eht_usig_mu {
enum ieee80211_radiotap_eht_usig_tb {
/* TB-USIG-1 */
- IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD = 0x0000001f,
+ IEEE80211_RADIOTAP_EHT_USIG1_TB_B20_B25_DISREGARD = 0x0000003f,
/* TB-USIG-2 */
IEEE80211_RADIOTAP_EHT_USIG2_TB_B0_B1_PPDU_TYPE = 0x000000c0,
@@ -604,6 +608,49 @@ enum ieee80211_radiotap_eht_usig_tb {
IEEE80211_RADIOTAP_EHT_USIG2_TB_B20_B25_TAIL = 0xfc000000,
};
+enum ieee80211_radiotap_uhr_usig_mu {
+ /* USIG-1 */
+ IEEE80211_RADIOTAP_UHR_USIG1_MU_BSS_COLOR_2 = 0x0000003f,
+ IEEE80211_RADIOTAP_UHR_USIG1_MU_B20_B24_DISREGARD = 0x0000001f,
+ IEEE80211_RADIOTAP_UHR_USIG1_MU_B25_VALIDATE = 0x00000020,
+ /* USIG-2 */
+ IEEE80211_RADIOTAP_UHR_USIG2_MU_B0_B1_PPDU_TYPE = 0x000000c0,
+ IEEE80211_RADIOTAP_UHR_USIG2_MU_B2_COBF_COSR = 0x00000100,
+ IEEE80211_RADIOTAP_UHR_USIG2_MU_B3_B7_PUNCTURED_INFO = 0x00003e00,
+ IEEE80211_RADIOTAP_UHR_USIG2_MU_B8_VALIDATE = 0x00004000,
+ IEEE80211_RADIOTAP_UHR_USIG2_MU_B9_B10_SIG_MCS = 0x00018000,
+ IEEE80211_RADIOTAP_UHR_USIG2_MU_B11_B15_UHR_SIG_SYMBOLS = 0x003e0000,
+ IEEE80211_RADIOTAP_UHR_USIG2_MU_B16_B19_CRC = 0x03c00000,
+ IEEE80211_RADIOTAP_UHR_USIG2_MU_B20_B25_TAIL = 0xfc000000,
+};
+
+enum ieee80211_radiotap_uhr_usig_tb {
+ /* USIG-1 */
+ IEEE80211_RADIOTAP_UHR_USIG1_TB_B20_B25_DISREGARD = 0x0000003f,
+
+ /* USIG-2 */
+ IEEE80211_RADIOTAP_UHR_USIG2_TB_B0_B1_PPDU_TYPE = 0x000000c0,
+ IEEE80211_RADIOTAP_UHR_USIG2_TB_B2_VALIDATE = 0x00000100,
+ IEEE80211_RADIOTAP_UHR_USIG2_TB_B3_B6_SPATIAL_REUSE_1 = 0x00001e00,
+ IEEE80211_RADIOTAP_UHR_USIG2_TB_B7_B10_SPATIAL_REUSE_2 = 0x0001e000,
+ IEEE80211_RADIOTAP_UHR_USIG2_TB_B11_B15_DISREGARD = 0x003e0000,
+ IEEE80211_RADIOTAP_UHR_USIG2_TB_B16_B19_CRC = 0x03c00000,
+ IEEE80211_RADIOTAP_UHR_USIG2_TB_B20_B25_TAIL = 0xfc000000,
+};
+
+enum ieee80211_radiotap_uhr_usig_elr {
+ /* USIG-1 */
+ IEEE80211_RADIOTAP_UHR_USIG1_ELR_B20_B24_DISREGARD = 0x0000001f,
+ IEEE80211_RADIOTAP_UHR_USIG1_ELR_B25_VALIDATE = 0x00000020,
+
+ /* USIG-2 */
+ IEEE80211_RADIOTAP_UHR_USIG2_ELR_B0_B1_PPDU_TYPE = 0x000000c0,
+ IEEE80211_RADIOTAP_UHR_USIG2_ELR_B2_B12_STA_ID = 0x0007ff00,
+ IEEE80211_RADIOTAP_UHR_USIG2_ELR_B13_B15_VALIDATE = 0x00380000,
+ IEEE80211_RADIOTAP_UHR_USIG2_ELR_B16_B19_CRC = 0x03c00000,
+ IEEE80211_RADIOTAP_UHR_USIG2_ELR_B20_B25_TAIL = 0xfc000000,
+};
+
/*
* ieee80211_radiotap_uhr_elr - content of UHR-ELR TLV (type 37)
* see https://www.radiotap.org/fields/UHR-ELR for details
@@ -792,6 +839,68 @@ enum ieee80211_radiotap_uhr_user_info {
IEEE80211_RADIOTAP_UHR_USER_INFO_2X_LDPC = 0x02000000,
};
+/*
+ * ieee80211_radiotap_s1g - content of S1G TLV (type 32)
+ * see www.radiotap.org/fields/S1G.html for details
+ */
+struct ieee80211_radiotap_s1g {
+ __le16 known;
+ __le16 data1;
+ __le16 data2;
+} __packed;
+
+enum ieee80211_radiotap_s1g_known {
+ IEEE80211_RADIOTAP_S1G_KNOWN_PPDU_FORMAT = 0x0001,
+ IEEE80211_RADIOTAP_S1G_KNOWN_RESPONSE_IND = 0x0002,
+ IEEE80211_RADIOTAP_S1G_KNOWN_GI = 0x0004,
+ IEEE80211_RADIOTAP_S1G_KNOWN_NSS = 0x0008,
+ IEEE80211_RADIOTAP_S1G_KNOWN_BW = 0x0010,
+ IEEE80211_RADIOTAP_S1G_KNOWN_MCS = 0x0020,
+ IEEE80211_RADIOTAP_S1G_KNOWN_COLOR = 0x0040,
+ IEEE80211_RADIOTAP_S1G_KNOWN_UPLINK_IND = 0x0080,
+};
+
+enum ieee80211_radiotap_s1g_data1 {
+ IEEE80211_RADIOTAP_S1G_DATA1_PPDU_FORMAT = 0x0003,
+ IEEE80211_RADIOTAP_S1G_DATA1_RESPONSE_IND = 0x000c,
+ IEEE80211_RADIOTAP_S1G_DATA1_GI = 0x0020,
+ IEEE80211_RADIOTAP_S1G_DATA1_NSS = 0x00c0,
+ IEEE80211_RADIOTAP_S1G_DATA1_BW = 0x0f00,
+ IEEE80211_RADIOTAP_S1G_DATA1_MCS = 0xf000,
+};
+
+enum ieee80211_radiotap_s1g_data2 {
+ IEEE80211_RADIOTAP_S1G_DATA2_COLOR = 0x0007,
+ IEEE80211_RADIOTAP_S1G_DATA2_UPLINK_IND = 0x0008,
+ IEEE80211_RADIOTAP_S1G_DATA2_RSSI = 0xff00,
+};
+
+enum ieee80211_radiotap_s1g_ppdu_format {
+ IEEE80211_RADIOTAP_S1G_PPDU_FORMAT_1M = 0,
+ IEEE80211_RADIOTAP_S1G_PPDU_FORMAT_SHORT = 1,
+ IEEE80211_RADIOTAP_S1G_PPDU_FORMAT_LONG = 2,
+};
+
+enum ieee80211_radiotap_s1g_response_ind {
+ IEEE80211_RADIOTAP_S1G_RESPONSE_IND_NONE = 0,
+ IEEE80211_RADIOTAP_S1G_RESPONSE_IND_NDP = 1,
+ IEEE80211_RADIOTAP_S1G_RESPONSE_IND_NORMAL = 2,
+ IEEE80211_RADIOTAP_S1G_RESPONSE_IND_LONG = 3,
+};
+
+enum ieee80211_radiotap_s1g_gi {
+ IEEE80211_RADIOTAP_S1G_GI_LONG = 0,
+ IEEE80211_RADIOTAP_S1G_GI_SHORT = 1,
+};
+
+enum ieee80211_radiotap_s1g_bw {
+ IEEE80211_RADIOTAP_S1G_BW_1MHZ = 0,
+ IEEE80211_RADIOTAP_S1G_BW_2MHZ = 1,
+ IEEE80211_RADIOTAP_S1G_BW_4MHZ = 2,
+ IEEE80211_RADIOTAP_S1G_BW_8MHZ = 3,
+ IEEE80211_RADIOTAP_S1G_BW_16MHZ = 4,
+};
+
/**
* ieee80211_get_radiotap_len - get radiotap header length
* @data: pointer to the header
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index 433c2df23076..903499581db7 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -94,6 +94,7 @@ struct inet_connection_sock {
u32 icsk_rto_max;
__u32 icsk_delack_max;
__u32 icsk_pmtu_cookie;
+ unsigned char unhashed_state;
const struct tcp_congestion_ops *icsk_ca_ops;
const struct inet_connection_sock_af_ops *icsk_af_ops;
const struct tcp_ulp_ops *icsk_ulp_ops;
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index 365925c9d262..b02d2472b003 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -171,6 +171,7 @@ extern const u8 ip_frag_ecn_table[16];
#define IPFRAG_OK 0
#define IPFRAG_DUP 1
#define IPFRAG_OVERLAP 2
+#define IPFRAG_MIXED_SECPATH 3
int inet_frag_queue_insert(struct inet_frag_queue *q, struct sk_buff *skb,
int offset, int end);
void *inet_frag_reasm_prepare(struct inet_frag_queue *q, struct sk_buff *skb,
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index 7cdcbed3e5cb..24cbabc24582 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -207,7 +207,7 @@ struct rtable;
* @inet_saddr - Sending source
* @uc_ttl - Unicast TTL
* @inet_sport - Source port
- * @inet_id - ID counter for DF pkts
+ * @inet_id - ID counter for non atomic pkts
* @tos - TOS
* @mc_ttl - Multicasting TTL
* @uc_index - Unicast outgoing device index
diff --git a/include/net/ip.h b/include/net/ip.h
index 6f602df72ee6..0acc4ba5e5b3 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -74,6 +74,13 @@ static inline unsigned int ip_hdrlen(const struct sk_buff *skb)
return ip_hdr(skb)->ihl * 4;
}
+static inline int ip_check_csum_start(const struct sk_buff *skb)
+{
+ if (unlikely(skb->csum_start < skb->network_header + ip_hdrlen(skb)))
+ return -EINVAL;
+ return 0;
+}
+
struct ipcm_cookie {
struct sockcm_cookie sockc;
__be32 addr;
@@ -506,31 +513,6 @@ out:
return res;
}
-/* Configured/administrative MTU of a route, for advertising the TCP MSS.
- *
- * Unlike ip_dst_mtu_maybe_forward(), this deliberately ignores the
- * ICMP-learned path MTU (rt->rt_pmtu). The advertised MSS bounds what the
- * peer may send to us and must reflect our receive capability (the device or
- * route-configured MTU), not a path MTU learned on the reverse (send)
- * direction, which may not apply to the peer->us path and outlives the fnhe
- * for the whole connection. See RFC 2923 section 2.3 and the comment above
- * tcp_advertise_mss().
- */
-static inline unsigned int ip_dst_mtu_configured(const struct dst_entry *dst)
-{
- unsigned int mtu, res;
-
- rcu_read_lock();
- mtu = dst_metric_raw(dst, RTAX_MTU);
- if (!mtu)
- mtu = READ_ONCE(dst_dev_rcu(dst)->mtu);
- mtu = min_t(unsigned int, mtu, IP_MAX_MTU);
- res = mtu - lwtunnel_headroom(dst->lwtstate, mtu);
- rcu_read_unlock();
-
- return res;
-}
-
static inline unsigned int ip_skb_dst_mtu(struct sock *sk,
const struct sk_buff *skb)
{
@@ -584,6 +566,13 @@ static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb,
{
struct iphdr *iph = ip_hdr(skb);
+ /* RFC 6864: the IPv4 ID of atomic datagrams has no meaning.
+ * DF packets without ignore_df can not be fragmented.
+ */
+ if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) {
+ iph->id = 0;
+ return;
+ }
/* We had many attacks based on IPID, use the private
* generator as much as we can.
*/
@@ -598,17 +587,13 @@ static inline void ip_select_ident_segs(struct net *net, struct sk_buff *skb,
val = atomic_read(&inet_sk(sk)->inet_id);
atomic_set(&inet_sk(sk)->inet_id, val + segs);
} else {
- val = atomic_add_return(segs, &inet_sk(sk)->inet_id);
+ val = atomic_fetch_add(segs, &inet_sk(sk)->inet_id);
}
iph->id = htons(val);
return;
}
- if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) {
- iph->id = 0;
- } else {
- /* Unfortunately we need the big hammer to get a suitable IPID */
- __ip_select_ident(net, iph, segs);
- }
+ /* Unfortunately we need the big hammer to get a suitable IPID */
+ __ip_select_ident(net, iph, segs);
}
static inline void ip_select_ident(struct net *net, struct sk_buff *skb,
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index c69f1c871922..95f936be32c6 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -101,12 +101,12 @@ static inline struct dst_entry *ip6_route_output(struct net *net,
}
/* Only conditionally release dst if flags indicates
- * !RT6_LOOKUP_F_DST_NOREF or dst is in uncached_list.
+ * !RT6_LOOKUP_F_DST_NOREF or dst is uncached.
*/
static inline void ip6_rt_put_flags(struct rt6_info *rt, int flags)
{
if (!(flags & RT6_LOOKUP_F_DST_NOREF) ||
- !list_empty(&rt->dst.rt_uncached))
+ rt->dst.rt_uncached_list)
ip6_rt_put(rt);
}
@@ -231,6 +231,13 @@ void rt6_multipath_rebalance(struct fib6_info *f6i);
void rt6_uncached_list_add(struct rt6_info *rt);
void rt6_uncached_list_del(struct rt6_info *rt);
+#ifdef CONFIG_IPV6
+void rt6_uncached_list_flush_dev(struct net_device *dev);
+#else
+static inline void rt6_uncached_list_flush_dev(struct net_device *dev)
+{
+}
+#endif
static inline const struct rt6_info *skb_rt6_info(const struct sk_buff *skb)
{
@@ -384,43 +391,8 @@ static inline unsigned int ip6_dst_mtu_maybe_forward(const struct dst_entry *dst
rcu_read_unlock();
out:
- return mtu - lwtunnel_headroom(dst->lwtstate, mtu);
-}
-
-/* Configured/administrative MTU of a route, for advertising the TCP MSS.
- *
- * Unlike ip6_dst_mtu_maybe_forward(), this ignores any ICMPv6-learned path
- * MTU (which is kept on the RTF_CACHE exception route) and returns the MTU of
- * the underlying route (fib6_pmtu) or the egress device. The advertised MSS
- * bounds what the peer may send to us and must reflect our receive
- * capability, not a path MTU learned on the reverse (send) direction. See
- * RFC 2923 section 2.3 and the comment above tcp_advertise_mss().
- */
-static inline unsigned int ip6_dst_mtu_configured(const struct dst_entry *dst)
-{
- const struct rt6_info *rt = dst_rt6_info(dst);
- const struct fib6_info *from;
- struct inet6_dev *idev;
- unsigned int mtu = 0;
-
- rcu_read_lock();
- /* IPv6 keeps the learned PMTU and the configured MTU in the same
- * RTAX_MTU slot: the learned value sits on this (possibly RTF_CACHE)
- * dst, the configured one on the underlying route. Reach the latter
- * via ->from (fib6_pmtu), populated by ip6_route_info_create().
- */
- from = rcu_dereference(rt->from);
- if (from)
- mtu = from->fib6_pmtu;
- if (!mtu) {
- mtu = IPV6_MIN_MTU;
- idev = __in6_dev_get(dst_dev_rcu(dst));
- if (idev)
- mtu = max_t(unsigned int, mtu, READ_ONCE(idev->cnf.mtu6));
- }
- rcu_read_unlock();
-
mtu = min_t(unsigned int, mtu, IP6_MAX_MTU);
+
return mtu - lwtunnel_headroom(dst->lwtstate, mtu);
}
@@ -428,7 +400,7 @@ u32 ip6_mtu_from_fib6(const struct fib6_result *res,
const struct in6_addr *daddr,
const struct in6_addr *saddr);
-struct neighbour *ip6_neigh_lookup(const struct in6_addr *gw,
- struct net_device *dev, struct sk_buff *skb,
- const void *daddr);
+struct neighbour *__ip6_dst_neigh_lookup(const struct in6_addr *gw,
+ struct net_device *dev, struct sk_buff *skb,
+ const void *daddr);
#endif
diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h
index b99805ee2fd1..d1f0a427e9c8 100644
--- a/include/net/ip6_tunnel.h
+++ b/include/net/ip6_tunnel.h
@@ -45,6 +45,7 @@ struct __ip6_tnl_parm {
/* IPv6 tunnel */
struct ip6_tnl {
struct ip6_tnl __rcu *next; /* next tunnel in list */
+ struct hlist_node hash_node;
struct net_device *dev; /* virtual device associated with tunnel */
netdevice_tracker dev_tracker;
struct net *net; /* netns for packet i/o */
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 0a35355fb0f3..92f4eb8b86d7 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -258,6 +258,7 @@ struct fib_table {
struct hlist_node tb_hlist;
u32 tb_id;
int tb_num_default;
+ struct net *tb_net;
struct rcu_head rcu;
unsigned long *tb_data;
unsigned long __data[];
@@ -591,7 +592,8 @@ void fib_nh_common_release(struct fib_nh_common *nhc);
/* Exported by fib_trie.c */
void fib_alias_hw_flags_set(struct net *net, const struct fib_rt_info *fri);
void fib_trie_init(void);
-struct fib_table *fib_trie_table(u32 id, struct fib_table *alias);
+struct fib_table *fib_trie_table(struct net *net, u32 id,
+ struct fib_table *alias);
bool fib_lookup_good_nhc(const struct fib_nh_common *nhc, int fib_flags,
const struct flowi4 *flp);
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 7c9aadfe8fe3..5cccf4c0e691 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -127,6 +127,7 @@ struct ip_tunnel_6rd_parm {
__be32 relay_prefix;
u16 prefixlen;
u16 relay_prefixlen;
+ struct rcu_head rcu;
};
#endif
@@ -148,6 +149,7 @@ struct ip_tunnel_parm_kern {
__be32 o_key;
int link;
struct iphdr iph;
+ struct rcu_head rcu;
};
struct ip_tunnel {
@@ -185,10 +187,11 @@ struct ip_tunnel {
/* for SIT */
#ifdef CONFIG_IPV6_SIT_6RD
- struct ip_tunnel_6rd_parm ip6rd;
+ struct ip_tunnel_6rd_parm __rcu *ip6rd;
#endif
struct ip_tunnel_prl_entry __rcu *prl; /* potential router list */
unsigned int prl_count; /* # of entries in PRL */
+ struct ip_tunnel_parm_kern __rcu *sit_parms;
unsigned int ip_tnl_net_id;
struct gro_cells gro_cells;
__u32 fwmark;
@@ -215,6 +218,7 @@ struct ip_tunnel_net {
struct net_device *fb_tunnel_dev;
struct rtnl_link_ops *rtnl_link_ops;
struct hlist_head tunnels[IP_TNL_HASH_SIZE];
+ struct mutex tunnels_lock;
struct ip_tunnel __rcu *collect_md_tun;
int type;
};
@@ -398,7 +402,6 @@ int ip_tunnel_get_iflink(const struct net_device *dev);
int ip_tunnel_init_net(struct net *net, unsigned int ip_tnl_net_id,
struct rtnl_link_ops *ops, char *devname);
void ip_tunnel_delete_net(struct net *net, unsigned int id,
- struct rtnl_link_ops *ops,
struct list_head *dev_to_kill);
void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
@@ -611,11 +614,13 @@ static inline u8 ip_tunnel_ecn_encap(u8 tos, const struct iphdr *iph,
return INET_ECN_encapsulate(tos, inner);
}
-int __iptunnel_pull_header(struct sk_buff *skb, int hdr_len,
- __be16 inner_proto, bool raw_proto, bool xnet);
+enum skb_drop_reason
+__iptunnel_pull_header(struct sk_buff *skb, int hdr_len,
+ __be16 inner_proto, bool raw_proto, bool xnet);
-static inline int iptunnel_pull_header(struct sk_buff *skb, int hdr_len,
- __be16 inner_proto, bool xnet)
+static inline enum skb_drop_reason
+iptunnel_pull_header(struct sk_buff *skb, int hdr_len,
+ __be16 inner_proto, bool xnet)
{
return __iptunnel_pull_header(skb, hdr_len, inner_proto, false, xnet);
}
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 32fde731bceb..9a83bff32569 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -36,9 +36,6 @@
#define IP_VS_HDR_INVERSE 1
#define IP_VS_HDR_ICMP 2
-/* Destination Server Flags */
-#define IP_VS_DEST_F_OVERLOAD 0x0002 /* server is overloaded */
-
/* Destination Server Config Flags */
#define IP_VS_DEST_CF_AVAILABLE 0x0001 /* server is available */
@@ -973,32 +970,43 @@ struct ip_vs_dest_dst {
* and so on.
*/
struct ip_vs_dest {
+ /* Cacheline for hash table nodes - read-mostly */
+
struct list_head n_list; /* for the dests in the service */
struct hlist_node d_list; /* for table with all the dests */
- u16 af; /* address family */
- __be16 port; /* port number of the server */
- union nf_inet_addr addr; /* IP address of the server */
- volatile unsigned int flags; /* dest status flags */
- atomic_t conn_flags; /* flags to copy to conn */
atomic_t weight; /* server weight */
- unsigned long cflags; /* config flags */
atomic_t last_weight; /* server latest weight */
+
+ /* connection thresholds */
+ u32 l_threshold_val;/* used lower threshold */
+ u32 u_threshold_val;/* used upper threshold */
+ /* 32/48 */
+ u32 l_threshold; /* lower threshold */
+ u32 u_threshold; /* upper threshold */
+
+ unsigned long cflags; /* config flags */
+
+ /* 44/64 */
+ atomic_t conn_flags; /* flags to copy to conn */
+
__u16 tun_type; /* tunnel type */
__be16 tun_port; /* tunnel port */
__u16 tun_flags; /* tunnel flags */
- refcount_t refcnt; /* reference counter */
- struct ip_vs_stats stats; /* statistics */
- unsigned long idle_start; /* start time, jiffies */
+ u16 af; /* address family */
+ __be16 port; /* port number of the server */
+ /* 60/80 */
+ union nf_inet_addr addr; /* IP address of the server */
- /* connection counters and thresholds */
- atomic_t activeconns; /* active connections */
+ /* connection counters */
atomic_t totalconns; /* total connections */
+ atomic_t activeconns; /* active connections */
atomic_t persistconns; /* persistent connections */
- __u32 u_threshold; /* upper threshold */
- __u32 l_threshold; /* lower threshold */
- __u32 l_threshold_val;/* used lower threshold */
+
+ refcount_t refcnt; /* reference counter */
+ struct ip_vs_stats stats; /* statistics */
+ unsigned long idle_start; /* start time, jiffies */
/* for destination cache */
spinlock_t dst_lock; /* lock of dst_cache */
@@ -1915,7 +1923,13 @@ static inline void ip_vs_dest_put_and_free(struct ip_vs_dest *dest)
kfree(dest);
}
-void ip_vs_dest_update_overload(struct ip_vs_dest *dest, int mode);
+void ip_vs_dest_update_overload(struct ip_vs_dest *dest, bool overload);
+
+/* Check if dest is in overloaded state */
+static inline bool ip_vs_dest_is_overloaded(const struct ip_vs_dest *dest)
+{
+ return READ_ONCE(dest->l_threshold_val);
+}
/* IPVS sync daemon data and function prototypes
* (from ip_vs_sync.c)
diff --git a/include/net/llc.h b/include/net/llc.h
index 029ba8a22319..ce7db08e8355 100644
--- a/include/net/llc.h
+++ b/include/net/llc.h
@@ -6,112 +6,44 @@
* 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
*/
-#include <linux/if.h>
-#include <linux/if_ether.h>
#include <linux/list.h>
-#include <linux/spinlock.h>
-#include <linux/rculist_nulls.h>
-#include <linux/hash.h>
-#include <linux/jhash.h>
-
-#include <linux/atomic.h>
+#include <linux/refcount.h>
struct net_device;
struct packet_type;
struct sk_buff;
-struct llc_addr {
- unsigned char lsap;
- unsigned char mac[IFHWADDRLEN];
-};
-
-#define LLC_SAP_STATE_INACTIVE 1
-#define LLC_SAP_STATE_ACTIVE 2
-
-#define LLC_SK_DEV_HASH_BITS 6
-#define LLC_SK_DEV_HASH_ENTRIES (1<<LLC_SK_DEV_HASH_BITS)
-
-#define LLC_SK_LADDR_HASH_BITS 6
-#define LLC_SK_LADDR_HASH_ENTRIES (1<<LLC_SK_LADDR_HASH_BITS)
-
/**
* struct llc_sap - Defines the SAP component
*
- * @station - station this sap belongs to
- * @state - sap state
- * @p_bit - only lowest-order bit used
- * @f_bit - only lowest-order bit used
- * @laddr - SAP value in this 'lsap'
- * @node - entry in station sap_list
- * @sk_list - LLC sockets this one manages
+ * @refcnt: reference count
+ * @lsap: SAP number
+ * @rcv_func: handler for the PDUs addressed to this SAP
+ * @node: entry in the SAP list
+ * @rcu: for deferred freeing
*/
struct llc_sap {
- unsigned char state;
- unsigned char p_bit;
- unsigned char f_bit;
refcount_t refcnt;
+ unsigned char lsap;
int (*rcv_func)(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt,
struct net_device *orig_dev);
- struct llc_addr laddr;
struct list_head node;
- spinlock_t sk_lock;
- int sk_count;
- struct hlist_nulls_head sk_laddr_hash[LLC_SK_LADDR_HASH_ENTRIES];
- struct hlist_head sk_dev_hash[LLC_SK_DEV_HASH_ENTRIES];
struct rcu_head rcu;
};
-static inline
-struct hlist_head *llc_sk_dev_hash(struct llc_sap *sap, int ifindex)
-{
- u32 bucket = hash_32(ifindex, LLC_SK_DEV_HASH_BITS);
-
- return &sap->sk_dev_hash[bucket];
-}
-
-static inline
-u32 llc_sk_laddr_hashfn(struct llc_sap *sap, const struct llc_addr *laddr)
-{
- return hash_32(jhash(laddr->mac, sizeof(laddr->mac), 0),
- LLC_SK_LADDR_HASH_BITS);
-}
-
-static inline
-struct hlist_nulls_head *llc_sk_laddr_hash(struct llc_sap *sap,
- const struct llc_addr *laddr)
-{
- return &sap->sk_laddr_hash[llc_sk_laddr_hashfn(sap, laddr)];
-}
-
-#define LLC_DEST_INVALID 0 /* Invalid LLC PDU type */
-#define LLC_DEST_SAP 1 /* Type 1 goes here */
-#define LLC_DEST_CONN 2 /* Type 2 goes here */
-
-extern struct list_head llc_sap_list;
-
int llc_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt,
struct net_device *orig_dev);
int llc_mac_hdr_init(struct sk_buff *skb, const unsigned char *sa,
const unsigned char *da);
-void llc_add_pack(int type,
- void (*handler)(struct llc_sap *sap, struct sk_buff *skb));
-void llc_remove_pack(int type);
-
-void llc_set_station_handler(void (*handler)(struct sk_buff *skb));
-
struct llc_sap *llc_sap_open(unsigned char lsap,
int (*rcv)(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt,
struct net_device *orig_dev));
-static inline void llc_sap_hold(struct llc_sap *sap)
-{
- refcount_inc(&sap->refcnt);
-}
static inline bool llc_sap_hold_safe(struct llc_sap *sap)
{
@@ -130,30 +62,4 @@ struct llc_sap *llc_sap_find(unsigned char sap_value);
int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
const unsigned char *dmac, unsigned char dsap);
-
-void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb);
-void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb);
-
-void llc_station_init(void);
-void llc_station_exit(void);
-
-#ifdef CONFIG_PROC_FS
-int llc_proc_init(void);
-void llc_proc_exit(void);
-#else
-#define llc_proc_init() (0)
-#define llc_proc_exit() do { } while(0)
-#endif /* CONFIG_PROC_FS */
-#ifdef CONFIG_SYSCTL
-int llc_sysctl_init(void);
-void llc_sysctl_exit(void);
-
-extern int sysctl_llc2_ack_timeout;
-extern int sysctl_llc2_busy_timeout;
-extern int sysctl_llc2_p_timeout;
-extern int sysctl_llc2_rej_timeout;
-#else
-#define llc_sysctl_init() (0)
-#define llc_sysctl_exit() do { } while(0)
-#endif /* CONFIG_SYSCTL */
#endif /* LLC_H */
diff --git a/include/net/llc_c_ac.h b/include/net/llc_c_ac.h
deleted file mode 100644
index af31a49bebb0..000000000000
--- a/include/net/llc_c_ac.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LLC_C_AC_H
-#define LLC_C_AC_H
-/*
- * Copyright (c) 1997 by Procom Technology,Inc.
- * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- */
-/* Connection component state transition actions */
-/*
- * Connection state transition actions
- * (Fb = F bit; Pb = P bit; Xb = X bit)
- */
-
-#include <linux/types.h>
-
-struct sk_buff;
-struct sock;
-struct timer_list;
-
-#define LLC_CONN_AC_CLR_REMOTE_BUSY 1
-#define LLC_CONN_AC_CONN_IND 2
-#define LLC_CONN_AC_CONN_CONFIRM 3
-#define LLC_CONN_AC_DATA_IND 4
-#define LLC_CONN_AC_DISC_IND 5
-#define LLC_CONN_AC_RESET_IND 6
-#define LLC_CONN_AC_RESET_CONFIRM 7
-#define LLC_CONN_AC_REPORT_STATUS 8
-#define LLC_CONN_AC_CLR_REMOTE_BUSY_IF_Fb_EQ_1 9
-#define LLC_CONN_AC_STOP_REJ_TMR_IF_DATA_FLAG_EQ_2 10
-#define LLC_CONN_AC_SEND_DISC_CMD_Pb_SET_X 11
-#define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_Pb 12
-#define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_1 13
-#define LLC_CONN_AC_SEND_DM_RSP_Fb_SET_F_FLAG 14
-#define LLC_CONN_AC_SEND_FRMR_RSP_Fb_SET_X 15
-#define LLC_CONN_AC_RESEND_FRMR_RSP_Fb_SET_0 16
-#define LLC_CONN_AC_RESEND_FRMR_RSP_Fb_SET_Pb 17
-#define LLC_CONN_AC_SEND_I_CMD_Pb_SET_1 18
-#define LLC_CONN_AC_RESEND_I_CMD_Pb_SET_1 19
-#define LLC_CONN_AC_RESEND_I_CMD_Pb_SET_1_OR_SEND_RR 20
-#define LLC_CONN_AC_SEND_I_XXX_Xb_SET_0 21
-#define LLC_CONN_AC_RESEND_I_XXX_Xb_SET_0 22
-#define LLC_CONN_AC_RESEND_I_XXX_Xb_SET_0_OR_SEND_RR 23
-#define LLC_CONN_AC_RESEND_I_RSP_Fb_SET_1 24
-#define LLC_CONN_AC_SEND_REJ_CMD_Pb_SET_1 25
-#define LLC_CONN_AC_SEND_REJ_RSP_Fb_SET_1 26
-#define LLC_CONN_AC_SEND_REJ_XXX_Xb_SET_0 27
-#define LLC_CONN_AC_SEND_RNR_CMD_Pb_SET_1 28
-#define LLC_CONN_AC_SEND_RNR_RSP_Fb_SET_1 29
-#define LLC_CONN_AC_SEND_RNR_XXX_Xb_SET_0 30
-#define LLC_CONN_AC_SET_REMOTE_BUSY 31
-#define LLC_CONN_AC_OPTIONAL_SEND_RNR_XXX_Xb_SET_0 32
-#define LLC_CONN_AC_SEND_RR_CMD_Pb_SET_1 33
-#define LLC_CONN_AC_SEND_ACK_CMD_Pb_SET_1 34
-#define LLC_CONN_AC_SEND_RR_RSP_Fb_SET_1 35
-#define LLC_CONN_AC_SEND_ACK_RSP_Fb_SET_1 36
-#define LLC_CONN_AC_SEND_RR_XXX_Xb_SET_0 37
-#define LLC_CONN_AC_SEND_ACK_XXX_Xb_SET_0 38
-#define LLC_CONN_AC_SEND_SABME_CMD_Pb_SET_X 39
-#define LLC_CONN_AC_SEND_UA_RSP_Fb_SET_Pb 40
-#define LLC_CONN_AC_SEND_UA_RSP_Fb_SET_F_FLAG 41
-#define LLC_CONN_AC_S_FLAG_SET_0 42
-#define LLC_CONN_AC_S_FLAG_SET_1 43
-#define LLC_CONN_AC_START_P_TMR 44
-#define LLC_CONN_AC_START_ACK_TMR 45
-#define LLC_CONN_AC_START_REJ_TMR 46
-#define LLC_CONN_AC_START_ACK_TMR_IF_NOT_RUNNING 47
-#define LLC_CONN_AC_STOP_ACK_TMR 48
-#define LLC_CONN_AC_STOP_P_TMR 49
-#define LLC_CONN_AC_STOP_REJ_TMR 50
-#define LLC_CONN_AC_STOP_ALL_TMRS 51
-#define LLC_CONN_AC_STOP_OTHER_TMRS 52
-#define LLC_CONN_AC_UPDATE_Nr_RECEIVED 53
-#define LLC_CONN_AC_UPDATE_P_FLAG 54
-#define LLC_CONN_AC_DATA_FLAG_SET_2 55
-#define LLC_CONN_AC_DATA_FLAG_SET_0 56
-#define LLC_CONN_AC_DATA_FLAG_SET_1 57
-#define LLC_CONN_AC_DATA_FLAG_SET_1_IF_DATA_FLAG_EQ_0 58
-#define LLC_CONN_AC_P_FLAG_SET_0 59
-#define LLC_CONN_AC_P_FLAG_SET_P 60
-#define LLC_CONN_AC_REMOTE_BUSY_SET_0 61
-#define LLC_CONN_AC_RETRY_CNT_SET_0 62
-#define LLC_CONN_AC_RETRY_CNT_INC_BY_1 63
-#define LLC_CONN_AC_Vr_SET_0 64
-#define LLC_CONN_AC_Vr_INC_BY_1 65
-#define LLC_CONN_AC_Vs_SET_0 66
-#define LLC_CONN_AC_Vs_SET_Nr 67
-#define LLC_CONN_AC_F_FLAG_SET_P 68
-#define LLC_CONN_AC_STOP_SENDACK_TMR 70
-#define LLC_CONN_AC_START_SENDACK_TMR_IF_NOT_RUNNING 71
-
-typedef int (*llc_conn_action_t)(struct sock *sk, struct sk_buff *skb);
-
-int llc_conn_ac_clear_remote_busy(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_conn_ind(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_conn_confirm(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_data_ind(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_disc_ind(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_rst_ind(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_rst_confirm(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_clear_remote_busy_if_f_eq_1(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ac_stop_rej_tmr_if_data_flag_eq_2(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ac_send_disc_cmd_p_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_dm_rsp_f_set_p(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_dm_rsp_f_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_frmr_rsp_f_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_resend_frmr_rsp_f_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_resend_frmr_rsp_f_set_p(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_i_cmd_p_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_resend_i_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ac_resend_i_rsp_f_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_rej_cmd_p_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_rej_rsp_f_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_rej_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_rnr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_rnr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_remote_busy(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_opt_send_rnr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_rr_cmd_p_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_rr_rsp_f_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_ack_rsp_f_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_rr_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_ack_xxx_x_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_sabme_cmd_p_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_ua_rsp_f_set_p(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_s_flag_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_s_flag_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_start_p_timer(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_start_ack_timer(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_start_rej_timer(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_start_ack_tmr_if_not_running(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ac_stop_ack_timer(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_stop_p_timer(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_stop_rej_timer(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_stop_all_timers(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_stop_other_timers(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_upd_nr_received(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_inc_tx_win_size(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_dec_tx_win_size(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_upd_p_flag(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_data_flag_2(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_data_flag_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_data_flag_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_data_flag_1_if_data_flag_eq_0(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ac_set_p_flag_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_remote_busy_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_retry_cnt_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_cause_flag_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_cause_flag_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_inc_retry_cnt_by_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_vr_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_inc_vr_by_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_vs_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_set_vs_nr(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_rst_vs(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_upd_vs(struct sock *sk, struct sk_buff *skb);
-int llc_conn_disc(struct sock *sk, struct sk_buff *skb);
-int llc_conn_reset(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_disc_confirm(struct sock *sk, struct sk_buff *skb);
-u8 llc_circular_between(u8 a, u8 b, u8 c);
-int llc_conn_ac_send_ack_if_needed(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_adjust_npta_by_rr(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_adjust_npta_by_rnr(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_rst_sendack_flag(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ac_send_i_as_ack(struct sock *sk, struct sk_buff *skb);
-
-void llc_conn_busy_tmr_cb(struct timer_list *t);
-void llc_conn_pf_cycle_tmr_cb(struct timer_list *t);
-void llc_conn_ack_tmr_cb(struct timer_list *t);
-void llc_conn_rej_tmr_cb(struct timer_list *t);
-
-void llc_conn_set_p_flag(struct sock *sk, u8 value);
-#endif /* LLC_C_AC_H */
diff --git a/include/net/llc_c_ev.h b/include/net/llc_c_ev.h
deleted file mode 100644
index d45140d4289a..000000000000
--- a/include/net/llc_c_ev.h
+++ /dev/null
@@ -1,217 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LLC_C_EV_H
-#define LLC_C_EV_H
-/*
- * Copyright (c) 1997 by Procom Technology,Inc.
- * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- */
-
-#include <net/sock.h>
-
-/* Connection component state transition event qualifiers */
-/* Types of events (possible values in 'ev->type') */
-#define LLC_CONN_EV_TYPE_SIMPLE 1
-#define LLC_CONN_EV_TYPE_CONDITION 2
-#define LLC_CONN_EV_TYPE_PRIM 3
-#define LLC_CONN_EV_TYPE_PDU 4 /* command/response PDU */
-#define LLC_CONN_EV_TYPE_ACK_TMR 5
-#define LLC_CONN_EV_TYPE_P_TMR 6
-#define LLC_CONN_EV_TYPE_REJ_TMR 7
-#define LLC_CONN_EV_TYPE_BUSY_TMR 8
-#define LLC_CONN_EV_TYPE_RPT_STATUS 9
-#define LLC_CONN_EV_TYPE_SENDACK_TMR 10
-
-#define NBR_CONN_EV 5
-/* Connection events which cause state transitions when fully qualified */
-
-#define LLC_CONN_EV_CONN_REQ 1
-#define LLC_CONN_EV_CONN_RESP 2
-#define LLC_CONN_EV_DATA_REQ 3
-#define LLC_CONN_EV_DISC_REQ 4
-#define LLC_CONN_EV_RESET_REQ 5
-#define LLC_CONN_EV_RESET_RESP 6
-#define LLC_CONN_EV_LOCAL_BUSY_DETECTED 7
-#define LLC_CONN_EV_LOCAL_BUSY_CLEARED 8
-#define LLC_CONN_EV_RX_BAD_PDU 9
-#define LLC_CONN_EV_RX_DISC_CMD_Pbit_SET_X 10
-#define LLC_CONN_EV_RX_DM_RSP_Fbit_SET_X 11
-#define LLC_CONN_EV_RX_FRMR_RSP_Fbit_SET_X 12
-#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X 13
-#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X_UNEXPD_Ns 14
-#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_X_INVAL_Ns 15
-#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X 16
-#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_UNEXPD_Ns 17
-#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_X_INVAL_Ns 18
-#define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_X 19
-#define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_X 20
-#define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_X 21
-#define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_X 22
-#define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_X 23
-#define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_X 24
-#define LLC_CONN_EV_RX_SABME_CMD_Pbit_SET_X 25
-#define LLC_CONN_EV_RX_UA_RSP_Fbit_SET_X 26
-#define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_X 27
-#define LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_X 28
-#define LLC_CONN_EV_RX_XXX_YYY 29
-#define LLC_CONN_EV_RX_ZZZ_CMD_Pbit_SET_X_INVAL_Nr 30
-#define LLC_CONN_EV_RX_ZZZ_RSP_Fbit_SET_X_INVAL_Nr 31
-#define LLC_CONN_EV_P_TMR_EXP 32
-#define LLC_CONN_EV_ACK_TMR_EXP 33
-#define LLC_CONN_EV_REJ_TMR_EXP 34
-#define LLC_CONN_EV_BUSY_TMR_EXP 35
-#define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_1 36
-#define LLC_CONN_EV_RX_XXX_CMD_Pbit_SET_0 37
-#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_0_UNEXPD_Ns 38
-#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_0_UNEXPD_Ns 39
-#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_1_UNEXPD_Ns 40
-#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_1_UNEXPD_Ns 41
-#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_0 42
-#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_0 43
-#define LLC_CONN_EV_RX_I_CMD_Pbit_SET_1 44
-#define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_0 45
-#define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_0 46
-#define LLC_CONN_EV_RX_RR_RSP_Fbit_SET_1 47
-#define LLC_CONN_EV_RX_RR_CMD_Pbit_SET_1 48
-#define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_0 49
-#define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_0 50
-#define LLC_CONN_EV_RX_RNR_RSP_Fbit_SET_1 51
-#define LLC_CONN_EV_RX_RNR_CMD_Pbit_SET_1 52
-#define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_0 53
-#define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_0 54
-#define LLC_CONN_EV_RX_REJ_CMD_Pbit_SET_1 55
-#define LLC_CONN_EV_RX_I_RSP_Fbit_SET_1 56
-#define LLC_CONN_EV_RX_REJ_RSP_Fbit_SET_1 57
-#define LLC_CONN_EV_RX_XXX_RSP_Fbit_SET_1 58
-#define LLC_CONN_EV_TX_BUFF_FULL 59
-
-#define LLC_CONN_EV_INIT_P_F_CYCLE 100
-/*
- * Connection event qualifiers; for some events a certain combination of
- * these qualifiers must be TRUE before event recognized valid for state;
- * these constants act as indexes into the Event Qualifier function
- * table
- */
-#define LLC_CONN_EV_QFY_DATA_FLAG_EQ_1 1
-#define LLC_CONN_EV_QFY_DATA_FLAG_EQ_0 2
-#define LLC_CONN_EV_QFY_DATA_FLAG_EQ_2 3
-#define LLC_CONN_EV_QFY_P_FLAG_EQ_1 4
-#define LLC_CONN_EV_QFY_P_FLAG_EQ_0 5
-#define LLC_CONN_EV_QFY_P_FLAG_EQ_Fbit 6
-#define LLC_CONN_EV_QFY_REMOTE_BUSY_EQ_0 7
-#define LLC_CONN_EV_QFY_RETRY_CNT_LT_N2 8
-#define LLC_CONN_EV_QFY_RETRY_CNT_GTE_N2 9
-#define LLC_CONN_EV_QFY_S_FLAG_EQ_1 10
-#define LLC_CONN_EV_QFY_S_FLAG_EQ_0 11
-#define LLC_CONN_EV_QFY_INIT_P_F_CYCLE 12
-
-struct llc_conn_state_ev {
- u8 type;
- u8 prim;
- u8 prim_type;
- u8 reason;
- u8 status;
- u8 ind_prim;
- u8 cfm_prim;
-};
-
-static __inline__ struct llc_conn_state_ev *llc_conn_ev(struct sk_buff *skb)
-{
- return (struct llc_conn_state_ev *)skb->cb;
-}
-
-typedef int (*llc_conn_ev_t)(struct sock *sk, struct sk_buff *skb);
-typedef int (*llc_conn_ev_qfyr_t)(struct sock *sk, struct sk_buff *skb);
-
-int llc_conn_ev_conn_req(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_data_req(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_disc_req(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rst_req(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_local_busy_detected(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_local_busy_cleared(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_bad_pdu(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_disc_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_dm_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_frmr_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_i_cmd_pbit_set_x_inval_ns(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_rx_i_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_i_rsp_fbit_set_x_unexpd_ns(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_rx_i_rsp_fbit_set_x_inval_ns(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_rx_rej_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_sabme_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_ua_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_xxx_cmd_pbit_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_xxx_rsp_fbit_set_x(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_zzz_cmd_pbit_set_x_inval_nr(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_rx_zzz_rsp_fbit_set_x_inval_nr(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_p_tmr_exp(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_ack_tmr_exp(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rej_tmr_exp(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_busy_tmr_exp(struct sock *sk, struct sk_buff *skb);
-/* NOT_USED functions and their variations */
-int llc_conn_ev_rx_xxx_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_xxx_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_i_cmd_pbit_set_0_unexpd_ns(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_rx_i_cmd_pbit_set_1_unexpd_ns(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_rx_i_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_i_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_i_rsp_fbit_set_0_unexpd_ns(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_rx_i_rsp_fbit_set_1_unexpd_ns(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_rx_i_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_i_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rnr_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rnr_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rnr_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rnr_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rej_cmd_pbit_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rej_cmd_pbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rej_rsp_fbit_set_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_rej_rsp_fbit_set_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_rx_any_frame(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_tx_buffer_full(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_init_p_f_cycle(struct sock *sk, struct sk_buff *skb);
-
-/* Available connection action qualifiers */
-int llc_conn_ev_qlfy_data_flag_eq_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_data_flag_eq_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_data_flag_eq_2(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_p_flag_eq_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_last_frame_eq_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_last_frame_eq_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_p_flag_eq_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_p_flag_eq_f(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_remote_busy_eq_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_remote_busy_eq_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_retry_cnt_lt_n2(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_retry_cnt_gte_n2(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_s_flag_eq_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_s_flag_eq_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_cause_flag_eq_1(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_cause_flag_eq_0(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_set_status_conn(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_set_status_disc(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_set_status_failed(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_set_status_remote_busy(struct sock *sk,
- struct sk_buff *skb);
-int llc_conn_ev_qlfy_set_status_refuse(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_set_status_conflict(struct sock *sk, struct sk_buff *skb);
-int llc_conn_ev_qlfy_set_status_rst_done(struct sock *sk, struct sk_buff *skb);
-
-static __inline__ int llc_conn_space(struct sock *sk, struct sk_buff *skb)
-{
- return atomic_read(&sk->sk_rmem_alloc) + skb->truesize <
- (unsigned int)sk->sk_rcvbuf;
-}
-#endif /* LLC_C_EV_H */
diff --git a/include/net/llc_c_st.h b/include/net/llc_c_st.h
deleted file mode 100644
index f52a4cc4880d..000000000000
--- a/include/net/llc_c_st.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LLC_C_ST_H
-#define LLC_C_ST_H
-/*
- * Copyright (c) 1997 by Procom Technology,Inc.
- * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- */
-
-#include <net/llc_c_ac.h>
-#include <net/llc_c_ev.h>
-
-/* Connection component state management */
-/* connection states */
-#define LLC_CONN_OUT_OF_SVC 0 /* prior to allocation */
-
-#define LLC_CONN_STATE_ADM 1 /* disc, initial state */
-#define LLC_CONN_STATE_SETUP 2 /* disconnected state */
-#define LLC_CONN_STATE_NORMAL 3 /* connected state */
-#define LLC_CONN_STATE_BUSY 4 /* connected state */
-#define LLC_CONN_STATE_REJ 5 /* connected state */
-#define LLC_CONN_STATE_AWAIT 6 /* connected state */
-#define LLC_CONN_STATE_AWAIT_BUSY 7 /* connected state */
-#define LLC_CONN_STATE_AWAIT_REJ 8 /* connected state */
-#define LLC_CONN_STATE_D_CONN 9 /* disconnected state */
-#define LLC_CONN_STATE_RESET 10 /* disconnected state */
-#define LLC_CONN_STATE_ERROR 11 /* disconnected state */
-#define LLC_CONN_STATE_TEMP 12 /* disconnected state */
-
-#define NBR_CONN_STATES 12 /* size of state table */
-#define NO_STATE_CHANGE 100
-
-/* Connection state table structure */
-struct llc_conn_state_trans {
- llc_conn_ev_t ev;
- u8 next_state;
- const llc_conn_ev_qfyr_t *ev_qualifiers;
- const llc_conn_action_t *ev_actions;
-};
-
-struct llc_conn_state {
- u8 current_state;
- const struct llc_conn_state_trans **transitions;
-};
-
-extern struct llc_conn_state llc_conn_state_table[];
-#endif /* LLC_C_ST_H */
diff --git a/include/net/llc_conn.h b/include/net/llc_conn.h
deleted file mode 100644
index e1a302696723..000000000000
--- a/include/net/llc_conn.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LLC_CONN_H
-#define LLC_CONN_H
-/*
- * Copyright (c) 1997 by Procom Technology, Inc.
- * 2001, 2002 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- */
-#include <linux/timer.h>
-#include <net/llc_if.h>
-#include <net/sock.h>
-#include <linux/llc.h>
-
-#define LLC_EVENT 1
-#define LLC_PACKET 2
-
-#define LLC2_P_TIME 2
-#define LLC2_ACK_TIME 1
-#define LLC2_REJ_TIME 3
-#define LLC2_BUSY_TIME 3
-
-struct llc_timer {
- struct timer_list timer;
- unsigned long expire; /* timer expire time */
-};
-
-struct llc_sock {
- /* struct sock must be the first member of llc_sock */
- struct sock sk;
- struct sockaddr_llc addr; /* address sock is bound to */
- u8 state; /* state of connection */
- struct llc_sap *sap; /* pointer to parent SAP */
- struct llc_addr laddr; /* lsap/mac pair */
- struct llc_addr daddr; /* dsap/mac pair */
- struct net_device *dev; /* device to send to remote */
- netdevice_tracker dev_tracker;
- u32 copied_seq; /* head of yet unread data */
- u8 retry_count; /* number of retries */
- u8 ack_must_be_send;
- u8 first_pdu_Ns;
- u8 npta;
- struct llc_timer ack_timer;
- struct llc_timer pf_cycle_timer;
- struct llc_timer rej_sent_timer;
- struct llc_timer busy_state_timer; /* ind busy clr at remote LLC */
- u8 vS; /* seq# next in-seq I-PDU tx'd*/
- u8 vR; /* seq# next in-seq I-PDU rx'd*/
- u32 n2; /* max nbr re-tx's for timeout*/
- u32 n1; /* max nbr octets in I PDU */
- u8 k; /* tx window size; max = 127 */
- u8 rw; /* rx window size; max = 127 */
- u8 p_flag; /* state flags */
- u8 f_flag;
- u8 s_flag;
- u8 data_flag;
- u8 remote_busy_flag;
- u8 cause_flag;
- struct sk_buff_head pdu_unack_q; /* PUDs sent/waiting ack */
- u16 link; /* network layer link number */
- u8 X; /* a temporary variable */
- u8 ack_pf; /* this flag indicates what is
- the P-bit of acknowledge */
- u8 failed_data_req; /* recognize that already exist a
- failed llc_data_req_handler
- (tx_buffer_full or unacceptable
- state */
- u8 dec_step;
- u8 inc_cntr;
- u8 dec_cntr;
- u8 connect_step;
- u8 last_nr; /* NR of last pdu received */
- u32 rx_pdu_hdr; /* used for saving header of last pdu
- received and caused sending FRMR.
- Used for resending FRMR */
- u32 cmsg_flags;
- struct hlist_node dev_hash_node;
-};
-
-static inline struct llc_sock *llc_sk(const struct sock *sk)
-{
- return (struct llc_sock *)sk;
-}
-
-static __inline__ void llc_set_backlog_type(struct sk_buff *skb, char type)
-{
- skb->cb[sizeof(skb->cb) - 1] = type;
-}
-
-static __inline__ char llc_backlog_type(struct sk_buff *skb)
-{
- return skb->cb[sizeof(skb->cb) - 1];
-}
-
-struct sock *llc_sk_alloc(struct net *net, int family, gfp_t priority,
- struct proto *prot, int kern);
-void llc_sk_stop_all_timers(struct sock *sk, bool sync);
-void llc_sk_free(struct sock *sk);
-
-void llc_sk_reset(struct sock *sk);
-
-/* Access to a connection */
-int llc_conn_state_process(struct sock *sk, struct sk_buff *skb);
-void llc_conn_send_pdu(struct sock *sk, struct sk_buff *skb);
-void llc_conn_rtn_pdu(struct sock *sk, struct sk_buff *skb);
-void llc_conn_resend_i_pdu_as_cmd(struct sock *sk, u8 nr, u8 first_p_bit);
-void llc_conn_resend_i_pdu_as_rsp(struct sock *sk, u8 nr, u8 first_f_bit);
-int llc_conn_remove_acked_pdus(struct sock *conn, u8 nr, u16 *how_many_unacked);
-struct sock *llc_lookup_established(struct llc_sap *sap, struct llc_addr *daddr,
- struct llc_addr *laddr, const struct net *net);
-void llc_sap_add_socket(struct llc_sap *sap, struct sock *sk);
-void llc_sap_remove_socket(struct llc_sap *sap, struct sock *sk);
-
-u8 llc_data_accept_state(u8 state);
-void llc_build_offset_table(void);
-#endif /* LLC_CONN_H */
diff --git a/include/net/llc_if.h b/include/net/llc_if.h
deleted file mode 100644
index a333259613ab..000000000000
--- a/include/net/llc_if.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LLC_IF_H
-#define LLC_IF_H
-/*
- * Copyright (c) 1997 by Procom Technology,Inc.
- * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- */
-/* Defines LLC interface to network layer */
-/* Available primitives */
-#include <linux/if.h>
-#include <linux/if_arp.h>
-#include <linux/llc.h>
-#include <linux/etherdevice.h>
-#include <net/llc.h>
-
-#define LLC_DATAUNIT_PRIM 1
-#define LLC_CONN_PRIM 2
-#define LLC_DATA_PRIM 3
-#define LLC_DISC_PRIM 4
-#define LLC_RESET_PRIM 5
-#define LLC_FLOWCONTROL_PRIM 6 /* Not supported at this time */
-#define LLC_DISABLE_PRIM 7
-#define LLC_XID_PRIM 8
-#define LLC_TEST_PRIM 9
-#define LLC_SAP_ACTIVATION 10
-#define LLC_SAP_DEACTIVATION 11
-
-#define LLC_NBR_PRIMITIVES 11
-
-#define LLC_IND 1
-#define LLC_CONFIRM 2
-
-/* Primitive type */
-#define LLC_PRIM_TYPE_REQ 1
-#define LLC_PRIM_TYPE_IND 2
-#define LLC_PRIM_TYPE_RESP 3
-#define LLC_PRIM_TYPE_CONFIRM 4
-
-/* Reset reasons, remote entity or local LLC */
-#define LLC_RESET_REASON_REMOTE 1
-#define LLC_RESET_REASON_LOCAL 2
-
-/* Disconnect reasons */
-#define LLC_DISC_REASON_RX_DM_RSP_PDU 0
-#define LLC_DISC_REASON_RX_DISC_CMD_PDU 1
-#define LLC_DISC_REASON_ACK_TMR_EXP 2
-
-/* Confirm reasons */
-#define LLC_STATUS_CONN 0 /* connect confirm & reset confirm */
-#define LLC_STATUS_DISC 1 /* connect confirm & reset confirm */
-#define LLC_STATUS_FAILED 2 /* connect confirm & reset confirm */
-#define LLC_STATUS_IMPOSSIBLE 3 /* connect confirm */
-#define LLC_STATUS_RECEIVED 4 /* data conn */
-#define LLC_STATUS_REMOTE_BUSY 5 /* data conn */
-#define LLC_STATUS_REFUSE 6 /* data conn */
-#define LLC_STATUS_CONFLICT 7 /* disconnect conn */
-#define LLC_STATUS_RESET_DONE 8 /* */
-
-int llc_establish_connection(struct sock *sk, const u8 *lmac, u8 *dmac,
- u8 dsap);
-int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb);
-int llc_send_disc(struct sock *sk);
-#endif /* LLC_IF_H */
diff --git a/include/net/llc_pdu.h b/include/net/llc_pdu.h
index f165237a3723..14c76b0d9832 100644
--- a/include/net/llc_pdu.h
+++ b/include/net/llc_pdu.h
@@ -6,201 +6,17 @@
* 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
*/
-#include <linux/if_ether.h>
-
-/* Lengths of frame formats */
-#define LLC_PDU_LEN_I 4 /* header and 2 control bytes */
-#define LLC_PDU_LEN_S 4
-#define LLC_PDU_LEN_U 3 /* header and 1 control byte */
-/* header and 1 control byte and XID info */
-#define LLC_PDU_LEN_U_XID (LLC_PDU_LEN_U + sizeof(struct llc_xid_info))
-/* Known SAP addresses */
-#define LLC_GLOBAL_SAP 0xFF
-#define LLC_NULL_SAP 0x00 /* not network-layer visible */
-#define LLC_MGMT_INDIV 0x02 /* station LLC mgmt indiv addr */
-#define LLC_MGMT_GRP 0x03 /* station LLC mgmt group addr */
-#define LLC_RDE_SAP 0xA6 /* route ... */
-
-/* SAP field bit masks */
-#define LLC_ISO_RESERVED_SAP 0x02
-#define LLC_SAP_GROUP_DSAP 0x01
-#define LLC_SAP_RESP_SSAP 0x01
-
-/* Group/individual DSAP indicator is DSAP field */
-#define LLC_PDU_GROUP_DSAP_MASK 0x01
-#define LLC_PDU_IS_GROUP_DSAP(pdu) \
- ((pdu->dsap & LLC_PDU_GROUP_DSAP_MASK) ? 0 : 1)
-#define LLC_PDU_IS_INDIV_DSAP(pdu) \
- (!(pdu->dsap & LLC_PDU_GROUP_DSAP_MASK) ? 0 : 1)
+#include <linux/skbuff.h>
/* Command/response PDU indicator in SSAP field */
-#define LLC_PDU_CMD_RSP_MASK 0x01
#define LLC_PDU_CMD 0
#define LLC_PDU_RSP 1
-#define LLC_PDU_IS_CMD(pdu) ((pdu->ssap & LLC_PDU_RSP) ? 0 : 1)
-#define LLC_PDU_IS_RSP(pdu) ((pdu->ssap & LLC_PDU_RSP) ? 1 : 0)
/* Get PDU type from 2 lowest-order bits of control field first byte */
-#define LLC_PDU_TYPE_I_MASK 0x01 /* 16-bit control field */
-#define LLC_PDU_TYPE_S_MASK 0x03
-#define LLC_PDU_TYPE_U_MASK 0x03 /* 8-bit control field */
#define LLC_PDU_TYPE_MASK 0x03
-
-#define LLC_PDU_TYPE_I 0 /* first bit */
-#define LLC_PDU_TYPE_S 1 /* first two bits */
#define LLC_PDU_TYPE_U 3 /* first two bits */
-#define LLC_PDU_TYPE_U_XID 4 /* private type for detecting XID commands */
-
-#define LLC_PDU_TYPE_IS_I(pdu) \
- ((!(pdu->ctrl_1 & LLC_PDU_TYPE_I_MASK)) ? 1 : 0)
-
-#define LLC_PDU_TYPE_IS_U(pdu) \
- (((pdu->ctrl_1 & LLC_PDU_TYPE_U_MASK) == LLC_PDU_TYPE_U) ? 1 : 0)
-
-#define LLC_PDU_TYPE_IS_S(pdu) \
- (((pdu->ctrl_1 & LLC_PDU_TYPE_S_MASK) == LLC_PDU_TYPE_S) ? 1 : 0)
-
-/* U-format PDU control field masks */
-#define LLC_U_PF_BIT_MASK 0x10 /* P/F bit mask */
-#define LLC_U_PF_IS_1(pdu) ((pdu->ctrl_1 & LLC_U_PF_BIT_MASK) ? 1 : 0)
-#define LLC_U_PF_IS_0(pdu) ((!(pdu->ctrl_1 & LLC_U_PF_BIT_MASK)) ? 1 : 0)
-
-#define LLC_U_PDU_CMD_MASK 0xEC /* cmd/rsp mask */
-#define LLC_U_PDU_CMD(pdu) (pdu->ctrl_1 & LLC_U_PDU_CMD_MASK)
-#define LLC_U_PDU_RSP(pdu) (pdu->ctrl_1 & LLC_U_PDU_CMD_MASK)
#define LLC_1_PDU_CMD_UI 0x00 /* Type 1 cmds/rsps */
-#define LLC_1_PDU_CMD_XID 0xAC
-#define LLC_1_PDU_CMD_TEST 0xE0
-
-#define LLC_2_PDU_CMD_SABME 0x6C /* Type 2 cmds/rsps */
-#define LLC_2_PDU_CMD_DISC 0x40
-#define LLC_2_PDU_RSP_UA 0x60
-#define LLC_2_PDU_RSP_DM 0x0C
-#define LLC_2_PDU_RSP_FRMR 0x84
-
-/* Type 1 operations */
-
-/* XID information field bit masks */
-
-/* LLC format identifier (byte 1) */
-#define LLC_XID_FMT_ID 0x81 /* first byte must be this */
-
-/* LLC types/classes identifier (byte 2) */
-#define LLC_XID_CLASS_ZEROS_MASK 0xE0 /* these must be zeros */
-#define LLC_XID_CLASS_MASK 0x1F /* AND with byte to get below */
-
-#define LLC_XID_NULL_CLASS_1 0x01 /* if NULL LSAP...use these */
-#define LLC_XID_NULL_CLASS_2 0x03
-#define LLC_XID_NULL_CLASS_3 0x05
-#define LLC_XID_NULL_CLASS_4 0x07
-
-#define LLC_XID_NNULL_TYPE_1 0x01 /* if non-NULL LSAP...use these */
-#define LLC_XID_NNULL_TYPE_2 0x02
-#define LLC_XID_NNULL_TYPE_3 0x04
-#define LLC_XID_NNULL_TYPE_1_2 0x03
-#define LLC_XID_NNULL_TYPE_1_3 0x05
-#define LLC_XID_NNULL_TYPE_2_3 0x06
-#define LLC_XID_NNULL_ALL 0x07
-
-/* Sender Receive Window (byte 3) */
-#define LLC_XID_RW_MASK 0xFE /* AND with value to get below */
-
-#define LLC_XID_MIN_RW 0x02 /* lowest-order bit always zero */
-
-/* Type 2 operations */
-
-#define LLC_2_SEQ_NBR_MODULO ((u8) 128)
-
-/* I-PDU masks ('ctrl' is I-PDU control word) */
-#define LLC_I_GET_NS(pdu) (u8)((pdu->ctrl_1 & 0xFE) >> 1)
-#define LLC_I_GET_NR(pdu) (u8)((pdu->ctrl_2 & 0xFE) >> 1)
-
-#define LLC_I_PF_BIT_MASK 0x01
-
-#define LLC_I_PF_IS_0(pdu) ((!(pdu->ctrl_2 & LLC_I_PF_BIT_MASK)) ? 1 : 0)
-#define LLC_I_PF_IS_1(pdu) ((pdu->ctrl_2 & LLC_I_PF_BIT_MASK) ? 1 : 0)
-
-/* S-PDU supervisory commands and responses */
-
-#define LLC_S_PDU_CMD_MASK 0x0C
-#define LLC_S_PDU_CMD(pdu) (pdu->ctrl_1 & LLC_S_PDU_CMD_MASK)
-#define LLC_S_PDU_RSP(pdu) (pdu->ctrl_1 & LLC_S_PDU_CMD_MASK)
-
-#define LLC_2_PDU_CMD_RR 0x00 /* rx ready cmd */
-#define LLC_2_PDU_RSP_RR 0x00 /* rx ready rsp */
-#define LLC_2_PDU_CMD_REJ 0x08 /* reject PDU cmd */
-#define LLC_2_PDU_RSP_REJ 0x08 /* reject PDU rsp */
-#define LLC_2_PDU_CMD_RNR 0x04 /* rx not ready cmd */
-#define LLC_2_PDU_RSP_RNR 0x04 /* rx not ready rsp */
-
-#define LLC_S_PF_BIT_MASK 0x01
-#define LLC_S_PF_IS_0(pdu) ((!(pdu->ctrl_2 & LLC_S_PF_BIT_MASK)) ? 1 : 0)
-#define LLC_S_PF_IS_1(pdu) ((pdu->ctrl_2 & LLC_S_PF_BIT_MASK) ? 1 : 0)
-
-#define PDU_SUPV_GET_Nr(pdu) ((pdu->ctrl_2 & 0xFE) >> 1)
-#define PDU_GET_NEXT_Vr(sn) (((sn) + 1) & ~LLC_2_SEQ_NBR_MODULO)
-
-/* FRMR information field macros */
-
-#define FRMR_INFO_LENGTH 5 /* 5 bytes of information */
-
-/*
- * info is pointer to FRMR info field structure; 'rej_ctrl' is byte pointer
- * (if U-PDU) or word pointer to rejected PDU control field
- */
-#define FRMR_INFO_SET_REJ_CNTRL(info,rej_ctrl) \
- info->rej_pdu_ctrl = ((*((u8 *) rej_ctrl) & \
- LLC_PDU_TYPE_U) != LLC_PDU_TYPE_U ? \
- (u16)*((u16 *) rej_ctrl) : \
- (((u16) *((u8 *) rej_ctrl)) & 0x00FF))
-
-/*
- * Info is pointer to FRMR info field structure; 'vs' is a byte containing
- * send state variable value in low-order 7 bits (insure the lowest-order
- * bit remains zero (0))
- */
-#define FRMR_INFO_SET_Vs(info,vs) (info->curr_ssv = (((u8) vs) << 1))
-#define FRMR_INFO_SET_Vr(info,vr) (info->curr_rsv = (((u8) vr) << 1))
-
-/*
- * Info is pointer to FRMR info field structure; 'cr' is a byte containing
- * the C/R bit value in the low-order bit
- */
-#define FRMR_INFO_SET_C_R_BIT(info, cr) (info->curr_rsv |= (((u8) cr) & 0x01))
-
-/*
- * In the remaining five macros, 'info' is pointer to FRMR info field
- * structure; 'ind' is a byte containing the bit value to set in the
- * lowest-order bit)
- */
-#define FRMR_INFO_SET_INVALID_PDU_CTRL_IND(info, ind) \
- (info->ind_bits = ((info->ind_bits & 0xFE) | (((u8) ind) & 0x01)))
-
-#define FRMR_INFO_SET_INVALID_PDU_INFO_IND(info, ind) \
- (info->ind_bits = ( (info->ind_bits & 0xFD) | (((u8) ind) & 0x02)))
-
-#define FRMR_INFO_SET_PDU_INFO_2LONG_IND(info, ind) \
- (info->ind_bits = ( (info->ind_bits & 0xFB) | (((u8) ind) & 0x04)))
-
-#define FRMR_INFO_SET_PDU_INVALID_Nr_IND(info, ind) \
- (info->ind_bits = ( (info->ind_bits & 0xF7) | (((u8) ind) & 0x08)))
-
-#define FRMR_INFO_SET_PDU_INVALID_Ns_IND(info, ind) \
- (info->ind_bits = ( (info->ind_bits & 0xEF) | (((u8) ind) & 0x10)))
-
-/* Sequence-numbered PDU format (4 bytes in length) */
-struct llc_pdu_sn {
- u8 dsap;
- u8 ssap;
- u8 ctrl_1;
- u8 ctrl_2;
-} __packed;
-
-static inline struct llc_pdu_sn *llc_pdu_sn_hdr(struct sk_buff *skb)
-{
- return (struct llc_pdu_sn *)skb_network_header(skb);
-}
/* Un-numbered PDU format (3 bytes in length) */
struct llc_pdu_un {
@@ -217,29 +33,18 @@ static inline struct llc_pdu_un *llc_pdu_un_hdr(struct sk_buff *skb)
/**
* llc_pdu_header_init - initializes pdu header
* @skb: input skb that header must be set into it.
- * @type: type of PDU (U, I or S).
* @ssap: source sap.
* @dsap: destination sap.
- * @cr: command/response bit (0 or 1).
+ * @cr: command/response bit (%LLC_PDU_CMD or %LLC_PDU_RSP).
*
* This function sets DSAP, SSAP and command/Response bit in LLC header.
*/
-static inline void llc_pdu_header_init(struct sk_buff *skb, u8 type,
- u8 ssap, u8 dsap, u8 cr)
+static inline void llc_pdu_header_init(struct sk_buff *skb, u8 ssap, u8 dsap,
+ u8 cr)
{
- int hlen = 4; /* default value for I and S types */
struct llc_pdu_un *pdu;
- switch (type) {
- case LLC_PDU_TYPE_U:
- hlen = 3;
- break;
- case LLC_PDU_TYPE_U_XID:
- hlen = 6;
- break;
- }
-
- skb_push(skb, hlen);
+ skb_push(skb, sizeof(*pdu));
skb_reset_network_header(skb);
pdu = llc_pdu_un_hdr(skb);
pdu->dsap = dsap;
@@ -248,56 +53,6 @@ static inline void llc_pdu_header_init(struct sk_buff *skb, u8 type,
}
/**
- * llc_pdu_decode_sa - extracts, source address (MAC) of input frame
- * @skb: input skb that source address must be extracted from it.
- * @sa: pointer to source address (6 byte array).
- *
- * This function extracts source address(MAC) of input frame.
- */
-static inline void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa)
-{
- memcpy(sa, eth_hdr(skb)->h_source, ETH_ALEN);
-}
-
-/**
- * llc_pdu_decode_da - extracts dest address of input frame
- * @skb: input skb that destination address must be extracted from it
- * @da: pointer to destination address (6 byte array).
- *
- * This function extracts destination address(MAC) of input frame.
- */
-static inline void llc_pdu_decode_da(struct sk_buff *skb, u8 *da)
-{
- memcpy(da, eth_hdr(skb)->h_dest, ETH_ALEN);
-}
-
-/**
- * llc_pdu_decode_ssap - extracts source SAP of input frame
- * @skb: input skb that source SAP must be extracted from it.
- * @ssap: source SAP (output argument).
- *
- * This function extracts source SAP of input frame. Right bit of SSAP is
- * command/response bit.
- */
-static inline void llc_pdu_decode_ssap(struct sk_buff *skb, u8 *ssap)
-{
- *ssap = llc_pdu_un_hdr(skb)->ssap & 0xFE;
-}
-
-/**
- * llc_pdu_decode_dsap - extracts dest SAP of input frame
- * @skb: input skb that destination SAP must be extracted from it.
- * @dsap: destination SAP (output argument).
- *
- * This function extracts destination SAP of input frame. right bit of
- * DSAP designates individual/group SAP.
- */
-static inline void llc_pdu_decode_dsap(struct sk_buff *skb, u8 *dsap)
-{
- *dsap = llc_pdu_un_hdr(skb)->dsap & 0xFE;
-}
-
-/**
* llc_pdu_init_as_ui_cmd - sets LLC header as UI PDU
* @skb: input skb that header must be set into it.
*
@@ -311,128 +66,4 @@ static inline void llc_pdu_init_as_ui_cmd(struct sk_buff *skb)
pdu->ctrl_1 |= LLC_1_PDU_CMD_UI;
}
-/**
- * llc_pdu_init_as_test_cmd - sets PDU as TEST
- * @skb: Address of the skb to build
- *
- * Sets a PDU as TEST
- */
-static inline void llc_pdu_init_as_test_cmd(struct sk_buff *skb)
-{
- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
-
- pdu->ctrl_1 = LLC_PDU_TYPE_U;
- pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
- pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
-}
-
-/**
- * llc_pdu_init_as_test_rsp - build TEST response PDU
- * @skb: Address of the skb to build
- * @ev_skb: The received TEST command PDU frame
- *
- * Builds a pdu frame as a TEST response.
- */
-static inline void llc_pdu_init_as_test_rsp(struct sk_buff *skb,
- struct sk_buff *ev_skb)
-{
- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
-
- pdu->ctrl_1 = LLC_PDU_TYPE_U;
- pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST;
- pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
- if (ev_skb->protocol == htons(ETH_P_802_2)) {
- struct llc_pdu_un *ev_pdu = llc_pdu_un_hdr(ev_skb);
- int dsize;
-
- dsize = ntohs(eth_hdr(ev_skb)->h_proto) - 3;
- memcpy(((u8 *)pdu) + 3, ((u8 *)ev_pdu) + 3, dsize);
- skb_put(skb, dsize);
- }
-}
-
-/* LLC Type 1 XID command/response information fields format */
-struct llc_xid_info {
- u8 fmt_id; /* always 0x81 for LLC */
- u8 type; /* different if NULL/non-NULL LSAP */
- u8 rw; /* sender receive window */
-} __packed;
-
-/**
- * llc_pdu_init_as_xid_cmd - sets bytes 3, 4 & 5 of LLC header as XID
- * @skb: input skb that header must be set into it.
- * @svcs_supported: The class of the LLC (I or II)
- * @rx_window: The size of the receive window of the LLC
- *
- * This function sets third,fourth,fifth and sixth bytes of LLC header as
- * a XID PDU.
- */
-static inline void llc_pdu_init_as_xid_cmd(struct sk_buff *skb,
- u8 svcs_supported, u8 rx_window)
-{
- struct llc_xid_info *xid_info;
- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
-
- pdu->ctrl_1 = LLC_PDU_TYPE_U;
- pdu->ctrl_1 |= LLC_1_PDU_CMD_XID;
- pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
- xid_info = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1);
- xid_info->fmt_id = LLC_XID_FMT_ID; /* 0x81 */
- xid_info->type = svcs_supported;
- xid_info->rw = rx_window << 1; /* size of receive window */
-
- /* no need to push/put since llc_pdu_header_init() has already
- * pushed 3 + 3 bytes
- */
-}
-
-/**
- * llc_pdu_init_as_xid_rsp - builds XID response PDU
- * @skb: Address of the skb to build
- * @svcs_supported: The class of the LLC (I or II)
- * @rx_window: The size of the receive window of the LLC
- *
- * Builds a pdu frame as an XID response.
- */
-static inline void llc_pdu_init_as_xid_rsp(struct sk_buff *skb,
- u8 svcs_supported, u8 rx_window)
-{
- struct llc_xid_info *xid_info;
- struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
-
- pdu->ctrl_1 = LLC_PDU_TYPE_U;
- pdu->ctrl_1 |= LLC_1_PDU_CMD_XID;
- pdu->ctrl_1 |= LLC_U_PF_BIT_MASK;
-
- xid_info = (struct llc_xid_info *)(((u8 *)&pdu->ctrl_1) + 1);
- xid_info->fmt_id = LLC_XID_FMT_ID;
- xid_info->type = svcs_supported;
- xid_info->rw = rx_window << 1;
- skb_put(skb, sizeof(struct llc_xid_info));
-}
-
-/* LLC Type 2 FRMR response information field format */
-struct llc_frmr_info {
- u16 rej_pdu_ctrl; /* bits 1-8 if U-PDU */
- u8 curr_ssv; /* current send state variable val */
- u8 curr_rsv; /* current receive state variable */
- u8 ind_bits; /* indicator bits set with macro */
-} __packed;
-
-void llc_pdu_set_cmd_rsp(struct sk_buff *skb, u8 type);
-void llc_pdu_set_pf_bit(struct sk_buff *skb, u8 bit_value);
-void llc_pdu_decode_pf_bit(struct sk_buff *skb, u8 *pf_bit);
-void llc_pdu_init_as_disc_cmd(struct sk_buff *skb, u8 p_bit);
-void llc_pdu_init_as_i_cmd(struct sk_buff *skb, u8 p_bit, u8 ns, u8 nr);
-void llc_pdu_init_as_rej_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
-void llc_pdu_init_as_rnr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
-void llc_pdu_init_as_rr_cmd(struct sk_buff *skb, u8 p_bit, u8 nr);
-void llc_pdu_init_as_sabme_cmd(struct sk_buff *skb, u8 p_bit);
-void llc_pdu_init_as_dm_rsp(struct sk_buff *skb, u8 f_bit);
-void llc_pdu_init_as_frmr_rsp(struct sk_buff *skb, struct llc_pdu_sn *prev_pdu,
- u8 f_bit, u8 vs, u8 vr, u8 vzyxw);
-void llc_pdu_init_as_rr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr);
-void llc_pdu_init_as_rej_rsp(struct sk_buff *skb, u8 f_bit, u8 nr);
-void llc_pdu_init_as_rnr_rsp(struct sk_buff *skb, u8 f_bit, u8 nr);
-void llc_pdu_init_as_ua_rsp(struct sk_buff *skb, u8 f_bit);
#endif /* LLC_PDU_H */
diff --git a/include/net/llc_s_ac.h b/include/net/llc_s_ac.h
deleted file mode 100644
index 076adc5217fd..000000000000
--- a/include/net/llc_s_ac.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LLC_S_AC_H
-#define LLC_S_AC_H
-/*
- * Copyright (c) 1997 by Procom Technology,Inc.
- * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- */
-
-struct llc_sap;
-struct sk_buff;
-
-/* SAP component actions */
-#define SAP_ACT_UNITDATA_IND 1
-#define SAP_ACT_SEND_UI 2
-#define SAP_ACT_SEND_XID_C 3
-#define SAP_ACT_SEND_XID_R 4
-#define SAP_ACT_SEND_TEST_C 5
-#define SAP_ACT_SEND_TEST_R 6
-#define SAP_ACT_REPORT_STATUS 7
-#define SAP_ACT_XID_IND 8
-#define SAP_ACT_TEST_IND 9
-
-/* All action functions must look like this */
-typedef int (*llc_sap_action_t)(struct llc_sap *sap, struct sk_buff *skb);
-
-int llc_sap_action_unitdata_ind(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_action_send_ui(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_action_send_xid_c(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_action_send_test_c(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_action_report_status(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_action_xid_ind(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_action_test_ind(struct llc_sap *sap, struct sk_buff *skb);
-#endif /* LLC_S_AC_H */
diff --git a/include/net/llc_s_ev.h b/include/net/llc_s_ev.h
deleted file mode 100644
index 7b9c94093336..000000000000
--- a/include/net/llc_s_ev.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LLC_S_EV_H
-#define LLC_S_EV_H
-/*
- * Copyright (c) 1997 by Procom Technology,Inc.
- * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- */
-
-#include <linux/skbuff.h>
-#include <net/llc.h>
-
-/* Defines SAP component events */
-/* Types of events (possible values in 'ev->type') */
-#define LLC_SAP_EV_TYPE_SIMPLE 1
-#define LLC_SAP_EV_TYPE_CONDITION 2
-#define LLC_SAP_EV_TYPE_PRIM 3
-#define LLC_SAP_EV_TYPE_PDU 4 /* command/response PDU */
-#define LLC_SAP_EV_TYPE_ACK_TMR 5
-#define LLC_SAP_EV_TYPE_RPT_STATUS 6
-
-#define LLC_SAP_EV_ACTIVATION_REQ 1
-#define LLC_SAP_EV_RX_UI 2
-#define LLC_SAP_EV_UNITDATA_REQ 3
-#define LLC_SAP_EV_XID_REQ 4
-#define LLC_SAP_EV_RX_XID_C 5
-#define LLC_SAP_EV_RX_XID_R 6
-#define LLC_SAP_EV_TEST_REQ 7
-#define LLC_SAP_EV_RX_TEST_C 8
-#define LLC_SAP_EV_RX_TEST_R 9
-#define LLC_SAP_EV_DEACTIVATION_REQ 10
-
-struct llc_sap_state_ev {
- u8 prim;
- u8 prim_type;
- u8 type;
- u8 reason;
- u8 ind_cfm_flag;
- struct llc_addr saddr;
- struct llc_addr daddr;
-};
-
-static __inline__ struct llc_sap_state_ev *llc_sap_ev(struct sk_buff *skb)
-{
- return (struct llc_sap_state_ev *)skb->cb;
-}
-
-struct llc_sap;
-
-typedef int (*llc_sap_ev_t)(struct llc_sap *sap, struct sk_buff *skb);
-
-int llc_sap_ev_activation_req(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_ev_rx_ui(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_ev_unitdata_req(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_ev_xid_req(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_ev_rx_xid_c(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_ev_rx_xid_r(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_ev_test_req(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_ev_rx_test_c(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_ev_rx_test_r(struct llc_sap *sap, struct sk_buff *skb);
-int llc_sap_ev_deactivation_req(struct llc_sap *sap, struct sk_buff *skb);
-#endif /* LLC_S_EV_H */
diff --git a/include/net/llc_s_st.h b/include/net/llc_s_st.h
deleted file mode 100644
index 85ce230fd946..000000000000
--- a/include/net/llc_s_st.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LLC_S_ST_H
-#define LLC_S_ST_H
-/*
- * Copyright (c) 1997 by Procom Technology,Inc.
- * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- */
-
-#include <linux/types.h>
-#include <net/llc_s_ac.h>
-#include <net/llc_s_ev.h>
-
-struct llc_sap_state_trans;
-
-#define LLC_NR_SAP_STATES 2 /* size of state table */
-
-/* structures and types */
-/* SAP state table structure */
-struct llc_sap_state_trans {
- llc_sap_ev_t ev;
- u8 next_state;
- const llc_sap_action_t *ev_actions;
-};
-
-struct llc_sap_state {
- u8 curr_state;
- const struct llc_sap_state_trans **transitions;
-};
-
-/* only access to SAP state table */
-extern struct llc_sap_state llc_sap_state_table[LLC_NR_SAP_STATES];
-#endif /* LLC_S_ST_H */
diff --git a/include/net/llc_sap.h b/include/net/llc_sap.h
deleted file mode 100644
index b259f5993c46..000000000000
--- a/include/net/llc_sap.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef LLC_SAP_H
-#define LLC_SAP_H
-
-#include <asm/types.h>
-
-/*
- * Copyright (c) 1997 by Procom Technology,Inc.
- * 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
- */
-struct llc_sap;
-struct net_device;
-struct sk_buff;
-struct sock;
-
-void llc_sap_rtn_pdu(struct llc_sap *sap, struct sk_buff *skb);
-void llc_save_primitive(struct sock *sk, struct sk_buff *skb,
- unsigned char prim);
-struct sk_buff *llc_alloc_frame(struct sock *sk, struct net_device *dev,
- u8 type, u32 data_size);
-
-void llc_build_and_send_test_pkt(struct llc_sap *sap, struct sk_buff *skb,
- unsigned char *dmac, unsigned char dsap);
-void llc_build_and_send_xid_pkt(struct llc_sap *sap, struct sk_buff *skb,
- unsigned char *dmac, unsigned char dsap);
-#endif /* LLC_SAP_H */
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 9d1fac6e8082..a1a6409b44c1 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -640,7 +640,6 @@ struct ieee80211_bss_npca_params {
* mode only, set if the AP advertises TWT responder role)
* @twt_responder: does this BSS support TWT requester (relevant for managed
* mode only, set if the AP advertises TWT responder role)
- * @twt_protected: does this BSS support protected TWT frames
* @twt_broadcast: does this BSS support broadcast TWT
* @use_cts_prot: use CTS protection
* @use_short_preamble: use 802.11b short preamble
@@ -812,7 +811,6 @@ struct ieee80211_bss_conf {
bool he_support;
bool twt_requester;
bool twt_responder;
- bool twt_protected;
bool twt_broadcast;
/* erp related data */
bool use_cts_prot;
@@ -923,12 +921,14 @@ struct ieee80211_bss_conf {
* @channel_entry: the Channel Entry blob as defined in Wi-Fi Aware
* (TM) 4.0 specification Table 100 (Channel Entry format for the NAN
* Availability attribute).
+ * @no_evacuate: if set, this channel must not be evacuated
*/
struct ieee80211_nan_channel {
struct ieee80211_chan_req chanreq;
u8 needed_rx_chains;
struct ieee80211_chanctx_conf *chanctx_conf;
u8 channel_entry[6];
+ bool no_evacuate;
};
/**
@@ -1770,10 +1770,9 @@ enum mac80211_rx_encoding {
* @ampdu_reference: A-MPDU reference number, must be a different value for
* each A-MPDU but the same for each subframe within one A-MPDU
* @zero_length_psdu_type: radiotap type of the 0-length PSDU
- * @link_valid: if the link which is identified by @link_id is valid. This flag
- * is set only when connection is MLO.
- * @link_id: id of the link used to receive the packet. This is used along with
- * @link_valid.
+ * @link_id: id of the link used to receive the packet. Set and used by
+ * mac80211 internally, it uses @freq set by the driver to identify the
+ * correct link per vif.
*/
struct ieee80211_rx_status {
u64 mactime;
@@ -1813,7 +1812,7 @@ struct ieee80211_rx_status {
u8 chains;
s8 chain_signal[IEEE80211_MAX_CHAINS];
u8 zero_length_psdu_type;
- u8 link_valid:1, link_id:4;
+ u8 link_id:4;
};
static_assert(sizeof(struct ieee80211_rx_status) <= sizeof_field(struct sk_buff, cb));
@@ -2396,6 +2395,8 @@ static inline bool lockdep_vif_wiphy_mutex_held(struct ieee80211_vif *vif)
* number generation only
* @IEEE80211_KEY_FLAG_SPP_AMSDU: SPP A-MSDUs can be used with this key
* (set by mac80211 from the sta->spp_amsdu flag)
+ * @IEEE80211_KEY_FLAG_CIP: This key is used for the Control Integrity
+ * Protocol, and is either a pairwise key or a CIGTK.
*/
enum ieee80211_key_flags {
IEEE80211_KEY_FLAG_GENERATE_IV_MGMT = BIT(0),
@@ -2410,6 +2411,7 @@ enum ieee80211_key_flags {
IEEE80211_KEY_FLAG_NO_AUTO_TX = BIT(9),
IEEE80211_KEY_FLAG_GENERATE_MMIE = BIT(10),
IEEE80211_KEY_FLAG_SPP_AMSDU = BIT(11),
+ IEEE80211_KEY_FLAG_CIP = BIT(12),
};
/**
@@ -2630,6 +2632,7 @@ struct ieee80211_sta_aggregates {
* @eht_cap: EHT capabilities of this STA
* @uhr_cap: UHR capabilities of this STA
* @s1g_cap: S1G capabilities of this STA
+ * @cip_cap: the CIP capabilities of this STA (or zero)
* @agg: per-link data for multi-link aggregation
* @bandwidth: current bandwidth the station can receive with.
* This is the minimum between the peer's capabilities and our own
@@ -2658,6 +2661,7 @@ struct ieee80211_link_sta {
struct ieee80211_sta_eht_cap eht_cap;
struct ieee80211_sta_uhr_cap uhr_cap;
struct ieee80211_sta_s1g_cap s1g_cap;
+ u8 cip_cap;
struct ieee80211_sta_aggregates agg;
@@ -2721,6 +2725,8 @@ struct ieee80211_link_sta {
* @valid_links: bitmap of valid links, or 0 for non-MLO
* @spp_amsdu: indicates whether the STA uses SPP A-MSDU or not.
* @epp_peer: indicates that the peer is an EPP peer.
+ * @cip: indicates whether the STA uses control frame protection or not.
+ * @twt_protected: does this STA support protected TWT frames
* @nmi: For NDI stations, pointer to the NMI station of the peer.
* @nan_sched: NAN peer schedule for this station. Valid only for NMI stations.
* @ext_mld_capa_ops: the MLD's extended MLD capabilities and operations
@@ -2742,6 +2748,9 @@ struct ieee80211_sta {
u8 max_amsdu_subframes;
u16 eml_cap;
+ bool cip;
+ bool twt_protected;
+
struct ieee80211_sta_aggregates *cur;
bool support_p2p_ps;
@@ -2919,8 +2928,8 @@ struct ieee80211_txq {
* autonomously manages the PS status of connected stations. When
* this flag is set mac80211 will not trigger PS mode for connected
* stations based on the PM bit of incoming frames.
- * Use ieee80211_start_ps()/ieee8021_end_ps() to manually configure
- * the PS mode of connected stations.
+ * Use ieee80211_sta_ps_transition() to manually toggle the PS mode
+ * of connected stations.
*
* @IEEE80211_HW_TX_AMPDU_SETUP_IN_HW: The device handles TX A-MPDU session
* setup strictly in HW. mac80211 should not attempt to do this in
@@ -4360,6 +4369,13 @@ struct ieee80211_prep_tx_info {
* Statistics that the driver doesn't fill will be filled by mac80211.
* The callback can sleep.
*
+ * @sta_statistics_atomic: Like @sta_statistics, but called under RCU, so it
+ * must be atomic. This is called instead of @sta_statistics if available,
+ * but may return -EAGAIN to fall back to @sta_statistics with the wiphy
+ * mutex held.
+ * Note that it's not guaranteed this will always be called first, some
+ * (internal) calls may call @sta_statistics directly.
+ *
* @link_sta_statistics: Get link statistics for this station. For example with
* beacon filtering, the statistics kept by mac80211 might not be
* accurate, so let the driver pre-fill the statistics. The driver can
@@ -4369,6 +4385,9 @@ struct ieee80211_prep_tx_info {
* Statistics that the driver doesn't fill will be filled by mac80211.
* The callback can sleep.
*
+ * @link_sta_statistics_atomic: Like @link_sta_statistics, with the same
+ * locking/retry semantics as @sta_statistics_atomic. Must be atomic.
+ *
* @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
* bursting) for a hardware TX queue.
* Returns a negative error code on failure.
@@ -4577,6 +4596,9 @@ struct ieee80211_prep_tx_info {
* just "paused" for scanning/ROC, which is indicated by the beacon being
* disabled/enabled via @bss_info_changed.
* @stop_ap: Stop operation on the AP interface.
+ * @update_beacon: Update the templates indicated by @changed (beacon, probe
+ * response, FILS discovery and/or unsolicitated bcast probe response)
+ * without the wiphy mutex held. This callback must not sleep.
*
* @reconfig_complete: Called after a call to ieee80211_restart_hw() and
* during resume, when the reconfiguration has completed.
@@ -4774,6 +4796,10 @@ struct ieee80211_ops {
struct ieee80211_bss_conf *link_conf);
void (*stop_ap)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link_conf);
+ void (*update_beacon)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_bss_conf *link_conf,
+ u64 changed);
u64 (*prepare_multicast)(struct ieee80211_hw *hw,
struct netdev_hw_addr_list *mc_list);
@@ -4867,6 +4893,10 @@ struct ieee80211_ops {
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
struct station_info *sinfo);
+ int (*sta_statistics_atomic)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ struct station_info *sinfo);
int (*conf_tx)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
unsigned int link_id, u16 ac,
@@ -4882,6 +4912,10 @@ struct ieee80211_ops {
struct ieee80211_vif *vif,
struct ieee80211_link_sta *link_sta,
struct link_station_info *link_sinfo);
+ int (*link_sta_statistics_atomic)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_link_sta *link_sta,
+ struct link_station_info *link_sinfo);
/**
* @ampdu_action:
@@ -5389,14 +5423,18 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw);
* mixed for a single hardware. Must not run concurrently with
* ieee80211_tx_status_skb() or ieee80211_tx_status_ni().
*
+ * For data frames, when hardware has done address translation, a link station
+ * has to be provided and the frequency information may be skipped.
+ *
* This function must be called with BHs disabled and RCU read lock
*
* @hw: the hardware this frame came in on
- * @sta: the station the frame was received from, or %NULL
+ * @link_sta: the link station the data frame was received from, or %NULL
* @skb: the buffer to receive, owned by mac80211 after this call
* @list: the destination list
*/
-void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+void ieee80211_rx_list(struct ieee80211_hw *hw,
+ struct ieee80211_link_sta *link_sta,
struct sk_buff *skb, struct list_head *list);
/**
@@ -5414,14 +5452,18 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
* mixed for a single hardware. Must not run concurrently with
* ieee80211_tx_status_skb() or ieee80211_tx_status_ni().
*
+ * For data frames, when hardware has done address translation, a link station
+ * has to be provided and the frequency information may be skipped.
+ *
* This function must be called with BHs disabled.
*
* @hw: the hardware this frame came in on
- * @sta: the station the frame was received from, or %NULL
+ * @link_sta: the link station the data frame was received from, or %NULL
* @skb: the buffer to receive, owned by mac80211 after this call
* @napi: the NAPI context
*/
-void ieee80211_rx_napi(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
+void ieee80211_rx_napi(struct ieee80211_hw *hw,
+ struct ieee80211_link_sta *link_sta,
struct sk_buff *skb, struct napi_struct *napi);
/**
@@ -5499,10 +5541,8 @@ static inline void ieee80211_rx_ni(struct ieee80211_hw *hw,
*
* @sta: currently connected sta
* @start: start or stop PS
- *
- * Return: 0 on success. -EINVAL when the requested PS mode is already set.
*/
-int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start);
+void ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start);
/**
* ieee80211_sta_ps_transition_ni - PS transition for connected sta
@@ -5514,19 +5554,13 @@ int ieee80211_sta_ps_transition(struct ieee80211_sta *sta, bool start);
*
* @sta: currently connected sta
* @start: start or stop PS
- *
- * Return: Like ieee80211_sta_ps_transition().
*/
-static inline int ieee80211_sta_ps_transition_ni(struct ieee80211_sta *sta,
+static inline void ieee80211_sta_ps_transition_ni(struct ieee80211_sta *sta,
bool start)
{
- int ret;
-
local_bh_disable();
- ret = ieee80211_sta_ps_transition(sta, start);
+ ieee80211_sta_ps_transition(sta, start);
local_bh_enable();
-
- return ret;
}
/**
@@ -6279,6 +6313,7 @@ void ieee80211_set_key_rx_seq(struct ieee80211_key_conf *keyconf,
* @key_len: the key data. Might be bigger than the actual key length,
* but not smaller (for the driver convinence)
* @link_id: the link id of the key or -1 for non-MLO
+ * @cigtk: whether this is a CIGTK
*
* When GTK rekeying was done while the system was suspended, (a) new
* key(s) will be available. These will be needed by mac80211 for proper
@@ -6305,7 +6340,7 @@ void ieee80211_set_key_rx_seq(struct ieee80211_key_conf *keyconf,
struct ieee80211_key_conf *
ieee80211_gtk_rekey_add(struct ieee80211_vif *vif,
u8 idx, u8 *key_data, u8 key_len,
- int link_id);
+ int link_id, bool cigtk);
/**
* ieee80211_gtk_rekey_notify - notify userspace supplicant of rekeying
@@ -7638,11 +7673,16 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
*
* @skb: packet injected by userspace
* @dev: the &struct device of this 802.11 device
+ * @chandef: the channel definition the frame will be transmitted on, or
+ * %NULL to skip the bandwidth checks
+ * @trim_fcs: trim the FCS trailer when present; validate it otherwise
*
* Return: %true if the radiotap header was parsed, %false otherwise
*/
bool ieee80211_parse_tx_radiotap(struct sk_buff *skb,
- struct net_device *dev);
+ struct net_device *dev,
+ const struct cfg80211_chan_def *chandef,
+ bool trim_fcs);
/**
* struct ieee80211_noa_data - holds temporary data for tracking P2P NoA state
@@ -8059,25 +8099,6 @@ ieee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
u64 color_bitmap, u8 link_id);
/**
- * ieee80211_is_tx_data - check if frame is a data frame
- *
- * The function is used to check if a frame is a data frame. Frames with
- * hardware encapsulation enabled are data frames.
- *
- * @skb: the frame to be transmitted.
- *
- * Return: %true if @skb is a data frame, %false otherwise
- */
-static inline bool ieee80211_is_tx_data(struct sk_buff *skb)
-{
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- struct ieee80211_hdr *hdr = (void *) skb->data;
-
- return info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP ||
- ieee80211_is_data(hdr->frame_control);
-}
-
-/**
* ieee80211_set_active_links - set active links in client mode
* @vif: interface to set active links on
* @active_links: the new active links bitmap
diff --git a/include/net/mana/gdma.h b/include/net/mana/gdma.h
index 308950f9b54b..0b52582118e8 100644
--- a/include/net/mana/gdma.h
+++ b/include/net/mana/gdma.h
@@ -6,6 +6,7 @@
#include <linux/dma-mapping.h>
#include <linux/netdevice.h>
+#include <rdma/ib_verbs.h>
#include "shm_channel.h"
@@ -54,6 +55,7 @@ enum gdma_work_request_flags {
GDMA_WR_NONE = 0,
GDMA_WR_OOB_IN_SGL = BIT(0),
GDMA_WR_PAD_BY_SGE0 = BIT(1),
+ GDMA_WR_IB_SGL = BIT(2),
};
enum gdma_eqe_type {
@@ -212,7 +214,10 @@ struct gdma_sge {
}; /* HW DATA */
struct gdma_wqe_request {
- struct gdma_sge *sgl;
+ union {
+ struct gdma_sge *sgl;
+ struct ib_sge *ib_sgl;
+ };
u32 num_sge;
u32 inline_oob_size;
@@ -422,14 +427,74 @@ enum gdma_context_flags {
GC_IN_SERVICE = 1,
};
+struct gdma_context;
+
+/**
+ * struct gdma_bus_ops - transport-specific operations
+ *
+ * Lets the bus-agnostic GDMA core drive PCI and CDX devices without
+ * testing configuration symbols. Each bus driver installs its own
+ * instance in gdma_context.bus_ops at probe time.
+ *
+ * @bus_name: Bus token used to build the per-vector IRQ names.
+ * @adev_prefix: Prefix used for auxiliary-device match names.
+ * @msix_can_alloc_dyn: True if the bus can allocate MSI-X vectors after
+ * probe time. Buses that size their vector pool at probe and cannot
+ * grow it later leave this NULL.
+ * @msix_virq: Return the Linux IRQ number backing an MSI vector, or
+ * -EINVAL if the vector has not been allocated yet.
+ * @msix_alloc_at: Allocate an MSI vector on demand and return its IRQ
+ * number, updating @msi with the index actually assigned. Buses that
+ * allocate their whole pool up front leave this NULL.
+ * @msix_free: Release a vector obtained from @msix_alloc_at. Only needed
+ * by buses that implement @msix_alloc_at.
+ * @msix_vec_count: Return the number of entries in the device MSI-X table,
+ * used to clamp the vector count the core asks for. Buses that cannot
+ * report a table size leave this NULL and the clamp is skipped.
+ * @setup_hwc_irqs: Set up the interrupts the hardware channel needs before
+ * it is created.
+ * @setup_remaining_irqs: Set up the remaining interrupts once the device
+ * resource limits are known.
+ * @remove_irqs: Release the interrupts set up by @setup_hwc_irqs and
+ * @setup_remaining_irqs.
+ * @dev_reset: Reset the device using the bus-level reset mechanism.
+ * @schedule_serv_work: Queue device servicing or recovery. Buses without
+ * a servicing path leave this NULL.
+ * @drv_cap_flags1: Extra capability bits this transport can honour, OR'ed
+ * into GDMA_DRV_CAP_FLAGS1 when the driver version is negotiated.
+ */
+struct gdma_bus_ops {
+ const char *bus_name;
+ const char *adev_prefix;
+ bool (*msix_can_alloc_dyn)(struct gdma_context *gc);
+ int (*msix_virq)(struct gdma_context *gc, int msi);
+ int (*msix_alloc_at)(struct gdma_context *gc, int *msi);
+ void (*msix_free)(struct gdma_context *gc, int msi, int irq);
+ int (*msix_vec_count)(struct gdma_context *gc);
+ int (*setup_hwc_irqs)(struct gdma_context *gc);
+ int (*setup_remaining_irqs)(struct gdma_context *gc);
+ void (*remove_irqs)(struct gdma_context *gc);
+ int (*dev_reset)(struct gdma_context *gc);
+ int (*schedule_serv_work)(struct gdma_context *gc,
+ enum gdma_eqe_type type);
+ u64 drv_cap_flags1;
+};
+
struct gdma_context {
struct device *dev;
struct dentry *mana_pci_debugfs;
+ /* Transport-specific operations, installed by the bus driver */
+ const struct gdma_bus_ops *bus_ops;
+
/* Hardware max number of queues */
unsigned int max_num_queues;
/* Per-vPort max number of queues */
unsigned int max_num_queues_vport;
+ /* Number of vPorts reported by the device, capped at
+ * MAX_PORTS_IN_MANA_DEV
+ */
+ u16 num_ports;
unsigned int max_num_msix;
unsigned int num_msix_usable;
struct xarray irq_contexts;
@@ -529,6 +594,10 @@ ssize_t mana_gd_read_ring(struct gdma_queue *q, char __user *buf,
int mana_schedule_serv_work(struct gdma_context *gc, enum gdma_eqe_type type);
+int mana_gd_alloc_service_wq(struct gdma_context *gc);
+
+void mana_gd_free_service_wq(struct gdma_context *gc);
+
void mana_gd_ring_dim(struct gdma_queue *cq, u32 mod_usec, bool mod_usec_vld,
u32 mod_comps, bool mod_comps_vld);
@@ -552,6 +621,7 @@ struct gdma_wqe {
#define INLINE_OOB_SMALL_SIZE 8
#define INLINE_OOB_LARGE_SIZE 24
+#define INLINE_OOB_EXTRA_LARGE_SIZE 32
#define MANA_MAX_TX_WQE_SGL_ENTRIES 30
@@ -622,8 +692,12 @@ struct gdma_eqe {
#define MANA_PF2_DEVICE_ID 0x00C1
#define MANA_VF_DEVICE_ID 0x00BA
+#define MANA_CDX_DEVICE_ID 0x00C2
+
struct gdma_posted_wqe_info {
u32 wqe_size_in_bu;
+ /* Unmasked WQE start offset in GDMA basic units. */
+ u32 wqe_offset;
};
/* GDMA_GENERATE_TEST_EQE */
@@ -686,21 +760,28 @@ enum {
/* Driver supports non-contiguous queue buffers */
#define GDMA_DRV_CAP_FLAG_1_NON_CONTIGUOUS_BUFFERS BIT(30)
+/* Capabilities in the PCI-only group below rely on dynamic MSI-X allocation
+ * and on the servicing and reset paths reached through
+ * mana_schedule_serv_work(). Transports that provide neither leave
+ * gdma_bus_ops.drv_cap_flags1 unset so the group is not advertised.
+ */
+#define GDMA_DRV_CAP_FLAGS1_PCI \
+ (GDMA_DRV_CAP_FLAG_1_DYNAMIC_IRQ_ALLOC_SUPPORT | \
+ GDMA_DRV_CAP_FLAG_1_SELF_RESET_ON_EQE | \
+ GDMA_DRV_CAP_FLAG_1_HANDLE_RECONFIG_EQE | \
+ GDMA_DRV_CAP_FLAG_1_PROBE_RECOVERY | \
+ GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECOVERY)
+
#define GDMA_DRV_CAP_FLAGS1 \
(GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT | \
GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX | \
GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECONFIG | \
GDMA_DRV_CAP_FLAG_1_VARIABLE_INDIRECTION_TABLE_SUPPORT | \
GDMA_DRV_CAP_FLAG_1_DEV_LIST_HOLES_SUP | \
- GDMA_DRV_CAP_FLAG_1_DYNAMIC_IRQ_ALLOC_SUPPORT | \
- GDMA_DRV_CAP_FLAG_1_SELF_RESET_ON_EQE | \
- GDMA_DRV_CAP_FLAG_1_HANDLE_RECONFIG_EQE | \
GDMA_DRV_CAP_FLAG_1_HW_VPORT_LINK_AWARE | \
GDMA_DRV_CAP_FLAG_1_PERIODIC_STATS_QUERY | \
GDMA_DRV_CAP_FLAG_1_SKB_LINEARIZE | \
- GDMA_DRV_CAP_FLAG_1_PROBE_RECOVERY | \
GDMA_DRV_CAP_FLAG_1_HANDLE_STALL_SQ_RECOVERY | \
- GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECOVERY | \
GDMA_DRV_CAP_FLAG_1_EQ_MSI_UNSHARE_MULTI_VPORT | \
GDMA_DRV_CAP_FLAG_1_DYN_INTERRUPT_MODERATION | \
GDMA_DRV_CAP_FLAG_1_NON_CONTIGUOUS_BUFFERS)
@@ -1044,7 +1125,24 @@ struct gdma_destroy_dm_resp {
struct gdma_resp_hdr hdr;
}; /* HW Data */
-int mana_gd_verify_vf_version(struct pci_dev *pdev);
+int mana_gd_verify_vf_version(struct gdma_context *gc);
+int mana_gd_query_max_resources(struct gdma_context *gc);
+int mana_gd_setup(struct gdma_context *gc);
+void mana_gd_cleanup(struct gdma_context *gc);
+int mana_gd_detect_devices(struct gdma_context *gc);
+int mana_gd_init_registers(struct gdma_context *gc);
+irqreturn_t mana_gd_intr(int irq, void *arg);
+void mana_gd_process_eq_events(void *arg);
+
+static inline u32 mana_gd_r32(struct gdma_context *g, u64 offset)
+{
+ return readl(g->bar0_va + offset);
+}
+
+static inline u64 mana_gd_r64(struct gdma_context *g, u64 offset)
+{
+ return readq(g->bar0_va + offset);
+}
int mana_gd_register_device(struct gdma_dev *gd);
int mana_gd_deregister_device(struct gdma_dev *gd);
@@ -1062,6 +1160,8 @@ void mana_gd_free_res_map(struct gdma_resource *r);
void mana_gd_wq_ring_doorbell(struct gdma_context *gc,
struct gdma_queue *queue);
+void mana_gd_wq_ring_doorbell_ext(struct gdma_context *gc, struct gdma_queue *queue,
+ u32 tail_ptr, u8 wqe_cnt, u8 client_offset);
int mana_gd_alloc_memory(struct gdma_context *gc, unsigned int length,
struct gdma_mem_info *gmi, bool allow_scatter);
@@ -1077,8 +1177,6 @@ void mana_unregister_debugfs(void);
int mana_rdma_service_event(struct gdma_context *gc, enum gdma_service_type event);
-int mana_gd_suspend(struct pci_dev *pdev, pm_message_t state);
-int mana_gd_resume(struct pci_dev *pdev);
bool mana_need_log(struct gdma_context *gc, int err);
@@ -1089,4 +1187,6 @@ void mana_gd_put_gic(struct gdma_context *gc, bool use_msi_bitmap, int msi);
int mana_gd_query_device_cfg(struct gdma_context *gc, u32 proto_major_ver,
u32 proto_minor_ver, u32 proto_micro_ver,
u16 *max_num_vports, u8 *bm_hostmode);
+int mana_gd_dev_reset(struct gdma_context *gc);
+
#endif /* _GDMA_H */
diff --git a/include/net/mana/hw_channel.h b/include/net/mana/hw_channel.h
index 16feb39616c1..1ab2d66c891e 100644
--- a/include/net/mana/hw_channel.h
+++ b/include/net/mana/hw_channel.h
@@ -20,8 +20,8 @@
#define HWC_INIT_DATA_MAX_NUM_CQS 7
#define HWC_INIT_DATA_PDID 8
#define HWC_INIT_DATA_GPA_MKEY 9
-#define HWC_INIT_DATA_PF_DEST_RQ_ID 10
-#define HWC_INIT_DATA_PF_DEST_CQ_ID 11
+#define HWC_INIT_DATA_DEST_RQ_ID 10
+#define HWC_INIT_DATA_DEST_CQ_ID 11
#define HWC_DATA_CFG_HWC_TIMEOUT 1
#define HWC_DATA_HW_LINK_CONNECT 2
@@ -195,8 +195,8 @@ struct hw_channel_context {
struct semaphore sema;
struct gdma_resource inflight_msg_res;
- u32 pf_dest_vrq_id;
- u32 pf_dest_vrcq_id;
+ u32 dest_vrq_id;
+ u32 dest_vrcq_id;
u32 hwc_timeout;
struct hwc_caller_ctx *caller_ctx;
diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h
index 83b7eff4646e..71d726b1f784 100644
--- a/include/net/mana/mana.h
+++ b/include/net/mana/mana.h
@@ -47,8 +47,8 @@ enum mana_priv_flag_bits {
#define COMP_ENTRY_SIZE 64
/* This Max value for RX buffers is derived from __alloc_page()'s max page
- * allocation calculation. It allows maximum 2^(MAX_ORDER -1) pages. RX buffer
- * size beyond this value gets rejected by __alloc_page() call.
+ * allocation calculation. It allows maximum 2^MAX_PAGE_ORDER pages. RX
+ * buffer size beyond this value gets rejected by __alloc_page() call.
*/
#define MAX_RX_BUFFERS_PER_QUEUE 8192
#define DEF_RX_BUFFERS_PER_QUEUE 1024
@@ -377,7 +377,18 @@ struct mana_recv_buf_oob {
#define MANA_RXBUF_PAD (SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) \
+ ETH_HLEN)
-#define MANA_XDP_MTU_MAX (PAGE_SIZE - MANA_RXBUF_PAD - XDP_PACKET_HEADROOM)
+/* Headroom an RX buffer has to reserve while XDP is attached: the XDP program
+ * needs XDP_PACKET_HEADROOM, and the TX path needs LL_RESERVED_SPACE() (see
+ * mana_get_rxbuf_headroom()). LL_RESERVED_SPACE() grows with MAX_SKB_FRAGS and
+ * exceeds XDP_PACKET_HEADROOM once CONFIG_MAX_SKB_FRAGS is 19 or more.
+ */
+static inline u32 mana_xdp_headroom(struct net_device *ndev)
+{
+ return max_t(u32, LL_RESERVED_SPACE(ndev), XDP_PACKET_HEADROOM);
+}
+
+#define MANA_XDP_MTU_MAX(ndev) \
+ (PAGE_SIZE - MANA_RXBUF_PAD - mana_xdp_headroom(ndev))
struct mana_rxq {
struct gdma_queue *gdma_rq;
@@ -661,6 +672,8 @@ struct mana_port_context {
u32 steer_cqe_coalescing;
};
+netdev_tx_t __mana_start_xmit(struct sk_buff *skb, struct net_device *ndev,
+ bool xdp);
netdev_tx_t mana_start_xmit(struct sk_buff *skb, struct net_device *ndev);
int mana_config_rss(struct mana_port_context *ac, enum TRI_STATE rx,
bool update_hash, bool update_tab);
@@ -691,6 +704,7 @@ int mana_query_link_cfg(struct mana_port_context *apc);
int mana_set_bw_clamp(struct mana_port_context *apc, u32 speed,
int enable_clamping);
void mana_query_phy_stats(struct mana_port_context *apc);
+bool mana_single_rxbuf_per_page_forced(struct mana_port_context *apc, u32 mtu);
int mana_pre_alloc_rxbufs(struct mana_port_context *apc, int mtu, int num_queues);
void mana_pre_dealloc_rxbufs(struct mana_port_context *apc);
void mana_unmap_skb(struct sk_buff *skb, struct mana_port_context *apc);
diff --git a/include/net/mptcp.h b/include/net/mptcp.h
index 485d55b66ea6..ad7005b574bb 100644
--- a/include/net/mptcp.h
+++ b/include/net/mptcp.h
@@ -219,6 +219,9 @@ int mptcp_subflow_init_cookie_req(struct request_sock *req,
struct request_sock *mptcp_subflow_reqsk_alloc(const struct request_sock_ops *ops,
struct sock *sk_listener,
bool attach_listener);
+/* Caller must hold an RCU read-side lock. */
+void mptcp_subflow_reqsk_clone(struct request_sock *req,
+ struct request_sock *new_req);
__be32 mptcp_get_reset_option(const struct sk_buff *skb);
@@ -305,6 +308,12 @@ static inline struct request_sock *mptcp_subflow_reqsk_alloc(const struct reques
return NULL;
}
+/* Caller must hold an RCU read-side lock. */
+static inline void mptcp_subflow_reqsk_clone(struct request_sock *req,
+ struct request_sock *new_req)
+{
+}
+
static inline __be32 mptcp_reset_option(const struct sk_buff *skb) { return htonl(0u); }
static inline void mptcp_active_detect_blackhole(struct sock *sk, bool expired) { }
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index 9e5379ad2d8e..91898a2475e7 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -67,6 +67,15 @@ struct prefix_info;
extern struct neigh_table nd_tbl;
+static inline struct neigh_table *nd_table(struct net *net)
+{
+#if IS_ENABLED(CONFIG_IPV6)
+ if (disable_ipv6_mod)
+ return &nd_tbl;
+#endif
+ return net->neigh_tables[NEIGH_ND_TABLE];
+}
+
struct nd_msg {
struct icmp6hdr icmph;
struct in6_addr target;
@@ -354,7 +363,9 @@ static inline u32 ndisc_hashfn(const void *pkey, const struct net_device *dev, _
static inline struct neighbour *__ipv6_neigh_lookup_noref(struct net_device *dev, const void *pkey)
{
- return ___neigh_lookup_noref(&nd_tbl, neigh_key_eq128, ndisc_hashfn, pkey, dev);
+ struct neigh_table *tbl = nd_table(dev_net(dev));
+
+ return ___neigh_lookup_noref(tbl, neigh_key_eq128, ndisc_hashfn, pkey, dev);
}
static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, const void *pkey)
@@ -370,6 +381,30 @@ static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, cons
return n;
}
+static inline struct neighbour *ipv6_neigh_lookup(struct net_device *dev,
+ const void *pkey)
+{
+ struct neigh_table *tbl = nd_table(dev_net(dev));
+
+ return neigh_lookup(tbl, pkey, dev);
+}
+
+static inline struct neighbour *ipv6_neigh_create(struct net_device *dev,
+ const void *pkey)
+{
+ struct neigh_table *tbl = nd_table(dev_net(dev));
+
+ return neigh_create(tbl, pkey, dev);
+}
+
+static inline struct neighbour *ipv6_neigh_create_noref(struct net_device *dev,
+ const void *pkey)
+{
+ struct neigh_table *tbl = nd_table(dev_net(dev));
+
+ return __neigh_create(tbl, pkey, dev, false);
+}
+
static inline void __ipv6_confirm_neigh(struct net_device *dev,
const void *pkey)
{
@@ -389,7 +424,7 @@ static inline struct neighbour *ip_neigh_gw6(struct net_device *dev,
neigh = __ipv6_neigh_lookup_noref(dev, addr);
if (unlikely(!neigh))
- neigh = __neigh_create(&nd_tbl, addr, dev, false);
+ neigh = ipv6_neigh_create_noref(dev, addr);
return neigh;
#else
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index 8860cc2175fc..79a5a548a129 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -31,6 +31,8 @@
#include <net/rtnetlink.h>
#include <net/neighbour_tables.h>
+extern int sysctl_neigh_inherit_init_net;
+
/*
* NUD stands for "neighbor unreachability detection"
*/
@@ -179,7 +181,6 @@ struct neigh_ops {
struct pneigh_entry {
struct pneigh_entry __rcu *next;
- possible_net_t net;
struct net_device *dev;
netdevice_tracker dev_tracker;
union {
@@ -234,7 +235,7 @@ struct neigh_table {
struct delayed_work managed_work;
struct timer_list proxy_timer;
struct sk_buff_head proxy_queue;
- atomic_t entries;
+ refcount_t entries;
atomic_t gc_entries;
struct list_head gc_list;
struct list_head managed_list;
@@ -339,8 +340,8 @@ static inline void neigh_confirm(struct neighbour *n)
}
}
-void neigh_table_init(int index, struct neigh_table *tbl);
-int neigh_table_clear(int index, struct neigh_table *tbl);
+int neigh_table_register(struct net *net, struct neigh_table *tbl, int index);
+void neigh_table_unregister(struct net *net, int index);
struct neighbour *neigh_lookup(struct neigh_table *tbl, const void *pkey,
struct net_device *dev);
struct neighbour *__neigh_create(struct neigh_table *tbl, const void *pkey,
@@ -389,24 +390,17 @@ static inline void neigh_set_reach_time(struct neigh_parms *p)
void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
struct sk_buff *skb);
-struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl, struct net *net,
+struct pneigh_entry *pneigh_lookup(struct neigh_table *tbl,
const void *key, struct net_device *dev);
-int pneigh_create(struct neigh_table *tbl, struct net *net, const void *key,
+int pneigh_create(struct neigh_table *tbl, const void *key,
struct net_device *dev, u32 flags, u8 protocol,
bool permanent);
-int pneigh_delete(struct neigh_table *tbl, struct net *net, const void *key,
+int pneigh_delete(struct neigh_table *tbl, const void *key,
struct net_device *dev);
-static inline struct net *pneigh_net(const struct pneigh_entry *pneigh)
-{
- return read_pnet(&pneigh->net);
-}
-
void neigh_app_ns(struct neighbour *n);
void neigh_for_each(struct neigh_table *tbl,
void (*cb)(struct neighbour *, void *), void *cookie);
-void __neigh_for_each_release(struct neigh_table *tbl,
- int (*cb)(struct neighbour *));
int neigh_xmit(int fam, struct net_device *, const void *, struct sk_buff *);
struct neigh_seq_state {
@@ -560,30 +554,6 @@ static inline int neigh_output(struct neighbour *n, struct sk_buff *skb,
return READ_ONCE(n->output)(n, skb);
}
-static inline struct neighbour *
-__neigh_lookup(struct neigh_table *tbl, const void *pkey, struct net_device *dev, int creat)
-{
- struct neighbour *n = neigh_lookup(tbl, pkey, dev);
-
- if (n || !creat)
- return n;
-
- n = neigh_create(tbl, pkey, dev);
- return IS_ERR(n) ? NULL : n;
-}
-
-static inline struct neighbour *
-__neigh_lookup_errno(struct neigh_table *tbl, const void *pkey,
- struct net_device *dev)
-{
- struct neighbour *n = neigh_lookup(tbl, pkey, dev);
-
- if (n)
- return n;
-
- return neigh_create(tbl, pkey, dev);
-}
-
struct neighbour_cb {
unsigned long sched_next;
unsigned int flags;
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index e5ee673b9fcf..c29a22ca178f 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -39,6 +39,7 @@
#include <net/netns/mctp.h>
#include <net/netns/vsock.h>
#include <net/net_trackers.h>
+#include <net/neighbour_tables.h>
#include <linux/ns_common.h>
#include <linux/idr.h>
#include <linux/skbuff.h>
@@ -47,6 +48,7 @@
struct user_namespace;
struct proc_dir_entry;
+struct neigh_table;
struct net_device;
struct sock;
struct ctl_table_header;
@@ -69,6 +71,7 @@ struct net {
spinlock_t rules_mod_lock;
unsigned int dev_base_seq; /* protected by rtnl_mutex */
+ atomic_t dev_mc_genid; /* dev->mc membership changes */
u32 ifindex;
spinlock_t nsid_lock;
@@ -103,6 +106,8 @@ struct net {
struct proc_dir_entry *proc_net;
struct proc_dir_entry *proc_net_stat;
+ struct neigh_table *neigh_tables[NEIGH_NR_TABLES];
+
#ifdef CONFIG_SYSCTL
struct ctl_table_set sysctls;
#endif
diff --git a/include/net/netdev_lock.h b/include/net/netdev_lock.h
index 9fb3e93857c3..edd8cc2e2b36 100644
--- a/include/net/netdev_lock.h
+++ b/include/net/netdev_lock.h
@@ -110,34 +110,20 @@ static inline int netdev_is_locked_ops_compat(const struct net_device *dev)
return lockdep_rtnl_is_held();
}
-static inline int netdev_lock_cmp_fn(const struct lockdep_map *a,
- const struct lockdep_map *b)
-{
- if (a == b)
- return 0;
-
- /* Allow locking multiple devices only under rtnl_lock,
- * the exact order doesn't matter.
- * Note that upper devices don't lock their ops, so nesting
- * mostly happens in batched device removal for now.
- */
- return lockdep_rtnl_is_held() ? -1 : 1;
-}
+void netdev_set_instance_lock_class(struct net_device *dev);
#define netdev_lockdep_set_classes(dev) \
{ \
static struct lock_class_key qdisc_tx_busylock_key; \
static struct lock_class_key qdisc_xmit_lock_key; \
static struct lock_class_key dev_addr_list_lock_key; \
- static struct lock_class_key dev_instance_lock_key; \
unsigned int i; \
\
(dev)->qdisc_tx_busylock = &qdisc_tx_busylock_key; \
lockdep_set_class(&(dev)->addr_list_lock, \
&dev_addr_list_lock_key); \
- lockdep_set_class(&(dev)->lock, \
- &dev_instance_lock_key); \
- lock_set_cmp_fn(&dev->lock, netdev_lock_cmp_fn, NULL); \
+ if (IS_ENABLED(CONFIG_PROVE_LOCKING)) \
+ netdev_set_instance_lock_class(dev); \
for (i = 0; i < (dev)->num_tx_queues; i++) \
lockdep_set_class(&(dev)->_tx[i]._xmit_lock, \
&qdisc_xmit_lock_key); \
diff --git a/include/net/netdev_queues.h b/include/net/netdev_queues.h
index 70c9fe9e83cc..c5335e935b7d 100644
--- a/include/net/netdev_queues.h
+++ b/include/net/netdev_queues.h
@@ -5,17 +5,55 @@
#include <linux/netdevice.h>
/**
+ * struct netdev_ring_config - accepted RX ring depth configuration
+ * @rx_pending: Size of the regular RX ring.
+ * @rx_mini_pending: Size of the RX mini ring.
+ * @rx_jumbo_pending: Size of the RX jumbo ring.
+ *
+ * This stores only persistent configuration values. Capability fields,
+ * such as max ring sizes, are reported by drivers but are not part of the
+ * accepted configuration.
+ *
+ * These values are only used for queue-configuration validation today.
+ * Drivers which normalize ring sizes must update the struct ethtool_ringparam
+ * passed to set_ringparam() with the applied sizes.
+ */
+struct netdev_ring_config {
+ u32 rx_pending;
+ u32 rx_mini_pending;
+ u32 rx_jumbo_pending;
+};
+
+/**
* struct netdev_config - queue-related configuration for a netdev
* @hds_thresh: HDS Threshold value.
* @hds_config: HDS value from userspace.
+ * @rings: Accepted RX ring depths.
+ *
+ * Direct values, such as @hds_thresh and @rings, hold the accepted
+ * configuration and always override callback-provided defaults, including
+ * when zero. Drivers which use @rings for queue rendering must initialize
+ * every RX ring depth before registering the netdev.
*/
struct netdev_config {
u32 hds_thresh;
u8 hds_config;
+
+ struct netdev_ring_config rings;
};
+/**
+ * struct netdev_queue_config - rendered configuration for an RX queue
+ * @rx_page_size: Size of one RX page-pool allocation.
+ * @rx_ring_size: Configured size of the regular RX ring.
+ * @rx_mini_ring_size: Configured size of the RX mini ring.
+ * @rx_jumbo_ring_size: Configured size of the RX jumbo ring.
+ */
struct netdev_queue_config {
u32 rx_page_size;
+ u32 rx_ring_size;
+ u32 rx_mini_ring_size;
+ u32 rx_jumbo_ring_size;
};
/* See the netdev.yaml spec for definition of each statistic */
@@ -139,16 +177,20 @@ enum {
* @ndo_queue_get_dma_dev: Get dma device for zero-copy operations to be used
* for this queue. Return NULL on error.
*
- * @ndo_default_qcfg: (Optional) Populate queue config struct with defaults.
- * Queue config structs are passed to this helper before
- * the user-requested settings are applied.
+ * @ndo_default_qcfg: (Optional) Populate queue config with defaults. Queue
+ * config structs are passed to this helper before the
+ * user-requested settings are applied. Ring depths from
+ * dev->cfg override these defaults. Drivers which consume
+ * them must initialize dev->cfg->rings before registering
+ * the netdev.
*
* @ndo_validate_qcfg: (Optional) Check if queue config is supported.
* Called when configuration affecting a queue may be
- * changing, either due to NIC-wide config, or config
- * scoped to the queue at a specified index.
- * When NIC-wide config is changed the callback will
- * be invoked for all queues.
+ * changing. When NIC-wide config is changed the
+ * callback will be invoked for the defaults and all
+ * queue overrides. Drivers which normalize device-wide
+ * values when applying them must use the same
+ * normalization during validation.
*
* @ndo_queue_create: Create a new RX queue on a virtual device that will
* be paired with a physical device's queue via leasing.
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index bc42dd0e10e6..c39425e54d87 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -185,6 +185,11 @@ static inline void nf_ct_put(struct nf_conn *ct)
nf_ct_destroy(&ct->ct_general);
}
+static inline bool nf_ct_shared(const struct nf_conn *ct)
+{
+ return refcount_read(&ct->ct_general.use) > 1;
+}
+
/* load module; enable/disable conntrack in this namespace */
int nf_ct_netns_get(struct net *net, u8 nfproto);
void nf_ct_netns_put(struct net *net, u8 nfproto);
diff --git a/include/net/netfilter/nf_conntrack_seqadj.h b/include/net/netfilter/nf_conntrack_seqadj.h
index 883c414b768e..0f5bbb14a25a 100644
--- a/include/net/netfilter/nf_conntrack_seqadj.h
+++ b/include/net/netfilter/nf_conntrack_seqadj.h
@@ -33,6 +33,7 @@ static inline struct nf_conn_seqadj *nfct_seqadj_ext_add(struct nf_conn *ct)
int nf_ct_seqadj_init(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
s32 off);
+void nf_ct_seqadj_reset(struct nf_conn *ct, enum ip_conntrack_info ctinfo);
int nf_ct_seqadj_set(struct nf_conn *ct, enum ip_conntrack_info ctinfo,
__be32 seq, s32 off);
void nf_ct_tcp_seqadj_set(struct sk_buff *skb, struct nf_conn *ct,
diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h
index f2e2771f188f..5b22d31cb140 100644
--- a/include/net/netfilter/nf_flow_table.h
+++ b/include/net/netfilter/nf_flow_table.h
@@ -118,6 +118,7 @@ struct flow_offload_tunnel {
};
u8 inner_proto;
+ u8 encap_proto;
};
struct flow_offload_tuple {
@@ -183,10 +184,10 @@ enum nf_flow_flags {
NF_FLOW_DNAT,
NF_FLOW_CLOSING,
NF_FLOW_TEARDOWN,
+ NF_FLOW_PENDING,
NF_FLOW_HW,
NF_FLOW_HW_DYING,
NF_FLOW_HW_DEAD,
- NF_FLOW_HW_PENDING,
NF_FLOW_HW_BIDIRECTIONAL,
NF_FLOW_HW_ESTABLISHED,
};
diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h
index fc3e81c07364..86021c55ba3c 100644
--- a/include/net/netfilter/nf_queue.h
+++ b/include/net/netfilter/nf_queue.h
@@ -35,7 +35,8 @@ struct nf_queue_entry {
struct nf_queue_handler {
int (*outfn)(struct nf_queue_entry *entry,
unsigned int queuenum);
- void (*nf_hook_drop)(struct net *net);
+ void (*nf_hook_drop)(struct net *net,
+ const struct nf_hook_ops *ops);
};
void nf_register_queue_handler(const struct nf_queue_handler *qh);
diff --git a/include/net/netmem.h b/include/net/netmem.h
index bccacd21b6c3..fb693bc1702a 100644
--- a/include/net/netmem.h
+++ b/include/net/netmem.h
@@ -70,16 +70,18 @@ enum net_iov_type {
NET_IOV_IOURING,
};
-/* A memory descriptor representing abstract networking I/O vectors,
- * generally for non-pages memory that doesn't have its corresponding
- * struct page and needs to be explicitly allocated through slab.
+/* A memory descriptor representing abstract networking I/O vectors.
*
* net_iovs are allocated and used by networking code, and the size of
* the chunk is PAGE_SIZE.
*
- * This memory can be any form of non-struct paged memory. Examples
- * include imported dmabuf memory and imported io_uring memory. See
- * net_iov_type for all the supported types.
+ * Examples include imported dmabuf memory and imported io_uring memory. See
+ * net_iov_type for all the supported types. While current net_iov types are
+ * unreadable by the CPU, net_iov has no inherent restrictions and may be
+ * CPU-readable or unreadable. New code must not assume net_iov implies
+ * unreadable memory (check readability via netmem_address() or
+ * skb_frags_readable() instead) and should, as much as possible, generalize
+ * existing limitations to match the design principles.
*
* @pp_magic: pp field, similar to the one in struct page/struct
* netmem_desc.
@@ -102,9 +104,6 @@ struct net_iov_area {
/* Array of net_iovs for this area. */
struct net_iov *niovs;
size_t num_niovs;
-
- /* Offset into the dma-buf where this chunk starts. */
- unsigned long base_virtual;
};
static inline struct net_iov_area *net_iov_owner(const struct net_iov *niov)
@@ -134,8 +133,17 @@ static inline void net_iov_init(struct net_iov *niov,
* network memory.
*
* A netmem_ref can be a struct page* or a struct net_iov* underneath.
+ * Memory providers (or the default page_pool allocator) allocate struct
+ * net_iov or struct page, cast them to netmem_ref, and hand them to
+ * page_pool.
*
- * Use the supplied helpers to obtain the underlying memory pointer and fields.
+ * The page_pool, drivers, and core networking stack should operate on
+ * netmem_ref rather than struct page or struct net_iov. Downcasting
+ * netmem_ref via netmem_to_page() or netmem_to_net_iov() in callers is
+ * not allowed unless a code path strictly requires a specific backing
+ * type (e.g., kmap_local_page()). In such cases, add a netmem helper here
+ * that handles both page and net_iov cases and returns an error if the
+ * underlying type cannot support the operation.
*/
typedef unsigned long __bitwise netmem_ref;
@@ -300,9 +308,8 @@ static inline atomic_long_t *netmem_get_pp_ref_count_ref(netmem_ref netmem)
static inline bool netmem_is_pref_nid(netmem_ref netmem, int pref_nid)
{
- /* NUMA node preference only makes sense if we're allocating
- * system memory. Memory providers (which give us net_iovs)
- * choose for us.
+ /* NUMA node preference only applies to struct page; net_iovs are
+ * managed by their memory provider.
*/
if (netmem_is_net_iov(netmem))
return true;
@@ -358,6 +365,33 @@ static inline bool netmem_is_pfmemalloc(netmem_ref netmem)
return page_is_pfmemalloc(netmem_to_page(netmem));
}
+#define NETMEM_32BIT_ARCH_WITH_64BIT_DMA \
+ (sizeof(dma_addr_t) > sizeof(unsigned long))
+
+static inline unsigned long netmem_dma_addr_encode(dma_addr_t addr)
+{
+ if (NETMEM_32BIT_ARCH_WITH_64BIT_DMA)
+ addr >>= PAGE_SHIFT;
+
+ return addr;
+}
+
+static inline dma_addr_t netmem_dma_addr_decode(unsigned long addr)
+{
+ if (NETMEM_32BIT_ARCH_WITH_64BIT_DMA)
+ return (dma_addr_t)addr << PAGE_SHIFT;
+
+ return addr;
+}
+
+static inline bool netmem_dma_addr_fits(dma_addr_t addr)
+{
+ /* We assume page alignment to shave off bottom bits,
+ * if this "compression" doesn't work we need to drop.
+ */
+ return addr == netmem_dma_addr_decode(netmem_dma_addr_encode(addr));
+}
+
static inline unsigned long netmem_get_dma_addr(netmem_ref netmem)
{
return netmem_to_nmdesc(netmem)->dma_addr;
@@ -375,21 +409,37 @@ static inline bool net_is_devmem_iov(const struct net_iov *niov)
}
#endif
-void __get_netmem(netmem_ref netmem);
-void __put_netmem(netmem_ref netmem);
+void net_iov_inc_ref(struct net_iov *niov);
+void net_iov_dec_ref(struct net_iov *niov);
-static __always_inline void get_netmem(netmem_ref netmem)
+/**
+ * netmem_inc_ref - acquire a non-page_pool reference on a netmem
+ * @netmem: netmem to reference
+ *
+ * Acquires a non-pp backing reference (page._refcount via get_page() or
+ * binding->ref via net_iov_inc_ref()) regardless of page_pool membership.
+ * Counterpart to netmem_dec_ref().
+ */
+static __always_inline void netmem_inc_ref(netmem_ref netmem)
{
if (netmem_is_net_iov(netmem))
- __get_netmem(netmem);
+ net_iov_inc_ref(netmem_to_net_iov(netmem));
else
get_page(netmem_to_page(netmem));
}
-static __always_inline void put_netmem(netmem_ref netmem)
+/**
+ * netmem_dec_ref - release a non-page_pool reference on a netmem
+ * @netmem: netmem to unreference
+ *
+ * Drops a non-pp backing reference (page._refcount via put_page() or
+ * binding->ref via net_iov_dec_ref()) regardless of page_pool membership.
+ * Counterpart to netmem_inc_ref().
+ */
+static __always_inline void netmem_dec_ref(netmem_ref netmem)
{
if (netmem_is_net_iov(netmem))
- __put_netmem(netmem);
+ net_iov_dec_ref(netmem_to_net_iov(netmem));
else
put_page(netmem_to_page(netmem));
}
diff --git a/include/net/netns/netfilter.h b/include/net/netns/netfilter.h
index a6a0bf4a247e..7fd78394d1e7 100644
--- a/include/net/netns/netfilter.h
+++ b/include/net/netns/netfilter.h
@@ -33,5 +33,7 @@ struct netns_nf {
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
unsigned int defrag_ipv6_users;
#endif
+ unsigned int hook_base_seq;
+ unsigned int nat_hook_base_seq;
};
#endif
diff --git a/include/net/nfc/hci.h b/include/net/nfc/hci.h
index 756c11084f65..86ed63e5d533 100644
--- a/include/net/nfc/hci.h
+++ b/include/net/nfc/hci.h
@@ -144,7 +144,7 @@ struct nfc_hci_dev {
data_exchange_cb_t async_cb;
void *async_cb_context;
- u8 *gb;
+ u8 gb[NFC_MAX_GT_LEN];
size_t gb_len;
unsigned long quirks;
diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h
index c54df042db6b..bcafab5c53e5 100644
--- a/include/net/nfc/nfc.h
+++ b/include/net/nfc/nfc.h
@@ -273,7 +273,8 @@ struct sk_buff *nfc_alloc_recv_skb(unsigned int size, gfp_t gfp);
int nfc_set_remote_general_bytes(struct nfc_dev *dev,
const u8 *gt, u8 gt_len);
-u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, size_t *gb_len);
+u8 *nfc_get_local_general_bytes(struct nfc_dev *dev, u8 *out_gb,
+ size_t gb_max_len, size_t *gb_len);
int nfc_fw_download_done(struct nfc_dev *dev, const char *firmware_name,
u32 result);
diff --git a/include/net/page_pool/helpers.h b/include/net/page_pool/helpers.h
index e2730dd273b2..28635ce9454e 100644
--- a/include/net/page_pool/helpers.h
+++ b/include/net/page_pool/helpers.h
@@ -8,12 +8,20 @@
/**
* DOC: page_pool allocator
*
- * The page_pool allocator is optimized for recycling page or page fragment used
- * by skb packet and xdp frame.
+ * The page_pool allocator is optimized for recycling network memory
+ * (netmem_ref) or fragments used by skb packets and xdp frames.
*
- * Basic use involves replacing any alloc_pages() calls with page_pool_alloc(),
- * which allocate memory with or without page splitting depending on the
- * requested memory size.
+ * page_pool natively operates on netmem_ref, which abstracts the underlying
+ * memory type (struct page or struct net_iov) supplied by the page allocator
+ * or a memory provider. Drivers and core networking code should use the
+ * netmem-based APIs (e.g. page_pool_alloc_netmem(), page_pool_put_netmem()).
+ * The struct page-based APIs (e.g. page_pool_alloc(), page_pool_alloc_pages(),
+ * page_pool_put_page()) are legacy compatibility wrappers for drivers not yet
+ * converted to netmem.
+ *
+ * Basic use involves replacing any alloc_pages() calls with
+ * page_pool_alloc_netmem() (or legacy page_pool_alloc()), which allocate memory
+ * with or without splitting depending on the requested memory size.
*
* If the driver knows that it always requires full pages or its allocations are
* always smaller than half a page, it can use one of the more specific API
@@ -408,16 +416,13 @@ static inline void page_pool_recycle_direct_netmem(struct page_pool *pool,
page_pool_put_full_netmem(pool, netmem, true);
}
-#define PAGE_POOL_32BIT_ARCH_WITH_64BIT_DMA \
- (sizeof(dma_addr_t) > sizeof(unsigned long))
-
/**
* page_pool_free_va() - free a va into the page_pool
* @pool: pool from which va was allocated
* @va: va to be freed
* @allow_direct: freed by the consumer, allow lockless caching
*
- * Free a va allocated from page_pool_allo_va().
+ * Free a va allocated from page_pool_alloc_va().
*/
static inline void page_pool_free_va(struct page_pool *pool, void *va,
bool allow_direct)
@@ -427,12 +432,7 @@ static inline void page_pool_free_va(struct page_pool *pool, void *va,
static inline dma_addr_t page_pool_get_dma_addr_netmem(netmem_ref netmem)
{
- dma_addr_t ret = netmem_get_dma_addr(netmem);
-
- if (PAGE_POOL_32BIT_ARCH_WITH_64BIT_DMA)
- ret <<= PAGE_SHIFT;
-
- return ret;
+ return netmem_dma_addr_decode(netmem_get_dma_addr(netmem));
}
/**
diff --git a/include/net/page_pool/memory_provider.h b/include/net/page_pool/memory_provider.h
index 255ce4cfd975..137cfc50833a 100644
--- a/include/net/page_pool/memory_provider.h
+++ b/include/net/page_pool/memory_provider.h
@@ -9,6 +9,16 @@ struct netdev_rx_queue;
struct netlink_ext_ack;
struct sk_buff;
+/* Memory providers allocate underlying memory (struct net_iov or struct page),
+ * cast it to netmem_ref, and supply it to page_pool. While current memory
+ * providers only return struct net_iov, they are not architecturally limited to
+ * net_iov; a provider returning page-backed netmems is allowed. New code must
+ * not assume a memory provider implies net_iov and should, as much as possible,
+ * generalize existing limitations to match the design principles.
+ *
+ * Per-provider custom logic must be delegated to memory_provider_ops rather
+ * than handled directly in page_pool core code.
+ */
struct memory_provider_ops {
netmem_ref (*alloc_netmems)(struct page_pool *pool, gfp_t gfp);
bool (*release_netmem)(struct page_pool *pool, netmem_ref netmem);
diff --git a/include/net/page_pool/types.h b/include/net/page_pool/types.h
index 03da138722f5..6d543076a0c0 100644
--- a/include/net/page_pool/types.h
+++ b/include/net/page_pool/types.h
@@ -22,9 +22,9 @@
*/
#define PP_FLAG_SYSTEM_POOL BIT(2) /* Global system page_pool */
-/* Allow unreadable (net_iov backed) netmem in this page_pool. Drivers setting
- * this must be able to support unreadable netmem, where netmem_address() would
- * return NULL. This flag should not be set for header page_pools.
+/* Allow unreadable netmem in this page_pool. Drivers setting this must be able
+ * to support unreadable netmem, where netmem_address() returns NULL. This flag
+ * should not be set for header page_pools.
*
* If the driver sets PP_FLAG_ALLOW_UNREADABLE_NETMEM, it should also set
* page_pool_params.slow.queue_idx.
diff --git a/include/net/phy/realtek_phy.h b/include/net/phy/realtek_phy.h
deleted file mode 100644
index d683bc1b0659..000000000000
--- a/include/net/phy/realtek_phy.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef _REALTEK_PHY_H
-#define _REALTEK_PHY_H
-
-#define PHY_ID_RTL_DUMMY_SFP 0x001ccbff
-
-#endif /* _REALTEK_PHY_H */
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 5f5cb36439fe..9382405b2bab 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -316,10 +316,8 @@ tcf_exts_hw_stats_update(const struct tcf_exts *exts,
continue;
}
- preempt_disable();
tcf_action_stats_update(a, stats->bytes, stats->pkts, stats->drops,
stats->lastused, true);
- preempt_enable();
a->used_hw_stats = stats->used_hw_stats;
a->used_hw_stats_valid = stats->used_hw_stats_valid;
diff --git a/include/net/psp/functions.h b/include/net/psp/functions.h
index c5c23a54774e..b23c30898389 100644
--- a/include/net/psp/functions.h
+++ b/include/net/psp/functions.h
@@ -24,11 +24,6 @@ int psp_dev_rcv(struct sk_buff *skb, u16 dev_id, u8 generation, bool strip_icv);
/* Kernel-facing API */
void psp_assoc_put(struct psp_assoc *pas);
-static inline void *psp_assoc_drv_data(struct psp_assoc *pas)
-{
- return pas->drv_data;
-}
-
#if IS_ENABLED(CONFIG_INET_PSP)
unsigned int psp_key_size(u32 version);
void psp_sk_assoc_free(struct sock *sk);
diff --git a/include/net/psp/types.h b/include/net/psp/types.h
index 87991a1ea02d..b8905efbd604 100644
--- a/include/net/psp/types.h
+++ b/include/net/psp/types.h
@@ -219,12 +219,16 @@ struct psp_dev_ops {
* @tx_key_add: add a Tx key to the device
* Install an association in the device. Core will allocate space
* for the driver to use at drv_data.
+ * Can be left NULL if device does not store Tx keys and @tx_key_del
+ * is also NULL.
*/
int (*tx_key_add)(struct psp_dev *psd, struct psp_assoc *pas,
struct netlink_ext_ack *extack);
/**
* @tx_key_del: remove a Tx key from the device
* Remove an association from the device.
+ * Can be left NULL if device does not store Tx keys and @tx_key_add
+ * is also NULL.
*/
void (*tx_key_del)(struct psp_dev *psd, struct psp_assoc *pas);
diff --git a/include/net/route.h b/include/net/route.h
index 45290177a33c..3fccd31eb74d 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -129,7 +129,13 @@ struct in_device;
int ip_rt_init(void);
void rt_cache_flush(struct net *net);
+#ifdef CONFIG_INET
void rt_flush_dev(struct net_device *dev);
+#else
+static inline void rt_flush_dev(struct net_device *dev)
+{
+}
+#endif
static inline void inet_sk_init_flowi4(const struct inet_sock *inet,
struct flowi4 *fl4)
@@ -405,8 +411,11 @@ static inline struct neighbour *ip_neigh_gw4(struct net_device *dev,
struct neighbour *neigh;
neigh = __ipv4_neigh_lookup_noref(dev, (__force u32)daddr);
- if (unlikely(!neigh))
- neigh = __neigh_create(&arp_tbl, &daddr, dev, false);
+ if (unlikely(!neigh)) {
+ struct neigh_table *tbl = arp_table(dev_net(dev));
+
+ neigh = __neigh_create(tbl, &daddr, dev, false);
+ }
return neigh;
}
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index cbc248776511..1acaadb3e2cf 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -793,7 +793,7 @@ void qdisc_offload_query_caps(struct net_device *dev,
struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
const struct Qdisc_ops *ops,
struct netlink_ext_ack *extack);
-void qdisc_free(struct Qdisc *qdisc);
+void qdisc_free_rcu(struct Qdisc *qdisc);
struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
const struct Qdisc_ops *ops, u32 parentid,
struct netlink_ext_ack *extack);
@@ -810,6 +810,15 @@ static inline bool skb_at_tc_ingress(const struct sk_buff *skb)
#endif
}
+static inline bool skb_at_tc_egress(const struct sk_buff *skb)
+{
+#ifdef CONFIG_NET_EGRESS
+ return skb->nf_skip_egress && !skb_at_tc_ingress(skb);
+#else
+ return false;
+#endif
+}
+
static inline bool skb_skip_tc_classify(struct sk_buff *skb)
{
#ifdef CONFIG_NET_CLS_ACT
diff --git a/include/net/scm.h b/include/net/scm.h
index 86ae6bc109ec..b68a143f42de 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -42,7 +42,7 @@ struct scm_fp_list {
};
struct scm_cookie {
- struct pid *pid; /* Skb credentials */
+ DECLARE_PIDS(pid, PIDTYPE_TGID); /* Skb credentials by pid type */
struct scm_fp_list *fp; /* Passed files */
struct scm_creds creds; /* Skb credentials */
#ifdef CONFIG_SECURITY_NETWORK
@@ -69,7 +69,6 @@ static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_co
static __inline__ void scm_set_cred(struct scm_cookie *scm,
struct pid *pid, kuid_t uid, kgid_t gid)
{
- scm->pid = get_pid(pid);
scm->creds.pid = pid_vnr(pid);
scm->creds.uid = uid;
scm->creds.gid = gid;
@@ -77,8 +76,7 @@ static __inline__ void scm_set_cred(struct scm_cookie *scm,
static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
{
- put_pid(scm->pid);
- scm->pid = NULL;
+ put_pids(scm->pid);
}
static __inline__ void scm_destroy(struct scm_cookie *scm)
@@ -94,8 +92,10 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
memset(scm, 0, sizeof(*scm));
scm->creds.uid = INVALID_UID;
scm->creds.gid = INVALID_GID;
- if (forcecreds)
+ if (forcecreds) {
+ scm->pid[PIDTYPE_TGID] = get_pid(task_tgid(current));
scm_set_cred(scm, task_tgid(current), current_uid(), current_gid());
+ }
unix_get_peersec_dgram(sock, scm);
if (msg->msg_controllen <= 0)
return 0;
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 3bfd261a53cc..76605d1ee839 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -252,6 +252,7 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
struct sctp_fwdtsn_skip *skiplist);
struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc,
__u16 key_id);
+void sctp_control_set_owner_w(struct sctp_chunk *chunk);
struct sctp_chunk *sctp_make_strreset_req(const struct sctp_association *asoc,
__u16 stream_num, __be16 *stream_list,
bool out, bool in);
diff --git a/include/net/seg6_hmac.h b/include/net/seg6_hmac.h
index e9f41725933e..3161a8104b89 100644
--- a/include/net/seg6_hmac.h
+++ b/include/net/seg6_hmac.h
@@ -48,7 +48,8 @@ extern int seg6_hmac_info_add(struct net *net, u32 key,
extern int seg6_hmac_info_del(struct net *net, u32 key);
extern int seg6_push_hmac(struct net *net, struct in6_addr *saddr,
struct ipv6_sr_hdr *srh);
-extern bool seg6_hmac_validate_skb(struct sk_buff *skb);
+extern bool seg6_hmac_validate_skb(struct sk_buff *skb,
+ struct ipv6_sr_hdr *srh);
#ifdef CONFIG_IPV6_SEG6_HMAC
extern int seg6_hmac_net_init(struct net *net);
extern void seg6_hmac_net_exit(struct net *net);
diff --git a/include/net/sock.h b/include/net/sock.h
index 51185222aac2..173b37b2b8bb 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -301,7 +301,7 @@ struct sk_filter;
* @sk_type: socket type (%SOCK_STREAM, etc)
* @sk_protocol: which protocol this socket belongs in this network family
* @sk_peer_lock: lock protecting @sk_peer_pid and @sk_peer_cred
- * @sk_peer_pid: &struct pid for this socket's peer
+ * @sk_peer_pid: &struct pid for this socket's peer, by pid type
* @sk_peer_cred: %SO_PEERCRED setting
* @sk_rcvlowat: %SO_RCVLOWAT setting
* @sk_rcvtimeo: %SO_RCVTIMEO setting
@@ -356,6 +356,7 @@ struct sk_filter;
* @sk_scm_security: flagged by SO_PASSSEC to recv SCM_SECURITY
* @sk_scm_pidfd: flagged by SO_PASSPIDFD to recv SCM_PIDFD
* @sk_scm_rights: flagged by SO_PASSRIGHTS to recv SCM_RIGHTS
+ * @sk_scm_pidfd_thread: flagged by SO_PASSPIDFD_THREAD to recv a thread SCM_PIDFD
* @sk_scm_unused: unused flags for scm_recv()
* @ns_tracker: tracker for netns reference
* @sk_user_frags: xarray of pages the user is holding a reference on.
@@ -545,7 +546,7 @@ struct sock {
u64 sk_ino;
spinlock_t sk_peer_lock;
int sk_bind_phc;
- struct pid *sk_peer_pid;
+ DECLARE_PIDS(sk_peer_pid, PIDTYPE_TGID);
const struct cred *sk_peer_cred;
ktime_t sk_stamp;
@@ -562,7 +563,8 @@ struct sock {
sk_scm_security : 1,
sk_scm_pidfd : 1,
sk_scm_rights : 1,
- sk_scm_unused : 4;
+ sk_scm_pidfd_thread : 1,
+ sk_scm_unused : 3;
};
};
u8 sk_clockid;
@@ -1129,6 +1131,8 @@ static inline void sk_forward_alloc_add(struct sock *sk, int val)
}
void sk_stream_write_space(struct sock *sk);
+void sk_set_nospace(struct sock *sk);
+void sk_clear_nospace(struct sock *sk);
/* OOB backlog add */
static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb)
@@ -2312,6 +2316,8 @@ static inline void sk_gso_disable(struct sock *sk)
sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
}
+bool sk_has_decrypt_user(const struct sock *sk);
+
static inline int skb_do_copy_data_nocache(struct sock *sk, struct sk_buff *skb,
struct iov_iter *from, char *to,
int copy, int offset)
diff --git a/include/net/strparser.h b/include/net/strparser.h
index 0ed73e364faa..c2938eda3e79 100644
--- a/include/net/strparser.h
+++ b/include/net/strparser.h
@@ -32,7 +32,6 @@ struct strp_aggr_stats {
unsigned int msg_too_big;
unsigned int msg_timeouts;
unsigned int bad_hdr_len;
- unsigned int aborts;
unsigned int interrupted;
unsigned int unrecov_intr;
};
@@ -46,9 +45,6 @@ struct strp_callbacks {
int (*read_sock)(struct strparser *strp, read_descriptor_t *desc,
sk_read_actor_t recv_actor);
int (*read_sock_done)(struct strparser *strp, int err);
- void (*abort_parser)(struct strparser *strp, int err);
- void (*lock)(struct strparser *strp);
- void (*unlock)(struct strparser *strp);
};
struct strp_msg {
@@ -91,11 +87,10 @@ static inline struct strp_msg *strp_msg(struct sk_buff *skb)
struct strparser {
struct sock *sk;
- u32 stopped : 1;
- u32 paused : 1;
- u32 aborted : 1;
- u32 interrupted : 1;
- u32 unrecov_intr : 1;
+ u8 stopped;
+ u8 paused;
+ u8 interrupted;
+ u8 unrecov_intr;
struct sk_buff **skb_nextp;
struct sk_buff *skb_head;
@@ -131,8 +126,6 @@ static inline void save_strp_stats(struct strparser *strp,
SAVE_PSOCK_STATS(bad_hdr_len);
#undef SAVE_PSOCK_STATS
- if (strp->aborted)
- agg_stats->aborts++;
if (strp->interrupted)
agg_stats->interrupted++;
if (strp->unrecov_intr)
@@ -150,7 +143,6 @@ static inline void aggregate_strp_stats(struct strp_aggr_stats *stats,
SAVE_PSOCK_STATS(msg_too_big);
SAVE_PSOCK_STATS(msg_timeouts);
SAVE_PSOCK_STATS(bad_hdr_len);
- SAVE_PSOCK_STATS(aborts);
SAVE_PSOCK_STATS(interrupted);
SAVE_PSOCK_STATS(unrecov_intr);
#undef SAVE_PSOCK_STATS
@@ -163,8 +155,5 @@ void strp_check_rcv(struct strparser *strp);
int strp_init(struct strparser *strp, struct sock *sk,
const struct strp_callbacks *cb);
void strp_data_ready(struct strparser *strp);
-int strp_process(struct strparser *strp, struct sk_buff *orig_skb,
- unsigned int orig_offset, size_t orig_len,
- size_t max_msg_size, long timeo);
#endif /* __NET_STRPARSER_H_ */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 436495ff2271..3560adddf821 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -512,6 +512,7 @@ void tcp_set_keepalive(struct sock *sk, int val);
void tcp_syn_ack_timeout(const struct request_sock *req);
int tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
int flags);
+int __tcp_set_rcvlowat(struct sock *sk, int val, bool wakeup);
int tcp_set_rcvlowat(struct sock *sk, int val);
void tcp_set_rcvbuf(struct sock *sk, int val);
int tcp_set_window_clamp(struct sock *sk, int val);
@@ -783,14 +784,42 @@ void tcp_done_with_error(struct sock *sk, int err);
void tcp_reset(struct sock *sk, struct sk_buff *skb);
void tcp_fin(struct sock *sk);
void __tcp_check_space(struct sock *sk);
+
+/* Mirror of SOCK_NOSPACE in tcp_sock, maintained by sk_set_nospace()
+ * and sk_clear_nospace().
+ *
+ * MPTCP subflows share the parent socket, and thus its SOCK_NOSPACE bit.
+ * Keep their mirror always set (see subflow_ulp_init()) so that they
+ * always reach __tcp_check_space() and behave as before.
+ */
+static inline void tcp_set_nospace(struct sock *sk)
+{
+ if (sk_is_tcp(sk)) {
+ /* pairs with smp_mb__before_atomic() in tcp_clear_nospace() */
+ smp_mb__after_atomic();
+ /* pairs with smp_mb() in tcp_check_space() */
+ smp_store_mb(tcp_sk(sk)->tcp_nospace, 1);
+ }
+}
+
+static inline void tcp_clear_nospace(struct sock *sk)
+{
+ if (sk_is_tcp(sk) && !sk_is_mptcp(sk)) {
+ WRITE_ONCE(tcp_sk(sk)->tcp_nospace, 0);
+ /* pairs with smp_mb__after_atomic() in tcp_set_nospace() */
+ smp_mb__before_atomic();
+ }
+}
+
static inline void tcp_check_space(struct sock *sk)
{
/* pairs with tcp_poll() */
smp_mb();
- if (sk->sk_socket && test_bit(SOCK_NOSPACE, &sk->sk_socket->flags))
+ if (unlikely(READ_ONCE(tcp_sk(sk)->tcp_nospace)))
__tcp_check_space(sk);
}
+
void tcp_sack_compress_send_ack(struct sock *sk);
static inline void tcp_cleanup_skb(struct sk_buff *skb)
@@ -823,6 +852,9 @@ unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu);
unsigned int tcp_current_mss(struct sock *sk);
u32 tcp_clamp_probe0_to_user_timeout(const struct sock *sk, u32 when);
+u32 tcp_tso_autosize(const struct sock *sk, unsigned int mss_now,
+ int min_tso_segs);
+
/* Bound MSS / TSO packet size with the half of the window */
static inline int tcp_bound_to_half_wnd(struct tcp_sock *tp, int pktsize)
{
@@ -1232,9 +1264,9 @@ static inline bool tcp_skb_can_collapse_to(const struct sk_buff *skb)
static inline bool tcp_skb_can_collapse(const struct sk_buff *to,
const struct sk_buff *from)
{
- /* skb_cmp_decrypted() not needed, use tcp_write_collapse_fence() */
return likely(tcp_skb_can_collapse_to(to) &&
mptcp_skb_can_collapse(to, from) &&
+ !skb_cmp_decrypted(to, from) &&
skb_pure_zcopy_same(to, from) &&
skb_frags_readable(to) == skb_frags_readable(from));
}
@@ -1360,8 +1392,16 @@ struct tcp_congestion_ops {
/* hook for packet ack accounting (optional) */
void (*pkts_acked)(struct sock *sk, const struct ack_sample *sample);
- /* override sysctl_tcp_min_tso_segs (optional) */
- u32 (*min_tso_segs)(struct sock *sk);
+ /* Override tcp_tso_autosize() (optional)
+ *
+ * If provided, this callback supplies the TSO segment target count
+ * instead of using tcp_tso_autosize(). The returned value is
+ * subsequently clamped to [1, sk->sk_gso_max_segs] by the caller.
+ *
+ * For the kernel callback path, mss_now originates from
+ * tcp_current_mss() and should never be zero.
+ */
+ u32 (*tso_segs)(struct sock *sk, u32 mss_now);
/* new value of cwnd after loss (required) */
u32 (*undo_cwnd)(struct sock *sk);
@@ -2327,7 +2367,7 @@ static inline void tcp_rtx_queue_unlink_and_free(struct sk_buff *skb, struct soc
static inline void tcp_write_collapse_fence(struct sock *sk)
{
- struct sk_buff *skb = tcp_write_queue_tail(sk);
+ struct sk_buff *skb = tcp_write_queue_tail(sk) ?: tcp_rtx_queue_tail(sk);
if (skb)
TCP_SKB_CB(skb)->eor = 1;
@@ -2891,7 +2931,7 @@ static inline void bpf_skops_init_skb(struct bpf_sock_ops_kern *skops,
* program loaded).
*/
#ifdef CONFIG_BPF
-static inline int tcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args)
+static inline int __tcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args)
{
struct bpf_sock_ops_kern sock_ops;
int ret;
@@ -2908,7 +2948,7 @@ static inline int tcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args)
if (nargs > 0)
memcpy(sock_ops.args, args, nargs * sizeof(*args));
- ret = BPF_CGROUP_RUN_PROG_SOCK_OPS(&sock_ops);
+ ret = __BPF_CGROUP_RUN_PROG_SOCK_OPS(&sock_ops);
if (ret == 0)
ret = sock_ops.reply;
else
@@ -2916,42 +2956,37 @@ static inline int tcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args)
return ret;
}
-static inline int tcp_call_bpf_2arg(struct sock *sk, int op, u32 arg1, u32 arg2)
-{
- u32 args[2] = {arg1, arg2};
-
- return tcp_call_bpf(sk, op, 2, args);
-}
-
-static inline int tcp_call_bpf_3arg(struct sock *sk, int op, u32 arg1, u32 arg2,
- u32 arg3)
-{
- u32 args[3] = {arg1, arg2, arg3};
-
- return tcp_call_bpf(sk, op, 3, args);
-}
+#define tcp_call_bpf(sk, op) \
+({ \
+ int __ret = 0; \
+ if (cgroup_bpf_enabled(CGROUP_SOCK_OPS)) { \
+ __ret = __tcp_call_bpf(sk, op, 0, NULL); \
+ } \
+ __ret; \
+})
+
+#define tcp_call_bpf_flag(sk, op, ...) \
+do { \
+ if (cgroup_bpf_enabled(CGROUP_SOCK_OPS) && \
+ BPF_SOCK_OPS_TEST_FLAG(tcp_sk(sk), op ## _FLAG)) { \
+ u32 __args[] = { __VA_ARGS__ }; \
+ __tcp_call_bpf(sk, op, ARRAY_SIZE(__args), __args); \
+ } \
+} while (0)
static inline void tcp_clear_sock_ops_cb_flags(struct sock *sk)
{
tcp_sk(sk)->bpf_sock_ops_cb_flags = 0;
+ WRITE_ONCE(tcp_sk(sk)->bpf_tcp_ops_flags, 0);
}
#else
-static inline int tcp_call_bpf(struct sock *sk, int op, u32 nargs, u32 *args)
+static inline int tcp_call_bpf(struct sock *sk, int op)
{
return -EPERM;
}
-static inline int tcp_call_bpf_2arg(struct sock *sk, int op, u32 arg1, u32 arg2)
-{
- return -EPERM;
-}
-
-static inline int tcp_call_bpf_3arg(struct sock *sk, int op, u32 arg1, u32 arg2,
- u32 arg3)
-{
- return -EPERM;
-}
+#define tcp_call_bpf_flag(sk, op, ...) do { } while (0)
static inline void tcp_clear_sock_ops_cb_flags(struct sock *sk)
{
@@ -2959,12 +2994,196 @@ static inline void tcp_clear_sock_ops_cb_flags(struct sock *sk)
#endif
+#if defined(CONFIG_BPF_JIT) && defined(CONFIG_CGROUP_BPF)
+
+struct bpf_tcp_ops {
+ /* Should return the initial SYN (active open) or SYN-ACK (passive open)
+ * retransmission timeout. Return the timeout in jiffies, or <= 0 for
+ * the kernel default.
+ *
+ * @req: request_sock on the passive (synack) path; NULL otherwise.
+ */
+ int (*timeout_init)(struct sock *sk, struct request_sock *req);
+
+ /* Should return the initial advertised receive window, in packets,
+ * or < 0 for the kernel default. @req as in timeout_init().
+ */
+ int (*rwnd_init)(struct sock *sk, struct request_sock *req);
+
+ /* Called when an active connection becomes established.
+ * @skb is the SYNACK that completed the 3WHS, or NULL for a
+ * TCP_REPAIR socket (tcp_finish_connect() with no skb).
+ */
+ void (*active_established)(struct sock *sk, struct sk_buff *skb__nullable);
+
+ /* Called when a passive connection becomes established.
+ * @skb is the ACK that completed the 3WHS.
+ */
+ void (*passive_established)(struct sock *sk, struct sk_buff *skb);
+
+ /* Called when the retransmission timer fires. */
+ void (*rto)(struct sock *sk);
+
+ /* Called on every RTT sample if BPF_TCP_OPS_FLAG_RTT is enabled.
+ * @mrtt: the measured RTT, in microseconds.
+ * @srtt: the updated smoothed RTT.
+ */
+ void (*rtt)(struct sock *sk, long mrtt, u32 srtt);
+
+ /* Called when the connection changes TCP state.
+ * @state: the new state (one of the TCP_* states).
+ */
+ void (*set_state)(struct sock *sk, int state);
+
+ /* Called when an skb is retransmitted.
+ * @skb: the retransmitted skb.
+ * @err: tcp_transmit_skb() return value (0 on success).
+ */
+ void (*retrans)(struct sock *sk, struct sk_buff *skb, int err);
+
+ /* Called right before an active connection is initialized. */
+ void (*connect)(struct sock *sk);
+
+ /* Called on listen(2), right after the socket enters TCP_LISTEN. */
+ void (*listen)(struct sock *sk);
+
+ /*
+ * Parse the TCP header options of an incoming skb received on an
+ * established connection. Use bpf_dynptr_from_skb()/bpf_skb_load_bytes()
+ * to access the options.
+ *
+ * Called if BPF_TCP_OPS_FLAG_PARSE_HDR_OPT_ALL is enabled, or if
+ * BPF_TCP_OPS_FLAG_PARSE_HDR_OPT_UNKNOWN is enabled and an unknown
+ * option is received.
+ */
+ void (*parse_hdr)(struct sock *sk, struct sk_buff *skb);
+
+ /*
+ * Reserve space in the outgoing TCP header for options to be written
+ * later by write_hdr_opt(). Call bpf_reserve_hdr_opt() to reserve bytes.
+ *
+ * Called if BPF_TCP_OPS_FLAG_WRITE_HDR_OPT is enabled.
+ *
+ * @skb: outgoing packet. NULL when called from tcp_current_mss()
+ * (MSS sizing).
+ * @req: request_sock on the synack path; NULL otherwise.
+ * @syn_skb: incoming SYN on the synack path; NULL otherwise.
+ * @synack_type: TCP_SYNACK_COOKIE indicates a stateless syncookie.
+ * @remaining: pointer to the size of space still available; cast it
+ * using bpf_rdonly_cast() before dereferencing.
+ */
+ void (*hdr_opt_len)(struct sock *sk, struct sk_buff *skb,
+ struct request_sock *req, struct sk_buff *syn_skb,
+ enum tcp_synack_type synack_type,
+ unsigned int *remaining);
+
+ /*
+ * Write header options into the space reserved earlier by hdr_opt_len().
+ * Use bpf_store_hdr_opt() to write; it appends within the reserved window
+ * shared with legacy SOCKOPS.
+ *
+ * Called if BPF_TCP_OPS_FLAG_WRITE_HDR_OPT is enabled.
+ *
+ * @skb: outgoing packet.
+ * @req: request_sock on the synack path; NULL otherwise.
+ * @syn_skb: incoming SYN on the synack path; NULL otherwise.
+ * @synack_type: TCP_SYNACK_COOKIE indicates a stateless syncookie.
+ * @opt_off: offset in the outgoing @skb's TCP header where the
+ * bpf_tcp_ops portion of the reserved window begins, i.e. after
+ * the kernel and legacy options.
+ */
+ void (*write_hdr_opt)(struct sock *sk, struct sk_buff *skb,
+ struct request_sock *req, struct sk_buff *syn_skb,
+ enum tcp_synack_type synack_type,
+ u32 opt_off);
+
+ /*
+ * Called when an incoming skb is enqueued to sk->sk_receive_queue
+ * if BPF_TCP_OPS_FLAG_RCVQ is enabled.
+ */
+ void (*enqueue_rcvq)(struct sock *sk, struct sk_buff *skb);
+
+ /*
+ * Called after data is dequeued from sk->sk_receive_queue
+ * if BPF_TCP_OPS_FLAG_RCVQ is enabled.
+ */
+ void (*dequeue_rcvq)(struct sock *sk);
+};
+
+#define __bpf_tcp_ops_call(op, sk, ...) \
+do { \
+ const struct bpf_prog_array_item *item; \
+ const struct bpf_tcp_ops *tcp_ops; \
+ struct cgroup *cgrp; \
+ \
+ cgrp = sock_cgroup_ptr(&sk->sk_cgrp_data); \
+ rcu_read_lock_dont_migrate(); \
+ bpf_cgroup_struct_ops_foreach(tcp_ops, item, cgrp, \
+ CGROUP_TCP_SOCK_OPS) { \
+ if (tcp_ops->op) \
+ tcp_ops->op(sk, ##__VA_ARGS__); \
+ } \
+ rcu_read_unlock_migrate(); \
+} while (0)
+
+#define bpf_tcp_ops_call(op, sk, ...) \
+do { \
+ if (cgroup_bpf_enabled(CGROUP_TCP_SOCK_OPS)) \
+ __bpf_tcp_ops_call(op, sk, ##__VA_ARGS__); \
+} while (0)
+
+#define bpf_tcp_ops_call_flag(op, flag, sk, ...) \
+do { \
+ if (cgroup_bpf_enabled(CGROUP_TCP_SOCK_OPS) && \
+ BPF_TCP_OPS_TEST_FLAG(tcp_sk(sk), flag)) \
+ __bpf_tcp_ops_call(op, sk, ##__VA_ARGS__); \
+} while (0)
+
+#define bpf_tcp_ops_call_int(op, init_retval, sk, ...) \
+({ \
+ int __retval = (init_retval); \
+ if (cgroup_bpf_enabled(CGROUP_TCP_SOCK_OPS)) { \
+ const struct bpf_prog_array_item *item; \
+ const struct bpf_tcp_ops *tcp_ops; \
+ struct bpf_tramp_run_ctx run_ctx; \
+ struct bpf_run_ctx *old_run_ctx; \
+ struct sock *__sk = sk_to_full_sk(sk); \
+ struct request_sock *req = NULL; \
+ struct cgroup *cgrp; \
+ \
+ if (__sk) { \
+ run_ctx.retval = (init_retval); \
+ cgrp = sock_cgroup_ptr(&__sk->sk_cgrp_data); \
+ if (!sk_fullsock(sk)) \
+ req = (struct request_sock *)sk; \
+ rcu_read_lock_dont_migrate(); \
+ old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx);\
+ bpf_cgroup_struct_ops_foreach(tcp_ops, item, cgrp, \
+ CGROUP_TCP_SOCK_OPS) { \
+ if (tcp_ops->op) \
+ run_ctx.retval = tcp_ops->op(__sk, req, ##__VA_ARGS__); \
+ } \
+ bpf_reset_run_ctx(old_run_ctx); \
+ rcu_read_unlock_migrate(); \
+ __retval = run_ctx.retval; \
+ } \
+ } \
+ __retval; \
+})
+
+#else
+#define __bpf_tcp_ops_call(op, sk, ...) do { } while (0)
+#define bpf_tcp_ops_call(op, sk, ...) do { } while (0)
+#define bpf_tcp_ops_call_flag(op, flag, sk, ...) do { } while (0)
+#define bpf_tcp_ops_call_int(op, init_retval, sk, ...) (init_retval)
+#endif
+
static inline u32 tcp_timeout_init(struct sock *sk)
{
int timeout;
- timeout = tcp_call_bpf(sk, BPF_SOCK_OPS_TIMEOUT_INIT, 0, NULL);
-
+ timeout = tcp_call_bpf(sk, BPF_SOCK_OPS_TIMEOUT_INIT);
+ timeout = bpf_tcp_ops_call_int(timeout_init, timeout, sk);
if (timeout <= 0)
timeout = TCP_TIMEOUT_INIT;
return min_t(int, timeout, TCP_RTO_MAX);
@@ -2974,8 +3193,8 @@ static inline u32 tcp_rwnd_init_bpf(struct sock *sk)
{
int rwnd;
- rwnd = tcp_call_bpf(sk, BPF_SOCK_OPS_RWND_INIT, 0, NULL);
-
+ rwnd = tcp_call_bpf(sk, BPF_SOCK_OPS_RWND_INIT);
+ rwnd = bpf_tcp_ops_call_int(rwnd_init, rwnd, sk);
if (rwnd < 0)
rwnd = 0;
return rwnd;
@@ -2983,13 +3202,13 @@ static inline u32 tcp_rwnd_init_bpf(struct sock *sk)
static inline bool tcp_bpf_ca_needs_ecn(struct sock *sk)
{
- return (tcp_call_bpf(sk, BPF_SOCK_OPS_NEEDS_ECN, 0, NULL) == 1);
+ return (tcp_call_bpf(sk, BPF_SOCK_OPS_NEEDS_ECN) == 1);
}
static inline void tcp_bpf_rtt(struct sock *sk, long mrtt, u32 srtt)
{
- if (BPF_SOCK_OPS_TEST_FLAG(tcp_sk(sk), BPF_SOCK_OPS_RTT_CB_FLAG))
- tcp_call_bpf_2arg(sk, BPF_SOCK_OPS_RTT_CB, mrtt, srtt);
+ tcp_call_bpf_flag(sk, BPF_SOCK_OPS_RTT_CB, mrtt, srtt);
+ bpf_tcp_ops_call_flag(rtt, RTT, sk, mrtt, srtt);
}
#if IS_ENABLED(CONFIG_SMC)
@@ -3082,7 +3301,7 @@ enum skb_drop_reason tcp_inbound_hash(struct sock *sk,
static inline int tcp_recv_should_stop(struct sock *sk)
{
- return sk->sk_err ||
+ return READ_ONCE(sk->sk_err) ||
sk->sk_state == TCP_CLOSE ||
(sk->sk_shutdown & RCV_SHUTDOWN) ||
signal_pending(current);
diff --git a/include/net/udp.h b/include/net/udp.h
index 1fee17274745..5bc25dcf25fb 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -613,7 +613,7 @@ static inline struct sk_buff *udp_rcv_segment(struct sock *sk,
/* the GSO CB lays after the UDP one, no need to save and restore any
* CB fragment
*/
- segs = __skb_gso_segment(skb, features, false);
+ segs = __skb_gso_segment(skb, features, false, 0);
if (IS_ERR_OR_NULL(segs)) {
drop_count = skb_shinfo(skb)->gso_segs;
goto drop;
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index 7b8207505523..c3c9f2ccc3d1 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -204,7 +204,6 @@ struct vxlan_rdst {
u8 offloaded:1;
__be32 remote_vni;
u32 remote_ifindex;
- struct net_device *remote_dev;
struct list_head list;
struct rcu_head rcu;
struct dst_cache dst_cache;
@@ -229,6 +228,7 @@ struct vxlan_config {
bool no_share;
enum ifla_vxlan_df df;
struct vxlanhdr reserved_bits;
+ struct rcu_head rcu;
};
enum {
@@ -294,14 +294,15 @@ struct vxlan_dev {
#endif
struct net_device *dev;
struct net *net; /* netns for packet i/o */
- struct vxlan_rdst default_dst; /* default destination */
+ struct net_device *lowerdev;
struct timer_list age_timer;
spinlock_t hash_lock;
unsigned int addrcnt;
struct gro_cells gro_cells;
+ unsigned long flags;
- struct vxlan_config cfg;
+ struct vxlan_config __rcu *cfg;
struct vxlan_vni_group __rcu *vnigrp;
@@ -313,6 +314,10 @@ struct vxlan_dev {
unsigned int mdb_seq;
};
+enum vxlan_dev_flags {
+ VXLAN_DEV_F_MDB,
+};
+
#define VXLAN_F_LEARN 0x01
#define VXLAN_F_PROXY 0x02
#define VXLAN_F_RSC 0x04
@@ -331,7 +336,6 @@ struct vxlan_dev {
#define VXLAN_F_IPV6_LINKLOCAL 0x8000
#define VXLAN_F_TTL_INHERIT 0x10000
#define VXLAN_F_VNIFILTER 0x20000
-#define VXLAN_F_MDB 0x40000
#define VXLAN_F_LOCALBYPASS 0x80000
#define VXLAN_F_MC_ROUTE 0x100000
diff --git a/include/net/xdp.h b/include/net/xdp.h
index aa742f413c35..07231adfb5f8 100644
--- a/include/net/xdp.h
+++ b/include/net/xdp.h
@@ -106,6 +106,11 @@ struct xdp_buff {
};
};
+static __always_inline void xdp_reinit_buff(struct xdp_buff *xdp)
+{
+ xdp->flags = 0;
+}
+
static __always_inline bool xdp_buff_has_frags(const struct xdp_buff *xdp)
{
return !!(xdp->flags & XDP_FLAGS_HAS_FRAGS);
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index a6d69aaa6cd2..298ca9bb0083 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1201,6 +1201,23 @@ secpath_reset(struct sk_buff *skb)
#endif
}
+static inline bool
+secpath_equal(const struct sk_buff *skb1, const struct sk_buff *skb2)
+{
+ const struct sec_path *sp1 = skb_sec_path(skb1);
+ const struct sec_path *sp2 = skb_sec_path(skb2);
+ int i;
+
+ if (!sp1 || !sp2)
+ return sp1 == sp2;
+ if (sp1->len != sp2->len)
+ return false;
+ for (i = 0; i < sp1->len; i++)
+ if (sp1->xvec[i] != sp2->xvec[i])
+ return false;
+ return true;
+}
+
static inline int
xfrm_addr_any(const xfrm_address_t *addr, unsigned short family)
{
diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h
index a7df573784fd..02e89350faf9 100644
--- a/include/net/xsk_buff_pool.h
+++ b/include/net/xsk_buff_pool.h
@@ -48,6 +48,8 @@ struct xsk_buff_pool {
struct device *dev;
struct net_device *netdev;
struct list_head xsk_tx_list;
+ /* Assigned pools, including deferred releases; ops protected. */
+ struct hlist_node dev_node;
/* Protects modifications to the xsk_tx_list */
spinlock_t xsk_tx_list_lock;
refcount_t users;
@@ -119,6 +121,7 @@ bool xp_put_pool(struct xsk_buff_pool *pool);
void xp_clear_dev(struct xsk_buff_pool *pool);
void xp_add_xsk(struct xsk_buff_pool *pool, struct xdp_sock *xs);
void xp_del_xsk(struct xsk_buff_pool *pool, struct xdp_sock *xs);
+void xp_clear_dev_all(struct net_device *dev);
/* AF_XDP, and XDP core. */
void xp_free(struct xdp_buff_xsk *xskb);