summaryrefslogtreecommitdiffstats
path: root/include/net
diff options
context:
space:
mode:
Diffstat (limited to 'include/net')
-rw-r--r--include/net/bluetooth/bluetooth.h18
-rw-r--r--include/net/bluetooth/hci.h135
-rw-r--r--include/net/bluetooth/hci_core.h134
-rw-r--r--include/net/bluetooth/l2cap.h36
-rw-r--r--include/net/bluetooth/mgmt.h99
-rw-r--r--include/net/cfg80211.h38
-rw-r--r--include/net/flow_keys.h15
-rw-r--r--include/net/if_inet6.h1
-rw-r--r--include/net/inet_sock.h6
-rw-r--r--include/net/inet_timewait_sock.h3
-rw-r--r--include/net/ip.h14
-rw-r--r--include/net/ipv6.h45
-rw-r--r--include/net/mac80211.h71
-rw-r--r--include/net/mac802154.h19
-rw-r--r--include/net/netns/ipv6.h1
-rw-r--r--include/net/rtnetlink.h1
-rw-r--r--include/net/sch_generic.h2
-rw-r--r--include/net/sctp/command.h39
-rw-r--r--include/net/sctp/sctp.h21
-rw-r--r--include/net/sock.h15
-rw-r--r--include/net/tcp.h61
-rw-r--r--include/net/udp.h29
-rw-r--r--include/net/udp_tunnel.h32
-rw-r--r--include/net/vxlan.h2
24 files changed, 672 insertions, 165 deletions
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 904777c1cd2..373000de610 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -260,15 +260,15 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock);
/* Skb helpers */
struct l2cap_ctrl {
- unsigned int sframe:1,
- poll:1,
- final:1,
- fcs:1,
- sar:2,
- super:2;
- __u16 reqseq;
- __u16 txseq;
- __u8 retries;
+ __u8 sframe:1,
+ poll:1,
+ final:1,
+ fcs:1,
+ sar:2,
+ super:2;
+ __u16 reqseq;
+ __u16 txseq;
+ __u8 retries;
};
struct hci_dev;
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 16587dcd6a9..a01236e2df1 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -81,10 +81,54 @@
/* HCI device quirks */
enum {
+ /* When this quirk is set, the HCI Reset command is send when
+ * closing the transport instead of when opening it.
+ *
+ * This quirk must be set before hci_register_dev is called.
+ */
HCI_QUIRK_RESET_ON_CLOSE,
+
+ /* When this quirk is set, the device is turned into a raw-only
+ * device and it will stay in unconfigured state.
+ *
+ * This quirk must be set before hci_register_dev is called.
+ */
HCI_QUIRK_RAW_DEVICE,
+
+ /* When this quirk is set, the buffer sizes reported by
+ * HCI Read Buffer Size command are corrected if invalid.
+ *
+ * This quirk must be set before hci_register_dev is called.
+ */
HCI_QUIRK_FIXUP_BUFFER_SIZE,
+
+ /* When this quirk is set, then no stored link key handling
+ * is performed. This is mainly due to the fact that the
+ * HCI Delete Stored Link Key command is advertised, but
+ * not supported.
+ *
+ * This quirk must be set before hci_register_dev is called.
+ */
HCI_QUIRK_BROKEN_STORED_LINK_KEY,
+
+ /* When this quirk is set, an external configuration step
+ * is required and will be indicated with the controller
+ * configuation.
+ *
+ * This quirk can be set before hci_register_dev is called or
+ * during the hdev->setup vendor callback.
+ */
+ HCI_QUIRK_EXTERNAL_CONFIG,
+
+ /* When this quirk is set, the public Bluetooth address
+ * initially reported by HCI Read BD Address command
+ * is considered invalid. Controller configuration is
+ * required before this device can be used.
+ *
+ * This quirk can be set before hci_register_dev is called or
+ * during the hdev->setup vendor callback.
+ */
+ HCI_QUIRK_INVALID_BDADDR,
};
/* HCI device flags */
@@ -104,24 +148,34 @@ enum {
HCI_RESET,
};
+/* BR/EDR and/or LE controller flags: the flags defined here should represent
+ * states configured via debugfs for debugging and testing purposes only.
+ */
+enum {
+ HCI_DUT_MODE,
+ HCI_FORCE_SC,
+ HCI_FORCE_STATIC_ADDR,
+};
+
/*
* BR/EDR and/or LE controller flags: the flags defined here should represent
* states from the controller.
*/
enum {
HCI_SETUP,
+ HCI_CONFIG,
HCI_AUTO_OFF,
HCI_RFKILLED,
HCI_MGMT,
HCI_PAIRABLE,
HCI_SERVICE_CACHE,
- HCI_DEBUG_KEYS,
- HCI_DUT_MODE,
- HCI_FORCE_SC,
- HCI_FORCE_STATIC_ADDR,
+ HCI_KEEP_DEBUG_KEYS,
+ HCI_USE_DEBUG_KEYS,
HCI_UNREGISTER,
+ HCI_UNCONFIGURED,
HCI_USER_CHANNEL,
-
+ HCI_EXT_CONFIGURED,
+ HCI_LE_ADV,
HCI_LE_SCAN,
HCI_SSP_ENABLED,
HCI_SC_ENABLED,
@@ -139,7 +193,6 @@ enum {
HCI_PERIODIC_INQ,
HCI_FAST_CONNECTABLE,
HCI_BREDR_ENABLED,
- HCI_6LOWPAN_ENABLED,
HCI_LE_SCAN_INTERRUPTED,
};
@@ -147,7 +200,7 @@ enum {
* or the HCI device is closed.
*/
#define HCI_PERSISTENT_MASK (BIT(HCI_LE_SCAN) | BIT(HCI_PERIODIC_INQ) | \
- BIT(HCI_FAST_CONNECTABLE))
+ BIT(HCI_FAST_CONNECTABLE) | BIT(HCI_LE_ADV))
/* HCI ioctl defines */
#define HCIDEVUP _IOW('H', 201, int)
@@ -185,6 +238,7 @@ enum {
#define HCI_AUTO_OFF_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
#define HCI_POWER_OFF_TIMEOUT msecs_to_jiffies(5000) /* 5 seconds */
#define HCI_LE_CONN_TIMEOUT msecs_to_jiffies(20000) /* 20 seconds */
+#define HCI_LE_AUTOCONN_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
/* HCI data types */
#define HCI_COMMAND_PKT 0x01
@@ -301,6 +355,10 @@ enum {
#define LMP_HOST_LE_BREDR 0x04
#define LMP_HOST_SC 0x08
+/* LE features */
+#define HCI_LE_CONN_PARAM_REQ_PROC 0x02
+#define HCI_LE_PING 0x10
+
/* Connection modes */
#define HCI_CM_ACTIVE 0x0000
#define HCI_CM_HOLD 0x0001
@@ -347,17 +405,9 @@ enum {
#define HCI_LK_CHANGED_COMBINATION 0x06
#define HCI_LK_UNAUTH_COMBINATION_P256 0x07
#define HCI_LK_AUTH_COMBINATION_P256 0x08
-/* The spec doesn't define types for SMP keys, the _MASTER suffix is implied */
-#define HCI_SMP_STK 0x80
-#define HCI_SMP_STK_SLAVE 0x81
-#define HCI_SMP_LTK 0x82
-#define HCI_SMP_LTK_SLAVE 0x83
-
-/* Long Term Key types */
-#define HCI_LTK_UNAUTH 0x00
-#define HCI_LTK_AUTH 0x01
/* ---- HCI Error Codes ---- */
+#define HCI_ERROR_UNKNOWN_CONN_ID 0x02
#define HCI_ERROR_AUTH_FAILURE 0x05
#define HCI_ERROR_MEMORY_EXCEEDED 0x07
#define HCI_ERROR_CONNECTION_TIMEOUT 0x08
@@ -367,6 +417,7 @@ enum {
#define HCI_ERROR_REMOTE_POWER_OFF 0x15
#define HCI_ERROR_LOCAL_HOST_TERM 0x16
#define HCI_ERROR_PAIRING_NOT_ALLOWED 0x18
+#define HCI_ERROR_INVALID_LL_PARAMS 0x1E
#define HCI_ERROR_ADVERTISING_TIMEOUT 0x3c
/* Flow control modes */
@@ -536,6 +587,11 @@ struct hci_cp_read_remote_version {
__le16 handle;
} __packed;
+#define HCI_OP_READ_CLOCK_OFFSET 0x041f
+struct hci_cp_read_clock_offset {
+ __le16 handle;
+} __packed;
+
#define HCI_OP_SETUP_SYNC_CONN 0x0428
struct hci_cp_setup_sync_conn {
__le16 handle;
@@ -1085,6 +1141,18 @@ struct hci_rp_read_rssi {
__s8 rssi;
} __packed;
+#define HCI_OP_READ_CLOCK 0x1407
+struct hci_cp_read_clock {
+ __le16 handle;
+ __u8 which;
+} __packed;
+struct hci_rp_read_clock {
+ __u8 status;
+ __le16 handle;
+ __le32 clock;
+ __le16 accuracy;
+} __packed;
+
#define HCI_OP_READ_LOCAL_AMP_INFO 0x1409
struct hci_rp_read_local_amp_info {
__u8 status;
@@ -1291,6 +1359,23 @@ struct hci_rp_le_read_supported_states {
__u8 le_states[8];
} __packed;
+#define HCI_OP_LE_CONN_PARAM_REQ_REPLY 0x2020
+struct hci_cp_le_conn_param_req_reply {
+ __le16 handle;
+ __le16 interval_min;
+ __le16 interval_max;
+ __le16 latency;
+ __le16 timeout;
+ __le16 min_ce_len;
+ __le16 max_ce_len;
+} __packed;
+
+#define HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY 0x2021
+struct hci_cp_le_conn_param_req_neg_reply {
+ __le16 handle;
+ __u8 reason;
+} __packed;
+
/* ---- HCI Events ---- */
#define HCI_EV_INQUIRY_COMPLETE 0x01
@@ -1670,6 +1755,15 @@ struct hci_ev_le_conn_complete {
__u8 clk_accurancy;
} __packed;
+#define HCI_EV_LE_CONN_UPDATE_COMPLETE 0x03
+struct hci_ev_le_conn_update_complete {
+ __u8 status;
+ __le16 handle;
+ __le16 interval;
+ __le16 latency;
+ __le16 supervision_timeout;
+} __packed;
+
#define HCI_EV_LE_LTK_REQ 0x05
struct hci_ev_le_ltk_req {
__le16 handle;
@@ -1677,6 +1771,15 @@ struct hci_ev_le_ltk_req {
__le16 ediv;
} __packed;
+#define HCI_EV_LE_REMOTE_CONN_PARAM_REQ 0x06
+struct hci_ev_le_remote_conn_param_req {
+ __le16 handle;
+ __le16 interval_min;
+ __le16 interval_max;
+ __le16 latency;
+ __le16 timeout;
+} __packed;
+
/* Advertising report event types */
#define LE_ADV_IND 0x00
#define LE_ADV_DIRECT_IND 0x01
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index b386bf17e6c..e69c2b08c0c 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -71,6 +71,7 @@ struct discovery_state {
bdaddr_t last_adv_addr;
u8 last_adv_addr_type;
s8 last_adv_rssi;
+ u32 last_adv_flags;
u8 last_adv_data[HCI_MAX_AD_LENGTH];
u8 last_adv_data_len;
};
@@ -170,6 +171,8 @@ struct hci_dev {
__u8 bus;
__u8 dev_type;
bdaddr_t bdaddr;
+ bdaddr_t setup_addr;
+ bdaddr_t public_addr;
bdaddr_t random_addr;
bdaddr_t static_addr;
__u8 adv_addr_type;
@@ -203,10 +206,13 @@ struct hci_dev {
__u16 le_scan_window;
__u16 le_conn_min_interval;
__u16 le_conn_max_interval;
+ __u16 le_conn_latency;
+ __u16 le_supv_timeout;
__u16 discov_interleaved_timeout;
__u16 conn_info_min_age;
__u16 conn_info_max_age;
__u8 ssp_debug_mode;
+ __u32 clock;
__u16 devid_source;
__u16 devid_vendor;
@@ -273,7 +279,7 @@ struct hci_dev {
struct delayed_work service_cache;
- struct timer_list cmd_timer;
+ struct delayed_work cmd_timer;
struct work_struct rx_work;
struct work_struct cmd_work;
@@ -299,6 +305,7 @@ struct hci_dev {
struct list_head mgmt_pending;
struct list_head blacklist;
+ struct list_head whitelist;
struct list_head uuids;
struct list_head link_keys;
struct list_head long_term_keys;
@@ -307,6 +314,7 @@ struct hci_dev {
struct list_head le_white_list;
struct list_head le_conn_params;
struct list_head pend_le_conns;
+ struct list_head pend_le_reports;
struct hci_dev_stats stat;
@@ -318,6 +326,7 @@ struct hci_dev {
struct rfkill *rfkill;
+ unsigned long dbg_flags;
unsigned long dev_flags;
struct delayed_work le_scan_disable;
@@ -339,6 +348,7 @@ struct hci_dev {
int (*setup)(struct hci_dev *hdev);
int (*send)(struct hci_dev *hdev, struct sk_buff *skb);
void (*notify)(struct hci_dev *hdev, unsigned int evt);
+ int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr);
};
#define HCI_PHY_HANDLE(handle) (handle & 0xff)
@@ -366,7 +376,6 @@ struct hci_conn {
__u8 features[HCI_MAX_PAGES][8];
__u16 pkt_type;
__u16 link_policy;
- __u32 link_mode;
__u8 key_type;
__u8 auth_type;
__u8 sec_level;
@@ -377,20 +386,26 @@ struct hci_conn {
__u32 passkey_notify;
__u8 passkey_entered;
__u16 disc_timeout;
+ __u16 conn_timeout;
__u16 setting;
__u16 le_conn_min_interval;
__u16 le_conn_max_interval;
+ __u16 le_conn_interval;
+ __u16 le_conn_latency;
+ __u16 le_supv_timeout;
__s8 rssi;
__s8 tx_power;
__s8 max_tx_power;
unsigned long flags;
+ __u32 clock;
+ __u16 clock_accuracy;
+
unsigned long conn_info_timestamp;
__u8 remote_cap;
__u8 remote_auth;
__u8 remote_id;
- bool flush_key;
unsigned int sent;
@@ -407,7 +422,6 @@ struct hci_conn {
struct hci_dev *hdev;
void *l2cap_data;
void *sco_data;
- void *smp_conn;
struct amp_mgr *amp_mgr;
struct hci_conn *link;
@@ -428,15 +442,19 @@ struct hci_chan {
struct hci_conn_params {
struct list_head list;
+ struct list_head action;
bdaddr_t addr;
u8 addr_type;
u16 conn_min_interval;
u16 conn_max_interval;
+ u16 conn_latency;
+ u16 supervision_timeout;
enum {
HCI_AUTO_CONN_DISABLED,
+ HCI_AUTO_CONN_REPORT,
HCI_AUTO_CONN_ALWAYS,
HCI_AUTO_CONN_LINK_LOSS,
} auto_connect;
@@ -501,8 +519,8 @@ struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
int state);
void hci_inquiry_cache_update_resolve(struct hci_dev *hdev,
struct inquiry_entry *ie);
-bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
- bool name_known, bool *ssp);
+u32 hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
+ bool name_known);
void hci_inquiry_cache_flush(struct hci_dev *hdev);
/* ----- HCI Connections ----- */
@@ -520,7 +538,13 @@ enum {
HCI_CONN_AES_CCM,
HCI_CONN_POWER_SAVE,
HCI_CONN_REMOTE_OOB,
- HCI_CONN_6LOWPAN,
+ HCI_CONN_FLUSH_KEY,
+ HCI_CONN_MASTER,
+ HCI_CONN_ENCRYPT,
+ HCI_CONN_AUTH,
+ HCI_CONN_SECURE,
+ HCI_CONN_FIPS,
+ HCI_CONN_STK_ENCRYPT,
};
static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)
@@ -681,7 +705,8 @@ void hci_chan_list_flush(struct hci_conn *conn);
struct hci_chan *hci_chan_lookup_handle(struct hci_dev *hdev, __u16 handle);
struct hci_conn *hci_connect_le(struct hci_dev *hdev, bdaddr_t *dst,
- u8 dst_type, u8 sec_level, u8 auth_type);
+ u8 dst_type, u8 sec_level, u16 conn_timeout,
+ bool master);
struct hci_conn *hci_connect_acl(struct hci_dev *hdev, bdaddr_t *dst,
u8 sec_level, u8 auth_type);
struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type, bdaddr_t *dst,
@@ -825,30 +850,25 @@ int hci_get_conn_info(struct hci_dev *hdev, void __user *arg);
int hci_get_auth_info(struct hci_dev *hdev, void __user *arg);
int hci_inquiry(void __user *arg);
-struct bdaddr_list *hci_blacklist_lookup(struct hci_dev *hdev,
- bdaddr_t *bdaddr, u8 type);
-int hci_blacklist_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
-int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
-
-struct bdaddr_list *hci_white_list_lookup(struct hci_dev *hdev,
- bdaddr_t *bdaddr, u8 type);
-void hci_white_list_clear(struct hci_dev *hdev);
-int hci_white_list_add(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
-int hci_white_list_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
+struct bdaddr_list *hci_bdaddr_list_lookup(struct list_head *list,
+ bdaddr_t *bdaddr, u8 type);
+int hci_bdaddr_list_add(struct list_head *list, bdaddr_t *bdaddr, u8 type);
+int hci_bdaddr_list_del(struct list_head *list, bdaddr_t *bdaddr, u8 type);
+void hci_bdaddr_list_clear(struct list_head *list);
struct hci_conn_params *hci_conn_params_lookup(struct hci_dev *hdev,
bdaddr_t *addr, u8 addr_type);
-int hci_conn_params_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
- u8 auto_connect, u16 conn_min_interval,
- u16 conn_max_interval);
+struct hci_conn_params *hci_conn_params_add(struct hci_dev *hdev,
+ bdaddr_t *addr, u8 addr_type);
+int hci_conn_params_set(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type,
+ u8 auto_connect);
void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
-void hci_conn_params_clear(struct hci_dev *hdev);
+void hci_conn_params_clear_all(struct hci_dev *hdev);
+void hci_conn_params_clear_disabled(struct hci_dev *hdev);
-struct bdaddr_list *hci_pend_le_conn_lookup(struct hci_dev *hdev,
- bdaddr_t *addr, u8 addr_type);
-void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
-void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
-void hci_pend_le_conns_clear(struct hci_dev *hdev);
+struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list,
+ bdaddr_t *addr,
+ u8 addr_type);
void hci_update_background_scan(struct hci_dev *hdev);
@@ -856,8 +876,9 @@ void hci_uuids_clear(struct hci_dev *hdev);
void hci_link_keys_clear(struct hci_dev *hdev);
struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
-int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
- bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
+struct link_key *hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn,
+ bdaddr_t *bdaddr, u8 *val, u8 type,
+ u8 pin_len, bool *persistent);
struct smp_ltk *hci_find_ltk(struct hci_dev *hdev, __le16 ediv, __le64 rand,
bool master);
struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr,
@@ -1021,7 +1042,7 @@ static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status)
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
return;
- encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
+ encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00;
l2cap_security_cfm(conn, status, encrypt);
if (conn->security_cfm_cb)
@@ -1062,7 +1083,7 @@ static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status)
if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags))
return;
- encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00;
+ encrypt = test_bit(HCI_CONN_ENCRYPT, &conn->flags) ? 0x01 : 0x00;
read_lock(&hci_cb_list_lock);
list_for_each_entry(cb, &hci_cb_list, list) {
@@ -1147,7 +1168,7 @@ static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type)
static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type)
{
- if (addr_type != 0x01)
+ if (addr_type != ADDR_LE_DEV_RANDOM)
return false;
if ((bdaddr->b[5] & 0xc0) == 0x40)
@@ -1156,6 +1177,18 @@ static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type)
return false;
}
+static inline bool hci_is_identity_address(bdaddr_t *addr, u8 addr_type)
+{
+ if (addr_type == ADDR_LE_DEV_PUBLIC)
+ return true;
+
+ /* Check for Random Static address type */
+ if ((addr->b[5] & 0xc0) == 0xc0)
+ return true;
+
+ return false;
+}
+
static inline struct smp_irk *hci_get_irk(struct hci_dev *hdev,
bdaddr_t *bdaddr, u8 addr_type)
{
@@ -1165,6 +1198,27 @@ static inline struct smp_irk *hci_get_irk(struct hci_dev *hdev,
return hci_find_irk_by_rpa(hdev, bdaddr);
}
+static inline int hci_check_conn_params(u16 min, u16 max, u16 latency,
+ u16 to_multiplier)
+{
+ u16 max_latency;
+
+ if (min > max || min < 6 || max > 3200)
+ return -EINVAL;
+
+ if (to_multiplier < 10 || to_multiplier > 3200)
+ return -EINVAL;
+
+ if (max >= to_multiplier * 8)
+ return -EINVAL;
+
+ max_latency = (to_multiplier * 8 / max) - 1;
+ if (latency > 499 || latency > max_latency)
+ return -EINVAL;
+
+ return 0;
+}
+
int hci_register_cb(struct hci_cb *hcb);
int hci_unregister_cb(struct hci_cb *hcb);
@@ -1227,6 +1281,7 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event);
#define DISCOV_BREDR_INQUIRY_LEN 0x08
int mgmt_control(struct sock *sk, struct msghdr *msg, size_t len);
+int mgmt_new_settings(struct hci_dev *hdev);
void mgmt_index_added(struct hci_dev *hdev);
void mgmt_index_removed(struct hci_dev *hdev);
void mgmt_set_powered_failed(struct hci_dev *hdev, int err);
@@ -1234,7 +1289,6 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered);
void mgmt_discoverable_timeout(struct hci_dev *hdev);
void mgmt_discoverable(struct hci_dev *hdev, u8 discoverable);
void mgmt_connectable(struct hci_dev *hdev, u8 connectable);
-void mgmt_advertising(struct hci_dev *hdev, u8 advertising);
void mgmt_write_scan_failed(struct hci_dev *hdev, u8 scan, u8 status);
void mgmt_new_link_key(struct hci_dev *hdev, struct link_key *key,
bool persistent);
@@ -1281,18 +1335,18 @@ void mgmt_read_local_oob_data_complete(struct hci_dev *hdev, u8 *hash192,
u8 *randomizer192, u8 *hash256,
u8 *randomizer256, u8 status);
void mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
- u8 addr_type, u8 *dev_class, s8 rssi, u8 cfm_name,
- u8 ssp, u8 *eir, u16 eir_len, u8 *scan_rsp,
- u8 scan_rsp_len);
+ u8 addr_type, u8 *dev_class, s8 rssi, u32 flags,
+ u8 *eir, u16 eir_len, u8 *scan_rsp, u8 scan_rsp_len);
void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
u8 addr_type, s8 rssi, u8 *name, u8 name_len);
void mgmt_discovering(struct hci_dev *hdev, u8 discovering);
-int mgmt_device_blocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
-int mgmt_device_unblocked(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type);
void mgmt_new_ltk(struct hci_dev *hdev, struct smp_ltk *key, bool persistent);
void mgmt_new_irk(struct hci_dev *hdev, struct smp_irk *irk);
void mgmt_new_csrk(struct hci_dev *hdev, struct smp_csrk *csrk,
bool persistent);
+void mgmt_new_conn_param(struct hci_dev *hdev, bdaddr_t *bdaddr,
+ u8 bdaddr_type, u8 store_hint, u16 min_interval,
+ u16 max_interval, u16 latency, u16 timeout);
void mgmt_reenable_advertising(struct hci_dev *hdev);
void mgmt_smp_complete(struct hci_conn *conn, bool complete);
@@ -1324,8 +1378,8 @@ struct hci_sec_filter {
#define hci_req_lock(d) mutex_lock(&d->req_lock)
#define hci_req_unlock(d) mutex_unlock(&d->req_lock)
-void hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max,
- u16 latency, u16 to_multiplier);
+u8 hci_le_conn_update(struct hci_conn *conn, u16 min, u16 max, u16 latency,
+ u16 to_multiplier);
void hci_le_start_enc(struct hci_conn *conn, __le16 ediv, __le64 rand,
__u8 ltk[16]);
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 4abdcb220e3..e0c6a9abdb6 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -137,7 +137,6 @@ struct l2cap_conninfo {
#define L2CAP_FC_L2CAP 0x02
#define L2CAP_FC_CONNLESS 0x04
#define L2CAP_FC_A2MP 0x08
-#define L2CAP_FC_6LOWPAN 0x3e /* reserved and temporary value */
/* L2CAP Control Field bit masks */
#define L2CAP_CTRL_SAR 0xC000
@@ -579,7 +578,7 @@ struct l2cap_chan {
struct list_head global_l;
void *data;
- struct l2cap_ops *ops;
+ const struct l2cap_ops *ops;
struct mutex lock;
};
@@ -600,7 +599,12 @@ struct l2cap_ops {
void (*set_shutdown) (struct l2cap_chan *chan);
long (*get_sndtimeo) (struct l2cap_chan *chan);
struct sk_buff *(*alloc_skb) (struct l2cap_chan *chan,
+ unsigned long hdr_len,
unsigned long len, int nb);
+ int (*memcpy_fromiovec) (struct l2cap_chan *chan,
+ unsigned char *kdata,
+ struct iovec *iov,
+ int len);
};
struct l2cap_conn {
@@ -856,6 +860,31 @@ static inline long l2cap_chan_no_get_sndtimeo(struct l2cap_chan *chan)
return 0;
}
+static inline int l2cap_chan_no_memcpy_fromiovec(struct l2cap_chan *chan,
+ unsigned char *kdata,
+ struct iovec *iov,
+ int len)
+{
+ /* Following is safe since for compiler definitions of kvec and
+ * iovec are identical, yielding the same in-core layout and alignment
+ */
+ struct kvec *vec = (struct kvec *)iov;
+
+ while (len > 0) {
+ if (vec->iov_len) {
+ int copy = min_t(unsigned int, len, vec->iov_len);
+ memcpy(kdata, vec->iov_base, copy);
+ len -= copy;
+ kdata += copy;
+ vec->iov_base += copy;
+ vec->iov_len -= copy;
+ }
+ vec++;
+ }
+
+ return 0;
+}
+
extern bool disable_ertm;
int l2cap_init_sockets(void);
@@ -872,8 +901,7 @@ struct l2cap_chan *l2cap_chan_create(void);
void l2cap_chan_close(struct l2cap_chan *chan, int reason);
int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
bdaddr_t *dst, u8 dst_type);
-int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
- u32 priority);
+int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len);
void l2cap_chan_busy(struct l2cap_chan *chan, int busy);
int l2cap_chan_check_security(struct l2cap_chan *chan);
void l2cap_chan_set_defaults(struct l2cap_chan *chan);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index bcffc9ae0c8..623d5203c59 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -97,6 +97,7 @@ struct mgmt_rp_read_index_list {
#define MGMT_SETTING_SECURE_CONN 0x00000800
#define MGMT_SETTING_DEBUG_KEYS 0x00001000
#define MGMT_SETTING_PRIVACY 0x00002000
+#define MGMT_SETTING_CONFIGURATION 0x00004000
#define MGMT_OP_READ_INFO 0x0004
#define MGMT_READ_INFO_SIZE 0
@@ -424,6 +425,76 @@ struct mgmt_rp_get_conn_info {
__s8 max_tx_power;
} __packed;
+#define MGMT_OP_GET_CLOCK_INFO 0x0032
+struct mgmt_cp_get_clock_info {
+ struct mgmt_addr_info addr;
+} __packed;
+#define MGMT_GET_CLOCK_INFO_SIZE MGMT_ADDR_INFO_SIZE
+struct mgmt_rp_get_clock_info {
+ struct mgmt_addr_info addr;
+ __le32 local_clock;
+ __le32 piconet_clock;
+ __le16 accuracy;
+} __packed;
+
+#define MGMT_OP_ADD_DEVICE 0x0033
+struct mgmt_cp_add_device {
+ struct mgmt_addr_info addr;
+ __u8 action;
+} __packed;
+#define MGMT_ADD_DEVICE_SIZE (MGMT_ADDR_INFO_SIZE + 1)
+
+#define MGMT_OP_REMOVE_DEVICE 0x0034
+struct mgmt_cp_remove_device {
+ struct mgmt_addr_info addr;
+} __packed;
+#define MGMT_REMOVE_DEVICE_SIZE MGMT_ADDR_INFO_SIZE
+
+struct mgmt_conn_param {
+ struct mgmt_addr_info addr;
+ __le16 min_interval;
+ __le16 max_interval;
+ __le16 latency;
+ __le16 timeout;
+} __packed;
+
+#define MGMT_OP_LOAD_CONN_PARAM 0x0035
+struct mgmt_cp_load_conn_param {
+ __le16 param_count;
+ struct mgmt_conn_param params[0];
+} __packed;
+#define MGMT_LOAD_CONN_PARAM_SIZE 2
+
+#define MGMT_OP_READ_UNCONF_INDEX_LIST 0x0036
+#define MGMT_READ_UNCONF_INDEX_LIST_SIZE 0
+struct mgmt_rp_read_unconf_index_list {
+ __le16 num_controllers;
+ __le16 index[0];
+} __packed;
+
+#define MGMT_OPTION_EXTERNAL_CONFIG 0x00000001
+#define MGMT_OPTION_PUBLIC_ADDRESS 0x00000002
+
+#define MGMT_OP_READ_CONFIG_INFO 0x0037
+#define MGMT_READ_CONFIG_INFO_SIZE 0
+struct mgmt_rp_read_config_info {
+ __le16 manufacturer;
+ __le32 supported_options;
+ __le32 missing_options;
+} __packed;
+
+#define MGMT_OP_SET_EXTERNAL_CONFIG 0x0038
+struct mgmt_cp_set_external_config {
+ __u8 config;
+} __packed;
+#define MGMT_SET_EXTERNAL_CONFIG_SIZE 1
+
+#define MGMT_OP_SET_PUBLIC_ADDRESS 0x0039
+struct mgmt_cp_set_public_address {
+ bdaddr_t bdaddr;
+} __packed;
+#define MGMT_SET_PUBLIC_ADDRESS_SIZE 6
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
__le16 opcode;
@@ -522,6 +593,7 @@ struct mgmt_ev_auth_failed {
#define MGMT_DEV_FOUND_CONFIRM_NAME 0x01
#define MGMT_DEV_FOUND_LEGACY_PAIRING 0x02
+#define MGMT_DEV_FOUND_NOT_CONNECTABLE 0x04
#define MGMT_EV_DEVICE_FOUND 0x0012
struct mgmt_ev_device_found {
@@ -578,3 +650,30 @@ struct mgmt_ev_new_csrk {
__u8 store_hint;
struct mgmt_csrk_info key;
} __packed;
+
+#define MGMT_EV_DEVICE_ADDED 0x001a
+struct mgmt_ev_device_added {
+ struct mgmt_addr_info addr;
+ __u8 action;
+} __packed;
+
+#define MGMT_EV_DEVICE_REMOVED 0x001b
+struct mgmt_ev_device_removed {
+ struct mgmt_addr_info addr;
+} __packed;
+
+#define MGMT_EV_NEW_CONN_PARAM 0x001c
+struct mgmt_ev_new_conn_param {
+ struct mgmt_addr_info addr;
+ __u8 store_hint;
+ __le16 min_interval;
+ __le16 max_interval;
+ __le16 latency;
+ __le16 timeout;
+} __packed;
+
+#define MGMT_EV_UNCONF_INDEX_ADDED 0x001d
+
+#define MGMT_EV_UNCONF_INDEX_REMOVED 0x001e
+
+#define MGMT_EV_NEW_CONFIG_OPTIONS 0x001f
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index e46c437944f..0a080c4de27 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2266,10 +2266,6 @@ struct cfg80211_qos_map {
*
* @get_antenna: Get current antenna configuration from device (tx_ant, rx_ant).
*
- * @set_ringparam: Set tx and rx ring sizes.
- *
- * @get_ringparam: Get tx and rx ring current and maximum sizes.
- *
* @tdls_mgmt: Transmit a TDLS management frame.
* @tdls_oper: Perform a high-level TDLS operation (e.g. TDLS link setup).
*
@@ -2278,16 +2274,6 @@ struct cfg80211_qos_map {
*
* @set_noack_map: Set the NoAck Map for the TIDs.
*
- * @get_et_sset_count: Ethtool API to get string-set count.
- * See @ethtool_ops.get_sset_count
- *
- * @get_et_stats: Ethtool API to get a set of u64 stats.
- * See @ethtool_ops.get_ethtool_stats
- *
- * @get_et_strings: Ethtool API to get a set of strings to describe stats
- * and perhaps other supported types of ethtool data-sets.
- * See @ethtool_ops.get_strings
- *
* @get_channel: Get the current operating channel for the virtual interface.
* For monitor interfaces, it should return %NULL unless there's a single
* current monitoring channel.
@@ -2315,7 +2301,12 @@ struct cfg80211_qos_map {
* reliability. This operation can not fail.
* @set_coalesce: Set coalesce parameters.
*
- * @channel_switch: initiate channel-switch procedure (with CSA)
+ * @channel_switch: initiate channel-switch procedure (with CSA). Driver is
+ * responsible for veryfing if the switch is possible. Since this is
+ * inherently tricky driver may decide to disconnect an interface later
+ * with cfg80211_stop_iface(). This doesn't mean driver can accept
+ * everything. It should do it's best to verify requests and reject them
+ * as soon as possible.
*
* @set_qos_map: Set QoS mapping information to the driver
*
@@ -2503,10 +2494,6 @@ struct cfg80211_ops {
int (*set_antenna)(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant);
int (*get_antenna)(struct wiphy *wiphy, u32 *tx_ant, u32 *rx_ant);
- int (*set_ringparam)(struct wiphy *wiphy, u32 tx, u32 rx);
- void (*get_ringparam)(struct wiphy *wiphy,
- u32 *tx, u32 *tx_max, u32 *rx, u32 *rx_max);
-
int (*sched_scan_start)(struct wiphy *wiphy,
struct net_device *dev,
struct cfg80211_sched_scan_request *request);
@@ -2518,7 +2505,7 @@ struct cfg80211_ops {
int (*tdls_mgmt)(struct wiphy *wiphy, struct net_device *dev,
const u8 *peer, u8 action_code, u8 dialog_token,
u16 status_code, u32 peer_capability,
- const u8 *buf, size_t len);
+ bool initiator, const u8 *buf, size_t len);
int (*tdls_oper)(struct wiphy *wiphy, struct net_device *dev,
const u8 *peer, enum nl80211_tdls_operation oper);
@@ -2529,13 +2516,6 @@ struct cfg80211_ops {
struct net_device *dev,
u16 noack_map);
- int (*get_et_sset_count)(struct wiphy *wiphy,
- struct net_device *dev, int sset);
- void (*get_et_stats)(struct wiphy *wiphy, struct net_device *dev,
- struct ethtool_stats *stats, u64 *data);
- void (*get_et_strings)(struct wiphy *wiphy, struct net_device *dev,
- u32 sset, u8 *data);
-
int (*get_channel)(struct wiphy *wiphy,
struct wireless_dev *wdev,
struct cfg80211_chan_def *chandef);
@@ -4843,6 +4823,10 @@ void cfg80211_stop_iface(struct wiphy *wiphy, struct wireless_dev *wdev,
*/
void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy);
+
+/* ethtool helper */
+void cfg80211_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
+
/* Logging, debugging and troubleshooting/diagnostic helpers. */
/* wiphy_printk helpers, similar to dev_printk */
diff --git a/include/net/flow_keys.h b/include/net/flow_keys.h
index 7e64bd8bbda..6667a054763 100644
--- a/include/net/flow_keys.h
+++ b/include/net/flow_keys.h
@@ -1,6 +1,19 @@
#ifndef _NET_FLOW_KEYS_H
#define _NET_FLOW_KEYS_H
+/* struct flow_keys:
+ * @src: source ip address in case of IPv4
+ * For IPv6 it contains 32bit hash of src address
+ * @dst: destination ip address in case of IPv4
+ * For IPv6 it contains 32bit hash of dst address
+ * @ports: port numbers of Transport header
+ * port16[0]: src port number
+ * port16[1]: dst port number
+ * @thoff: Transport header offset
+ * @n_proto: Network header protocol (eg. IPv4/IPv6)
+ * @ip_proto: Transport header protocol (eg. TCP/UDP)
+ * All the members, except thoff, are in network byte order.
+ */
struct flow_keys {
/* (src,dst) must be grouped, in the same way than in IP header */
__be32 src;
@@ -10,9 +23,11 @@ struct flow_keys {
__be16 port16[2];
};
u16 thoff;
+ u16 n_proto;
u8 ip_proto;
};
bool skb_flow_dissect(const struct sk_buff *skb, struct flow_keys *flow);
__be32 skb_flow_get_ports(const struct sk_buff *skb, int thoff, u8 ip_proto);
+u32 flow_hash_from_keys(struct flow_keys *keys);
#endif
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index b4956a5fcc3..d07b1a64b4e 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -205,6 +205,7 @@ struct inet6_dev {
struct timer_list rs_timer;
__u8 rs_probes;
+ __u8 addr_gen_mode;
unsigned long tstamp; /* ipv6InterfaceTable update timestamp */
struct rcu_head rcu;
};
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h
index b1edf17bec0..a829b77523c 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -88,8 +88,10 @@ struct inet_request_sock {
acked : 1,
no_srccheck: 1;
kmemcheck_bitfield_end(flags);
- struct ip_options_rcu *opt;
- struct sk_buff *pktopts;
+ union {
+ struct ip_options_rcu *opt;
+ struct sk_buff *pktopts;
+ };
u32 ir_mark;
};
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index 61474ea0215..6c566034e26 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -108,6 +108,7 @@ struct inet_timewait_sock {
#define tw_family __tw_common.skc_family
#define tw_state __tw_common.skc_state
#define tw_reuse __tw_common.skc_reuse
+#define tw_ipv6only __tw_common.skc_ipv6only
#define tw_bound_dev_if __tw_common.skc_bound_dev_if
#define tw_node __tw_common.skc_nulls_node
#define tw_bind_node __tw_common.skc_bind_node
@@ -131,7 +132,7 @@ struct inet_timewait_sock {
__be16 tw_sport;
kmemcheck_bitfield_begin(flags);
/* And these are ours. */
- unsigned int tw_ipv6only : 1,
+ unsigned int tw_pad0 : 1, /* 1 bit hole */
tw_transparent : 1,
tw_flowlabel : 20,
tw_pad : 2, /* 2 bits hole */
diff --git a/include/net/ip.h b/include/net/ip.h
index 0e795df05ec..2e8f055989c 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -31,6 +31,7 @@
#include <net/route.h>
#include <net/snmp.h>
#include <net/flow.h>
+#include <net/flow_keys.h>
struct sock;
@@ -353,6 +354,19 @@ static inline __wsum inet_compute_pseudo(struct sk_buff *skb, int proto)
skb->len, proto, 0);
}
+static inline void inet_set_txhash(struct sock *sk)
+{
+ struct inet_sock *inet = inet_sk(sk);
+ struct flow_keys keys;
+
+ keys.src = inet->inet_saddr;
+ keys.dst = inet->inet_daddr;
+ keys.port16[0] = inet->inet_sport;
+ keys.port16[1] = inet->inet_dport;
+
+ sk->sk_txhash = flow_hash_from_keys(&keys);
+}
+
/*
* Map a multicast IP onto multicast MAC for type ethernet.
*/
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 574337fe72d..b9ac2357e7d 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -19,6 +19,7 @@
#include <net/if_inet6.h>
#include <net/ndisc.h>
#include <net/flow.h>
+#include <net/flow_keys.h>
#include <net/snmp.h>
#define SIN6_LEN_RFC2133 24
@@ -684,6 +685,50 @@ static inline int ip6_sk_dst_hoplimit(struct ipv6_pinfo *np, struct flowi6 *fl6,
return hlimit;
}
+#if IS_ENABLED(CONFIG_IPV6)
+static inline void ip6_set_txhash(struct sock *sk)
+{
+ struct inet_sock *inet = inet_sk(sk);
+ struct ipv6_pinfo *np = inet6_sk(sk);
+ struct flow_keys keys;
+
+ keys.src = (__force __be32)ipv6_addr_hash(&np->saddr);
+ keys.dst = (__force __be32)ipv6_addr_hash(&sk->sk_v6_daddr);
+ keys.port16[0] = inet->inet_sport;
+ keys.port16[1] = inet->inet_dport;
+
+ sk->sk_txhash = flow_hash_from_keys(&keys);
+}
+
+static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb,
+ __be32 flowlabel, bool autolabel)
+{
+ if (!flowlabel && (autolabel || net->ipv6.sysctl.auto_flowlabels)) {
+ __be32 hash;
+
+ hash = skb_get_hash(skb);
+
+ /* Since this is being sent on the wire obfuscate hash a bit
+ * to minimize possbility that any useful information to an
+ * attacker is leaked. Only lower 20 bits are relevant.
+ */
+ hash ^= hash >> 12;
+
+ flowlabel = hash & IPV6_FLOWLABEL_MASK;
+ }
+
+ return flowlabel;
+}
+#else
+static inline void ip6_set_txhash(struct sock *sk) { }
+static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb,
+ __be32 flowlabel, bool autolabel)
+{
+ return flowlabel;
+}
+#endif
+
+
/*
* Header manipulation
*/
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 421b6ecb4b2..9ce5cb17ed8 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -754,20 +754,25 @@ struct ieee80211_tx_info {
};
/**
- * struct ieee80211_sched_scan_ies - scheduled scan IEs
+ * struct ieee80211_scan_ies - descriptors for different blocks of IEs
*
- * This structure is used to pass the appropriate IEs to be used in scheduled
- * scans for all bands. It contains both the IEs passed from the userspace
+ * This structure is used to point to different blocks of IEs in HW scan
+ * and scheduled scan. These blocks contain the IEs passed by userspace
* and the ones generated by mac80211.
*
- * @ie: array with the IEs for each supported band
- * @len: array with the total length of the IEs for each band
+ * @ies: pointers to band specific IEs.
+ * @len: lengths of band_specific IEs.
+ * @common_ies: IEs for all bands (especially vendor specific ones)
+ * @common_ie_len: length of the common_ies
*/
-struct ieee80211_sched_scan_ies {
- u8 *ie[IEEE80211_NUM_BANDS];
+struct ieee80211_scan_ies {
+ const u8 *ies[IEEE80211_NUM_BANDS];
size_t len[IEEE80211_NUM_BANDS];
+ const u8 *common_ies;
+ size_t common_ie_len;
};
+
static inline struct ieee80211_tx_info *IEEE80211_SKB_CB(struct sk_buff *skb)
{
return (struct ieee80211_tx_info *)skb->cb;
@@ -1601,11 +1606,8 @@ struct ieee80211_tx_control {
* is not enabled the default action is to disconnect when getting the
* CSA frame.
*
- * @IEEE80211_HW_CHANGE_RUNNING_CHANCTX: The hardware can change a
- * channel context on-the-fly. This is needed for channel switch
- * on single-channel hardware. It can also be used as an
- * optimization in certain channel switch cases with
- * multi-channel.
+ * @IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS: The HW supports scanning on all bands
+ * in one command, mac80211 doesn't have to run separate scans per band.
*/
enum ieee80211_hw_flags {
IEEE80211_HW_HAS_RATE_CONTROL = 1<<0,
@@ -1637,7 +1639,8 @@ enum ieee80211_hw_flags {
IEEE80211_HW_TIMING_BEACON_ONLY = 1<<26,
IEEE80211_HW_SUPPORTS_HT_CCK_RATES = 1<<27,
IEEE80211_HW_CHANCTX_STA_CSA = 1<<28,
- IEEE80211_HW_CHANGE_RUNNING_CHANCTX = 1<<29,
+ /* bit 29 unused */
+ IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS = 1<<30,
};
/**
@@ -1764,6 +1767,19 @@ struct ieee80211_hw {
};
/**
+ * struct ieee80211_scan_request - hw scan request
+ *
+ * @ies: pointers different parts of IEs (in req.ie)
+ * @req: cfg80211 request.
+ */
+struct ieee80211_scan_request {
+ struct ieee80211_scan_ies ies;
+
+ /* Keep last */
+ struct cfg80211_scan_request req;
+};
+
+/**
* wiphy_to_ieee80211_hw - return a mac80211 driver hw struct from a wiphy
*
* @wiphy: the &struct wiphy which we want to query
@@ -2764,6 +2780,15 @@ enum ieee80211_roc_type {
* mac80211 will transmit the frame right away.
* The callback is optional and can (should!) sleep.
*
+ * @mgd_protect_tdls_discover: Protect a TDLS discovery session. After sending
+ * a TDLS discovery-request, we expect a reply to arrive on the AP's
+ * channel. We must stay on the channel (no PSM, scan, etc.), since a TDLS
+ * setup-response is a direct packet not buffered by the AP.
+ * mac80211 will call this function just before the transmission of a TDLS
+ * discovery-request. The recommended period of protection is at least
+ * 2 * (DTIM period).
+ * The callback is optional and can sleep.
+ *
* @add_chanctx: Notifies device driver about new channel context creation.
* @remove_chanctx: Notifies device driver about channel context destruction.
* @change_chanctx: Notifies device driver about channel context changes that
@@ -2865,13 +2890,13 @@ struct ieee80211_ops {
void (*set_default_unicast_key)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, int idx);
int (*hw_scan)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
- struct cfg80211_scan_request *req);
+ struct ieee80211_scan_request *req);
void (*cancel_hw_scan)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
int (*sched_scan_start)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct cfg80211_sched_scan_request *req,
- struct ieee80211_sched_scan_ies *ies);
+ struct ieee80211_scan_ies *ies);
int (*sched_scan_stop)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
void (*sw_scan_start)(struct ieee80211_hw *hw);
@@ -2981,6 +3006,9 @@ struct ieee80211_ops {
void (*mgd_prepare_tx)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
+ void (*mgd_protect_tdls_discover)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif);
+
int (*add_chanctx)(struct ieee80211_hw *hw,
struct ieee80211_chanctx_conf *ctx);
void (*remove_chanctx)(struct ieee80211_hw *hw,
@@ -4815,4 +4843,17 @@ int ieee80211_parse_p2p_noa(const struct ieee80211_p2p_noa_attr *attr,
*/
void ieee80211_update_p2p_noa(struct ieee80211_noa_data *data, u32 tsf);
+/**
+ * ieee80211_tdls_oper - request userspace to perform a TDLS operation
+ * @vif: virtual interface
+ * @peer: the peer's destination address
+ * @oper: the requested TDLS operation
+ * @reason_code: reason code for the operation, valid for TDLS teardown
+ * @gfp: allocation flags
+ *
+ * See cfg80211_tdls_oper_request().
+ */
+void ieee80211_tdls_oper_request(struct ieee80211_vif *vif, const u8 *peer,
+ enum nl80211_tdls_operation oper,
+ u16 reason_code, gfp_t gfp);
#endif /* MAC80211_H */
diff --git a/include/net/mac802154.h b/include/net/mac802154.h
index a591053cae6..2e67cdd19cd 100644
--- a/include/net/mac802154.h
+++ b/include/net/mac802154.h
@@ -80,6 +80,25 @@ struct ieee802154_dev {
#define IEEE802154_HW_OMIT_CKSUM 0x00000001
/* Indicates that receiver will autorespond with ACK frames. */
#define IEEE802154_HW_AACK 0x00000002
+/* Indicates that transceiver will support transmit power setting. */
+#define IEEE802154_HW_TXPOWER 0x00000004
+/* Indicates that transceiver will support listen before transmit. */
+#define IEEE802154_HW_LBT 0x00000008
+/* Indicates that transceiver will support cca mode setting. */
+#define IEEE802154_HW_CCA_MODE 0x00000010
+/* Indicates that transceiver will support cca ed level setting. */
+#define IEEE802154_HW_CCA_ED_LEVEL 0x00000020
+/* Indicates that transceiver will support csma (max_be, min_be, csma retries)
+ * settings. */
+#define IEEE802154_HW_CSMA_PARAMS 0x00000040
+/* Indicates that transceiver will support ARET frame retries setting. */
+#define IEEE802154_HW_FRAME_RETRIES 0x00000080
+
+/* This groups the most common CSMA support fields into one. */
+#define IEEE802154_HW_CSMA (IEEE802154_HW_CCA_MODE | \
+ IEEE802154_HW_CCA_ED_LEVEL | \
+ IEEE802154_HW_CSMA_PARAMS | \
+ IEEE802154_HW_FRAME_RETRIES)
/* struct ieee802154_ops - callbacks from mac802154 to the driver
*
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 19d3446e59d..eade27adecf 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -28,6 +28,7 @@ struct netns_sysctl_ipv6 {
int ip6_rt_mtu_expires;
int ip6_rt_min_advmss;
int flowlabel_consistency;
+ int auto_flowlabels;
int icmpv6_time;
int anycast_src_echo_reply;
int fwmark_reflect;
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index 72240e5ac2c..e21b9f9653c 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -136,6 +136,7 @@ void rtnl_af_unregister(struct rtnl_af_ops *ops);
struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]);
struct net_device *rtnl_create_link(struct net *net, char *ifname,
+ unsigned char name_assign_type,
const struct rtnl_link_ops *ops,
struct nlattr *tb[]);
int rtnl_configure_link(struct net_device *dev, const struct ifinfomsg *ifm);
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 624f9857c83..a3cfb8ebeb5 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -231,7 +231,7 @@ struct qdisc_skb_cb {
unsigned int pkt_len;
u16 slave_dev_queue_mapping;
u16 _pad;
- unsigned char data[20];
+ unsigned char data[24];
};
static inline void qdisc_cb_private_validate(const struct sk_buff *skb, int sz)
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h
index 4b7cd695e43..f22538e6824 100644
--- a/include/net/sctp/command.h
+++ b/include/net/sctp/command.h
@@ -118,6 +118,7 @@ typedef enum {
#define SCTP_MAX_NUM_COMMANDS 14
typedef union {
+ void *zero_all; /* Set to NULL to clear the entire union */
__s32 i32;
__u32 u32;
__be32 be32;
@@ -154,7 +155,7 @@ typedef union {
static inline sctp_arg_t \
SCTP_## name (type arg) \
{ sctp_arg_t retval;\
- memset(&retval, 0, sizeof(sctp_arg_t));\
+ retval.zero_all = NULL;\
retval.elt = arg;\
return retval;\
}
@@ -191,7 +192,7 @@ static inline sctp_arg_t SCTP_NOFORCE(void)
static inline sctp_arg_t SCTP_NULL(void)
{
sctp_arg_t retval;
- memset(&retval, 0, sizeof(sctp_arg_t));
+ retval.zero_all = NULL;
return retval;
}
@@ -202,27 +203,49 @@ typedef struct {
typedef struct {
sctp_cmd_t cmds[SCTP_MAX_NUM_COMMANDS];
- __u8 next_free_slot;
- __u8 next_cmd;
+ sctp_cmd_t *last_used_slot;
+ sctp_cmd_t *next_cmd;
} sctp_cmd_seq_t;
/* Initialize a block of memory as a command sequence.
* Return 0 if the initialization fails.
*/
-int sctp_init_cmd_seq(sctp_cmd_seq_t *seq);
+static inline int sctp_init_cmd_seq(sctp_cmd_seq_t *seq)
+{
+ /* cmds[] is filled backwards to simplify the overflow BUG() check */
+ seq->last_used_slot = seq->cmds + SCTP_MAX_NUM_COMMANDS;
+ seq->next_cmd = seq->last_used_slot;
+ return 1; /* We always succeed. */
+}
+
/* Add a command to an sctp_cmd_seq_t.
*
* Use the SCTP_* constructors defined by SCTP_ARG_CONSTRUCTOR() above
* to wrap data which goes in the obj argument.
*/
-void sctp_add_cmd_sf(sctp_cmd_seq_t *seq, sctp_verb_t verb, sctp_arg_t obj);
+static inline void sctp_add_cmd_sf(sctp_cmd_seq_t *seq, sctp_verb_t verb,
+ sctp_arg_t obj)
+{
+ sctp_cmd_t *cmd = seq->last_used_slot - 1;
+
+ BUG_ON(cmd < seq->cmds);
+
+ cmd->verb = verb;
+ cmd->obj = obj;
+ seq->last_used_slot = cmd;
+}
/* Return the next command structure in an sctp_cmd_seq.
* Return NULL at the end of the sequence.
*/
-sctp_cmd_t *sctp_next_cmd(sctp_cmd_seq_t *seq);
+static inline sctp_cmd_t *sctp_next_cmd(sctp_cmd_seq_t *seq)
+{
+ if (seq->next_cmd <= seq->last_used_slot)
+ return NULL;
-#endif /* __net_sctp_command_h__ */
+ return --seq->next_cmd;
+}
+#endif /* __net_sctp_command_h__ */
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 8e4de46c052..c2035c96a2e 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -388,27 +388,6 @@ static inline int sctp_list_single_entry(struct list_head *head)
return (head->next != head) && (head->next == head->prev);
}
-/* Generate a random jitter in the range of -50% ~ +50% of input RTO. */
-static inline __s32 sctp_jitter(__u32 rto)
-{
- static __u32 sctp_rand;
- __s32 ret;
-
- /* Avoid divide by zero. */
- if (!rto)
- rto = 1;
-
- sctp_rand += jiffies;
- sctp_rand ^= (sctp_rand << 12);
- sctp_rand ^= (sctp_rand >> 20);
-
- /* Choose random number from 0 to rto, then move to -50% ~ +50%
- * of rto.
- */
- ret = sctp_rand % rto - (rto >> 1);
- return ret;
-}
-
/* Break down data chunks at this point. */
static inline int sctp_frag_point(const struct sctp_association *asoc, int pmtu)
{
diff --git a/include/net/sock.h b/include/net/sock.h
index 15635074570..29e48a6d1de 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -181,7 +181,8 @@ struct sock_common {
unsigned short skc_family;
volatile unsigned char skc_state;
unsigned char skc_reuse:4;
- unsigned char skc_reuseport:4;
+ unsigned char skc_reuseport:1;
+ unsigned char skc_ipv6only:1;
int skc_bound_dev_if;
union {
struct hlist_node skc_bind_node;
@@ -272,6 +273,7 @@ struct cg_proto;
* @sk_rcvtimeo: %SO_RCVTIMEO setting
* @sk_sndtimeo: %SO_SNDTIMEO setting
* @sk_rxhash: flow hash received from netif layer
+ * @sk_txhash: computed flow hash for use on transmit
* @sk_filter: socket filtering instructions
* @sk_protinfo: private area, net family specific, when not using slab
* @sk_timer: sock cleanup timer
@@ -317,6 +319,7 @@ struct sock {
#define sk_state __sk_common.skc_state
#define sk_reuse __sk_common.skc_reuse
#define sk_reuseport __sk_common.skc_reuseport
+#define sk_ipv6only __sk_common.skc_ipv6only
#define sk_bound_dev_if __sk_common.skc_bound_dev_if
#define sk_bind_node __sk_common.skc_bind_node
#define sk_prot __sk_common.skc_prot
@@ -345,6 +348,7 @@ struct sock {
#ifdef CONFIG_RPS
__u32 sk_rxhash;
#endif
+ __u32 sk_txhash;
#ifdef CONFIG_NET_RX_BUSY_POLL
unsigned int sk_napi_id;
unsigned int sk_ll_usec;
@@ -1978,6 +1982,14 @@ static inline void sock_poll_wait(struct file *filp,
}
}
+static inline void skb_set_hash_from_sk(struct sk_buff *skb, struct sock *sk)
+{
+ if (sk->sk_txhash) {
+ skb->l4_hash = 1;
+ skb->hash = sk->sk_txhash;
+ }
+}
+
/*
* Queue a received datagram if it will fit. Stream and sequenced
* protocols can't normally use this as they need to fit buffers in
@@ -1992,6 +2004,7 @@ static inline void skb_set_owner_w(struct sk_buff *skb, struct sock *sk)
skb_orphan(skb);
skb->sk = sk;
skb->destructor = sock_wfree;
+ skb_set_hash_from_sk(skb, sk);
/*
* We used to take a refcount on sk, but following operation
* is enough to guarantee sk_free() wont free this sock until
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 7286db80e8b..0aeb2eb749d 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -493,14 +493,8 @@ static inline u32 tcp_cookie_time(void)
u32 __cookie_v4_init_sequence(const struct iphdr *iph, const struct tcphdr *th,
u16 *mssp);
-__u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mss);
-#else
-static inline __u32 cookie_v4_init_sequence(struct sock *sk,
- struct sk_buff *skb,
- __u16 *mss)
-{
- return 0;
-}
+__u32 cookie_v4_init_sequence(struct sock *sk, const struct sk_buff *skb,
+ __u16 *mss);
#endif
__u32 cookie_init_timestamp(struct request_sock *req);
@@ -516,13 +510,6 @@ u32 __cookie_v6_init_sequence(const struct ipv6hdr *iph,
const struct tcphdr *th, u16 *mssp);
__u32 cookie_v6_init_sequence(struct sock *sk, const struct sk_buff *skb,
__u16 *mss);
-#else
-static inline __u32 cookie_v6_init_sequence(struct sock *sk,
- struct sk_buff *skb,
- __u16 *mss)
-{
- return 0;
-}
#endif
/* tcp_output.c */
@@ -941,7 +928,7 @@ static inline __u32 tcp_current_ssthresh(const struct sock *sk)
/* Use define here intentionally to get WARN_ON location shown at the caller */
#define tcp_verify_left_out(tp) WARN_ON(tcp_left_out(tp) > tp->packets_out)
-void tcp_enter_cwr(struct sock *sk, const int set_ssthresh);
+void tcp_enter_cwr(struct sock *sk);
__u32 tcp_init_cwnd(const struct tcp_sock *tp, const struct dst_entry *dst);
/* The maximum number of MSS of available cwnd for which TSO defers
@@ -1098,7 +1085,7 @@ static inline int tcp_full_space(const struct sock *sk)
static inline void tcp_openreq_init(struct request_sock *req,
struct tcp_options_received *rx_opt,
- struct sk_buff *skb)
+ struct sk_buff *skb, struct sock *sk)
{
struct inet_request_sock *ireq = inet_rsk(req);
@@ -1106,7 +1093,7 @@ static inline void tcp_openreq_init(struct request_sock *req,
req->cookie_ts = 0;
tcp_rsk(req)->rcv_isn = TCP_SKB_CB(skb)->seq;
tcp_rsk(req)->rcv_nxt = TCP_SKB_CB(skb)->seq + 1;
- tcp_rsk(req)->snt_synack = 0;
+ tcp_rsk(req)->snt_synack = tcp_time_stamp;
req->mss = rx_opt->mss_clamp;
req->ts_recent = rx_opt->saw_tstamp ? rx_opt->rcv_tsval : 0;
ireq->tstamp_ok = rx_opt->tstamp_ok;
@@ -1117,6 +1104,7 @@ static inline void tcp_openreq_init(struct request_sock *req,
ireq->ecn_ok = 0;
ireq->ir_rmt_port = tcp_hdr(skb)->source;
ireq->ir_num = ntohs(tcp_hdr(skb)->dest);
+ ireq->ir_mark = inet_request_mark(sk, skb);
}
extern void tcp_openreq_init_rwin(struct request_sock *req,
@@ -1585,6 +1573,11 @@ int tcp4_proc_init(void);
void tcp4_proc_exit(void);
#endif
+int tcp_rtx_synack(struct sock *sk, struct request_sock *req);
+int tcp_conn_request(struct request_sock_ops *rsk_ops,
+ const struct tcp_request_sock_ops *af_ops,
+ struct sock *sk, struct sk_buff *skb);
+
/* TCP af-specific functions */
struct tcp_sock_af_ops {
#ifdef CONFIG_TCP_MD5SIG
@@ -1602,6 +1595,7 @@ struct tcp_sock_af_ops {
};
struct tcp_request_sock_ops {
+ u16 mss_clamp;
#ifdef CONFIG_TCP_MD5SIG
struct tcp_md5sig_key *(*md5_lookup) (struct sock *sk,
struct request_sock *req);
@@ -1611,8 +1605,39 @@ struct tcp_request_sock_ops {
const struct request_sock *req,
const struct sk_buff *skb);
#endif
+ void (*init_req)(struct request_sock *req, struct sock *sk,
+ struct sk_buff *skb);
+#ifdef CONFIG_SYN_COOKIES
+ __u32 (*cookie_init_seq)(struct sock *sk, const struct sk_buff *skb,
+ __u16 *mss);
+#endif
+ struct dst_entry *(*route_req)(struct sock *sk, struct flowi *fl,
+ const struct request_sock *req,
+ bool *strict);
+ __u32 (*init_seq)(const struct sk_buff *skb);
+ int (*send_synack)(struct sock *sk, struct dst_entry *dst,
+ struct flowi *fl, struct request_sock *req,
+ u16 queue_mapping, struct tcp_fastopen_cookie *foc);
+ void (*queue_hash_add)(struct sock *sk, struct request_sock *req,
+ const unsigned long timeout);
};
+#ifdef CONFIG_SYN_COOKIES
+static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops,
+ struct sock *sk, struct sk_buff *skb,
+ __u16 *mss)
+{
+ return ops->cookie_init_seq(sk, skb, mss);
+}
+#else
+static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops,
+ struct sock *sk, struct sk_buff *skb,
+ __u16 *mss)
+{
+ return 0;
+}
+#endif
+
int tcpv4_offload_init(void);
void tcp_v4_init(void);
diff --git a/include/net/udp.h b/include/net/udp.h
index 68a1fefe3df..70f941368ac 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -176,6 +176,35 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
int (*)(const struct sock *, const struct sock *),
unsigned int hash2_nulladdr);
+static inline __be16 udp_flow_src_port(struct net *net, struct sk_buff *skb,
+ int min, int max, bool use_eth)
+{
+ u32 hash;
+
+ if (min >= max) {
+ /* Use default range */
+ inet_get_local_port_range(net, &min, &max);
+ }
+
+ hash = skb_get_hash(skb);
+ if (unlikely(!hash) && use_eth) {
+ /* Can't find a normal hash, caller has indicated an Ethernet
+ * packet so use that to compute a hash.
+ */
+ hash = jhash(skb->data, 2 * ETH_ALEN,
+ (__force u32) skb->protocol);
+ }
+
+ /* Since this is being sent on the wire obfuscate hash a bit
+ * to minimize possbility that any useful information to an
+ * attacker is leaked. Only upper 16 bits are relevant in the
+ * computation for 16 bit port value.
+ */
+ hash ^= hash << 16;
+
+ return htons((((u64) hash * (max - min)) >> 32) + min);
+}
+
/* net/ipv4/udp.c */
void udp_v4_early_demux(struct sk_buff *skb);
int udp_get_port(struct sock *sk, unsigned short snum,
diff --git a/include/net/udp_tunnel.h b/include/net/udp_tunnel.h
new file mode 100644
index 00000000000..ffd69cbded3
--- /dev/null
+++ b/include/net/udp_tunnel.h
@@ -0,0 +1,32 @@
+#ifndef __NET_UDP_TUNNEL_H
+#define __NET_UDP_TUNNEL_H
+
+struct udp_port_cfg {
+ u8 family;
+
+ /* Used only for kernel-created sockets */
+ union {
+ struct in_addr local_ip;
+#if IS_ENABLED(CONFIG_IPV6)
+ struct in6_addr local_ip6;
+#endif
+ };
+
+ union {
+ struct in_addr peer_ip;
+#if IS_ENABLED(CONFIG_IPV6)
+ struct in6_addr peer_ip6;
+#endif
+ };
+
+ __be16 local_udp_port;
+ __be16 peer_udp_port;
+ unsigned int use_udp_checksums:1,
+ use_udp6_tx_checksums:1,
+ use_udp6_rx_checksums:1;
+};
+
+int udp_sock_create(struct net *net, struct udp_port_cfg *cfg,
+ struct socket **sockp);
+
+#endif
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index 12196ce661d..d5f59f3fc35 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -45,8 +45,6 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
__be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
__be16 src_port, __be16 dst_port, __be32 vni, bool xnet);
-__be16 vxlan_src_port(__u16 port_min, __u16 port_max, struct sk_buff *skb);
-
/* IP header + UDP + VXLAN + Ethernet header */
#define VXLAN_HEADROOM (20 + 8 + 8 + 14)
/* IPv6 header + UDP + VXLAN + Ethernet header */