diff options
Diffstat (limited to 'include/net')
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); |
