diff options
Diffstat (limited to 'include/net')
59 files changed, 1013 insertions, 217 deletions
diff --git a/include/net/act_api.h b/include/net/act_api.h index 20d9e55f8564..fd03f6319e88 100644 --- a/include/net/act_api.h +++ b/include/net/act_api.h @@ -270,6 +270,25 @@ int tcf_action_check_ctrlact(int action, struct tcf_proto *tp, struct tcf_chain *tcf_action_set_ctrlact(struct tc_action *a, int action, struct tcf_chain *newchain); +/* Range check for a control action supplied by user space. + * + * This is the same test tcf_action_check_ctrlact() applies to the primary + * control action, factored out for the *fallback* control actions + * (act_gact's TCA_GACT_PROB.paction and act_police's TCA_POLICE_RESULT), + * which must not reach tcf_action_check_ctrlact() because they have no + * goto_chain to allocate. Without it, user space can store kernel-internal + * verdicts such as TC_ACT_CONSUMED, which is TC_ACT_VALUE_MAX + 1 and is + * deliberately not part of the UAPI value range. + */ +static inline bool tcf_action_valid(int action) +{ + int opcode = TC_ACT_EXT_OPCODE(action); + + if (!opcode) + return action <= TC_ACT_VALUE_MAX; + return opcode <= TC_ACT_EXT_OPCODE_MAX || action == TC_ACT_UNSPEC; +} + #ifdef CONFIG_INET DECLARE_STATIC_KEY_FALSE(tcf_frag_xmit_count); #endif diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 539bbbe54b14..e6764245995f 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -405,8 +405,8 @@ static inline struct inet6_dev *in6_dev_get(const struct net_device *dev) rcu_read_lock(); idev = rcu_dereference(dev->ip6_ptr); - if (idev) - refcount_inc(&idev->refcnt); + if (idev && !refcount_inc_not_zero(&idev->refcnt)) + idev = NULL; rcu_read_unlock(); return idev; } @@ -446,6 +446,11 @@ static inline void in6_dev_hold(struct inet6_dev *idev) refcount_inc(&idev->refcnt); } +static inline bool in6_dev_hold_safe(struct inet6_dev *idev) +{ + return refcount_inc_not_zero(&idev->refcnt); +} + /* called with rcu_read_lock held */ static inline bool ip6_ignore_linkdown(const struct net_device *dev) { diff --git a/include/net/af_unix.h b/include/net/af_unix.h index 34f53dde65ce..bb1b3dee02e8 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -49,6 +49,7 @@ struct unix_sock { struct scm_stat scm_stat; int inq_len; bool recvmsg_inq; + bool scm_rights_notrunc; #if IS_ENABLED(CONFIG_AF_UNIX_OOB) struct sk_buff *oob_skb; #endif diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h index 30046a3c20f7..3357ee62d10b 100644 --- a/include/net/af_vsock.h +++ b/include/net/af_vsock.h @@ -52,13 +52,10 @@ struct vsock_sock { * The listening socket is the head for both lists. Sockets created * for connection requests are placed in the pending list until they * are connected, at which point they are put in the accept queue list - * so they can be accepted in accept(). If accept() cannot accept the - * connection, it is marked as rejected so the cleanup function knows - * to clean up the socket. + * so they can be accepted in accept(). */ struct list_head pending_links; struct list_head accept_queue; - bool rejected; struct delayed_work connect_work; struct delayed_work pending_work; struct delayed_work close_work; diff --git a/include/net/bluetooth/coredump.h b/include/net/bluetooth/coredump.h index 72f51b587a04..1f071ab55416 100644 --- a/include/net/bluetooth/coredump.h +++ b/include/net/bluetooth/coredump.h @@ -8,6 +8,13 @@ #define DEVCOREDUMP_TIMEOUT msecs_to_jiffies(10000) /* 10 sec */ +/* + * Max header size, shared by both the devcoredump core and + * the dmp_hdr() registered by driver via hci_devcd_register() + */ +#define HCI_DEVCD_HDR_SIZE_MAX 512 +#define HCI_DEVCD_HDR_END_MARKER "--- Start dump ---\n" + typedef void (*coredump_t)(struct hci_dev *hdev); typedef void (*dmp_hdr_t)(struct hci_dev *hdev, struct sk_buff *skb); typedef void (*notify_change_t)(struct hci_dev *hdev, int state); @@ -60,6 +67,8 @@ struct hci_devcoredump { #ifdef CONFIG_DEV_COREDUMP +const char *hci_devcd_state_name(enum devcoredump_state state); + void hci_devcd_reset(struct hci_dev *hdev); void hci_devcd_rx(struct work_struct *work); void hci_devcd_timeout(struct work_struct *work); @@ -74,6 +83,11 @@ int hci_devcd_abort(struct hci_dev *hdev); #else +static inline const char *hci_devcd_state_name(enum devcoredump_state state) +{ + return ""; +} + static inline void hci_devcd_reset(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 38186a245f14..1641d879dbda 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -653,6 +653,8 @@ enum { #define HCI_LE_LL_EXT_FEATURE 0x80 #define HCI_LE_CS 0x40 #define HCI_LE_CS_HOST 0x80 +#define HCI_LE_SCI 0x01 /* byte 9 - Shorter Connection Intervals */ +#define HCI_LE_SCI_HOST 0x02 /* byte 9 - Shorter Connection Intervals (Host) */ /* Connection modes */ #define HCI_CM_ACTIVE 0x0000 @@ -2489,6 +2491,46 @@ struct hci_cp_le_set_host_feature_v2 { __u8 bit_value; } __packed; +#define HCI_OP_LE_CONN_RATE 0x20a1 +struct hci_cp_le_conn_rate { + __le16 handle; + __le16 interval_min; + __le16 interval_max; + __le16 subrate_min; + __le16 subrate_max; + __le16 max_latency; + __le16 cont_num; + __le16 supv_timeout; + __le16 min_ce_len; + __le16 max_ce_len; +} __packed; + +#define HCI_OP_LE_SET_DEF_RATE 0x20a2 +struct hci_cp_le_set_def_rate { + __le16 interval_min; + __le16 interval_max; + __le16 subrate_min; + __le16 subrate_max; + __le16 max_latency; + __le16 cont_num; + __le16 supv_timeout; + __le16 min_ce_len; + __le16 max_ce_len; +} __packed; + +#define HCI_OP_LE_READ_CONN_INTERVAL 0x20a3 +struct hci_le_conn_interval_group { + __le16 min; + __le16 max; + __le16 stride; +} __packed; + +struct hci_rp_le_read_conn_interval { + __u8 status; + __u8 num_grps; + struct hci_le_conn_interval_group grps[]; +} __packed; + /* ---- HCI Events ---- */ struct hci_ev_status { __u8 status; @@ -3303,6 +3345,17 @@ struct hci_evt_le_cs_test_end_complete { __u8 status; } __packed; +#define HCI_EVT_LE_CONN_RATE_CHANGE 0x37 +struct hci_evt_le_conn_rate_change { + __u8 status; + __le16 handle; + __le16 interval; + __le16 subrate; + __le16 latency; + __le16 cont_number; + __le16 supv_timeout; +} __packed; + #define HCI_EV_VENDOR 0xff /* Internal events generated by Bluetooth stack */ @@ -3329,6 +3382,7 @@ struct hci_ev_si_security { /* ---- HCI Packet structures ---- */ #define HCI_COMMAND_HDR_SIZE 3 #define HCI_EVENT_HDR_SIZE 2 +#define HCI_MAX_EVENT_PLEN 255 #define HCI_ACL_HDR_SIZE 4 #define HCI_SCO_HDR_SIZE 3 #define HCI_ISO_HDR_SIZE 4 @@ -3407,14 +3461,25 @@ static inline struct hci_iso_hdr *hci_iso_hdr(const struct sk_buff *skb) #define hci_handle(h) (h & 0x0fff) #define hci_flags(h) (h >> 12) +static inline __u16 hci_acl_handle(const struct sk_buff *skb) +{ + return hci_handle(__le16_to_cpu(hci_acl_hdr(skb)->handle)); +} + +static inline __u16 hci_acl_dlen(const struct sk_buff *skb) +{ + return __le16_to_cpu(hci_acl_hdr(skb)->dlen); +} + /* ISO handle and flags pack/unpack */ #define hci_iso_flags_pb(f) (f & 0x0003) #define hci_iso_flags_ts(f) ((f >> 2) & 0x0001) #define hci_iso_flags_pack(pb, ts) ((pb & 0x03) | ((ts & 0x01) << 2)) /* ISO data length and flags pack/unpack */ -#define hci_iso_data_len_pack(h, f) ((__u16) ((h) | ((f) << 14))) -#define hci_iso_data_len(h) ((h) & 0x3fff) +#define hci_iso_data_len_pack(h, f) ((__u16) (((h) & 0x0fff) | \ + (((f) & 0x3) << 14))) +#define hci_iso_data_len(h) ((h) & 0x0fff) #define hci_iso_data_flags(h) ((h) >> 14) /* codec transport types */ diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 7e15da47fe3a..4105c446ca98 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -416,6 +416,7 @@ struct hci_dev { __u16 le_conn_max_interval; __u16 le_conn_latency; __u16 le_supv_timeout; + __u16 le_min_rate_interval; __u16 le_def_tx_len; __u16 le_def_tx_time; __u16 le_max_tx_len; @@ -645,6 +646,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); + /* 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); void (*hw_error)(struct hci_dev *hdev, u8 code); int (*post_init)(struct hci_dev *hdev); @@ -720,6 +723,11 @@ struct hci_conn { __u16 le_conn_interval; __u16 le_conn_latency; __u16 le_supv_timeout; + __u16 le_rate_interval; + __u16 le_subrate; + __u16 le_rate_latency; + __u16 le_cont_num; + __u16 le_rate_supv_timeout; __u8 le_adv_data[HCI_MAX_EXT_AD_LENGTH]; __u8 le_adv_data_len; __u8 le_per_adv_data[HCI_MAX_PER_AD_TOT_LEN]; @@ -767,9 +775,11 @@ struct hci_conn { struct dentry *debugfs; struct hci_dev *hdev; - void *l2cap_data; + + spinlock_t proto_lock; /* lock guarding protocol data */ + void *l2cap_data __guarded_by(&proto_lock, &hdev->lock); void *sco_data; - void *iso_data; + void *iso_data __guarded_by(&proto_lock); struct list_head link_list; struct hci_conn *parent; @@ -810,6 +820,14 @@ struct hci_conn_params { u16 conn_latency; u16 supervision_timeout; + u16 rate_min_interval; + u16 rate_max_interval; + u16 subrate_min; + u16 subrate_max; + u16 max_latency; + u16 cont_num; + u16 rate_supv_timeout; + enum { HCI_AUTO_CONN_DISABLED, HCI_AUTO_CONN_REPORT, @@ -917,9 +935,9 @@ static inline void hci_discovery_filter_clear(struct hci_dev *hdev) hdev->discovery.result_filtering = false; hdev->discovery.report_invalid_rssi = true; hdev->discovery.rssi = HCI_RSSI_INVALID; - hdev->discovery.uuid_count = 0; spin_lock(&hdev->discovery.lock); + hdev->discovery.uuid_count = 0; kfree(hdev->discovery.uuids); hdev->discovery.uuids = NULL; spin_unlock(&hdev->discovery.lock); @@ -985,6 +1003,7 @@ enum { HCI_CONN_AUTH_FAILURE, HCI_CONN_PER_ADV, HCI_CONN_BIG_CREATED, + HCI_CONN_CREATE, HCI_CONN_CREATE_CIS, HCI_CONN_CREATE_BIG_SYNC, HCI_CONN_BIG_SYNC, @@ -1768,7 +1787,13 @@ int hci_register_suspend_notifier(struct hci_dev *hdev); int hci_unregister_suspend_notifier(struct hci_dev *hdev); int hci_suspend_dev(struct hci_dev *hdev); int hci_resume_dev(struct hci_dev *hdev); -int hci_reset_dev(struct hci_dev *hdev); +int __hci_reset_dev(struct hci_dev *hdev, u8 hw_err_code); + +static inline int hci_reset_dev(struct hci_dev *hdev) +{ + return __hci_reset_dev(hdev, 0); +} + int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb); int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb); __printf(2, 3) void hci_set_hw_info(struct hci_dev *hdev, const char *fmt, ...); @@ -2076,6 +2101,11 @@ void hci_conn_del_sysfs(struct hci_conn *conn); #define le_cs_host_capable(dev) \ ((dev)->le_features[5] & HCI_LE_CS_HOST) +#define le_sci_capable(dev) \ + ((dev)->le_features[9] & HCI_LE_SCI) +#define le_sci_enabled(dev) \ + (le_enabled(dev) && le_sci_capable(dev)) + #define mws_transport_config_capable(dev) (((dev)->commands[30] & 0x08) && \ (!hci_test_quirk((dev), HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG))) @@ -2429,6 +2459,7 @@ void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key, bool persistent); void mgmt_device_connected(struct hci_dev *hdev, struct hci_conn *conn, u8 *name, u8 name_len); +u8 hci_to_mgmt_reason(u8 err); void mgmt_device_disconnected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, u8 addr_type, u8 reason, bool mgmt_connected); @@ -2490,6 +2521,8 @@ void mgmt_advertising_removed(struct sock *sk, struct hci_dev *hdev, int mgmt_phy_configuration_changed(struct hci_dev *hdev, struct sock *skip); void mgmt_adv_monitor_device_lost(struct hci_dev *hdev, u16 handle, bdaddr_t *bdaddr, u8 addr_type); +void mgmt_conn_subrate_notify(struct hci_dev *hdev, struct hci_conn *conn, + u8 status); int hci_abort_conn(struct hci_conn *conn, u8 reason); void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency, diff --git a/include/net/bluetooth/hci_sync.h b/include/net/bluetooth/hci_sync.h index 73e494b2591d..a6579a868678 100644 --- a/include/net/bluetooth/hci_sync.h +++ b/include/net/bluetooth/hci_sync.h @@ -59,6 +59,7 @@ int __hci_cmd_sync_status(struct hci_dev *hdev, u16 opcode, u32 plen, int __hci_cmd_sync_status_sk(struct hci_dev *hdev, u16 opcode, u32 plen, const void *param, u8 event, u32 timeout, struct sock *sk); +int __hci_reset_sync(struct hci_dev *hdev); int hci_cmd_sync_status(struct hci_dev *hdev, u16 opcode, u32 plen, const void *param, u32 timeout); @@ -84,9 +85,6 @@ void hci_cmd_sync_cancel_entry(struct hci_dev *hdev, struct hci_cmd_sync_work_entry *entry); bool hci_cmd_sync_dequeue(struct hci_dev *hdev, hci_cmd_sync_work_func_t func, void *data, hci_cmd_sync_work_destroy_t destroy); -bool hci_cmd_sync_dequeue_once(struct hci_dev *hdev, - hci_cmd_sync_work_func_t func, void *data, - hci_cmd_sync_work_destroy_t destroy); int hci_update_eir_sync(struct hci_dev *hdev); int hci_update_class_sync(struct hci_dev *hdev); @@ -185,6 +183,7 @@ int hci_connect_le_sync(struct hci_dev *hdev, struct hci_conn *conn); int hci_cancel_connect_sync(struct hci_dev *hdev, struct hci_conn *conn); int hci_le_conn_update_sync(struct hci_dev *hdev, struct hci_conn *conn, struct hci_conn_params *params); +int hci_le_conn_rate_request(struct hci_dev *hdev, struct hci_conn *conn); int hci_connect_pa_sync(struct hci_dev *hdev, struct hci_conn *conn); int hci_connect_big_sync(struct hci_dev *hdev, struct hci_conn *conn); diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 1640cc9bf83a..3d9a32094347 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -617,7 +617,8 @@ struct l2cap_chan { struct l2cap_ops { char *name; - struct l2cap_chan *(*new_connection) (struct l2cap_chan *chan); + 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); @@ -698,7 +699,12 @@ struct l2cap_rx_busy { struct l2cap_pinfo { struct bt_sock bt; + + /* With owning sk_socket chan may be read without lock, other access + * should hold lock_sock. + */ struct l2cap_chan *chan; + struct list_head rx_busy; }; @@ -882,9 +888,10 @@ static inline __u16 __next_seq(struct l2cap_chan *chan, __u16 seq) return (seq + 1) % (chan->tx_win_max + 1); } -static inline struct l2cap_chan *l2cap_chan_no_new_connection(struct l2cap_chan *chan) +static inline int l2cap_chan_no_new_connection(struct l2cap_chan *chan, + struct l2cap_chan *new_chan) { - return NULL; + return -EOPNOTSUPP; } static inline int l2cap_chan_no_recv(struct l2cap_chan *chan, struct sk_buff *skb) @@ -961,7 +968,7 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len, void l2cap_chan_busy(struct l2cap_chan *chan, int busy); void l2cap_chan_rx_avail(struct l2cap_chan *chan, ssize_t rx_avail); int l2cap_chan_check_security(struct l2cap_chan *chan, bool initiator); -void l2cap_chan_set_defaults(struct l2cap_chan *chan); +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); diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h index 08daed7a96d5..1e22eab1081c 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -118,6 +118,7 @@ struct mgmt_rp_read_index_list { #define MGMT_SETTING_LL_PRIVACY BIT(22) #define MGMT_SETTING_PAST_SENDER BIT(23) #define MGMT_SETTING_PAST_RECEIVER BIT(24) +#define MGMT_SETTING_SCI BIT(25) #define MGMT_OP_READ_INFO 0x0004 #define MGMT_READ_INFO_SIZE 0 @@ -893,6 +894,23 @@ struct mgmt_cp_hci_cmd_sync { } __packed; #define MGMT_HCI_CMD_SYNC_SIZE 6 +#define MGMT_OP_LOAD_CONN_SUBRATE 0x005C +struct mgmt_conn_subrate { + struct mgmt_addr_info addr; + __le16 min_interval; + __le16 max_interval; + __le16 subrate_min; + __le16 subrate_max; + __le16 max_latency; + __le16 cont_num; + __le16 supv_timeout; +} __packed; +struct mgmt_cp_load_conn_subrate { + __le16 param_count; + struct mgmt_conn_subrate params[] __counted_by_le(param_count); +} __packed; +#define MGMT_LOAD_CONN_SUBRATE_SIZE 2 + #define MGMT_EV_CMD_COMPLETE 0x0001 struct mgmt_ev_cmd_complete { __le16 opcode; @@ -1192,3 +1210,14 @@ struct mgmt_ev_mesh_device_found { struct mgmt_ev_mesh_pkt_cmplt { __u8 handle; } __packed; + +#define MGMT_EV_CONN_SUBRATE 0x0033 +struct mgmt_ev_conn_subrate { + struct mgmt_addr_info addr; + __u8 status; + __le16 interval; + __le16 subrate; + __le16 latency; + __le16 cont_num; + __le16 supv_timeout; +} __packed; diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h index feb6b3ae5e69..102c278e3584 100644 --- a/include/net/bluetooth/rfcomm.h +++ b/include/net/bluetooth/rfcomm.h @@ -226,6 +226,9 @@ int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci, u8 bit_rate, u8 data_bits, u8 stop_bits, u8 parity, u8 flow_ctrl_settings, u8 xon_char, u8 xoff_char, u16 param_mask); +int rfcomm_dlc_send_rpn(struct rfcomm_dlc *d, u8 bit_rate, u8 data_bits, + u8 stop_bits, u8 parity, u8 flow_ctrl_settings, + u8 xon_char, u8 xoff_char, u16 param_mask); /* ---- RFCOMM DLCs (channels) ---- */ struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio); diff --git a/include/net/bond_3ad.h b/include/net/bond_3ad.h index 05572c19e14b..ef667dff2972 100644 --- a/include/net/bond_3ad.h +++ b/include/net/bond_3ad.h @@ -302,8 +302,8 @@ void bond_3ad_state_machine_handler(struct work_struct *); void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout); void bond_3ad_adapter_speed_duplex_changed(struct slave *slave); void bond_3ad_handle_link_change(struct slave *slave, char link); -int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); -int __bond_3ad_get_active_agg_info(struct bonding *bond, +int bond_3ad_get_active_agg_info(const struct bonding *bond, struct ad_info *ad_info); +int __bond_3ad_get_active_agg_info(const struct bonding *bond, struct ad_info *ad_info); int bond_3ad_lacpdu_recv(const struct sk_buff *skb, struct bonding *bond, struct slave *slave); diff --git a/include/net/bonding.h b/include/net/bonding.h index 2c54a36a8477..598d56b1bc97 100644 --- a/include/net/bonding.h +++ b/include/net/bonding.h @@ -345,14 +345,14 @@ static inline bool bond_mode_uses_primary(int mode) mode == BOND_MODE_ALB; } -static inline bool bond_uses_primary(struct bonding *bond) +static inline bool bond_uses_primary(const struct bonding *bond) { return bond_mode_uses_primary(BOND_MODE(bond)); } -static inline struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond) +static inline struct net_device *bond_option_active_slave_get_rcu(const struct bonding *bond) { - struct slave *slave = rcu_dereference_rtnl(bond->curr_active_slave); + const struct slave *slave = rcu_dereference_rtnl(bond->curr_active_slave); return bond_uses_primary(bond) && slave ? slave->dev : NULL; } @@ -703,7 +703,7 @@ void bond_setup(struct net_device *bond_dev); unsigned int bond_get_num_tx_queues(void); int bond_netlink_init(void); void bond_netlink_fini(void); -struct net_device *bond_option_active_slave_get_rcu(struct bonding *bond); +struct net_device *bond_option_active_slave_get_rcu(const struct bonding *bond); const char *bond_slave_link_status(s8 link); struct bond_vlan_tag *bond_verify_device_path(struct net_device *start_dev, struct net_device *end_dev, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 8188ad200de5..97c16d4ff127 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -1237,6 +1237,26 @@ ieee80211_chandef_max_power(struct cfg80211_chan_def *chandef) } /** + * cfg80211_chandef_s1g_pri_width - return S1G primary width in MHz + * + * An S1G interface may have a primary channel width of either 1 + * or 2MHz depending on whether chandef::s1g_primary_2mhz is set. + * + * Note: There is _always_ a 1MHz primary subchannel, regardless + * of the primary width. So chandef::chan always points to this + * 1MHz primary channel. + * + * @chandef: the chandef to use + * + * Returns: width in MHz of the S1G primary channel in use + */ +static inline int +cfg80211_chandef_s1g_pri_width(struct cfg80211_chan_def *chandef) +{ + return chandef->s1g_primary_2mhz ? 2 : 1; +} + +/** * cfg80211_any_usable_channels - check for usable channels * @wiphy: the wiphy to check for * @band_mask: which bands to check on @@ -2803,7 +2823,7 @@ struct mesh_setup { u8 path_metric; u8 auth_id; const u8 *ie; - u8 ie_len; + size_t ie_len; bool is_authenticated; bool is_secure; bool user_mpm; @@ -3722,6 +3742,7 @@ enum wiphy_params_flags { /* The per TXQ device queue limit in airtime */ #define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_L 5000 #define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_H 12000 +#define IEEE80211_DEFAULT_AQL_TXQ_LIMIT_MC 50000 /* The per interface airtime threshold to switch to lower queue limit */ #define IEEE80211_AQL_THRESHOLD 24000 @@ -5086,8 +5107,9 @@ struct mgmt_frame_regs { * @tdls_mgmt: Transmit a TDLS management frame. * @tdls_oper: Perform a high-level TDLS operation (e.g. TDLS link setup). * - * @probe_client: probe an associated client, must return a cookie that it - * later passes to cfg80211_probe_status(). + * @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(). * * @set_noack_map: Set the NoAck Map for the TIDs. * @@ -5198,7 +5220,8 @@ struct mgmt_frame_regs { * user space * * @tx_control_port: TX a control port frame (EAPoL). The noencrypt parameter - * tells the driver that the frame should not be encrypted. + * tells the driver that the frame should not be encrypted. A @cookie + * value of 0 means the caller does not want TX status reporting. * * @get_ftm_responder_stats: Retrieve FTM responder statistics, if available. * Statistics should be cumulative, currently no way to reset is provided. @@ -5435,14 +5458,14 @@ struct cfg80211_ops { struct wireless_dev *wdev, struct ieee80211_channel *chan, unsigned int duration, - u64 *cookie, const u8 *rx_addr); + u64 cookie, const u8 *rx_addr); int (*cancel_remain_on_channel)(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); int (*mgmt_tx)(struct wiphy *wiphy, struct wireless_dev *wdev, struct cfg80211_mgmt_tx_params *params, - u64 *cookie); + u64 cookie); int (*mgmt_tx_cancel_wait)(struct wiphy *wiphy, struct wireless_dev *wdev, u64 cookie); @@ -5488,8 +5511,8 @@ struct cfg80211_ops { int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev, const u8 *peer, enum nl80211_tdls_operation oper); - int (*probe_client)(struct wiphy *wiphy, struct net_device *dev, - const u8 *peer, u64 *cookie); + int (*probe_peer)(struct wiphy *wiphy, struct net_device *dev, + const u8 *peer, u64 cookie); int (*set_noack_map)(struct wiphy *wiphy, struct net_device *dev, @@ -5587,7 +5610,7 @@ struct cfg80211_ops { const u8 *buf, size_t len, const u8 *dest, const __be16 proto, const bool noencrypt, int link_id, - u64 *cookie); + u64 cookie); int (*get_ftm_responder_stats)(struct wiphy *wiphy, struct net_device *dev, @@ -5690,7 +5713,6 @@ struct cfg80211_ops { * set this flag to update channels on beacon hints. * @WIPHY_FLAG_SUPPORTS_NSTR_NONPRIMARY: support connection to non-primary link * of an NSTR mobile AP MLD. - * @WIPHY_FLAG_DISABLE_WEXT: disable wireless extensions for this device */ enum wiphy_flags { WIPHY_FLAG_SUPPORTS_EXT_KEK_KCK = BIT(0), @@ -5702,7 +5724,7 @@ enum wiphy_flags { WIPHY_FLAG_4ADDR_STATION = BIT(6), WIPHY_FLAG_CONTROL_PORT_PROTOCOL = BIT(7), WIPHY_FLAG_IBSS_RSN = BIT(8), - WIPHY_FLAG_DISABLE_WEXT = BIT(9), + /* reuse bit 9 */ WIPHY_FLAG_MESH_AUTH = BIT(10), WIPHY_FLAG_SUPPORTS_EXT_KCK_32 = BIT(11), WIPHY_FLAG_SUPPORTS_NSTR_NONPRIMARY = BIT(12), @@ -7228,7 +7250,7 @@ struct wireless_dev { enum ieee80211_bss_type conn_bss_type; u32 conn_owner_nlportid; - struct work_struct disconnect_wk; + struct wiphy_work disconnect_wk; u8 disconnect_bssid[ETH_ALEN]; struct list_head event_list; @@ -7265,7 +7287,7 @@ struct wireless_dev { struct list_head pmsr_list; spinlock_t pmsr_lock; - struct work_struct pmsr_free_wk; + struct wiphy_work pmsr_free_wk; unsigned long unprot_beacon_reported; @@ -8405,6 +8427,8 @@ cfg80211_inform_bss(struct wiphy *wiphy, * @bss_type: type of BSS, see &enum ieee80211_bss_type * @privacy: privacy filter, see &enum ieee80211_privacy * @use_for: indicates which use is intended + * @extack: (optional) extack that is filled with the reason when no + * usable entry was found; may be %NULL * * Return: Reference-counted BSS on success. %NULL on error. */ @@ -8414,7 +8438,8 @@ struct cfg80211_bss *__cfg80211_get_bss(struct wiphy *wiphy, const u8 *ssid, size_t ssid_len, enum ieee80211_bss_type bss_type, enum ieee80211_privacy privacy, - u32 use_for); + u32 use_for, + struct netlink_ext_ack *extack); /** * cfg80211_get_bss - get a BSS reference @@ -8438,7 +8463,7 @@ cfg80211_get_bss(struct wiphy *wiphy, struct ieee80211_channel *channel, { return __cfg80211_get_bss(wiphy, channel, bssid, ssid, ssid_len, bss_type, privacy, - NL80211_BSS_USE_FOR_NORMAL); + NL80211_BSS_USE_FOR_NORMAL, NULL); } static inline struct cfg80211_bss * @@ -9846,15 +9871,17 @@ bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev, const u8 *addr, /** * cfg80211_probe_status - notify userspace about probe status * @dev: the device the probe was sent on - * @addr: the address of the peer - * @cookie: the cookie filled in @probe_client previously + * @peer: The peer MAC address (or MLD address for MLO) or %NULL if not + * applicable (e.g. for STA/P2P-client) + * @cookie: the cookie filled in @probe_peer previously + * @link_id: The link ID on which the probe was sent (or -1 for non-MLO) * @acked: indicates whether probe was acked or not * @ack_signal: signal strength (in dBm) of the ACK frame. * @is_valid_ack_signal: indicates the ack_signal is valid or not. * @gfp: allocation flags */ -void cfg80211_probe_status(struct net_device *dev, const u8 *addr, - u64 cookie, bool acked, s32 ack_signal, +void cfg80211_probe_status(struct net_device *dev, const u8 *peer, u64 cookie, + int link_id, bool acked, s32 ack_signal, bool is_valid_ack_signal, gfp_t gfp); /** diff --git a/include/net/devlink.h b/include/net/devlink.h index dd546dbd57cf..7abd23376319 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -36,7 +36,7 @@ struct devlink_port_phys_attrs { * struct devlink_port_pci_pf_attrs - devlink port's PCI PF attributes * @controller: Associated controller number * @pf: associated PCI function number for the devlink port instance - * @external: when set, indicates if a port is for an external controller + * @external: when set, indicates if a port is for an external host controller. */ struct devlink_port_pci_pf_attrs { u32 controller; @@ -50,7 +50,7 @@ struct devlink_port_pci_pf_attrs { * @pf: associated PCI function number for the devlink port instance * @vf: associated PCI VF number of a PF for the devlink port instance; * VF number starts from 0 for the first PCI virtual function - * @external: when set, indicates if a port is for an external controller + * @external: when set, indicates if a port is for an external host controller. */ struct devlink_port_pci_vf_attrs { u32 controller; @@ -64,7 +64,7 @@ struct devlink_port_pci_vf_attrs { * @controller: Associated controller number * @sf: associated SF number of a PF for the devlink port instance * @pf: associated PCI function number for the devlink port instance - * @external: when set, indicates if a port is for an external controller + * @external: when set, indicates if a port is for an external host controller. */ struct devlink_port_pci_sf_attrs { u32 controller; @@ -554,6 +554,7 @@ enum devlink_param_generic_id { DEVLINK_PARAM_GENERIC_ID_TOTAL_VFS, DEVLINK_PARAM_GENERIC_ID_NUM_DOORBELLS, DEVLINK_PARAM_GENERIC_ID_MAX_MAC_PER_VF, + DEVLINK_PARAM_GENERIC_ID_MAX_SFS, /* add new param generic ids above here*/ __DEVLINK_PARAM_GENERIC_ID_MAX, @@ -627,6 +628,9 @@ enum devlink_param_generic_id { #define DEVLINK_PARAM_GENERIC_MAX_MAC_PER_VF_NAME "max_mac_per_vf" #define DEVLINK_PARAM_GENERIC_MAX_MAC_PER_VF_TYPE DEVLINK_PARAM_TYPE_U32 +#define DEVLINK_PARAM_GENERIC_MAX_SFS_NAME "max_sfs" +#define DEVLINK_PARAM_GENERIC_MAX_SFS_TYPE DEVLINK_PARAM_TYPE_U32 + #define DEVLINK_PARAM_GENERIC(_id, _cmodes, _get, _set, _validate) \ { \ .id = DEVLINK_PARAM_GENERIC_ID_##_id, \ @@ -1594,6 +1598,15 @@ struct devlink_ops { struct devlink_rate *parent, void *priv_child, void *priv_parent, struct netlink_ext_ack *extack); + /* Indicates if cross-device rate nodes are supported. + * This also requires a shared common ancestor object all devices that + * could share rate nodes are nested in. + * If enabled, rate operations may be called on an instance with only + * the common ancestor lock held and *without that instance lock held*. + * It is the driver's responsibility to ensure proper serialization + * with other operations. + */ + bool supported_cross_device_rate_nodes; /** * selftests_check() - queries if selftest is supported * @devlink: devlink instance diff --git a/include/net/dsa.h b/include/net/dsa.h index 8c16ef23cc10..7507d632e7c6 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -59,6 +59,8 @@ struct tc_action; #define DSA_TAG_PROTO_MXL_GSW1XX_VALUE 31 #define DSA_TAG_PROTO_MXL862_VALUE 32 #define DSA_TAG_PROTO_NETC_VALUE 33 +#define DSA_TAG_PROTO_KSZ8463_VALUE 34 +#define DSA_TAG_PROTO_MT7628_VALUE 35 enum dsa_tag_protocol { DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE, @@ -95,6 +97,8 @@ enum dsa_tag_protocol { DSA_TAG_PROTO_MXL_GSW1XX = DSA_TAG_PROTO_MXL_GSW1XX_VALUE, DSA_TAG_PROTO_MXL862 = DSA_TAG_PROTO_MXL862_VALUE, 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, }; struct dsa_switch; diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h index 7dee0ae616e3..c6b94790fa81 100644 --- a/include/net/fib_rules.h +++ b/include/net/fib_rules.h @@ -82,7 +82,7 @@ struct fib_rules_ops { struct fib_rule_hdr *, struct nlattr **, struct netlink_ext_ack *); - int (*delete)(struct fib_rule *); + void (*delete)(struct fib_rule *); int (*compare)(struct fib_rule *, struct fib_rule_hdr *, struct nlattr **); @@ -93,11 +93,13 @@ struct fib_rules_ops { /* Called after modifications to the rules set, must flush * the route cache if one exists. */ void (*flush_cache)(struct fib_rules_ops *ops); + bool (*need_rtnl)(struct net *net); int nlgroup; struct list_head rules_list; struct module *owner; struct net *fro_net; + struct mutex lock; struct rcu_head rcu; }; diff --git a/include/net/geneve.h b/include/net/geneve.h index 5c96827a487e..ba2c14d61e90 100644 --- a/include/net/geneve.h +++ b/include/net/geneve.h @@ -68,9 +68,4 @@ static inline bool netif_is_geneve(const struct net_device *dev) !strcmp(dev->rtnl_link_ops->kind, "geneve"); } -#ifdef CONFIG_INET -struct net_device *geneve_dev_create_fb(struct net *net, const char *name, - u8 name_assign_type, u16 dst_port); -#endif /*ifdef CONFIG_INET */ - #endif /*ifdef__NET_GENEVE_H */ diff --git a/include/net/gre.h b/include/net/gre.h index ccd293203284..b55f67ecd2fc 100644 --- a/include/net/gre.h +++ b/include/net/gre.h @@ -32,8 +32,6 @@ struct gre_protocol { int gre_add_protocol(const struct gre_protocol *proto, u8 version); int gre_del_protocol(const struct gre_protocol *proto, u8 version); -struct net_device *gretap_fb_dev_create(struct net *net, const char *name, - u8 name_assign_type); int gre_parse_header(struct sk_buff *skb, struct tnl_ptk_info *tpi, bool *csum_err, __be16 proto, int nhs); diff --git a/include/net/gue.h b/include/net/gue.h index dfca298bec9c..caefd6da8693 100644 --- a/include/net/gue.h +++ b/include/net/gue.h @@ -80,7 +80,7 @@ static inline size_t guehdr_flags_len(__be16 flags) static inline size_t guehdr_priv_flags_len(__be32 flags) { - return 0; + return (flags & GUE_PFLAG_REMCSUM) ? GUE_PLEN_REMCSUM : 0; } /* Validate standard and private flags. Returns non-zero (meaning invalid) diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h index c60867e7e43c..8bbaf77da7cf 100644 --- a/include/net/ieee80211_radiotap.h +++ b/include/net/ieee80211_radiotap.h @@ -95,6 +95,8 @@ enum ieee80211_radiotap_presence { IEEE80211_RADIOTAP_EXT = 31, IEEE80211_RADIOTAP_EHT_USIG = 33, IEEE80211_RADIOTAP_EHT = 34, + IEEE80211_RADIOTAP_UHR_ELR = 37, + IEEE80211_RADIOTAP_UHR = 38, }; /* for IEEE80211_RADIOTAP_FLAGS */ @@ -602,6 +604,194 @@ enum ieee80211_radiotap_eht_usig_tb { IEEE80211_RADIOTAP_EHT_USIG2_TB_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 + */ +struct ieee80211_radiotap_uhr_elr { + __le32 known; + __le32 sig1, sig2, mark; +} __packed; + +enum ieee80211_radiotap_uhr_elr_known { + IEEE80211_RADIOTAP_UHR_ELR_KNOWN_VERSION_ID = 0x00000001, + IEEE80211_RADIOTAP_UHR_ELR_KNOWN_UL_DL = 0x00000002, + IEEE80211_RADIOTAP_UHR_ELR_KNOWN_MCS = 0x00000004, + IEEE80211_RADIOTAP_UHR_ELR_KNOWN_CODING = 0x00000008, + IEEE80211_RADIOTAP_UHR_ELR_KNOWN_LENGTH = 0x00000010, + IEEE80211_RADIOTAP_UHR_ELR_KNOWN_LDPC_EXTRA_OFDM_SYM = 0x00000020, + IEEE80211_RADIOTAP_UHR_ELR_KNOWN_SIG_1_CRC = 0x00000040, + IEEE80211_RADIOTAP_UHR_ELR_KNOWN_SIG_1_TAIL = 0x00000080, + IEEE80211_RADIOTAP_UHR_ELR_KNOWN_STA_ID = 0x00000100, + IEEE80211_RADIOTAP_UHR_ELR_KNOWN_DISREGARD = 0x00000200, + IEEE80211_RADIOTAP_UHR_ELR_KNOWN_SIG_2_CRC = 0x00000400, + IEEE80211_RADIOTAP_UHR_ELR_KNOWN_SIG_2_TAIL = 0x00000800, + IEEE80211_RADIOTAP_UHR_ELR_KNOWN_SIG_1_CRC_CHECKED = 0x00001000, + IEEE80211_RADIOTAP_UHR_ELR_KNOWN_SIG_2_CRC_CHECKED = 0x00002000, + IEEE80211_RADIOTAP_UHR_ELR_KNOWN_MARK_BSS_COLOR = 0x00010000, +}; + +enum ieee80211_radiotap_uhr_elr_sig1 { + IEEE80211_RADIOTAP_UHR_ELR_SIG1_VERSION_ID = 0x00000001, + IEEE80211_RADIOTAP_UHR_ELR_SIG1_UL_DL = 0x00000002, + IEEE80211_RADIOTAP_UHR_ELR_SIG1_MCS = 0x00000004, + IEEE80211_RADIOTAP_UHR_ELR_SIG1_CODING = 0x00000008, + IEEE80211_RADIOTAP_UHR_ELR_SIG1_LENGTH = 0x00001FF0, + IEEE80211_RADIOTAP_UHR_ELR_SIG1_LDPC_EXTRA_OFDM_SYM = 0x00002000, + IEEE80211_RADIOTAP_UHR_ELR_SIG1_CRC = 0x0003C000, + IEEE80211_RADIOTAP_UHR_ELR_SIG1_TAIL = 0x00FC0000, + IEEE80211_RADIOTAP_UHR_ELR_SIG1_CRC_VALID = 0x80000000, +}; + +enum ieee80211_radiotap_uhr_elr_sig2 { + IEEE80211_RADIOTAP_UHR_ELR_SIG2_STA_ID = 0x000007FF, + IEEE80211_RADIOTAP_UHR_ELR_SIG2_DISREGARD = 0x00003800, + IEEE80211_RADIOTAP_UHR_ELR_SIG2_CRC = 0x0003C000, + IEEE80211_RADIOTAP_UHR_ELR_SIG2_TAIL = 0x00FC0000, + IEEE80211_RADIOTAP_UHR_ELR_SIG2_CRC_VALID = 0x80000000, +}; + +enum ieee80211_radiotap_uhr_elr_mark { + IEEE80211_RADIOTAP_UHR_ELR_MARK_BSS_COLOR = 0x0000003F, +}; + +/* + * ieee80211_radiotap_uhr - content of UHR TLV (type 38) + * see https://www.radiotap.org/fields/UHR for details + */ +struct ieee80211_radiotap_uhr { + __le32 known; + __le32 data[9]; + struct { + __le32 known, info; + } user[]; +} __packed; + +enum ieee80211_radiotap_uhr_known { + IEEE80211_RADIOTAP_UHR_KNOWN_SPATIAL_REUSE = 0x00000001, + IEEE80211_RADIOTAP_UHR_KNOWN_GI_LTF_SIZE = 0x00000002, + IEEE80211_RADIOTAP_UHR_KNOWN_NUMBER_OF_UHR_LTF_SYMBOLS = 0x00000004, + IEEE80211_RADIOTAP_UHR_KNOWN_LDPC_EXTRA_SYMBOL_SEGMENT = 0x00000008, + IEEE80211_RADIOTAP_UHR_KNOWN_PRE_FEC_PADDING_FACTOR = 0x00000010, + IEEE80211_RADIOTAP_UHR_KNOWN_PE_DISAMBIGUITY = 0x00000020, + IEEE80211_RADIOTAP_UHR_KNOWN_DISREGARD_OFDMA = 0x00000040, + IEEE80211_RADIOTAP_UHR_KNOWN_CRC1 = 0x00000080, + IEEE80211_RADIOTAP_UHR_KNOWN_TAIL1 = 0x00000100, + IEEE80211_RADIOTAP_UHR_KNOWN_CRC2 = 0x00000200, + IEEE80211_RADIOTAP_UHR_KNOWN_TAIL2 = 0x00000400, + IEEE80211_RADIOTAP_UHR_KNOWN_INTERFERENCE_MITIGATION = 0x00000800, + IEEE80211_RADIOTAP_UHR_KNOWN_DISREGARD_NON_OFDMA = 0x00001000, + IEEE80211_RADIOTAP_UHR_KNOWN_NUMBER_OF_NON_OFDMA_USERS = 0x00002000, + IEEE80211_RADIOTAP_UHR_KNOWN_COMMON_ENCODING_BLOCK_CRC = 0x00004000, + IEEE80211_RADIOTAP_UHR_KNOWN_COMMON_ENCODING_BLOCK_TAIL = 0x00008000, + IEEE80211_RADIOTAP_UHR_KNOWN_RU_MRU_DRU_SIZE = 0x00010000, + IEEE80211_RADIOTAP_UHR_KNOWN_RU_MRU_INDEX = 0x00020000, + IEEE80211_RADIOTAP_UHR_KNOWN_DRU_RRU_ALLOC_TB_FMT = 0x00040000, + IEEE80211_RADIOTAP_UHR_KNOWN_PRI80_CHAN_POS = 0x00080000, +}; + +enum ieee80211_radiotap_uhr_data { + /* data[0] */ + IEEE80211_RADIOTAP_UHR_DATA0_SPATIAL_REUSE = 0x0000000F, + IEEE80211_RADIOTAP_UHR_DATA0_GI_LTF_SIZE = 0x00000030, + IEEE80211_RADIOTAP_UHR_DATA0_NUMBER_OF_LTF_SYMBOLS = 0x00000700, + IEEE80211_RADIOTAP_UHR_DATA0_LDPC_EXTRA_SYMBOL_SEGMENT = 0x00000800, + IEEE80211_RADIOTAP_UHR_DATA0_PRE_FEC_PADDING_FACTOR = 0x00003000, + IEEE80211_RADIOTAP_UHR_DATA0_PE_DISAMBIGUITY = 0x00004000, + IEEE80211_RADIOTAP_UHR_DATA0_DISREGARD_OFDMA = 0x00078000, + IEEE80211_RADIOTAP_UHR_DATA0_CRC1 = 0x00780000, + IEEE80211_RADIOTAP_UHR_DATA0_TAIL1 = 0x1f800000, + /* data[1] */ + IEEE80211_RADIOTAP_UHR_DATA1_RU_MRU_DRU_SIZE = 0x0000001f, + IEEE80211_RADIOTAP_UHR_DATA1_RU_MRU_INDEX = 0x00001fe0, + IEEE80211_RADIOTAP_UHR_DATA1_RU_ALLOC_CC_1_1_1 = 0x003fe000, + IEEE80211_RADIOTAP_UHR_DATA1_RU_ALLOC_CC_1_1_1_KNOWN = 0x00400000, + IEEE80211_RADIOTAP_UHR_DATA1_PRI80_CHAN_POS = 0xc0000000, + /* data[2] */ + IEEE80211_RADIOTAP_UHR_DATA2_RU_ALLOC_CC_2_1_1 = 0x000001ff, + IEEE80211_RADIOTAP_UHR_DATA2_RU_ALLOC_CC_2_1_1_KNOWN = 0x00000200, + IEEE80211_RADIOTAP_UHR_DATA2_RU_ALLOC_CC_1_1_2 = 0x0007fc00, + IEEE80211_RADIOTAP_UHR_DATA2_RU_ALLOC_CC_1_1_2_KNOWN = 0x00080000, + IEEE80211_RADIOTAP_UHR_DATA2_RU_ALLOC_CC_2_1_2 = 0x1ff00000, + IEEE80211_RADIOTAP_UHR_DATA2_RU_ALLOC_CC_2_1_2_KNOWN = 0x20000000, + /* data[3] */ + IEEE80211_RADIOTAP_UHR_DATA3_RU_ALLOC_CC_1_2_1 = 0x000001ff, + IEEE80211_RADIOTAP_UHR_DATA3_RU_ALLOC_CC_1_2_1_KNOWN = 0x00000200, + IEEE80211_RADIOTAP_UHR_DATA3_RU_ALLOC_CC_2_2_1 = 0x0007fc00, + IEEE80211_RADIOTAP_UHR_DATA3_RU_ALLOC_CC_2_2_1_KNOWN = 0x00080000, + IEEE80211_RADIOTAP_UHR_DATA3_RU_ALLOC_CC_1_2_2 = 0x1ff00000, + IEEE80211_RADIOTAP_UHR_DATA3_RU_ALLOC_CC_1_2_2_KNOWN = 0x20000000, + /* data[4] */ + IEEE80211_RADIOTAP_UHR_DATA4_RU_ALLOC_CC_2_2_2 = 0x000001ff, + IEEE80211_RADIOTAP_UHR_DATA4_RU_ALLOC_CC_2_2_2_KNOWN = 0x00000200, + IEEE80211_RADIOTAP_UHR_DATA4_RU_ALLOC_CC_1_2_3 = 0x0007fc00, + IEEE80211_RADIOTAP_UHR_DATA4_RU_ALLOC_CC_1_2_3_KNOWN = 0x00080000, + IEEE80211_RADIOTAP_UHR_DATA4_RU_ALLOC_CC_2_2_3 = 0x1ff00000, + IEEE80211_RADIOTAP_UHR_DATA4_RU_ALLOC_CC_2_2_3_KNOWN = 0x20000000, + /* data[5] */ + IEEE80211_RADIOTAP_UHR_DATA5_RU_ALLOC_CC_1_2_4 = 0x000001ff, + IEEE80211_RADIOTAP_UHR_DATA5_RU_ALLOC_CC_1_2_4_KNOWN = 0x00000200, + IEEE80211_RADIOTAP_UHR_DATA5_RU_ALLOC_CC_2_2_4 = 0x0007fc00, + IEEE80211_RADIOTAP_UHR_DATA5_RU_ALLOC_CC_2_2_4_KNOWN = 0x00080000, + IEEE80211_RADIOTAP_UHR_DATA5_RU_ALLOC_CC_1_2_5 = 0x1ff00000, + IEEE80211_RADIOTAP_UHR_DATA5_RU_ALLOC_CC_1_2_5_KNOWN = 0x20000000, + /* data[6] */ + IEEE80211_RADIOTAP_UHR_DATA6_RU_ALLOC_CC_2_2_5 = 0x000001ff, + IEEE80211_RADIOTAP_UHR_DATA6_RU_ALLOC_CC_2_2_5_KNOWN = 0x00000200, + IEEE80211_RADIOTAP_UHR_DATA6_RU_ALLOC_CC_1_2_6 = 0x0007fc00, + IEEE80211_RADIOTAP_UHR_DATA6_RU_ALLOC_CC_1_2_6_KNOWN = 0x00080000, + IEEE80211_RADIOTAP_UHR_DATA6_RU_ALLOC_CC_2_2_6 = 0x1ff00000, + IEEE80211_RADIOTAP_UHR_DATA6_RU_ALLOC_CC_2_2_6_KNOWN = 0x20000000, + /* data[7] */ + IEEE80211_RADIOTAP_UHR_DATA7_CRC2 = 0x0000000f, + IEEE80211_RADIOTAP_UHR_DATA7_TAIL2 = 0x000003f0, + IEEE80211_RADIOTAP_UHR_DATA7_INTERFERENCE_MITIGATION = 0x00000400, + IEEE80211_RADIOTAP_UHR_DATA7_DISREGARD_NON_OFDMA = 0x00001800, + IEEE80211_RADIOTAP_UHR_DATA7_NUMBER_OF_NON_OFDMA_USERS = 0x0000e000, + IEEE80211_RADIOTAP_UHR_DATA7_COMMON_ENCODING_BLOCK_CRC = 0x000f0000, + IEEE80211_RADIOTAP_UHR_DATA7_COMMON_ENCODING_BLOCK_TAIL = 0x03f00000, + /* data[8] */ + IEEE80211_RADIOTAP_UHR_DATA8_DRU_RRU_ALLOC_TB_FMT_PS_160= 0x00000001, + IEEE80211_RADIOTAP_UHR_DATA8_DRU_RRU_ALLOC_TB_FMT_B0 = 0x00000002, + IEEE80211_RADIOTAP_UHR_DATA8_DRU_RRU_ALLOC_TB_FMT_B7_B1 = 0x000001fc, + IEEE80211_RADIOTAP_UHR_DATA8_DRU_RRU_INDICATION = 0x00000200, +}; + +enum ieee80211_radiotap_uhr_user_known { + IEEE80211_RADIOTAP_UHR_USER_KNOWN_STA_ID = 0x00000001, + IEEE80211_RADIOTAP_UHR_USER_KNOWN_MCS = 0x00000002, + IEEE80211_RADIOTAP_UHR_USER_KNOWN_NSS = 0x00000004, + IEEE80211_RADIOTAP_UHR_USER_KNOWN_UEQM = 0x00000008, + IEEE80211_RADIOTAP_UHR_USER_KNOWN_BF = 0x00000010, + IEEE80211_RADIOTAP_UHR_USER_KNOWN_CODING = 0x00000020, + IEEE80211_RADIOTAP_UHR_USER_KNOWN_UEQM_PATTERN = 0x00000040, + IEEE80211_RADIOTAP_UHR_USER_KNOWN_2X_LDPC = 0x00000080, + IEEE80211_RADIOTAP_UHR_USER_KNOWN_SPATIAL_CONFIG = 0x00000100, + IEEE80211_RADIOTAP_UHR_USER_KNOWN_DISREGARD = 0x00000200, + IEEE80211_RADIOTAP_UHR_USER_KNOWN_BSS_COLOR_INDICATION = 0x00000400, + IEEE80211_RADIOTAP_UHR_USER_KNOWN_USR_ENC_BLK_CRC = 0x00000800, + IEEE80211_RADIOTAP_UHR_USER_KNOWN_USR_ENC_BLK_TAIL = 0x00001000, + /* really 'known' but actual data */ + IEEE80211_RADIOTAP_UHR_USER_KNOWN_DATA_USR_ENC_BLK_CRC = 0x000f0000, + IEEE80211_RADIOTAP_UHR_USER_KNOWN_DATA_USR_ENC_BLK_TAIL = 0x03f00000, + /* indicates this user was captured */ + IEEE80211_RADIOTAP_UHR_USER_KNOWN_USER_CAPTURED = 0x80000000, +}; + +enum ieee80211_radiotap_uhr_user_info { + IEEE80211_RADIOTAP_UHR_USER_INFO_STA_ID = 0x000007ff, + IEEE80211_RADIOTAP_UHR_USER_INFO_MCS = 0x0000f800, + IEEE80211_RADIOTAP_UHR_USER_INFO_NSS = 0x00070000, + IEEE80211_RADIOTAP_UHR_USER_INFO_SPATIAL_CONFIG = 0x000f0000, + IEEE80211_RADIOTAP_UHR_USER_INFO_UEQM = 0x00100000, + IEEE80211_RADIOTAP_UHR_USER_INFO_DISREGARD = 0x00100000, + IEEE80211_RADIOTAP_UHR_USER_INFO_BF = 0x00200000, + IEEE80211_RADIOTAP_UHR_USER_INFO_BSS_COLOR_INDICATION = 0x00200000, + IEEE80211_RADIOTAP_UHR_USER_INFO_UEQM_PATTERN = 0x00c00000, + IEEE80211_RADIOTAP_UHR_USER_INFO_CODING = 0x01000000, + IEEE80211_RADIOTAP_UHR_USER_INFO_2X_LDPC = 0x02000000, +}; + /** * ieee80211_get_radiotap_len - get radiotap header length * @data: pointer to the header diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h index f475757daafb..414e9adf4c51 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -35,6 +35,7 @@ struct inetpeer_addr { struct inet_peer { struct rb_node rb_node; + u64 hash; struct inetpeer_addr daddr; u32 metrics[RTAX_MAX]; @@ -125,6 +126,9 @@ static inline int inetpeer_addr_cmp(const struct inetpeer_addr *a, { int i, n; + if (a->family != b->family) + return a->family < b->family ? -1 : 1; + if (a->family == AF_INET) n = sizeof(a->a4) / sizeof(u32); else diff --git a/include/net/ip.h b/include/net/ip.h index 7f2fe1a8401b..a8f57b4f4aa2 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -506,6 +506,31 @@ 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) { diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index 9cd27e1b9b69..232289b439c3 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -468,7 +468,8 @@ void fib6_clean_all_skip_notify(struct net *net, int fib6_add(struct fib6_node *root, struct fib6_info *rt, struct nl_info *info, struct netlink_ext_ack *extack); -int fib6_del(struct fib6_info *rt, struct nl_info *info); +int fib6_del(struct fib6_info *rt, struct nl_info *info, + enum rt_del_reason del_reason); static inline void rt6_get_prefsrc(const struct rt6_info *rt, struct in6_addr *addr) @@ -532,6 +533,8 @@ static inline void fib6_rt_update(struct net *net, struct fib6_info *rt, #endif void inet6_rt_notify(int event, struct fib6_info *rt, struct nl_info *info, unsigned int flags); +void inet6_rt_del_notify(struct fib6_info *rt, struct nl_info *info, + enum rt_del_reason del_reason); void fib6_age_exceptions(struct fib6_info *rt, struct fib6_gc_args *gc_args, unsigned long now); diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 09ffe0f13ce7..c69f1c871922 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -126,6 +126,8 @@ int ipv6_route_ioctl(struct net *net, unsigned int cmd, int ip6_route_add(struct fib6_config *cfg, gfp_t gfp_flags, struct netlink_ext_ack *extack); int ip6_ins_rt(struct net *net, struct fib6_info *f6i); +int ip6_del_rt_reason(struct net *net, struct fib6_info *f6i, + enum rt_del_reason del_reason); #if IS_ENABLED(CONFIG_IPV6) int ip6_del_rt(struct net *net, struct fib6_info *f6i, bool skip_notify); #else @@ -385,6 +387,43 @@ 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); +} + u32 ip6_mtu_from_fib6(const struct fib6_result *res, const struct in6_addr *daddr, const struct in6_addr *saddr); diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index c63a3c4967ae..0a35355fb0f3 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -302,7 +302,8 @@ static inline struct fib_table *fib_get_table(struct net *net, u32 id) &net->ipv4.fib_table_hash[TABLE_LOCAL_INDEX] : &net->ipv4.fib_table_hash[TABLE_MAIN_INDEX]; - tb_hlist = rcu_dereference_rtnl(hlist_first_rcu(ptr)); + /* Only fib4_rules_init() adds fib_table. */ + tb_hlist = rcu_dereference_protected(hlist_first_rcu(ptr), true); return hlist_entry(tb_hlist, struct fib_table, tb_hlist); } diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index d708b66e55cd..7c9aadfe8fe3 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -412,7 +412,6 @@ bool ip_tunnel_parm_from_user(struct ip_tunnel_parm_kern *kp, bool ip_tunnel_parm_to_user(void __user *data, struct ip_tunnel_parm_kern *kp); int ip_tunnel_siocdevprivate(struct net_device *dev, struct ifreq *ifr, void __user *data, int cmd); -int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict); int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu); struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, @@ -629,8 +628,7 @@ struct metadata_dst *iptunnel_metadata_reply(struct metadata_dst *md, int skb_tunnel_check_pmtu(struct sk_buff *skb, struct dst_entry *encap_dst, int headroom, bool reply); -static inline void ip_tunnel_adj_headroom(struct net_device *dev, - unsigned int headroom) +static inline unsigned int ip_tunnel_limit_headroom(unsigned int headroom) { /* we must cap headroom to some upperlimit, else pskb_expand_head * will overflow header offsets in skb_headers_offset_update(). @@ -640,6 +638,14 @@ static inline void ip_tunnel_adj_headroom(struct net_device *dev, if (headroom > max_allowed) headroom = max_allowed; + return headroom; +} + +static inline void ip_tunnel_adj_headroom(struct net_device *dev, + unsigned int headroom) +{ + headroom = ip_tunnel_limit_headroom(headroom); + if (headroom > READ_ONCE(dev->needed_headroom)) WRITE_ONCE(dev->needed_headroom, headroom); } diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 49297fec448a..32fde731bceb 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -36,6 +36,12 @@ #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 */ + /* conn_tab limits (as per Kconfig) */ #define IP_VS_CONN_TAB_MIN_BITS 8 #if BITS_PER_LONG > 32 @@ -752,7 +758,8 @@ struct ip_vs_protocol { void (*state_transition)(struct ip_vs_conn *cp, int direction, const struct sk_buff *skb, - struct ip_vs_proto_data *pd); + struct ip_vs_proto_data *pd, + unsigned int iph_len); int (*register_app)(struct netns_ipvs *ipvs, struct ip_vs_app *inc); @@ -975,6 +982,7 @@ struct ip_vs_dest { 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 */ __u16 tun_type; /* tunnel type */ __be16 tun_port; /* tunnel port */ @@ -986,10 +994,11 @@ struct ip_vs_dest { /* connection counters and thresholds */ atomic_t activeconns; /* active connections */ - atomic_t inactconns; /* inactive connections */ + atomic_t totalconns; /* total connections */ atomic_t persistconns; /* persistent connections */ __u32 u_threshold; /* upper threshold */ __u32 l_threshold; /* lower threshold */ + __u32 l_threshold_val;/* used lower threshold */ /* for destination cache */ spinlock_t dst_lock; /* lock of dst_cache */ @@ -1906,6 +1915,8 @@ 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); + /* IPVS sync daemon data and function prototypes * (from ip_vs_sync.c) */ @@ -1971,8 +1982,8 @@ int ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, int ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph); int ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, - struct ip_vs_protocol *pp, int offset, - unsigned int hooknum, struct ip_vs_iphdr *iph); + struct ip_vs_protocol *pp, unsigned int toff, + unsigned int hooknum, struct ip_vs_iphdr *ciph); void ip_vs_dest_dst_rcu_free(struct rcu_head *head); #ifdef CONFIG_IP_VS_IPV6 @@ -1985,8 +1996,8 @@ int ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, int ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, struct ip_vs_protocol *pp, struct ip_vs_iphdr *iph); int ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp, - struct ip_vs_protocol *pp, int offset, - unsigned int hooknum, struct ip_vs_iphdr *iph); + struct ip_vs_protocol *pp, unsigned int toff, + unsigned int hooknum, struct ip_vs_iphdr *ciph); #endif #ifdef CONFIG_SYSCTL @@ -2057,16 +2068,16 @@ static inline bool ip_vs_conn_use_hash2(struct ip_vs_conn *cp) !(cp->flags & IP_VS_CONN_F_TEMPLATE); } -void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp, - struct ip_vs_conn *cp, int dir); +bool ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp, + struct ip_vs_conn *cp, int dir, unsigned int toff, + bool has_ports, struct ip_vs_iphdr *ciph); #ifdef CONFIG_IP_VS_IPV6 void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp, - struct ip_vs_conn *cp, int dir); + struct ip_vs_conn *cp, int dir, unsigned int toff, + bool has_ports, struct ip_vs_iphdr *ciph); #endif -__sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset); - static inline __wsum ip_vs_check_diff4(__be32 old, __be32 new, __wsum oldsum) { __be32 diff[2] = { ~old, new }; @@ -2092,6 +2103,26 @@ static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum) return csum_partial(diff, sizeof(diff), oldsum); } +static inline bool ip_vs_checksum_needed(struct sk_buff *skb) +{ + /* Checksum unnecessary or already validated? */ + if (skb_csum_unnecessary(skb)) + return false; + /* Locally generated ? */ + if (!skb->dev) + return false; + return true; +} + +static inline bool ip_vs_checksum_common_check(struct sk_buff *skb, + int offset, int proto, int af) +{ + if (!ip_vs_checksum_needed(skb)) + return true; + /* Validate csum even for FORWARD */ + return !nf_checksum(skb, NF_INET_LOCAL_IN, offset, proto, af); +} + /* Forget current conntrack (unconfirmed) and attach notrack entry */ static inline void ip_vs_notrack(struct sk_buff *skb) { @@ -2100,7 +2131,7 @@ static inline void ip_vs_notrack(struct sk_buff *skb) struct nf_conn *ct = nf_ct_get(skb, &ctinfo); if (ct) { - nf_conntrack_put(&ct->ct_general); + nf_reset_ct(skb); nf_ct_set(skb, NULL, IP_CT_UNTRACKED); } #endif @@ -2123,7 +2154,7 @@ void ip_vs_update_conntrack(struct sk_buff *skb, struct ip_vs_conn *cp, int outin); int ip_vs_confirm_conntrack(struct sk_buff *skb); void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct, - struct ip_vs_conn *cp, u_int8_t proto, + struct ip_vs_conn *cp, u8 proto, const __be16 port, int from_rs); void ip_vs_conn_drop_conntrack(struct ip_vs_conn *cp); @@ -2199,14 +2230,21 @@ void ip_vs_unregister_hooks(struct netns_ipvs *ipvs, unsigned int af); static inline int ip_vs_dest_conn_overhead(struct ip_vs_dest *dest) { - /* We think the overhead of processing active connections is 256 + /* We think the overhead of processing active connections is 257 * times higher than that of inactive connections in average. (This - * 256 times might not be accurate, we will change it later) We + * 257 times might not be accurate, we will change it later) We * use the following formula to estimate the overhead now: - * dest->activeconns*256 + dest->inactconns + * dest->activeconns*256 + dest->totalconns */ return (atomic_read(&dest->activeconns) << 8) + - atomic_read(&dest->inactconns); + atomic_read(&dest->totalconns); +} + +static inline int +ip_vs_dest_inactconns(const struct ip_vs_dest *dest) +{ + return max(atomic_read(&dest->totalconns) - + atomic_read(&dest->activeconns), 0); } #ifdef CONFIG_IP_VS_PROTO_TCP diff --git a/include/net/libeth/rx.h b/include/net/libeth/rx.h index 5d991404845e..0e736846c5e8 100644 --- a/include/net/libeth/rx.h +++ b/include/net/libeth/rx.h @@ -69,6 +69,7 @@ enum libeth_fqe_type { * @type: type of the buffers this queue has * @hsplit: flag whether header split is enabled * @xdp: flag indicating whether XDP is enabled + * @no_napi: the queue is not a data queue and does not have NAPI * @buf_len: HW-writeable length per each buffer * @nid: ID of the closest NUMA node with memory */ @@ -85,12 +86,13 @@ struct libeth_fq { enum libeth_fqe_type type:2; bool hsplit:1; bool xdp:1; + bool no_napi:1; u32 buf_len; int nid; }; -int libeth_rx_fq_create(struct libeth_fq *fq, struct napi_struct *napi); +int libeth_rx_fq_create(struct libeth_fq *fq, void *napi_dev); void libeth_rx_fq_destroy(struct libeth_fq *fq); /** diff --git a/include/net/libeth/xsk.h b/include/net/libeth/xsk.h index 82b5d21aae87..a452b7828ce4 100644 --- a/include/net/libeth/xsk.h +++ b/include/net/libeth/xsk.h @@ -196,7 +196,7 @@ __libeth_xsk_xmit_fill_buf_md(const struct xdp_desc *xdesc, struct libeth_xdp_tx_desc desc; struct xdp_desc_ctx ctx; - ctx = xsk_buff_raw_get_ctx(sq->pool, xdesc->addr); + ctx = xsk_buff_raw_get_ctx(sq->pool, xdesc->addr, xdesc->options); desc = (typeof(desc)){ .addr = ctx.dma, __libeth_xdp_tx_len(xdesc->len), @@ -205,7 +205,7 @@ __libeth_xsk_xmit_fill_buf_md(const struct xdp_desc *xdesc, BUILD_BUG_ON(!__builtin_constant_p(tmo == libeth_xsktmo)); tmo = tmo == libeth_xsktmo ? &__libeth_xsktmo : tmo; - xsk_tx_metadata_request(ctx.meta, tmo, &desc); + xsk_tx_metadata_request(sq->pool, &ctx.meta, tmo, &desc); return desc; } diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 4f95da023746..9d1fac6e8082 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -790,6 +790,10 @@ struct ieee80211_bss_npca_params { * be updated to 1, even if bss_param_ch_cnt didn't change. This allows * the link to know that it heard the latest value from its own beacon * (as opposed to hearing its value from another link's beacon). + * @enh_bss_param_ch_cnt: In BSS-mode, the enhanced BSS parameters change + * counter. See @bss_param_ch_cnt, it works the same way. + * @enh_bss_param_ch_cnt_link_id: In BSS-mode, the link_id for the enhanced + * BSS parameter change counter, see @bss_param_ch_cnt_link_id. * @s1g_long_beacon_period: number of beacon intervals between each long * beacon transmission. * @npca: NPCA parameters @@ -894,6 +898,8 @@ struct ieee80211_bss_conf { u8 bss_param_ch_cnt; u8 bss_param_ch_cnt_link_id; + u8 enh_bss_param_ch_cnt; + u8 enh_bss_param_ch_cnt_link_id; u8 s1g_long_beacon_period; @@ -1317,6 +1323,7 @@ ieee80211_rate_get_vht_nss(const struct ieee80211_tx_rate *rate) * @status_data: internal data for TX status handling, assigned privately, * see also &enum ieee80211_status_data for the internal documentation * @status_data_idr: indicates status data is IDR allocated ID for ack frame + * @tx_time_mc: TX time estimate is for a multicast frame, used internally * @tx_time_est: TX time estimate in units of 4us, used internally * @control: union part for control data * @control.rates: TX rates array to try @@ -1342,6 +1349,11 @@ ieee80211_rate_get_vht_nss(const struct ieee80211_tx_rate *rate) * @status.tx_time: airtime consumed for transmission; note this is only * used for WMM AC, not for airtime fairness * @status.flags: status flags, see &enum mac80211_tx_status_flags + * @status.link_valid: if the link which is identified by @status.link_id is + * valid. This flag is set by the driver in the TX status callback when the + * connection is MLO and the driver knows which link was used for TX. + * @status.link_id: id of the link used to transmit the packet. This is used + * along with @status.link_valid. * @status.status_driver_data: driver use area * @ack: union part for pure ACK data * @ack.cookie: cookie for the ACK @@ -1354,8 +1366,8 @@ struct ieee80211_tx_info { status_data_idr:1, status_data:13, hw_queue:4, + tx_time_mc:1, tx_time_est:10; - /* 1 free bit */ union { struct { @@ -1396,7 +1408,7 @@ struct ieee80211_tx_info { u8 pad; u16 tx_time; u8 flags; - u8 pad2; + u8 link_valid:1, link_id:4; void *status_driver_data[16 / sizeof(void *)]; } status; struct { @@ -6877,6 +6889,17 @@ bool ieee80211_txq_airtime_check(struct ieee80211_hw *hw, struct ieee80211_txq *txq); /** + * ieee80211_txq_aql_pending - get pending AQL airtime for a txq + * + * @hw: pointer obtained from ieee80211_alloc_hw() + * @txq: pointer obtained from station or virtual interface + * + * Return: pending airtime (in usec) for the given txq. + */ +u32 ieee80211_txq_aql_pending(struct ieee80211_hw *hw, + struct ieee80211_txq *txq); + +/** * ieee80211_iter_keys - iterate keys programmed into the device * @hw: pointer obtained from ieee80211_alloc_hw() * @vif: virtual interface to iterate, may be %NULL for all diff --git a/include/net/mana/gdma.h b/include/net/mana/gdma.h index 0c395917b214..308950f9b54b 100644 --- a/include/net/mana/gdma.h +++ b/include/net/mana/gdma.h @@ -47,6 +47,7 @@ enum gdma_queue_type { GDMA_RQ, GDMA_CQ, GDMA_EQ, + GDMA_DIM, }; enum gdma_work_request_flags { @@ -126,6 +127,17 @@ union gdma_doorbell_entry { u64 tail_ptr : 31; u64 arm : 1; } eq; + + struct { + u64 id : 24; + u64 reserved : 8; + u64 mod_usec : 10; + u64 reserve1 : 5; + u64 mod_usec_vld : 1; + u64 mod_comps : 8; + u64 reserve2 : 7; + u64 mod_comps_vld: 1; + } dim; }; /* HW DATA */ struct gdma_msg_hdr { @@ -170,6 +182,7 @@ struct gdma_general_req { #define GDMA_MESSAGE_V2 2 #define GDMA_MESSAGE_V3 3 #define GDMA_MESSAGE_V4 4 +#define GDMA_MESSAGE_V5 5 struct gdma_general_resp { struct gdma_resp_hdr hdr; @@ -228,6 +241,14 @@ struct gdma_mem_info { void *virt_addr; u64 length; + /* Scattered fallback: when @nr_pages > 0 the ring is that many + * PAGE_SIZE coherent allocations in @pages_va/@pages_dma, not + * @virt_addr/@dma_handle. + */ + void **pages_va; + dma_addr_t *pages_dma; + unsigned int nr_pages; + /* Allocated by the PF driver */ u64 dma_region_handle; }; @@ -416,6 +437,9 @@ struct gdma_context { /* L2 MTU */ u16 adapter_mtu; + /* NIC supports CQE x8 coalescing */ + bool cqe8_coalescing_sup; + /* This maps a CQ index to the queue structure. */ unsigned int max_num_cqs; struct gdma_queue **cq_table; @@ -500,8 +524,14 @@ int mana_gd_poll_cq(struct gdma_queue *cq, struct gdma_comp *comp, int num_cqe); void mana_gd_ring_cq(struct gdma_queue *cq, u8 arm_bit); +ssize_t mana_gd_read_ring(struct gdma_queue *q, char __user *buf, + size_t count, loff_t *pos); + int mana_schedule_serv_work(struct gdma_context *gc, enum gdma_eqe_type type); +void mana_gd_ring_dim(struct gdma_queue *cq, u32 mod_usec, bool mod_usec_vld, + u32 mod_comps, bool mod_comps_vld); + struct gdma_wqe { u32 reserved :24; u32 last_vbytes :8; @@ -650,6 +680,12 @@ enum { /* Driver supports self recovery on Hardware Channel timeouts */ #define GDMA_DRV_CAP_FLAG_1_HWC_TIMEOUT_RECOVERY BIT(25) +/* Driver supports dynamic interrupt moderation - DIM */ +#define GDMA_DRV_CAP_FLAG_1_DYN_INTERRUPT_MODERATION BIT(28) + +/* Driver supports non-contiguous queue buffers */ +#define GDMA_DRV_CAP_FLAG_1_NON_CONTIGUOUS_BUFFERS BIT(30) + #define GDMA_DRV_CAP_FLAGS1 \ (GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT | \ GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX | \ @@ -665,7 +701,9 @@ enum { 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_EQ_MSI_UNSHARE_MULTI_VPORT | \ + GDMA_DRV_CAP_FLAG_1_DYN_INTERRUPT_MODERATION | \ + GDMA_DRV_CAP_FLAG_1_NON_CONTIGUOUS_BUFFERS) #define GDMA_DRV_CAP_FLAGS2 0 @@ -701,6 +739,9 @@ struct gdma_verify_ver_req { u8 os_ver_str4[128]; }; /* HW DATA */ +/* HW supports dynamic interrupt moderation - DIM */ +#define GDMA_PF_CAP_FLAG_1_DYN_INTERRUPT_MODERATION BIT(15) + struct gdma_verify_ver_resp { struct gdma_resp_hdr hdr; u64 gdma_protocol_ver; @@ -867,8 +908,8 @@ struct gdma_destroy_dma_region_req { }; /* HW DATA */ enum gdma_pd_flags { - GDMA_PD_FLAG_INVALID = 0, - GDMA_PD_FLAG_ALLOW_GPA_MR = 1, + GDMA_PD_FLAG_ALLOW_GPA_MR = BIT(0), + GDMA_PD_FLAG_SHORT_PDN = BIT(2), }; struct gdma_create_pd_req { @@ -889,7 +930,7 @@ struct gdma_destroy_pd_req { u64 pd_handle; };/* HW DATA */ -struct gdma_destory_pd_resp { +struct gdma_destroy_pd_resp { struct gdma_resp_hdr hdr; };/* HW DATA */ @@ -1023,7 +1064,7 @@ void mana_gd_wq_ring_doorbell(struct gdma_context *gc, struct gdma_queue *queue); int mana_gd_alloc_memory(struct gdma_context *gc, unsigned int length, - struct gdma_mem_info *gmi); + struct gdma_mem_info *gmi, bool allow_scatter); void mana_gd_free_memory(struct gdma_mem_info *gmi); diff --git a/include/net/mana/mana.h b/include/net/mana/mana.h index 13c87baf018e..83b7eff4646e 100644 --- a/include/net/mana/mana.h +++ b/include/net/mana/mana.h @@ -4,6 +4,7 @@ #ifndef _MANA_H #define _MANA_H +#include <linux/dim.h> #include <net/xdp.h> #include <net/net_shaper.h> @@ -30,6 +31,12 @@ enum TRI_STATE { TRI_STATE_TRUE = 1 }; +/* MANA ethtool private flag bit positions */ +enum mana_priv_flag_bits { + MANA_PRIV_FLAG_USE_FULL_PAGE_RXBUF = 0, + MANA_PRIV_FLAG_MAX, +}; + /* Number of entries for hardware indirection table must be in power of 2 */ #define MANA_INDIRECT_TABLE_MAX_SIZE 512 #define MANA_INDIRECT_TABLE_DEF_SIZE 64 @@ -61,11 +68,27 @@ enum TRI_STATE { #define MAX_PORTS_IN_MANA_DEV 256 -/* Maximum number of packets per coalesced CQE */ +/* Maximum number of PPIs per coalesced CQE */ #define MANA_RXCOMP_OOB_NUM_PPI 4 +/* 8-pkt mode packs up to 2 packets per PPI entry */ +#define MANA_CQE_COAL_PKTS_8 8 + +/* Default/max interrupt moderation settings */ +#define MANA_INTR_MODR_USEC_DEF 0 +#define MANA_INTR_MODR_COMP_DEF 0 + +#define MANA_ADAPTIVE_RX_DEF true +#define MANA_ADAPTIVE_TX_DEF true + +/* DIM doorbell value field layout */ +#define MANA_INTR_MODR_USEC_MAX GENMASK(9, 0) +#define MANA_INTR_MODR_USEC_VLD BIT(15) +#define MANA_INTR_MODR_COMP_MAX GENMASK(7, 0) +#define MANA_INTR_MODR_COMP_MASK GENMASK(23, 16) + /* Update this count whenever the respective structures are changed */ -#define MANA_STATS_RX_COUNT (6 + MANA_RXCOMP_OOB_NUM_PPI - 1) +#define MANA_STATS_RX_COUNT (6 + MANA_CQE_COAL_PKTS_8 - 1) #define MANA_STATS_TX_COUNT 11 #define MANA_RX_FRAG_ALIGNMENT 64 @@ -77,7 +100,7 @@ struct mana_stats_rx { u64 xdp_tx; u64 xdp_redirect; u64 pkt_len0_err; - u64 coalesced_cqe[MANA_RXCOMP_OOB_NUM_PPI - 1]; + u64 coalesced_cqe[MANA_CQE_COAL_PKTS_8 - 1]; struct u64_stats_sync syncp; }; @@ -188,6 +211,7 @@ enum mana_cqe_type { CQE_RX_COALESCED_4 = 2, CQE_RX_OBJECT_FENCE = 3, CQE_RX_TRUNCATED = 4, + CQE_RX_COALESCED_8 = 7, CQE_TX_OKAY = 32, CQE_TX_SA_DROP = 33, @@ -224,12 +248,26 @@ struct mana_cqe_header { #define MANA_HASH_L4 \ (NDIS_HASH_TCP_IPV4 | NDIS_HASH_UDP_IPV4 | NDIS_HASH_TCP_IPV6 | \ NDIS_HASH_UDP_IPV6 | NDIS_HASH_TCP_IPV6_EX | NDIS_HASH_UDP_IPV6_EX) +#define MANA_HASH_ENABLE_SUPPORTED \ + (NDIS_HASH_IPV4 | NDIS_HASH_TCP_IPV4 | NDIS_HASH_UDP_IPV4 | \ + NDIS_HASH_IPV6 | NDIS_HASH_TCP_IPV6 | NDIS_HASH_UDP_IPV6) + +/* Read PPI in two different layouts based on cqe_type */ +union mana_rxcomp_perpkt_info { + struct { + u32 pkt_len : 16; + u32 reserved1 : 16; + u32 reserved2; + u32 pkt_hash; + }; -struct mana_rxcomp_perpkt_info { - u32 pkt_len : 16; - u32 reserved1 : 16; - u32 reserved2; - u32 pkt_hash; + /* Up to two pkts per PPI entry */ + struct { + u32 pkt_hash0; + u16 pkt_len0; + u16 pkt_len1; + u32 pkt_hash1; + }; }; /* HW DATA */ /* Receive completion OOB */ @@ -250,7 +288,7 @@ struct mana_rxcomp_oob { u32 rx_udp_csum_fail : 1; u32 reserved2 : 1; - struct mana_rxcomp_perpkt_info ppi[MANA_RXCOMP_OOB_NUM_PPI]; + union mana_rxcomp_perpkt_info ppi[MANA_RXCOMP_OOB_NUM_PPI]; u32 rx_wqe_offset; }; /* HW DATA */ @@ -297,6 +335,17 @@ struct mana_cq { int work_done; int work_done_since_doorbell; int budget; + + /* DIM - Dynamic Interrupt Moderation */ + struct dim dim; + u16 dim_event_ctr; + + /* Cumulative TX completions fed to DIM. Updated and read only in + * NAPI context (mana_poll_tx_cq() / mana_update_tx_dim()), so they + * measure the hardware completion rate and need no u64_stats_sync. + */ + u64 tx_dim_pkts; + u64 tx_dim_bytes; }; struct mana_recv_buf_oob { @@ -305,6 +354,14 @@ struct mana_recv_buf_oob { void *buf_va; bool from_pool; /* allocated from a page pool */ + /* head page of the page_pool fragment; valid only when + * from_pool && frag_count > 1. + */ + struct page *pp_page; + /* Fragment offset plus rxq->headroom, passed to + * page_pool_dma_sync_for_cpu(). + */ + u32 dma_sync_offset; /* SGL of the buffer going to be sent as part of the work request. */ u32 num_sge; @@ -497,6 +554,9 @@ struct mana_port_context { struct net_device *ndev; struct work_struct queue_reset_work; + /* Debug knob to log TX timeout but skip recovery reset */ + bool tx_timeout_skip_reset; + u8 mac_addr[ETH_ALEN]; struct mana_eq *eqs; @@ -532,6 +592,8 @@ struct mana_port_context { u32 rxbpre_headroom; u32 rxbpre_frag_count; + u32 priv_flags; + struct bpf_prog *bpf_prog; /* Create num_queues EQs, SQs, SQ-CQs, RQs and RQ-CQs, respectively. */ @@ -571,8 +633,18 @@ struct mana_port_context { bool port_st_save; /* Saved port state */ u8 cqe_coalescing_enable; + u8 cqe8_coalescing_enable; u32 cqe_coalescing_timeout_ns; + /* Interrupt moderation settings */ + u16 intr_modr_rx_usec; + u16 intr_modr_rx_comp; + u16 intr_modr_tx_usec; + u16 intr_modr_tx_comp; + + bool rx_dim_enabled; + bool tx_dim_enabled; + struct mana_ethtool_stats eth_stats; struct mana_ethtool_phy_stats phy_stats; @@ -598,6 +670,8 @@ int mana_alloc_queues(struct net_device *ndev); int mana_attach(struct net_device *ndev); int mana_detach(struct net_device *ndev, bool from_close); +void mana_dim_change(struct mana_cq *cq, bool enable); + int mana_probe(struct gdma_dev *gd, bool resuming); void mana_remove(struct gdma_dev *gd, bool suspending); @@ -633,6 +707,9 @@ struct mana_obj_spec { u32 queue_size; u32 attached_eq; u32 modr_ctx_id; + u8 req_cq_moderation; + u16 cq_moderation_comp; + u16 cq_moderation_usec; }; enum mana_command_code { @@ -701,6 +778,8 @@ struct mana_query_device_cfg_req { u32 reserved; }; /* HW DATA */ +#define MANA_PF_FLAG_1_CQE_8_COALESCING_SUPPORTED BIT(5) + struct mana_query_device_cfg_resp { struct gdma_resp_hdr hdr; @@ -764,6 +843,15 @@ struct mana_create_wqobj_req { u32 cq_size; u32 cq_moderation_ctx_id; u32 cq_parent_qid; + + /* V2 */ + u8 allow_rqwqe_chain; + + /* V3 */ + u8 req_cq_moderation; + u16 cq_moderation_comp; + u16 cq_moderation_usec; + u8 reserved2[2]; }; /* HW DATA */ struct mana_create_wqobj_resp { @@ -771,6 +859,12 @@ struct mana_create_wqobj_resp { u32 wq_id; u32 cq_id; mana_handle_t wq_obj; + + /* V2 */ + u16 cq_moderation_comp; + u16 cq_moderation_usec; + u8 cq_moderation_enabled; + u8 reserved1[3]; }; /* HW DATA */ /* Destroy WQ Object */ @@ -921,7 +1015,10 @@ struct mana_cfg_rx_steer_req_v2 { mana_handle_t default_rxobj; u8 hashkey[MANA_HASH_KEY_SIZE]; u8 cqe_coalescing_enable; - u8 reserved2[7]; + u8 reserved2[3]; + u16 rss_hash_types; + u8 cqe8_coalescing_enable; /* v5 message */ + u8 reserved3; mana_handle_t indir_tab[] __counted_by(num_indir_entries); }; /* HW DATA */ diff --git a/include/net/mptcp.h b/include/net/mptcp.h index 71b9fc5a5796..485d55b66ea6 100644 --- a/include/net/mptcp.h +++ b/include/net/mptcp.h @@ -19,10 +19,6 @@ struct seq_file; /* MPTCP sk_buff extension data */ struct mptcp_ext { - union { - u64 data_ack; - u32 data_ack32; - }; u64 data_seq; u32 subflow_seq; u16 data_len; diff --git a/include/net/ndisc.h b/include/net/ndisc.h index 3da1a6f8d3f9..9e5379ad2d8e 100644 --- a/include/net/ndisc.h +++ b/include/net/ndisc.h @@ -430,6 +430,8 @@ void ndisc_update(const struct net_device *dev, struct neighbour *neigh, const u8 *lladdr, u8 new, u32 flags, u8 icmp6_type, struct ndisc_options *ndopts); +int ndisc_check_ns_na(struct sk_buff *skb); + /* * IGMP */ diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 80de5e98a66d..e5ee673b9fcf 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -197,6 +197,9 @@ struct net { #ifdef CONFIG_DEBUG_NET_SMALL_RTNL /* Move to a better place when the config guard is removed. */ struct mutex rtnl_mutex; + struct work_struct rtnl_work; + struct list_head dev_unreg_head; + spinlock_t dev_unreg_lock; #endif #if IS_ENABLED(CONFIG_VSOCKETS) struct netns_vsock vsock; @@ -522,12 +525,13 @@ struct ctl_table; #ifdef CONFIG_SYSCTL int net_sysctl_init(void); struct ctl_table_header *register_net_sysctl_sz(struct net *net, const char *path, - struct ctl_table *table, size_t table_size); + const struct ctl_table *table, + size_t table_size); void unregister_net_sysctl_table(struct ctl_table_header *header); #else static inline int net_sysctl_init(void) { return 0; } static inline struct ctl_table_header *register_net_sysctl_sz(struct net *net, - const char *path, struct ctl_table *table, size_t table_size) + const char *path, const struct ctl_table *table, size_t table_size) { return NULL; } diff --git a/include/net/net_shaper.h b/include/net/net_shaper.h index 3939b816b001..330517a1cb5c 100644 --- a/include/net/net_shaper.h +++ b/include/net/net_shaper.h @@ -68,21 +68,52 @@ struct net_shaper { * The operations are serialized via a per device lock. * * Device not supporting any kind of nesting should not provide the - * group operation. + * @group operation. * * Each shaper is uniquely identified within the device with a 'handle' * comprising the shaper scope and a scope-specific id. + * + * Driver ops vs uAPI + * ------------------ + * Members of the driver ops mirror the Netlink uAPI but driver calls do not + * map 1:1 to user calls. Drivers need to be careful when assuming that calls + * disallowed at the uAPI level will never be made at the driver level. + * The shaper core performs automatic reparenting and cleanup, generating + * additional calls. Notably: + * + * - @group calls in the driver facing API may have nodes as leaves (user is + * only allowed to construct groups with queues as leaves) + * - @group calls may update leaf's parent if the parent is about + * to be removed (re-parenting nodes explicitly is not supported in the uAPI) + * + * Implicit creation + * ----------------- + * Shapers are created implicitly, meaning that @set and @group operations + * are called both for existing and new shapers. The driver has to infer + * whether the operation is an update or a creation by tracking the handles. + * Removal of shapers is explicit and done with a @delete call. + * + * The @set operation implicitly creates NET_SHAPER_SCOPE_NETDEV and + * NET_SHAPER_SCOPE_QUEUE shapers. + * The @group operation implicitly creates NET_SHAPER_SCOPE_NETDEV and + * NET_SHAPER_SCOPE_NODE shapers (the group shaper itself), as well as + * NET_SHAPER_SCOPE_QUEUE shapers (leaves). */ struct net_shaper_ops { /** - * @group: create the specified shapers scheduling group + * @group: create a scheduling group or add leaves * - * Nest the @leaves shapers identified under the * @node shaper. + * Nest the @leaves shapers identified under the @node shaper. * All the shapers belong to the device specified by @binding. - * The @leaves arrays size is specified by @leaves_count. - * Create either the @leaves and the @node shaper; or if they already - * exists, links them together in the desired way. - * @leaves scope must be NET_SHAPER_SCOPE_QUEUE. + * The @leaves array's size is specified by @leaves_count. + * + * @node and @leaves may or may not already exist + * (see the "Implicit creation" note). If @node already exists, + * the @leaves should be *added* to its children. In this case, + * the @leaves array only holds new/modified leaves, not the full list. + * + * Re-parenting @leaves is implemented by a @group call on a new parent. + * There's no explicit call to remove the children from the old parent. */ int (*group)(struct net_shaper_binding *binding, int leaves_count, const struct net_shaper *leaves, @@ -103,6 +134,13 @@ struct net_shaper_ops { * * Removes the shaper configuration as identified by the given @handle * on the device specified by @binding, restoring the default behavior. + * + * Note that a @delete call on a NET_SHAPER_SCOPE_QUEUE shaper also + * implicitly removes the associated queue from the scheduling + * hierarchy. The driver must take care of that step. + * @delete calls on NET_SHAPER_SCOPE_NODE should not require any + * implicit re-parenting in the driver as core will re-parent the leaves + * first, before deleting the SCOPE_NODE shaper. */ int (*delete)(struct net_shaper_binding *binding, const struct net_shaper_handle *handle, diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h index c024345c9bd8..8c978b9a467d 100644 --- a/include/net/netfilter/nf_conntrack_expect.h +++ b/include/net/netfilter/nf_conntrack_expect.h @@ -42,6 +42,9 @@ struct nf_conntrack_expect { /* Expectation class */ unsigned int class; + /* Event filter mask */ + u16 event_mask; + /* Function to call after setup and insertion */ void (*expectfn)(struct nf_conn *new, struct nf_conntrack_expect *this); @@ -161,6 +164,9 @@ static inline int nf_ct_expect_related(struct nf_conntrack_expect *expect, return nf_ct_expect_related_report(expect, 0, 0, flags); } +int nf_ct_expect_related_pair(struct nf_conntrack_expect *expect[], + unsigned int flag); + struct nf_conn_help; void nf_ct_expectation_gc(struct nf_conn_help *master_help); diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index c761cd8158b2..335b8c43694f 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -43,11 +43,10 @@ struct nf_conntrack_helper { refcount_t ct_refcnt; - /* Tuple of things we will help (compared against server response) */ - struct nf_conntrack_tuple tuple; + u8 nfproto; /* NFPROTO_*, can be NFPROTO_UNSPEC */ + u8 l4proto; /* IPPROTO_UDP/TCP */ - /* Function to call when data passes; return verdict, or -1 to - invalidate. */ + /* Function to call when data passes; return verdict */ int __rcu (*help)(struct sk_buff *skb, unsigned int protoff, struct nf_conn *ct, enum ip_conntrack_info conntrackinfo); @@ -94,8 +93,7 @@ struct nf_conntrack_helper *nf_conntrack_helper_try_module_get(const char *name, void nf_conntrack_helper_put(struct nf_conntrack_helper *helper); void nf_ct_helper_init(struct nf_conntrack_helper *helper, - u16 l3num, u16 protonum, const char *name, - u16 default_port, u16 spec_port, u32 id, + u8 l3num, u16 protonum, const char *name, const struct nf_conntrack_expect_policy *exp_pol, u32 expect_class_max, int (*help)(struct sk_buff *skb, unsigned int protoff, @@ -108,6 +106,7 @@ void nf_ct_helper_init(struct nf_conntrack_helper *helper, int nf_conntrack_helper_register(struct nf_conntrack_helper *, struct nf_conntrack_helper **); int __nf_conntrack_helper_register(struct nf_conntrack_helper *); void nf_conntrack_helper_unregister(struct nf_conntrack_helper *); +void nf_conntrack_helper_release(struct nf_conntrack_helper *); int nf_conntrack_helpers_register(struct nf_conntrack_helper *, unsigned int, struct nf_conntrack_helper **); diff --git a/include/net/netfilter/nf_flow_table.h b/include/net/netfilter/nf_flow_table.h index 7b23b245a5a8..f2e2771f188f 100644 --- a/include/net/netfilter/nf_flow_table.h +++ b/include/net/netfilter/nf_flow_table.h @@ -117,7 +117,7 @@ struct flow_offload_tunnel { struct in6_addr dst_v6; }; - u8 l3_proto; + u8 inner_proto; }; struct flow_offload_tuple { @@ -155,11 +155,12 @@ struct flow_offload_tuple { tun_num:2, in_vlan_ingress:2; u16 mtu; + u32 dst_cookie; + struct dst_entry *dst_cache; + union { struct { - struct dst_entry *dst_cache; u32 ifidx; - u32 dst_cookie; }; struct { u32 ifidx; @@ -309,6 +310,14 @@ int flow_offload_add(struct nf_flowtable *flow_table, struct flow_offload *flow) void flow_offload_refresh(struct nf_flowtable *flow_table, struct flow_offload *flow, bool force); +static inline bool nf_flow_dst_check(struct flow_offload_tuple *tuple) +{ + if (!tuple->dst_cache) + return true; + + return dst_check(tuple->dst_cache, tuple->dst_cookie); +} + struct flow_offload_tuple_rhash *flow_offload_lookup(struct nf_flowtable *flow_table, struct flow_offload_tuple *tuple); void nf_flow_table_gc_run(struct nf_flowtable *flow_table); @@ -357,6 +366,8 @@ static inline int nf_flow_register_bpf(void) void nf_flow_offload_add(struct nf_flowtable *flowtable, struct flow_offload *flow); +void nf_flow_offload_refresh(struct nf_flowtable *flowtable, + struct flow_offload *flow); void nf_flow_offload_del(struct nf_flowtable *flowtable, struct flow_offload *flow); void nf_flow_offload_stats(struct nf_flowtable *flowtable, diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index 9d844354c4d9..9d597482363d 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -870,8 +870,6 @@ struct nft_elem_priv *nft_set_elem_init(const struct nft_set *set, const u32 *key, const u32 *key_end, const u32 *data, u64 timeout, u64 expiration, gfp_t gfp); -int nft_set_elem_expr_clone(const struct nft_ctx *ctx, struct nft_set *set, - struct nft_expr *expr_array[]); void nft_set_elem_expr_destroy(const struct nft_ctx *ctx, struct nft_set_elem_expr *elem_expr); void nft_set_elem_destroy(const struct nft_set *set, @@ -1294,6 +1292,7 @@ static inline void nft_use_inc_restore(u32 *use) * @sets: sets in the table * @objects: stateful objects in the table * @flowtables: flow tables in the table + * @objname_ht: hashtable for objects lookup by name * @hgenerator: handle generator state * @handle: table handle * @use: number of chain references to this table @@ -1313,6 +1312,7 @@ struct nft_table { struct list_head sets; struct list_head objects; struct list_head flowtables; + struct rhltable objname_ht; u64 hgenerator; u64 handle; u32 use; @@ -1400,7 +1400,7 @@ static inline void *nft_obj_data(const struct nft_object *obj) #define nft_expr_obj(expr) *((struct nft_object **)nft_expr_priv(expr)) struct nft_object *nft_obj_lookup(const struct net *net, - const struct nft_table *table, + struct nft_table *table, const struct nlattr *nla, u32 objtype, u8 genmask); @@ -1947,6 +1947,7 @@ struct nftables_pernet { struct list_head binding_list; struct list_head module_list; struct list_head notify_list; + struct list_head set_update_list; struct mutex commit_mutex; u64 table_handle; u64 tstamp; diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index 6e27c56514df..cb7f8bf15671 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -118,6 +118,7 @@ struct netns_ipv4 { struct fib_rules_ops *rules_ops; struct fib_table __rcu *fib_main; struct fib_table __rcu *fib_default; + spinlock_t fib_table_hash_lock; unsigned int fib_rules_require_fldissect; bool fib_has_custom_rules; #endif diff --git a/include/net/nexthop.h b/include/net/nexthop.h index 572e69cda476..f86c115074d7 100644 --- a/include/net/nexthop.h +++ b/include/net/nexthop.h @@ -28,6 +28,7 @@ struct nh_config { u8 nh_protocol; u8 nh_blackhole; u8 nh_fdb; + __be16 nh_dst_port; u32 nh_flags; int nh_ifindex; @@ -63,6 +64,7 @@ struct nh_info { u8 family; bool reject_nh; bool fdb_nh; + __be16 dst_port; union { struct fib_nh_common fib_nhc; @@ -574,7 +576,8 @@ struct fib_nh_common *nexthop_fdb_nhc(struct nexthop *nh) } static inline struct fib_nh_common *nexthop_path_fdb_result(struct nexthop *nh, - int hash) + int hash, + __be16 *dst_port) { struct nh_info *nhi; struct nexthop *nhp; @@ -583,6 +586,7 @@ static inline struct fib_nh_common *nexthop_path_fdb_result(struct nexthop *nh, if (unlikely(!nhp)) return NULL; nhi = rcu_dereference(nhp->nh_info); + *dst_port = nhi->dst_port; return &nhi->fib_nhc; } #endif diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index 3bd08d7f39c1..5f5cb36439fe 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -156,8 +156,20 @@ static inline int tcf_classify(struct sk_buff *skb, { return TC_ACT_UNSPEC; } - #endif +static inline int tcf_classify_qdisc(struct sk_buff *skb, + const struct tcf_proto *tp, + struct tcf_result *res, bool compat_mode) +{ + int ret = tcf_classify(skb, NULL, tp, res, compat_mode); + + /* TC_ACT_REDIRECT from qdisc filter chains is not supported. + * Use BPF via tcx or mirred redirect instead. + */ + if (unlikely(ret == TC_ACT_REDIRECT)) + ret = TC_ACT_SHOT; + return ret; +} static inline unsigned long __cls_set_class(unsigned long *clp, unsigned long cl) diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index 18a419cd9d94..90d3e7943b19 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -12,6 +12,7 @@ #define DEFAULT_TX_QUEUE_LEN 1000 #define STAB_SIZE_LOG_MAX 30 +#define QDISC_PKT_LEN_MAX (1 << 20) /* 1 MiB */ struct qdisc_walker { int stop; diff --git a/include/net/route.h b/include/net/route.h index f90106f383c5..45290177a33c 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -276,6 +276,8 @@ int fib_dump_info_fnhe(struct sk_buff *skb, struct netlink_callback *cb, u32 table_id, struct fib_info *fi, int *fa_index, int fa_start, unsigned int flags); +void fnhe_update_pmtu(struct fib_nh_exception *fnhe, u32 new, u32 orig); + static inline void ip_rt_put(struct rtable *rt) { /* dst_release() accepts a NULL parameter. diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 45a1e8c78222..cbc248776511 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -99,6 +99,7 @@ struct Qdisc { struct hlist_node hash; u32 handle; u32 parent; + int depth; struct netdev_queue *dev_queue; diff --git a/include/net/scm.h b/include/net/scm.h index c52519669349..86ae6bc109ec 100644 --- a/include/net/scm.h +++ b/include/net/scm.h @@ -50,8 +50,8 @@ struct scm_cookie { #endif }; -void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm); -void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm); +void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm, bool notrunc); +void scm_detach_fds_compat(struct msghdr *msg, struct scm_cookie *scm, bool notrunc); int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm); void __scm_destroy(struct scm_cookie *scm); struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl); @@ -107,13 +107,8 @@ void scm_recv(struct socket *sock, struct msghdr *msg, void scm_recv_unix(struct socket *sock, struct msghdr *msg, struct scm_cookie *scm, int flags); -static inline int scm_recv_one_fd(struct file *f, int __user *ufd, - unsigned int flags) -{ - if (!ufd) - return -EFAULT; - return receive_fd(f, ufd, flags); -} +int scm_recv_one_fd(struct file *f, int __user *ufd, unsigned int flags, + bool notrunc); #endif /* __LINUX_NET_SCM_H */ diff --git a/include/net/sctp/auth.h b/include/net/sctp/auth.h index 6f2cd562b1de..85efa65d3912 100644 --- a/include/net/sctp/auth.h +++ b/include/net/sctp/auth.h @@ -22,6 +22,7 @@ struct sctp_endpoint; struct sctp_association; struct sctp_authkey; struct sctp_hmacalgo; +struct sctp_cookie; /* Defines an HMAC algorithm supported by SCTP chunk authentication */ struct sctp_hmac { @@ -72,6 +73,8 @@ struct sctp_shared_key *sctp_auth_get_shkey( int sctp_auth_asoc_copy_shkeys(const struct sctp_endpoint *ep, struct sctp_association *asoc, gfp_t gfp); +bool sctp_auth_verify_cookie_params(const struct sctp_endpoint *ep, + const struct sctp_cookie *cookie); const struct sctp_hmac *sctp_auth_get_hmac(__u16 hmac_id); const struct sctp_hmac * sctp_auth_asoc_get_hmac(const struct sctp_association *asoc); @@ -83,9 +86,9 @@ int sctp_auth_send_cid(enum sctp_cid chunk, const struct sctp_association *asoc); int sctp_auth_recv_cid(enum sctp_cid chunk, const struct sctp_association *asoc); -void sctp_auth_calculate_hmac(const struct sctp_association *asoc, - struct sk_buff *skb, struct sctp_auth_chunk *auth, - struct sctp_shared_key *ep_key, gfp_t gfp); +int sctp_auth_calculate_hmac(const struct sctp_association *asoc, + struct sk_buff *skb, struct sctp_auth_chunk *auth, + struct sctp_shared_key *ep_key, gfp_t gfp); void sctp_auth_shkey_release(struct sctp_shared_key *sh_key); void sctp_auth_shkey_hold(struct sctp_shared_key *sh_key); diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index affee44bd38e..b21f23b736fd 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -312,7 +312,8 @@ struct sctp_cookie { __u8 auth_random[sizeof(struct sctp_paramhdr) + SCTP_AUTH_RANDOM_LENGTH]; - __u8 auth_hmacs[SCTP_AUTH_NUM_HMACS * sizeof(__u16) + 2]; + __u8 auth_hmacs[sizeof(struct sctp_paramhdr) + + SCTP_AUTH_NUM_HMACS * sizeof(__u16)]; __u8 auth_chunks[sizeof(struct sctp_paramhdr) + SCTP_AUTH_MAX_CHUNKS]; /* This is a shim for my peer's INIT packet, followed by @@ -2056,7 +2057,7 @@ struct sctp_association { force_delay:1; __u8 strreset_enable; - __u8 strreset_outstanding; /* request param count on the fly */ + __u8 strreset_outstanding; /* request param bitmask on the fly */ __u32 strreset_outseq; /* Update after receiving response */ __u32 strreset_inseq; /* Update after receiving request */ diff --git a/include/net/tc_act/tc_pedit.h b/include/net/tc_act/tc_pedit.h index cb7b82f2cbc7..97754ea0a827 100644 --- a/include/net/tc_act/tc_pedit.h +++ b/include/net/tc_act/tc_pedit.h @@ -37,17 +37,15 @@ static inline bool is_tcf_pedit(const struct tc_action *a) return false; } -static inline int tcf_pedit_nkeys(const struct tc_action *a) +/* Must be called with act->tcfa_lock held to ensure consistency of parallel + * reads of the same action's pedit keys (e.g. flow_offload count vs fill). + * Note, this is only used for pedit offload. + */ +static inline int tcf_pedit_nkeys_locked(const struct tc_action *a) { - struct tcf_pedit_parms *parms; - int nkeys; - - rcu_read_lock(); - parms = to_pedit_parms(a); - nkeys = parms->tcfp_nkeys; - rcu_read_unlock(); - - return nkeys; + lockdep_assert_held(&a->tcfa_lock); + return rcu_dereference_protected(to_pedit(a)->parms, + lockdep_is_held(&a->tcfa_lock))->tcfp_nkeys; } static inline u32 tcf_pedit_htype(const struct tc_action *a, int index) diff --git a/include/net/tcp.h b/include/net/tcp.h index 6d376ea4d1c0..670c20876f26 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1782,6 +1782,11 @@ static inline int tcp_full_space(const struct sock *sk) return tcp_win_from_space(sk, READ_ONCE(sk->sk_rcvbuf)); } +static inline u32 tcp_dst_advmss(const struct dst_entry *dst) +{ + return max_t(u32, dst_metric_advmss(dst), TCP_MIN_MSS); +} + static inline void __tcp_adjust_rcv_ssthresh(struct sock *sk, u32 new_ssthresh) { int unused_mem = sk_unused_reserved_mem(sk); @@ -1974,6 +1979,8 @@ static inline void tcp_fast_path_check(struct sock *sk) bool tcp_oow_rate_limited(struct net *net, const struct sk_buff *skb, int mib_idx, u32 *last_oow_ack_time); +void tcp_reqsk_send_challenge_ack(struct sock *sk, struct sk_buff *skb, + struct request_sock *req); static inline void tcp_mib_init(struct net *net) { diff --git a/include/net/tcp_ao.h b/include/net/tcp_ao.h index 29fd7b735afa..9a2333e62e99 100644 --- a/include/net/tcp_ao.h +++ b/include/net/tcp_ao.h @@ -145,6 +145,7 @@ struct tcp_ao_info { u32 snd_sne; u32 rcv_sne; refcount_t refcnt; /* Protects twsk destruction */ + struct rcu_head rcu; }; #ifdef CONFIG_TCP_MD5SIG diff --git a/include/net/udp.h b/include/net/udp.h index 8262e2b215b4..1fee17274745 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -430,7 +430,7 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb, netdev_features_t features, bool is_ipv6); int udp_lib_getsockopt(struct sock *sk, int level, int optname, - char __user *optval, int __user *optlen); + sockopt_t *opt); int udp_lib_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval, unsigned int optlen, int (*push_pending_frames)(struct sock *)); diff --git a/include/net/vxlan.h b/include/net/vxlan.h index dfba89695efc..7b8207505523 100644 --- a/include/net/vxlan.h +++ b/include/net/vxlan.h @@ -359,9 +359,6 @@ struct vxlan_dev { VXLAN_F_MC_ROUTE | \ 0) -struct net_device *vxlan_dev_create(struct net *net, const char *name, - u8 name_assign_type, struct vxlan_config *conf); - static inline netdev_features_t vxlan_features_check(struct sk_buff *skb, netdev_features_t features) { @@ -567,8 +564,9 @@ static inline bool vxlan_fdb_nh_path_select(struct nexthop *nh, struct vxlan_rdst *rdst) { struct fib_nh_common *nhc; + __be16 dst_port = 0; - nhc = nexthop_path_fdb_result(nh, hash >> 1); + nhc = nexthop_path_fdb_result(nh, hash >> 1, &dst_port); if (unlikely(!nhc)) return false; @@ -583,6 +581,8 @@ static inline bool vxlan_fdb_nh_path_select(struct nexthop *nh, break; } + rdst->remote_port = dst_port; + return true; } diff --git a/include/net/xdp_sock.h b/include/net/xdp_sock.h index ebac60a3d8a1..6e70b320b399 100644 --- a/include/net/xdp_sock.h +++ b/include/net/xdp_sock.h @@ -80,6 +80,7 @@ struct xdp_sock { * call of __xsk_generic_xmit(). */ struct sk_buff *skb; + bool drain_cont; struct list_head map_list; /* Protects map_list */ @@ -140,45 +141,16 @@ INDIRECT_CALLABLE_DECLARE(void xsk_destruct_skb(struct sk_buff *)); static inline void xsk_tx_metadata_to_compl(struct xsk_tx_metadata *meta, struct xsk_tx_metadata_compl *compl) { - if (!meta) - return; + compl->tx_timestamp = NULL; - if (meta->flags & XDP_TXMD_FLAGS_TIMESTAMP) - compl->tx_timestamp = &meta->completion.tx_timestamp; - else - compl->tx_timestamp = NULL; -} - -/** - * xsk_tx_metadata_request - Evaluate AF_XDP TX metadata at submission - * and call appropriate xsk_tx_metadata_ops operation. - * @meta: pointer to AF_XDP metadata area - * @ops: pointer to struct xsk_tx_metadata_ops - * @priv: pointer to driver-private aread - * - * This function should be called by the networking device when - * it prepares AF_XDP egress packet. - */ -static inline void xsk_tx_metadata_request(const struct xsk_tx_metadata *meta, - const struct xsk_tx_metadata_ops *ops, - void *priv) -{ if (!meta) return; - if (ops->tmo_request_launch_time) - if (meta->flags & XDP_TXMD_FLAGS_LAUNCH_TIME) - ops->tmo_request_launch_time(meta->request.launch_time, - priv); - - if (ops->tmo_request_timestamp) - if (meta->flags & XDP_TXMD_FLAGS_TIMESTAMP) - ops->tmo_request_timestamp(priv); + /* we can only arrive here if the completion timestamp has been + * requested via XDP_TXMD_FLAGS_TIMESTAMP, see xsk_tx_metadata_request + */ - if (ops->tmo_request_checksum) - if (meta->flags & XDP_TXMD_FLAGS_CHECKSUM) - ops->tmo_request_checksum(meta->request.csum_start, - meta->request.csum_offset, priv); + compl->tx_timestamp = &meta->completion.tx_timestamp; } /** @@ -230,12 +202,6 @@ static inline void xsk_tx_metadata_to_compl(struct xsk_tx_metadata *meta, { } -static inline void xsk_tx_metadata_request(struct xsk_tx_metadata *meta, - const struct xsk_tx_metadata_ops *ops, - void *priv) -{ -} - static inline void xsk_tx_metadata_complete(struct xsk_tx_metadata_compl *compl, const struct xsk_tx_metadata_ops *ops, void *priv) diff --git a/include/net/xdp_sock_drv.h b/include/net/xdp_sock_drv.h index 46797645a0c2..d94aeb506379 100644 --- a/include/net/xdp_sock_drv.h +++ b/include/net/xdp_sock_drv.h @@ -240,17 +240,18 @@ static inline void *xsk_buff_raw_get_data(struct xsk_buff_pool *pool, u64 addr) * xsk_buff_raw_get_ctx - get &xdp_desc context * @pool: XSk buff pool desc address belongs to * @addr: desc address (from userspace) + * @options: desc options (from userspace) * * Wrapper for xp_raw_get_ctx() to be used in drivers, see its kdoc for * details. * * Return: new &xdp_desc_ctx struct containing desc's DMA address and metadata - * pointer, if it is present and valid (initialized to %NULL otherwise). + * pointer, if it is present (initialized to %NULL otherwise). */ static inline struct xdp_desc_ctx -xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr) +xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr, u32 options) { - return xp_raw_get_ctx(pool, addr); + return xp_raw_get_ctx(pool, addr, options); } #define XDP_TXMD_FLAGS_VALID ( \ @@ -260,30 +261,78 @@ xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr) 0) static inline bool -xsk_buff_valid_tx_metadata(const struct xsk_tx_metadata *meta) +xsk_buff_valid_tx_metadata(const struct xsk_buff_pool *pool, + const struct xsk_tx_metadata *meta, u64 *flags) { - return !(meta->flags & ~XDP_TXMD_FLAGS_VALID); + *flags = READ_ONCE(meta->flags); + if (*flags & XDP_TXMD_FLAGS_LAUNCH_TIME) + if (pool->tx_metadata_len < + offsetofend(struct xsk_tx_metadata, request.launch_time)) + return false; + return !(*flags & ~XDP_TXMD_FLAGS_VALID); } -static inline struct xsk_tx_metadata * -__xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data) +/** + * xsk_tx_metadata_request - Evaluate AF_XDP TX metadata at submission + * and call appropriate xsk_tx_metadata_ops operation. + * @pool: pointer to AF_XDP buffer pool, used to validate the metadata + * @pmeta: pointer to pointer to AF_XDP metadata area + * @ops: pointer to struct xsk_tx_metadata_ops + * @priv: pointer to driver-private area + * + * This function should be called by the networking device when + * it prepares AF_XDP egress packet. + */ +static inline void +xsk_tx_metadata_request(const struct xsk_buff_pool *pool, + struct xsk_tx_metadata **pmeta, + const struct xsk_tx_metadata_ops *ops, void *priv) { - struct xsk_tx_metadata *meta; + const struct xsk_tx_metadata *meta = *pmeta; + u64 flags; - if (!pool->tx_metadata_len) - return NULL; + if (!meta) + return; - meta = data - pool->tx_metadata_len; - if (unlikely(!xsk_buff_valid_tx_metadata(meta))) - return NULL; /* no way to signal the error to the user */ + if (unlikely(!xsk_buff_valid_tx_metadata(pool, meta, &flags))) { + *pmeta = NULL; + return; /* no way to signal the error to the user */ + } + + if (ops->tmo_request_launch_time) + if (flags & XDP_TXMD_FLAGS_LAUNCH_TIME) + ops->tmo_request_launch_time( + READ_ONCE(meta->request.launch_time), priv); + + if (ops->tmo_request_timestamp) + if (flags & XDP_TXMD_FLAGS_TIMESTAMP) + ops->tmo_request_timestamp(priv); - return meta; + if (ops->tmo_request_checksum) + if (flags & XDP_TXMD_FLAGS_CHECKSUM) + ops->tmo_request_checksum( + READ_ONCE(meta->request.csum_start), + READ_ONCE(meta->request.csum_offset), priv); + + if (!(flags & XDP_TXMD_FLAGS_TIMESTAMP)) + *pmeta = NULL; } static inline struct xsk_tx_metadata * -xsk_buff_get_metadata(struct xsk_buff_pool *pool, u64 addr) +__xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data, + unsigned int options) { - return __xsk_buff_get_metadata(pool, xp_raw_get_data(pool, addr)); + if (!pool->tx_metadata_len || !(options & XDP_TX_METADATA)) + return NULL; + + return data - pool->tx_metadata_len; +} + +static inline struct xsk_tx_metadata * +xsk_buff_get_metadata(struct xsk_buff_pool *pool, u64 addr, u32 options) +{ + return __xsk_buff_get_metadata(pool, xp_raw_get_data(pool, addr), + options); } static inline void xsk_buff_dma_sync_for_cpu(struct xdp_buff *xdp) @@ -464,24 +513,34 @@ static inline void *xsk_buff_raw_get_data(struct xsk_buff_pool *pool, u64 addr) } static inline struct xdp_desc_ctx -xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr) +xsk_buff_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr, u32 options) { return (struct xdp_desc_ctx){ }; } -static inline bool xsk_buff_valid_tx_metadata(struct xsk_tx_metadata *meta) +static inline bool +xsk_buff_valid_tx_metadata(const struct xsk_buff_pool *pool, + const struct xsk_tx_metadata *meta, u64 *flags) { return false; } +static inline void +xsk_tx_metadata_request(const struct xsk_buff_pool *pool, + struct xsk_tx_metadata **pmeta, + const struct xsk_tx_metadata_ops *ops, void *priv) +{ +} + static inline struct xsk_tx_metadata * -__xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data) +__xsk_buff_get_metadata(const struct xsk_buff_pool *pool, void *data, + unsigned int options) { return NULL; } static inline struct xsk_tx_metadata * -xsk_buff_get_metadata(struct xsk_buff_pool *pool, u64 addr) +xsk_buff_get_metadata(struct xsk_buff_pool *pool, u64 addr, u32 options) { return NULL; } diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 519a0156a05c..a6d69aaa6cd2 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -162,6 +162,8 @@ struct xfrm_dev_offload { */ struct net_device *real_dev; unsigned long offload_handle; + /* Snapshot the attached device index for dump paths. */ + int ifindex; u8 dir : 2; u8 type : 2; u8 flags : 2; diff --git a/include/net/xsk_buff_pool.h b/include/net/xsk_buff_pool.h index ccb3b350001f..a7df573784fd 100644 --- a/include/net/xsk_buff_pool.h +++ b/include/net/xsk_buff_pool.h @@ -78,6 +78,9 @@ struct xsk_buff_pool { u32 chunk_size; u32 chunk_shift; u32 frame_len; + u32 tx_descs_nentries; + u32 reclaim_descs; + u32 tx_zc_pending_descs; u32 xdp_zc_max_segs; u8 tx_metadata_len; /* inherited from umem */ u8 cached_need_wakeup; @@ -102,12 +105,14 @@ struct xsk_buff_pool { /* AF_XDP core. */ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs, - struct xdp_umem *umem); + struct xdp_umem *umem, + u32 max_segs); int xp_assign_dev(struct xsk_buff_pool *pool, struct net_device *dev, u16 queue_id, u16 flags); int xp_assign_dev_shared(struct xsk_buff_pool *pool, struct xdp_sock *umem_xs, struct net_device *dev, u16 queue_id); -int xp_alloc_tx_descs(struct xsk_buff_pool *pool, struct xdp_sock *xs); +int xp_alloc_tx_descs(struct xsk_buff_pool *pool, struct xdp_sock *xs, + u32 max_segs); void xp_destroy(struct xsk_buff_pool *pool); void xp_get_pool(struct xsk_buff_pool *pool); bool xp_put_pool(struct xsk_buff_pool *pool); @@ -149,7 +154,8 @@ struct xdp_desc_ctx { struct xsk_tx_metadata *meta; }; -struct xdp_desc_ctx xp_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr); +struct xdp_desc_ctx xp_raw_get_ctx(const struct xsk_buff_pool *pool, u64 addr, + u32 options); static inline dma_addr_t xp_get_dma(struct xdp_buff_xsk *xskb) { |
