diff options
Diffstat (limited to 'include/net')
73 files changed, 2165 insertions, 906 deletions
diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h index f7d372b7d4ff..d184df1d0d41 100644 --- a/include/net/6lowpan.h +++ b/include/net/6lowpan.h @@ -54,6 +54,7 @@ #define __6LOWPAN_H__ #include <net/ipv6.h> +#include <net/net_namespace.h> #define UIP_802154_SHORTADDR_LEN 2 /* compressed ipv6 address length */ #define UIP_IPH_LEN 40 /* ipv6 fixed header size */ @@ -74,20 +75,6 @@ (((a)->s6_addr[14]) == (m)[6]) && \ (((a)->s6_addr[15]) == (m)[7])) -/* ipv6 address is unspecified */ -#define is_addr_unspecified(a) \ - ((((a)->s6_addr32[0]) == 0) && \ - (((a)->s6_addr32[1]) == 0) && \ - (((a)->s6_addr32[2]) == 0) && \ - (((a)->s6_addr32[3]) == 0)) - -/* compare ipv6 addresses prefixes */ -#define ipaddr_prefixcmp(addr1, addr2, length) \ - (memcmp(addr1, addr2, length >> 3) == 0) - -/* local link, i.e. FE80::/10 */ -#define is_addr_link_local(a) (((a)->s6_addr16[0]) == htons(0xFE80)) - /* * check whether we can compress the IID to 16 bits, * it's possible for unicast adresses with first 49 bits are zero only. @@ -99,22 +86,8 @@ (((a)->s6_addr[12]) == 0xfe) && \ (((a)->s6_addr[13]) == 0)) -/* multicast address */ -#define is_addr_mcast(a) (((a)->s6_addr[0]) == 0xFF) - /* check whether the 112-bit gid of the multicast address is mappable to: */ -/* 9 bits, for FF02::1 (all nodes) and FF02::2 (all routers) addresses only. */ -#define lowpan_is_mcast_addr_compressable(a) \ - ((((a)->s6_addr16[1]) == 0) && \ - (((a)->s6_addr16[2]) == 0) && \ - (((a)->s6_addr16[3]) == 0) && \ - (((a)->s6_addr16[4]) == 0) && \ - (((a)->s6_addr16[5]) == 0) && \ - (((a)->s6_addr16[6]) == 0) && \ - (((a)->s6_addr[14]) == 0) && \ - ((((a)->s6_addr[15]) == 1) || (((a)->s6_addr[15]) == 2))) - /* 48 bits, FFXX::00XX:XXXX:XXXX */ #define lowpan_is_mcast_addr_compressable48(a) \ ((((a)->s6_addr16[1]) == 0) && \ @@ -167,17 +140,6 @@ #define LOWPAN_FRAGN_HEAD_SIZE 0x5 /* - * According IEEE802.15.4 standard: - * - MTU is 127 octets - * - maximum MHR size is 37 octets - * - MFR size is 2 octets - * - * so minimal payload size that we may guarantee is: - * MTU - MHR - MFR = 88 octets - */ -#define LOWPAN_FRAG_SIZE 88 - -/* * Values of fields within the IPHC encoding first byte * (C stands for compressed and I for inline) */ @@ -278,17 +240,6 @@ static inline int lowpan_fetch_skb_u8(struct sk_buff *skb, u8 *val) return 0; } -static inline int lowpan_fetch_skb_u16(struct sk_buff *skb, u16 *val) -{ - if (unlikely(!pskb_may_pull(skb, 2))) - return -EINVAL; - - *val = (skb->data[0] << 8) | skb->data[1]; - skb_pull(skb, 2); - - return 0; -} - static inline bool lowpan_fetch_skb(struct sk_buff *skb, void *data, const unsigned int len) { diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 933a9f22a05f..f679877bb601 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -306,11 +306,6 @@ static inline void addrconf_addr_solict_mult(const struct in6_addr *addr, htonl(0xFF000000) | addr->s6_addr32[3]); } -static inline bool ipv6_addr_is_multicast(const struct in6_addr *addr) -{ - return (addr->s6_addr32[0] & htonl(0xFF000000)) == htonl(0xFF000000); -} - static inline bool ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr) { #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 diff --git a/include/net/af_ieee802154.h b/include/net/af_ieee802154.h index f79ae2aa76d6..085940f7eeec 100644 --- a/include/net/af_ieee802154.h +++ b/include/net/af_ieee802154.h @@ -57,6 +57,14 @@ struct sockaddr_ieee802154 { /* get/setsockopt */ #define SOL_IEEE802154 0 -#define WPAN_WANTACK 0 +#define WPAN_WANTACK 0 +#define WPAN_SECURITY 1 +#define WPAN_SECURITY_LEVEL 2 + +#define WPAN_SECURITY_DEFAULT 0 +#define WPAN_SECURITY_OFF 1 +#define WPAN_SECURITY_ON 2 + +#define WPAN_SECURITY_LEVEL_DEFAULT (-1) #endif diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 904777c1cd24..373000de610d 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 be150cf8cd43..3f8547f1c6f8 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_BONDABLE, 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,34 +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)) - -/* HCI ioctl defines */ -#define HCIDEVUP _IOW('H', 201, int) -#define HCIDEVDOWN _IOW('H', 202, int) -#define HCIDEVRESET _IOW('H', 203, int) -#define HCIDEVRESTAT _IOW('H', 204, int) - -#define HCIGETDEVLIST _IOR('H', 210, int) -#define HCIGETDEVINFO _IOR('H', 211, int) -#define HCIGETCONNLIST _IOR('H', 212, int) -#define HCIGETCONNINFO _IOR('H', 213, int) -#define HCIGETAUTHINFO _IOR('H', 215, int) - -#define HCISETRAW _IOW('H', 220, int) -#define HCISETSCAN _IOW('H', 221, int) -#define HCISETAUTH _IOW('H', 222, int) -#define HCISETENCRYPT _IOW('H', 223, int) -#define HCISETPTYPE _IOW('H', 224, int) -#define HCISETLINKPOL _IOW('H', 225, int) -#define HCISETLINKMODE _IOW('H', 226, int) -#define HCISETACLMTU _IOW('H', 227, int) -#define HCISETSCOMTU _IOW('H', 228, int) - -#define HCIBLOCKADDR _IOW('H', 230, int) -#define HCIUNBLOCKADDR _IOW('H', 231, int) - -#define HCIINQUIRY _IOR('H', 240, int) + BIT(HCI_FAST_CONNECTABLE) | BIT(HCI_LE_ADV)) /* HCI timeouts */ #define HCI_DISCONN_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ @@ -185,6 +211,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 +328,11 @@ enum { #define LMP_HOST_LE_BREDR 0x04 #define LMP_HOST_SC 0x08 +/* LE features */ +#define HCI_LE_ENCRYPTION 0x01 +#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 +379,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 +391,8 @@ 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 */ #define HCI_FLOW_CTL_MODE_PACKET_BASED 0x00 @@ -375,6 +401,9 @@ enum { /* The core spec defines 127 as the "not available" value */ #define HCI_TX_POWER_INVALID 127 +#define HCI_ROLE_MASTER 0x00 +#define HCI_ROLE_SLAVE 0x01 + /* Extended Inquiry Response field types */ #define EIR_FLAGS 0x01 /* flags */ #define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */ @@ -535,6 +564,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; @@ -1040,6 +1074,8 @@ struct hci_rp_read_data_block_size { __le16 num_blocks; } __packed; +#define HCI_OP_READ_LOCAL_CODECS 0x100b + #define HCI_OP_READ_PAGE_SCAN_ACTIVITY 0x0c1b struct hci_rp_read_page_scan_activity { __u8 status; @@ -1053,6 +1089,17 @@ struct hci_cp_write_page_scan_activity { __le16 window; } __packed; +#define HCI_OP_READ_TX_POWER 0x0c2d +struct hci_cp_read_tx_power { + __le16 handle; + __u8 type; +} __packed; +struct hci_rp_read_tx_power { + __u8 status; + __le16 handle; + __s8 tx_power; +} __packed; + #define HCI_OP_READ_PAGE_SCAN_TYPE 0x0c46 struct hci_rp_read_page_scan_type { __u8 status; @@ -1063,6 +1110,28 @@ struct hci_rp_read_page_scan_type { #define PAGE_SCAN_TYPE_STANDARD 0x00 #define PAGE_SCAN_TYPE_INTERLACED 0x01 +#define HCI_OP_READ_RSSI 0x1405 +struct hci_cp_read_rssi { + __le16 handle; +} __packed; +struct hci_rp_read_rssi { + __u8 status; + __le16 handle; + __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; @@ -1103,6 +1172,8 @@ struct hci_rp_write_remote_amp_assoc { __u8 phy_handle; } __packed; +#define HCI_OP_GET_MWS_TRANSPORT_CONFIG 0x140c + #define HCI_OP_ENABLE_DUT_MODE 0x1803 #define HCI_OP_WRITE_SSP_DEBUG_MODE 0x1804 @@ -1269,6 +1340,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 @@ -1632,9 +1720,6 @@ struct hci_ev_sync_train_complete { #define HCI_EV_SLAVE_PAGE_RESP_TIMEOUT 0x54 -/* Low energy meta events */ -#define LE_CONN_ROLE_MASTER 0x00 - #define HCI_EV_LE_CONN_COMPLETE 0x01 struct hci_ev_le_conn_complete { __u8 status; @@ -1648,6 +1733,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; @@ -1655,6 +1749,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 @@ -1746,126 +1849,4 @@ static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb) #define hci_handle(h) (h & 0x0fff) #define hci_flags(h) (h >> 12) -/* ---- HCI Sockets ---- */ - -/* Socket options */ -#define HCI_DATA_DIR 1 -#define HCI_FILTER 2 -#define HCI_TIME_STAMP 3 - -/* CMSG flags */ -#define HCI_CMSG_DIR 0x0001 -#define HCI_CMSG_TSTAMP 0x0002 - -struct sockaddr_hci { - sa_family_t hci_family; - unsigned short hci_dev; - unsigned short hci_channel; -}; -#define HCI_DEV_NONE 0xffff - -#define HCI_CHANNEL_RAW 0 -#define HCI_CHANNEL_USER 1 -#define HCI_CHANNEL_MONITOR 2 -#define HCI_CHANNEL_CONTROL 3 - -struct hci_filter { - unsigned long type_mask; - unsigned long event_mask[2]; - __le16 opcode; -}; - -struct hci_ufilter { - __u32 type_mask; - __u32 event_mask[2]; - __le16 opcode; -}; - -#define HCI_FLT_TYPE_BITS 31 -#define HCI_FLT_EVENT_BITS 63 -#define HCI_FLT_OGF_BITS 63 -#define HCI_FLT_OCF_BITS 127 - -/* ---- HCI Ioctl requests structures ---- */ -struct hci_dev_stats { - __u32 err_rx; - __u32 err_tx; - __u32 cmd_tx; - __u32 evt_rx; - __u32 acl_tx; - __u32 acl_rx; - __u32 sco_tx; - __u32 sco_rx; - __u32 byte_rx; - __u32 byte_tx; -}; - -struct hci_dev_info { - __u16 dev_id; - char name[8]; - - bdaddr_t bdaddr; - - __u32 flags; - __u8 type; - - __u8 features[8]; - - __u32 pkt_type; - __u32 link_policy; - __u32 link_mode; - - __u16 acl_mtu; - __u16 acl_pkts; - __u16 sco_mtu; - __u16 sco_pkts; - - struct hci_dev_stats stat; -}; - -struct hci_conn_info { - __u16 handle; - bdaddr_t bdaddr; - __u8 type; - __u8 out; - __u16 state; - __u32 link_mode; -}; - -struct hci_dev_req { - __u16 dev_id; - __u32 dev_opt; -}; - -struct hci_dev_list_req { - __u16 dev_num; - struct hci_dev_req dev_req[0]; /* hci_dev_req structures */ -}; - -struct hci_conn_list_req { - __u16 dev_id; - __u16 conn_num; - struct hci_conn_info conn_info[0]; -}; - -struct hci_conn_info_req { - bdaddr_t bdaddr; - __u8 type; - struct hci_conn_info conn_info[0]; -}; - -struct hci_auth_info_req { - bdaddr_t bdaddr; - __u8 type; -}; - -struct hci_inquiry_req { - __u16 dev_id; - __u16 flags; - __u8 lap[3]; - __u8 length; - __u8 num_rsp; -}; -#define IREQ_CACHE_FLUSH 0x0001 - #endif /* __HCI_H */ diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 5f8bc05694ac..b5d5af3aa469 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -26,6 +26,7 @@ #define __HCI_CORE_H #include <net/bluetooth/hci.h> +#include <net/bluetooth/hci_sock.h> /* HCI priority */ #define HCI_PRIO_MAX 7 @@ -68,6 +69,12 @@ struct discovery_state { struct list_head unknown; /* Name state not known */ struct list_head resolve; /* Name needs to be resolved */ __u32 timestamp; + 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; }; struct hci_conn_hash { @@ -76,6 +83,7 @@ struct hci_conn_hash { unsigned int amp_num; unsigned int sco_num; unsigned int le_num; + unsigned int le_num_slave; }; struct bdaddr_list { @@ -140,6 +148,10 @@ struct oob_data { /* Default LE RPA expiry time, 15 minutes */ #define HCI_DEFAULT_RPA_TIMEOUT (15 * 60) +/* Default min/max age of connection information (1s/3s) */ +#define DEFAULT_CONN_INFO_MIN_AGE 1000 +#define DEFAULT_CONN_INFO_MAX_AGE 3000 + struct amp_assoc { __u16 len; __u16 offset; @@ -161,6 +173,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; @@ -189,12 +203,20 @@ struct hci_dev { __u16 page_scan_window; __u8 page_scan_type; __u8 le_adv_channel_map; + __u16 le_adv_min_interval; + __u16 le_adv_max_interval; __u8 le_scan_type; __u16 le_scan_interval; __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; @@ -261,7 +283,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; @@ -287,6 +309,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; @@ -295,6 +318,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; @@ -306,6 +330,7 @@ struct hci_dev { struct rfkill *rfkill; + unsigned long dbg_flags; unsigned long dev_flags; struct delayed_work le_scan_disable; @@ -327,6 +352,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) @@ -348,13 +374,13 @@ struct hci_conn { __u16 state; __u8 mode; __u8 type; + __u8 role; bool out; __u8 attempt; __u8 dev_class[3]; __u8 features[HCI_MAX_PAGES][8]; __u16 pkt_type; __u16 link_policy; - __u32 link_mode; __u8 key_type; __u8 auth_type; __u8 sec_level; @@ -365,15 +391,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; @@ -390,7 +427,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; @@ -411,15 +447,20 @@ 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_DIRECT, HCI_AUTO_CONN_ALWAYS, HCI_AUTO_CONN_LINK_LOSS, } auto_connect; @@ -484,8 +525,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 ----- */ @@ -503,7 +544,13 @@ enum { HCI_CONN_AES_CCM, HCI_CONN_POWER_SAVE, HCI_CONN_REMOTE_OOB, - HCI_CONN_6LOWPAN, + HCI_CONN_FLUSH_KEY, + HCI_CONN_ENCRYPT, + HCI_CONN_AUTH, + HCI_CONN_SECURE, + HCI_CONN_FIPS, + HCI_CONN_STK_ENCRYPT, + HCI_CONN_AUTH_INITIATOR, }; static inline bool hci_conn_ssp_enabled(struct hci_conn *conn) @@ -533,6 +580,8 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) break; case LE_LINK: h->le_num++; + if (c->role == HCI_ROLE_SLAVE) + h->le_num_slave++; break; case SCO_LINK: case ESCO_LINK: @@ -557,6 +606,8 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c) break; case LE_LINK: h->le_num--; + if (c->role == HCI_ROLE_SLAVE) + h->le_num_slave--; break; case SCO_LINK: case ESCO_LINK: @@ -653,7 +704,8 @@ void hci_disconnect(struct hci_conn *conn, __u8 reason); bool hci_setup_sync(struct hci_conn *conn, __u16 handle); void hci_sco_setup(struct hci_conn *conn, __u8 status); -struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst); +struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst, + u8 role); int hci_conn_del(struct hci_conn *conn); void hci_conn_hash_flush(struct hci_dev *hdev); void hci_conn_check_pending(struct hci_dev *hdev); @@ -664,14 +716,16 @@ 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, + u8 role); 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, __u16 setting); int hci_conn_check_link_mode(struct hci_conn *conn); int hci_conn_check_secure(struct hci_conn *conn, __u8 sec_level); -int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type); +int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type, + bool initiator); int hci_conn_change_link_key(struct hci_conn *conn); int hci_conn_switch_role(struct hci_conn *conn, __u8 role); @@ -808,30 +862,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); @@ -839,15 +888,16 @@ 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); + u8 role); struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type, u8 authenticated, u8 tk[16], u8 enc_size, __le16 ediv, __le64 rand); struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr, - u8 addr_type, bool master); + u8 addr_type, u8 role); int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 bdaddr_type); void hci_smp_ltks_clear(struct hci_dev *hdev); int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr); @@ -1004,7 +1054,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) @@ -1045,7 +1095,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) { @@ -1130,7 +1180,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) @@ -1139,6 +1189,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) { @@ -1148,6 +1210,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); @@ -1168,6 +1251,7 @@ void hci_req_add(struct hci_request *req, u16 opcode, u32 plen, void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen, const void *param, u8 event); void hci_req_cmd_complete(struct hci_dev *hdev, u16 opcode, u8 status); +bool hci_req_pending(struct hci_dev *hdev); void hci_req_add_le_scan_disable(struct hci_request *req); void hci_req_add_le_passive_scan(struct hci_request *req); @@ -1204,21 +1288,19 @@ void hci_sock_dev_event(struct hci_dev *hdev, int event); */ #define DISCOV_LE_SCAN_WIN 0x12 #define DISCOV_LE_SCAN_INT 0x12 -#define DISCOV_LE_TIMEOUT msecs_to_jiffies(10240) -#define DISCOV_INTERLEAVED_TIMEOUT msecs_to_jiffies(5120) +#define DISCOV_LE_TIMEOUT 10240 /* msec */ +#define DISCOV_INTERLEAVED_TIMEOUT 5120 /* msec */ #define DISCOV_INTERLEAVED_INQUIRY_LEN 0x04 #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); int mgmt_powered(struct hci_dev *hdev, u8 powered); +int mgmt_update_adv_data(struct hci_dev *hdev); 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); void mgmt_device_connected(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, @@ -1264,50 +1346,23 @@ 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 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); -/* HCI info for socket */ -#define hci_pi(sk) ((struct hci_pinfo *) sk) - -struct hci_pinfo { - struct bt_sock bt; - struct hci_dev *hdev; - struct hci_filter filter; - __u32 cmsg_mask; - unsigned short channel; -}; - -/* HCI security filter */ -#define HCI_SFLT_MAX_OGF 5 - -struct hci_sec_filter { - __u32 type_mask; - __u32 event_mask[2]; - __u32 ocf_mask[HCI_SFLT_MAX_OGF + 1][4]; -}; - -/* ----- HCI requests ----- */ -#define HCI_REQ_DONE 0 -#define HCI_REQ_PEND 1 -#define HCI_REQ_CANCELED 2 - -#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/hci_sock.h b/include/net/bluetooth/hci_sock.h new file mode 100644 index 000000000000..9a46d665c1b5 --- /dev/null +++ b/include/net/bluetooth/hci_sock.h @@ -0,0 +1,175 @@ +/* + BlueZ - Bluetooth protocol stack for Linux + Copyright (C) 2000-2001 Qualcomm Incorporated + + Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License version 2 as + published by the Free Software Foundation; + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. + IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY + CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS, + COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS + SOFTWARE IS DISCLAIMED. +*/ + +#ifndef __HCI_SOCK_H +#define __HCI_SOCK_H + +/* Socket options */ +#define HCI_DATA_DIR 1 +#define HCI_FILTER 2 +#define HCI_TIME_STAMP 3 + +/* CMSG flags */ +#define HCI_CMSG_DIR 0x0001 +#define HCI_CMSG_TSTAMP 0x0002 + +struct sockaddr_hci { + sa_family_t hci_family; + unsigned short hci_dev; + unsigned short hci_channel; +}; +#define HCI_DEV_NONE 0xffff + +#define HCI_CHANNEL_RAW 0 +#define HCI_CHANNEL_USER 1 +#define HCI_CHANNEL_MONITOR 2 +#define HCI_CHANNEL_CONTROL 3 + +struct hci_filter { + unsigned long type_mask; + unsigned long event_mask[2]; + __le16 opcode; +}; + +struct hci_ufilter { + __u32 type_mask; + __u32 event_mask[2]; + __le16 opcode; +}; + +#define HCI_FLT_TYPE_BITS 31 +#define HCI_FLT_EVENT_BITS 63 +#define HCI_FLT_OGF_BITS 63 +#define HCI_FLT_OCF_BITS 127 + +/* Ioctl defines */ +#define HCIDEVUP _IOW('H', 201, int) +#define HCIDEVDOWN _IOW('H', 202, int) +#define HCIDEVRESET _IOW('H', 203, int) +#define HCIDEVRESTAT _IOW('H', 204, int) + +#define HCIGETDEVLIST _IOR('H', 210, int) +#define HCIGETDEVINFO _IOR('H', 211, int) +#define HCIGETCONNLIST _IOR('H', 212, int) +#define HCIGETCONNINFO _IOR('H', 213, int) +#define HCIGETAUTHINFO _IOR('H', 215, int) + +#define HCISETRAW _IOW('H', 220, int) +#define HCISETSCAN _IOW('H', 221, int) +#define HCISETAUTH _IOW('H', 222, int) +#define HCISETENCRYPT _IOW('H', 223, int) +#define HCISETPTYPE _IOW('H', 224, int) +#define HCISETLINKPOL _IOW('H', 225, int) +#define HCISETLINKMODE _IOW('H', 226, int) +#define HCISETACLMTU _IOW('H', 227, int) +#define HCISETSCOMTU _IOW('H', 228, int) + +#define HCIBLOCKADDR _IOW('H', 230, int) +#define HCIUNBLOCKADDR _IOW('H', 231, int) + +#define HCIINQUIRY _IOR('H', 240, int) + +/* Ioctl requests structures */ +struct hci_dev_stats { + __u32 err_rx; + __u32 err_tx; + __u32 cmd_tx; + __u32 evt_rx; + __u32 acl_tx; + __u32 acl_rx; + __u32 sco_tx; + __u32 sco_rx; + __u32 byte_rx; + __u32 byte_tx; +}; + +struct hci_dev_info { + __u16 dev_id; + char name[8]; + + bdaddr_t bdaddr; + + __u32 flags; + __u8 type; + + __u8 features[8]; + + __u32 pkt_type; + __u32 link_policy; + __u32 link_mode; + + __u16 acl_mtu; + __u16 acl_pkts; + __u16 sco_mtu; + __u16 sco_pkts; + + struct hci_dev_stats stat; +}; + +struct hci_conn_info { + __u16 handle; + bdaddr_t bdaddr; + __u8 type; + __u8 out; + __u16 state; + __u32 link_mode; +}; + +struct hci_dev_req { + __u16 dev_id; + __u32 dev_opt; +}; + +struct hci_dev_list_req { + __u16 dev_num; + struct hci_dev_req dev_req[0]; /* hci_dev_req structures */ +}; + +struct hci_conn_list_req { + __u16 dev_id; + __u16 conn_num; + struct hci_conn_info conn_info[0]; +}; + +struct hci_conn_info_req { + bdaddr_t bdaddr; + __u8 type; + struct hci_conn_info conn_info[0]; +}; + +struct hci_auth_info_req { + bdaddr_t bdaddr; + __u8 type; +}; + +struct hci_inquiry_req { + __u16 dev_id; + __u16 flags; + __u8 lap[3]; + __u8 length; + __u8 num_rsp; +}; +#define IREQ_CACHE_FLUSH 0x0001 + +#endif /* __HCI_SOCK_H */ diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h index 4abdcb220e3a..8df15ad0d43f 100644 --- a/include/net/bluetooth/l2cap.h +++ b/include/net/bluetooth/l2cap.h @@ -134,10 +134,12 @@ struct l2cap_conninfo { #define L2CAP_FCS_CRC16 0x01 /* L2CAP fixed channels */ -#define L2CAP_FC_L2CAP 0x02 +#define L2CAP_FC_SIG_BREDR 0x02 #define L2CAP_FC_CONNLESS 0x04 #define L2CAP_FC_A2MP 0x08 -#define L2CAP_FC_6LOWPAN 0x3e /* reserved and temporary value */ +#define L2CAP_FC_ATT 0x10 +#define L2CAP_FC_SIG_LE 0x20 +#define L2CAP_FC_SMP_LE 0x40 /* L2CAP Control Field bit masks */ #define L2CAP_CTRL_SAR 0xC000 @@ -579,7 +581,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 +602,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 { @@ -618,11 +625,10 @@ struct l2cap_conn { struct delayed_work info_timer; - spinlock_t lock; - struct sk_buff *rx_skb; __u32 rx_len; __u8 tx_ident; + struct mutex ident_lock; struct sk_buff_head pending_rx; struct work_struct pending_rx_work; @@ -856,6 +862,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,10 +903,9 @@ 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); +int l2cap_chan_check_security(struct l2cap_chan *chan, bool initiator); void l2cap_chan_set_defaults(struct l2cap_chan *chan); int l2cap_ertm_init(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 d4b571c2f9fd..414cd2f9a437 100644 --- a/include/net/bluetooth/mgmt.h +++ b/include/net/bluetooth/mgmt.h @@ -87,7 +87,7 @@ struct mgmt_rp_read_index_list { #define MGMT_SETTING_CONNECTABLE 0x00000002 #define MGMT_SETTING_FAST_CONNECTABLE 0x00000004 #define MGMT_SETTING_DISCOVERABLE 0x00000008 -#define MGMT_SETTING_PAIRABLE 0x00000010 +#define MGMT_SETTING_BONDABLE 0x00000010 #define MGMT_SETTING_LINK_SECURITY 0x00000020 #define MGMT_SETTING_SSP 0x00000040 #define MGMT_SETTING_BREDR 0x00000080 @@ -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 @@ -130,7 +131,7 @@ struct mgmt_cp_set_discoverable { #define MGMT_OP_SET_FAST_CONNECTABLE 0x0008 -#define MGMT_OP_SET_PAIRABLE 0x0009 +#define MGMT_OP_SET_BONDABLE 0x0009 #define MGMT_OP_SET_LINK_SECURITY 0x000A @@ -181,6 +182,9 @@ struct mgmt_cp_load_link_keys { } __packed; #define MGMT_LOAD_LINK_KEYS_SIZE 3 +#define MGMT_LTK_UNAUTHENTICATED 0x00 +#define MGMT_LTK_AUTHENTICATED 0x01 + struct mgmt_ltk_info { struct mgmt_addr_info addr; __u8 type; @@ -409,6 +413,88 @@ struct mgmt_cp_load_irks { } __packed; #define MGMT_LOAD_IRKS_SIZE 2 +#define MGMT_OP_GET_CONN_INFO 0x0031 +struct mgmt_cp_get_conn_info { + struct mgmt_addr_info addr; +} __packed; +#define MGMT_GET_CONN_INFO_SIZE MGMT_ADDR_INFO_SIZE +struct mgmt_rp_get_conn_info { + struct mgmt_addr_info addr; + __s8 rssi; + __s8 tx_power; + __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; @@ -507,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 { @@ -563,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/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h index 2611cc389d7d..578b83127af1 100644 --- a/include/net/bluetooth/rfcomm.h +++ b/include/net/bluetooth/rfcomm.h @@ -173,7 +173,7 @@ struct rfcomm_dlc { struct sk_buff_head tx_queue; struct timer_list timer; - spinlock_t lock; + struct mutex lock; unsigned long state; unsigned long flags; atomic_t refcnt; @@ -244,8 +244,8 @@ int rfcomm_dlc_get_modem_status(struct rfcomm_dlc *d, u8 *v24_sig); void rfcomm_dlc_accept(struct rfcomm_dlc *d); struct rfcomm_dlc *rfcomm_dlc_exists(bdaddr_t *src, bdaddr_t *dst, u8 channel); -#define rfcomm_dlc_lock(d) spin_lock(&d->lock) -#define rfcomm_dlc_unlock(d) spin_unlock(&d->lock) +#define rfcomm_dlc_lock(d) mutex_lock(&d->lock) +#define rfcomm_dlc_unlock(d) mutex_unlock(&d->lock) static inline void rfcomm_dlc_hold(struct rfcomm_dlc *d) { diff --git a/include/net/bluetooth/sco.h b/include/net/bluetooth/sco.h index 2019d1a0996a..f40ddb4264fc 100644 --- a/include/net/bluetooth/sco.h +++ b/include/net/bluetooth/sco.h @@ -27,11 +27,6 @@ /* SCO defaults */ #define SCO_DEFAULT_MTU 500 -#define SCO_DEFAULT_FLUSH_TO 0xFFFF - -#define SCO_CONN_TIMEOUT (HZ * 40) -#define SCO_DISCONN_TIMEOUT (HZ * 2) -#define SCO_CONN_IDLE_TIMEOUT (HZ * 60) /* SCO socket address */ struct sockaddr_sco { @@ -51,29 +46,4 @@ struct sco_conninfo { __u8 dev_class[3]; }; -/* ---- SCO connections ---- */ -struct sco_conn { - struct hci_conn *hcon; - - spinlock_t lock; - struct sock *sk; - - unsigned int mtu; -}; - -#define sco_conn_lock(c) spin_lock(&c->lock); -#define sco_conn_unlock(c) spin_unlock(&c->lock); - -/* ----- SCO socket info ----- */ -#define sco_pi(sk) ((struct sco_pinfo *) sk) - -struct sco_pinfo { - struct bt_sock bt; - bdaddr_t src; - bdaddr_t dst; - __u32 flags; - __u16 setting; - struct sco_conn *conn; -}; - #endif /* __SCO_H */ diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index f856e5a746fa..0a080c4de275 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -109,6 +109,13 @@ enum ieee80211_band { * channel as the control or any of the secondary channels. * This may be due to the driver or due to regulatory bandwidth * restrictions. + * @IEEE80211_CHAN_INDOOR_ONLY: see %NL80211_FREQUENCY_ATTR_INDOOR_ONLY + * @IEEE80211_CHAN_GO_CONCURRENT: see %NL80211_FREQUENCY_ATTR_GO_CONCURRENT + * @IEEE80211_CHAN_NO_20MHZ: 20 MHz bandwidth is not permitted + * on this channel. + * @IEEE80211_CHAN_NO_10MHZ: 10 MHz bandwidth is not permitted + * on this channel. + * */ enum ieee80211_channel_flags { IEEE80211_CHAN_DISABLED = 1<<0, @@ -120,6 +127,10 @@ enum ieee80211_channel_flags { IEEE80211_CHAN_NO_OFDM = 1<<6, IEEE80211_CHAN_NO_80MHZ = 1<<7, IEEE80211_CHAN_NO_160MHZ = 1<<8, + IEEE80211_CHAN_INDOOR_ONLY = 1<<9, + IEEE80211_CHAN_GO_CONCURRENT = 1<<10, + IEEE80211_CHAN_NO_20MHZ = 1<<11, + IEEE80211_CHAN_NO_10MHZ = 1<<12, }; #define IEEE80211_CHAN_NO_HT40 \ @@ -330,8 +341,8 @@ struct vif_params { * @seq_len: length of @seq. */ struct key_params { - u8 *key; - u8 *seq; + const u8 *key; + const u8 *seq; int key_len; int seq_len; u32 cipher; @@ -441,10 +452,13 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy, * cfg80211_chandef_dfs_required - checks if radar detection is required * @wiphy: the wiphy to validate against * @chandef: the channel definition to check - * Return: 1 if radar detection is required, 0 if it is not, < 0 on error + * @iftype: the interface type as specified in &enum nl80211_iftype + * Returns: + * 1 if radar detection is required, 0 if it is not, < 0 on error */ int cfg80211_chandef_dfs_required(struct wiphy *wiphy, - const struct cfg80211_chan_def *chandef); + const struct cfg80211_chan_def *chandef, + enum nl80211_iftype iftype); /** * ieee80211_chandef_rate_flags - returns rate flags for a channel @@ -654,7 +668,6 @@ struct cfg80211_acl_data { * @p2p_opp_ps: P2P opportunistic PS * @acl: ACL configuration used by the drivers which has support for * MAC address based access control - * @radar_required: set if radar detection is required */ struct cfg80211_ap_settings { struct cfg80211_chan_def chandef; @@ -672,7 +685,6 @@ struct cfg80211_ap_settings { u8 p2p_ctwindow; bool p2p_opp_ps; const struct cfg80211_acl_data *acl; - bool radar_required; }; /** @@ -682,8 +694,10 @@ struct cfg80211_ap_settings { * * @chandef: defines the channel to use after the switch * @beacon_csa: beacon data while performing the switch - * @counter_offset_beacon: offset for the counter within the beacon (tail) - * @counter_offset_presp: offset for the counter within the probe response + * @counter_offsets_beacon: offsets of the counters within the beacon (tail) + * @counter_offsets_presp: offsets of the counters within the probe response + * @n_counter_offsets_beacon: number of csa counters the beacon (tail) + * @n_counter_offsets_presp: number of csa counters in the probe response * @beacon_after: beacon data to be used on the new channel * @radar_required: whether radar detection is required on the new channel * @block_tx: whether transmissions should be blocked while changing @@ -692,7 +706,10 @@ struct cfg80211_ap_settings { struct cfg80211_csa_settings { struct cfg80211_chan_def chandef; struct cfg80211_beacon_data beacon_csa; - u16 counter_offset_beacon, counter_offset_presp; + const u16 *counter_offsets_beacon; + const u16 *counter_offsets_presp; + unsigned int n_counter_offsets_beacon; + unsigned int n_counter_offsets_presp; struct cfg80211_beacon_data beacon_after; bool radar_required; bool block_tx; @@ -856,36 +873,38 @@ int cfg80211_check_station_change(struct wiphy *wiphy, * @STATION_INFO_NONPEER_PM: @nonpeer_pm filled * @STATION_INFO_CHAIN_SIGNAL: @chain_signal filled * @STATION_INFO_CHAIN_SIGNAL_AVG: @chain_signal_avg filled + * @STATION_INFO_EXPECTED_THROUGHPUT: @expected_throughput filled */ enum station_info_flags { - STATION_INFO_INACTIVE_TIME = 1<<0, - STATION_INFO_RX_BYTES = 1<<1, - STATION_INFO_TX_BYTES = 1<<2, - STATION_INFO_LLID = 1<<3, - STATION_INFO_PLID = 1<<4, - STATION_INFO_PLINK_STATE = 1<<5, - STATION_INFO_SIGNAL = 1<<6, - STATION_INFO_TX_BITRATE = 1<<7, - STATION_INFO_RX_PACKETS = 1<<8, - STATION_INFO_TX_PACKETS = 1<<9, - STATION_INFO_TX_RETRIES = 1<<10, - STATION_INFO_TX_FAILED = 1<<11, - STATION_INFO_RX_DROP_MISC = 1<<12, - STATION_INFO_SIGNAL_AVG = 1<<13, - STATION_INFO_RX_BITRATE = 1<<14, - STATION_INFO_BSS_PARAM = 1<<15, - STATION_INFO_CONNECTED_TIME = 1<<16, - STATION_INFO_ASSOC_REQ_IES = 1<<17, - STATION_INFO_STA_FLAGS = 1<<18, - STATION_INFO_BEACON_LOSS_COUNT = 1<<19, - STATION_INFO_T_OFFSET = 1<<20, - STATION_INFO_LOCAL_PM = 1<<21, - STATION_INFO_PEER_PM = 1<<22, - STATION_INFO_NONPEER_PM = 1<<23, - STATION_INFO_RX_BYTES64 = 1<<24, - STATION_INFO_TX_BYTES64 = 1<<25, - STATION_INFO_CHAIN_SIGNAL = 1<<26, - STATION_INFO_CHAIN_SIGNAL_AVG = 1<<27, + STATION_INFO_INACTIVE_TIME = BIT(0), + STATION_INFO_RX_BYTES = BIT(1), + STATION_INFO_TX_BYTES = BIT(2), + STATION_INFO_LLID = BIT(3), + STATION_INFO_PLID = BIT(4), + STATION_INFO_PLINK_STATE = BIT(5), + STATION_INFO_SIGNAL = BIT(6), + STATION_INFO_TX_BITRATE = BIT(7), + STATION_INFO_RX_PACKETS = BIT(8), + STATION_INFO_TX_PACKETS = BIT(9), + STATION_INFO_TX_RETRIES = BIT(10), + STATION_INFO_TX_FAILED = BIT(11), + STATION_INFO_RX_DROP_MISC = BIT(12), + STATION_INFO_SIGNAL_AVG = BIT(13), + STATION_INFO_RX_BITRATE = BIT(14), + STATION_INFO_BSS_PARAM = BIT(15), + STATION_INFO_CONNECTED_TIME = BIT(16), + STATION_INFO_ASSOC_REQ_IES = BIT(17), + STATION_INFO_STA_FLAGS = BIT(18), + STATION_INFO_BEACON_LOSS_COUNT = BIT(19), + STATION_INFO_T_OFFSET = BIT(20), + STATION_INFO_LOCAL_PM = BIT(21), + STATION_INFO_PEER_PM = BIT(22), + STATION_INFO_NONPEER_PM = BIT(23), + STATION_INFO_RX_BYTES64 = BIT(24), + STATION_INFO_TX_BYTES64 = BIT(25), + STATION_INFO_CHAIN_SIGNAL = BIT(26), + STATION_INFO_CHAIN_SIGNAL_AVG = BIT(27), + STATION_INFO_EXPECTED_THROUGHPUT = BIT(28), }; /** @@ -1007,6 +1026,8 @@ struct sta_bss_parameters { * @local_pm: local mesh STA power save mode * @peer_pm: peer mesh STA power save mode * @nonpeer_pm: non-peer mesh STA power save mode + * @expected_throughput: expected throughput in kbps (including 802.11 headers) + * towards this station. */ struct station_info { u32 filled; @@ -1045,6 +1066,8 @@ struct station_info { enum nl80211_mesh_power_mode peer_pm; enum nl80211_mesh_power_mode nonpeer_pm; + u32 expected_throughput; + /* * Note: Add a new enum station_info_flags value for each new field and * use it to check which fields are initialized. @@ -1052,6 +1075,19 @@ struct station_info { }; /** + * cfg80211_get_station - retrieve information about a given station + * @dev: the device where the station is supposed to be connected to + * @mac_addr: the mac address of the station of interest + * @sinfo: pointer to the structure to fill with the information + * + * Returns 0 on success and sinfo is filled with the available information + * otherwise returns a negative error code and the content of sinfo has to be + * considered undefined. + */ +int cfg80211_get_station(struct net_device *dev, const u8 *mac_addr, + struct station_info *sinfo); + +/** * enum monitor_flags - monitor flags * * Monitor interface configuration flags. Note that these must be the bits @@ -1152,7 +1188,7 @@ struct bss_parameters { int use_cts_prot; int use_short_preamble; int use_short_slot_time; - u8 *basic_rates; + const u8 *basic_rates; u8 basic_rates_len; int ap_isolate; int ht_opmode; @@ -1682,10 +1718,10 @@ struct cfg80211_disassoc_request { * @ht_capa_mask: The bits of ht_capa which are to be used. */ struct cfg80211_ibss_params { - u8 *ssid; - u8 *bssid; + const u8 *ssid; + const u8 *bssid; struct cfg80211_chan_def chandef; - u8 *ie; + const u8 *ie; u8 ssid_len, ie_len; u16 beacon_interval; u32 basic_rates; @@ -1794,8 +1830,8 @@ struct cfg80211_bitrate_mask { * @pmkid: The PMK material itself. */ struct cfg80211_pmksa { - u8 *bssid; - u8 *pmkid; + const u8 *bssid; + const u8 *pmkid; }; /** @@ -1810,7 +1846,7 @@ struct cfg80211_pmksa { * memory, free @mask only! */ struct cfg80211_pkt_pattern { - u8 *mask, *pattern; + const u8 *mask, *pattern; int pattern_len; int pkt_offset; }; @@ -1974,6 +2010,8 @@ struct cfg80211_update_ft_ies_params { * @len: buffer length * @no_cck: don't use cck rates for this frame * @dont_wait_for_ack: tells the low level not to wait for an ack + * @n_csa_offsets: length of csa_offsets array + * @csa_offsets: array of all the csa offsets in the frame */ struct cfg80211_mgmt_tx_params { struct ieee80211_channel *chan; @@ -1983,6 +2021,8 @@ struct cfg80211_mgmt_tx_params { size_t len; bool no_cck; bool dont_wait_for_ack; + int n_csa_offsets; + const u16 *csa_offsets; }; /** @@ -2226,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). * @@ -2238,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. @@ -2275,9 +2301,18 @@ 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 + * + * @set_ap_chanwidth: Set the AP (including P2P GO) mode channel width for the + * given interface This is used e.g. for dynamic HT 20/40 MHz channel width + * changes during the lifetime of the BSS. */ struct cfg80211_ops { int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow); @@ -2320,28 +2355,29 @@ struct cfg80211_ops { int (*add_station)(struct wiphy *wiphy, struct net_device *dev, - u8 *mac, struct station_parameters *params); + const u8 *mac, + struct station_parameters *params); int (*del_station)(struct wiphy *wiphy, struct net_device *dev, - u8 *mac); + const u8 *mac); int (*change_station)(struct wiphy *wiphy, struct net_device *dev, - u8 *mac, struct station_parameters *params); + const u8 *mac, + struct station_parameters *params); int (*get_station)(struct wiphy *wiphy, struct net_device *dev, - u8 *mac, struct station_info *sinfo); + const u8 *mac, struct station_info *sinfo); int (*dump_station)(struct wiphy *wiphy, struct net_device *dev, - int idx, u8 *mac, struct station_info *sinfo); + int idx, u8 *mac, struct station_info *sinfo); int (*add_mpath)(struct wiphy *wiphy, struct net_device *dev, - u8 *dst, u8 *next_hop); + const u8 *dst, const u8 *next_hop); int (*del_mpath)(struct wiphy *wiphy, struct net_device *dev, - u8 *dst); + const u8 *dst); int (*change_mpath)(struct wiphy *wiphy, struct net_device *dev, - u8 *dst, u8 *next_hop); + const u8 *dst, const u8 *next_hop); int (*get_mpath)(struct wiphy *wiphy, struct net_device *dev, - u8 *dst, u8 *next_hop, - struct mpath_info *pinfo); + u8 *dst, u8 *next_hop, struct mpath_info *pinfo); int (*dump_mpath)(struct wiphy *wiphy, struct net_device *dev, - int idx, u8 *dst, u8 *next_hop, - struct mpath_info *pinfo); + int idx, u8 *dst, u8 *next_hop, + struct mpath_info *pinfo); int (*get_mesh_config)(struct wiphy *wiphy, struct net_device *dev, struct mesh_config *conf); @@ -2458,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); @@ -2471,11 +2503,11 @@ struct cfg80211_ops { struct cfg80211_gtk_rekey_data *data); int (*tdls_mgmt)(struct wiphy *wiphy, struct net_device *dev, - u8 *peer, u8 action_code, u8 dialog_token, + 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, - u8 *peer, enum nl80211_tdls_operation oper); + const u8 *peer, enum nl80211_tdls_operation oper); int (*probe_client)(struct wiphy *wiphy, struct net_device *dev, const u8 *peer, u64 *cookie); @@ -2484,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); @@ -2521,9 +2546,13 @@ struct cfg80211_ops { int (*channel_switch)(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_csa_settings *params); + int (*set_qos_map)(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_qos_map *qos_map); + + int (*set_ap_chanwidth)(struct wiphy *wiphy, struct net_device *dev, + struct cfg80211_chan_def *chandef); }; /* @@ -2618,6 +2647,7 @@ struct ieee80211_iface_limit { * between infrastructure and AP types must match. This is required * only in special cases. * @radar_detect_widths: bitmap of channel widths supported for radar detection + * @radar_detect_regions: bitmap of regions supported for radar detection * * With this structure the driver can describe which interface * combinations it supports concurrently. @@ -2675,6 +2705,7 @@ struct ieee80211_iface_combination { u8 n_limits; bool beacon_int_infra_match; u8 radar_detect_widths; + u8 radar_detect_regions; }; struct ieee80211_txrx_stypes { @@ -2905,6 +2936,17 @@ struct wiphy_vendor_command { * (including P2P GO) or 0 to indicate no such limit is advertised. The * driver is allowed to advertise a theoretical limit that it can reach in * some cases, but may not always reach. + * + * @max_num_csa_counters: Number of supported csa_counters in beacons + * and probe responses. This value should be set if the driver + * wishes to limit the number of csa counters. Default (0) means + * infinite. + * @max_adj_channel_rssi_comp: max offset of between the channel on which the + * frame was sent and the channel on which the frame was heard for which + * the reported rssi is still valid. If a driver is able to compensate the + * low rssi when a frame is heard on different channel, then it should set + * this variable to the maximal offset for which it can compensate. + * This value should be set in MHz. */ struct wiphy { /* assign these fields before you register the wiphy */ @@ -3022,6 +3064,9 @@ struct wiphy { u16 max_ap_assoc_sta; + u8 max_num_csa_counters; + u8 max_adj_channel_rssi_comp; + char priv[0] __aligned(NETDEV_ALIGN); }; @@ -3194,6 +3239,7 @@ struct cfg80211_cached_keys; * @ibss_dfs_possible: (private) IBSS may change to a DFS channel * @event_list: (private) list for internal event processing * @event_lock: (private) lock for event list + * @owner_nlportid: (private) owner socket port ID */ struct wireless_dev { struct wiphy *wiphy; @@ -3241,13 +3287,15 @@ struct wireless_dev { unsigned long cac_start_time; unsigned int cac_time_ms; + u32 owner_nlportid; + #ifdef CONFIG_CFG80211_WEXT /* wext data */ struct { struct cfg80211_ibss_params ibss; struct cfg80211_connect_params connect; struct cfg80211_cached_keys *keys; - u8 *ie; + const u8 *ie; size_t ie_len; u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; u8 ssid[IEEE80211_MAX_SSID_LEN]; @@ -3488,7 +3536,8 @@ int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr, * Return: 0 on success, or a negative error code. */ int ieee80211_data_from_8023(struct sk_buff *skb, const u8 *addr, - enum nl80211_iftype iftype, u8 *bssid, bool qos); + enum nl80211_iftype iftype, const u8 *bssid, + bool qos); /** * ieee80211_amsdu_to_8023s - decode an IEEE 802.11n A-MSDU frame @@ -3600,7 +3649,7 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2); * default channel settings will be disregarded. If no rule is found for a * channel on the regulatory domain the channel will be disabled. * Drivers using this for a wiphy should also set the wiphy flag - * WIPHY_FLAG_CUSTOM_REGULATORY or cfg80211 will set it for the wiphy + * REGULATORY_CUSTOM_REG or cfg80211 will set it for the wiphy * that called this helper. */ void wiphy_apply_custom_regulatory(struct wiphy *wiphy, @@ -4289,7 +4338,7 @@ void cfg80211_roamed_bss(struct net_device *dev, struct cfg80211_bss *bss, * and not try to connect to any AP any more. */ void cfg80211_disconnected(struct net_device *dev, u16 reason, - u8 *ie, size_t ie_len, gfp_t gfp); + const u8 *ie, size_t ie_len, gfp_t gfp); /** * cfg80211_ready_on_channel - notification of remain_on_channel start @@ -4543,12 +4592,14 @@ void cfg80211_report_obss_beacon(struct wiphy *wiphy, * cfg80211_reg_can_beacon - check if beaconing is allowed * @wiphy: the wiphy * @chandef: the channel definition + * @iftype: interface type * * Return: %true if there is no secondary channel or the secondary channel(s) * can be used for beaconing (i.e. is not a radar channel etc.) */ bool cfg80211_reg_can_beacon(struct wiphy *wiphy, - struct cfg80211_chan_def *chandef); + struct cfg80211_chan_def *chandef, + enum nl80211_iftype iftype); /* * cfg80211_ch_switch_notify - update wdev channel and notify userspace @@ -4694,6 +4745,88 @@ void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp); */ unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy); +/** + * cfg80211_check_combinations - check interface combinations + * + * @wiphy: the wiphy + * @num_different_channels: the number of different channels we want + * to use for verification + * @radar_detect: a bitmap where each bit corresponds to a channel + * width where radar detection is needed, as in the definition of + * &struct ieee80211_iface_combination.@radar_detect_widths + * @iftype_num: array with the numbers of interfaces of each interface + * type. The index is the interface type as specified in &enum + * nl80211_iftype. + * + * This function can be called by the driver to check whether a + * combination of interfaces and their types are allowed according to + * the interface combinations. + */ +int cfg80211_check_combinations(struct wiphy *wiphy, + const int num_different_channels, + const u8 radar_detect, + const int iftype_num[NUM_NL80211_IFTYPES]); + +/** + * cfg80211_iter_combinations - iterate over matching combinations + * + * @wiphy: the wiphy + * @num_different_channels: the number of different channels we want + * to use for verification + * @radar_detect: a bitmap where each bit corresponds to a channel + * width where radar detection is needed, as in the definition of + * &struct ieee80211_iface_combination.@radar_detect_widths + * @iftype_num: array with the numbers of interfaces of each interface + * type. The index is the interface type as specified in &enum + * nl80211_iftype. + * @iter: function to call for each matching combination + * @data: pointer to pass to iter function + * + * This function can be called by the driver to check what possible + * combinations it fits in at a given moment, e.g. for channel switching + * purposes. + */ +int cfg80211_iter_combinations(struct wiphy *wiphy, + const int num_different_channels, + const u8 radar_detect, + const int iftype_num[NUM_NL80211_IFTYPES], + void (*iter)(const struct ieee80211_iface_combination *c, + void *data), + void *data); + +/* + * cfg80211_stop_iface - trigger interface disconnection + * + * @wiphy: the wiphy + * @wdev: wireless device + * @gfp: context flags + * + * Trigger interface to be stopped as if AP was stopped, IBSS/mesh left, STA + * disconnected. + * + * Note: This doesn't need any locks and is asynchronous. + */ +void cfg80211_stop_iface(struct wiphy *wiphy, struct wireless_dev *wdev, + gfp_t gfp); + +/** + * cfg80211_shutdown_all_interfaces - shut down all interfaces for a wiphy + * @wiphy: the wiphy to shut down + * + * This function shuts down all interfaces belonging to this wiphy by + * calling dev_close() (and treating non-netdev interfaces as needed). + * It shouldn't really be used unless there are some fatal device errors + * that really can't be recovered in any other way. + * + * Callers must hold the RTNL and be able to deal with callbacks into + * the driver while the function is running. + */ +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/checksum.h b/include/net/checksum.h index a28f4e0f6251..87cb1903640d 100644 --- a/include/net/checksum.h +++ b/include/net/checksum.h @@ -57,12 +57,14 @@ static __inline__ __wsum csum_and_copy_to_user } #endif +#ifndef HAVE_ARCH_CSUM_ADD static inline __wsum csum_add(__wsum csum, __wsum addend) { u32 res = (__force u32)csum; res += (__force u32)addend; return (__force __wsum)(res + (res < (__force u32)addend)); } +#endif static inline __wsum csum_sub(__wsum csum, __wsum addend) { diff --git a/include/net/dcbnl.h b/include/net/dcbnl.h index a975edf21b22..597b88a94332 100644 --- a/include/net/dcbnl.h +++ b/include/net/dcbnl.h @@ -81,8 +81,8 @@ struct dcbnl_rtnl_ops { void (*setbcncfg)(struct net_device *, int, u32); void (*getbcnrp)(struct net_device *, int, u8 *); void (*setbcnrp)(struct net_device *, int, u8); - u8 (*setapp)(struct net_device *, u8, u16, u8); - u8 (*getapp)(struct net_device *, u8, u16); + int (*setapp)(struct net_device *, u8, u16, u8); + int (*getapp)(struct net_device *, u8, u16); u8 (*getfeatcfg)(struct net_device *, int, u8 *); u8 (*setfeatcfg)(struct net_device *, int, u8); diff --git a/include/net/dsa.h b/include/net/dsa.h index 7828ebf99ee1..6efce384451e 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -181,6 +181,11 @@ struct dsa_switch_driver { void register_switch_driver(struct dsa_switch_driver *type); void unregister_switch_driver(struct dsa_switch_driver *type); +static inline void *ds_to_priv(struct dsa_switch *ds) +{ + return (void *)(ds + 1); +} + /* * The original DSA tag format and some other tag formats have no * ethertype, which means that we need to add a little hack to the diff --git a/include/net/flow_keys.h b/include/net/flow_keys.h index 7e64bd8bbda9..6667a054763a 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/gre.h b/include/net/gre.h index 70046a0b0b89..b53182018743 100644 --- a/include/net/gre.h +++ b/include/net/gre.h @@ -37,9 +37,10 @@ void gre_build_header(struct sk_buff *skb, const struct tnl_ptk_info *tpi, int hdr_len); static inline struct sk_buff *gre_handle_offloads(struct sk_buff *skb, - bool gre_csum) + bool csum) { - return iptunnel_handle_offloads(skb, gre_csum, SKB_GSO_GRE); + return iptunnel_handle_offloads(skb, csum, + csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE); } diff --git a/include/net/ieee802154.h b/include/net/ieee802154.h index c7ae0ac528dc..0aa7122e8f15 100644 --- a/include/net/ieee802154.h +++ b/include/net/ieee802154.h @@ -79,6 +79,15 @@ #define IEEE802154_SCF_KEY_SHORT_INDEX 2 #define IEEE802154_SCF_KEY_HW_INDEX 3 +#define IEEE802154_SCF_SECLEVEL_NONE 0 +#define IEEE802154_SCF_SECLEVEL_MIC32 1 +#define IEEE802154_SCF_SECLEVEL_MIC64 2 +#define IEEE802154_SCF_SECLEVEL_MIC128 3 +#define IEEE802154_SCF_SECLEVEL_ENC 4 +#define IEEE802154_SCF_SECLEVEL_ENC_MIC32 5 +#define IEEE802154_SCF_SECLEVEL_ENC_MIC64 6 +#define IEEE802154_SCF_SECLEVEL_ENC_MIC128 7 + /* MAC footer size */ #define IEEE802154_MFR_SIZE 2 /* 2 octets */ diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index 5a719ca892f4..3b53c8e405e4 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h @@ -27,6 +27,7 @@ #ifndef IEEE802154_NETDEVICE_H #define IEEE802154_NETDEVICE_H +#include <net/ieee802154.h> #include <net/af_ieee802154.h> #include <linux/netdevice.h> #include <linux/skbuff.h> @@ -114,6 +115,34 @@ int ieee802154_hdr_pull(struct sk_buff *skb, struct ieee802154_hdr *hdr); int ieee802154_hdr_peek_addrs(const struct sk_buff *skb, struct ieee802154_hdr *hdr); +/* parses the full 802.15.4 header a given skb and stores them into hdr, + * performing pan id decompression and length checks to be suitable for use in + * header_ops.parse + */ +int ieee802154_hdr_peek(const struct sk_buff *skb, struct ieee802154_hdr *hdr); + +int ieee802154_max_payload(const struct ieee802154_hdr *hdr); + +static inline int +ieee802154_sechdr_authtag_len(const struct ieee802154_sechdr *sec) +{ + switch (sec->level) { + case IEEE802154_SCF_SECLEVEL_MIC32: + case IEEE802154_SCF_SECLEVEL_ENC_MIC32: + return 4; + case IEEE802154_SCF_SECLEVEL_MIC64: + case IEEE802154_SCF_SECLEVEL_ENC_MIC64: + return 8; + case IEEE802154_SCF_SECLEVEL_MIC128: + case IEEE802154_SCF_SECLEVEL_ENC_MIC128: + return 16; + case IEEE802154_SCF_SECLEVEL_NONE: + case IEEE802154_SCF_SECLEVEL_ENC: + default: + return 0; + } +} + static inline int ieee802154_hdr_length(struct sk_buff *skb) { struct ieee802154_hdr hdr; @@ -193,8 +222,12 @@ static inline void ieee802154_addr_to_sa(struct ieee802154_addr_sa *sa, */ struct ieee802154_mac_cb { u8 lqi; - u8 flags; - u8 seq; + u8 type; + bool ackreq; + bool secen; + bool secen_override; + u8 seclevel; + bool seclevel_override; struct ieee802154_addr source; struct ieee802154_addr dest; }; @@ -204,25 +237,96 @@ static inline struct ieee802154_mac_cb *mac_cb(struct sk_buff *skb) return (struct ieee802154_mac_cb *)skb->cb; } -#define MAC_CB_FLAG_TYPEMASK ((1 << 3) - 1) - -#define MAC_CB_FLAG_ACKREQ (1 << 3) -#define MAC_CB_FLAG_SECEN (1 << 4) - -static inline bool mac_cb_is_ackreq(struct sk_buff *skb) +static inline struct ieee802154_mac_cb *mac_cb_init(struct sk_buff *skb) { - return mac_cb(skb)->flags & MAC_CB_FLAG_ACKREQ; -} + BUILD_BUG_ON(sizeof(struct ieee802154_mac_cb) > sizeof(skb->cb)); -static inline bool mac_cb_is_secen(struct sk_buff *skb) -{ - return mac_cb(skb)->flags & MAC_CB_FLAG_SECEN; + memset(skb->cb, 0, sizeof(struct ieee802154_mac_cb)); + return mac_cb(skb); } -static inline int mac_cb_type(struct sk_buff *skb) -{ - return mac_cb(skb)->flags & MAC_CB_FLAG_TYPEMASK; -} +#define IEEE802154_LLSEC_KEY_SIZE 16 + +struct ieee802154_llsec_key_id { + u8 mode; + u8 id; + union { + struct ieee802154_addr device_addr; + __le32 short_source; + __le64 extended_source; + }; +}; + +struct ieee802154_llsec_key { + u8 frame_types; + u32 cmd_frame_ids; + u8 key[IEEE802154_LLSEC_KEY_SIZE]; +}; + +struct ieee802154_llsec_key_entry { + struct list_head list; + + struct ieee802154_llsec_key_id id; + struct ieee802154_llsec_key *key; +}; + +struct ieee802154_llsec_device_key { + struct list_head list; + + struct ieee802154_llsec_key_id key_id; + u32 frame_counter; +}; + +enum { + IEEE802154_LLSEC_DEVKEY_IGNORE, + IEEE802154_LLSEC_DEVKEY_RESTRICT, + IEEE802154_LLSEC_DEVKEY_RECORD, + + __IEEE802154_LLSEC_DEVKEY_MAX, +}; + +struct ieee802154_llsec_device { + struct list_head list; + + __le16 pan_id; + __le16 short_addr; + __le64 hwaddr; + u32 frame_counter; + bool seclevel_exempt; + + u8 key_mode; + struct list_head keys; +}; + +struct ieee802154_llsec_seclevel { + struct list_head list; + + u8 frame_type; + u8 cmd_frame_id; + bool device_override; + u32 sec_levels; +}; + +struct ieee802154_llsec_params { + bool enabled; + + __be32 frame_counter; + u8 out_level; + struct ieee802154_llsec_key_id out_key; + + __le64 default_key_source; + + __le16 pan_id; + __le64 hwaddr; + __le64 coord_hwaddr; + __le16 coord_shortaddr; +}; + +struct ieee802154_llsec_table { + struct list_head keys; + struct list_head devices; + struct list_head security_levels; +}; #define IEEE802154_MAC_SCAN_ED 0 #define IEEE802154_MAC_SCAN_ACTIVE 1 @@ -242,6 +346,53 @@ struct ieee802154_mac_params { }; struct wpan_phy; + +enum { + IEEE802154_LLSEC_PARAM_ENABLED = 1 << 0, + IEEE802154_LLSEC_PARAM_FRAME_COUNTER = 1 << 1, + IEEE802154_LLSEC_PARAM_OUT_LEVEL = 1 << 2, + IEEE802154_LLSEC_PARAM_OUT_KEY = 1 << 3, + IEEE802154_LLSEC_PARAM_KEY_SOURCE = 1 << 4, + IEEE802154_LLSEC_PARAM_PAN_ID = 1 << 5, + IEEE802154_LLSEC_PARAM_HWADDR = 1 << 6, + IEEE802154_LLSEC_PARAM_COORD_HWADDR = 1 << 7, + IEEE802154_LLSEC_PARAM_COORD_SHORTADDR = 1 << 8, +}; + +struct ieee802154_llsec_ops { + int (*get_params)(struct net_device *dev, + struct ieee802154_llsec_params *params); + int (*set_params)(struct net_device *dev, + const struct ieee802154_llsec_params *params, + int changed); + + int (*add_key)(struct net_device *dev, + const struct ieee802154_llsec_key_id *id, + const struct ieee802154_llsec_key *key); + int (*del_key)(struct net_device *dev, + const struct ieee802154_llsec_key_id *id); + + int (*add_dev)(struct net_device *dev, + const struct ieee802154_llsec_device *llsec_dev); + int (*del_dev)(struct net_device *dev, __le64 dev_addr); + + int (*add_devkey)(struct net_device *dev, + __le64 device_addr, + const struct ieee802154_llsec_device_key *key); + int (*del_devkey)(struct net_device *dev, + __le64 device_addr, + const struct ieee802154_llsec_device_key *key); + + int (*add_seclevel)(struct net_device *dev, + const struct ieee802154_llsec_seclevel *sl); + int (*del_seclevel)(struct net_device *dev, + const struct ieee802154_llsec_seclevel *sl); + + void (*lock_table)(struct net_device *dev); + void (*get_table)(struct net_device *dev, + struct ieee802154_llsec_table **t); + void (*unlock_table)(struct net_device *dev); +}; /* * This should be located at net_device->ml_priv * @@ -272,6 +423,8 @@ struct ieee802154_mlme_ops { void (*get_mac_params)(struct net_device *dev, struct ieee802154_mac_params *params); + struct ieee802154_llsec_ops *llsec; + /* The fields below are required. */ struct wpan_phy *(*get_phy)(const struct net_device *dev); diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index b4956a5fcc3f..d07b1a64b4e7 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_ecn.h b/include/net/inet_ecn.h index 3bd22795c3e2..84b20835b736 100644 --- a/include/net/inet_ecn.h +++ b/include/net/inet_ecn.h @@ -150,7 +150,7 @@ static inline int INET_ECN_set_ce(struct sk_buff *skb) } /* - * RFC 6080 4.2 + * RFC 6040 4.2 * To decapsulate the inner header at the tunnel egress, a compliant * tunnel egress MUST set the outgoing ECN field to the codepoint at the * intersection of the appropriate arriving inner header (row) and outer diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h index 6f59de98dabd..65a8855e99fe 100644 --- a/include/net/inet_frag.h +++ b/include/net/inet_frag.h @@ -4,10 +4,6 @@ #include <linux/percpu_counter.h> struct netns_frags { - int nqueues; - struct list_head lru_list; - spinlock_t lru_lock; - /* The percpu_counter "mem" need to be cacheline aligned. * mem.count must not share cacheline with other writers */ @@ -19,25 +15,49 @@ struct netns_frags { int low_thresh; }; +/** + * fragment queue flags + * + * @INET_FRAG_FIRST_IN: first fragment has arrived + * @INET_FRAG_LAST_IN: final fragment has arrived + * @INET_FRAG_COMPLETE: frag queue has been processed and is due for destruction + * @INET_FRAG_EVICTED: frag queue is being evicted + */ +enum { + INET_FRAG_FIRST_IN = BIT(0), + INET_FRAG_LAST_IN = BIT(1), + INET_FRAG_COMPLETE = BIT(2), + INET_FRAG_EVICTED = BIT(3) +}; + +/** + * struct inet_frag_queue - fragment queue + * + * @lock: spinlock protecting the queue + * @timer: queue expiration timer + * @list: hash bucket list + * @refcnt: reference count of the queue + * @fragments: received fragments head + * @fragments_tail: received fragments tail + * @stamp: timestamp of the last received fragment + * @len: total length of the original datagram + * @meat: length of received fragments so far + * @flags: fragment queue flags + * @max_size: (ipv4 only) maximum received fragment size with IP_DF set + * @net: namespace that this frag belongs to + */ struct inet_frag_queue { spinlock_t lock; - struct timer_list timer; /* when will this queue expire? */ - struct list_head lru_list; /* lru list member */ + struct timer_list timer; struct hlist_node list; atomic_t refcnt; - struct sk_buff *fragments; /* list of received fragments */ + struct sk_buff *fragments; struct sk_buff *fragments_tail; ktime_t stamp; - int len; /* total length of orig datagram */ + int len; int meat; - __u8 last_in; /* first/last segment arrived? */ - -#define INET_FRAG_COMPLETE 4 -#define INET_FRAG_FIRST_IN 2 -#define INET_FRAG_LAST_IN 1 - + __u8 flags; u16 max_size; - struct netns_frags *net; }; @@ -48,7 +68,7 @@ struct inet_frag_queue { * rounded up (SKB_TRUELEN(0) + sizeof(struct ipq or * struct frag_queue)) */ -#define INETFRAGS_MAXDEPTH 128 +#define INETFRAGS_MAXDEPTH 128 struct inet_frag_bucket { struct hlist_head chain; @@ -57,49 +77,52 @@ struct inet_frag_bucket { struct inet_frags { struct inet_frag_bucket hash[INETFRAGS_HASHSZ]; - /* This rwlock is a global lock (seperate per IPv4, IPv6 and - * netfilter). Important to keep this on a seperate cacheline. - * Its primarily a rebuild protection rwlock. - */ - rwlock_t lock ____cacheline_aligned_in_smp; - int secret_interval; - struct timer_list secret_timer; + + struct work_struct frags_work; + unsigned int next_bucket; + unsigned long last_rebuild_jiffies; + bool rebuild; /* The first call to hashfn is responsible to initialize * rnd. This is best done with net_get_random_once. + * + * rnd_seqlock is used to let hash insertion detect + * when it needs to re-lookup the hash chain to use. */ u32 rnd; + seqlock_t rnd_seqlock; int qsize; - unsigned int (*hashfn)(struct inet_frag_queue *); - bool (*match)(struct inet_frag_queue *q, void *arg); + unsigned int (*hashfn)(const struct inet_frag_queue *); + bool (*match)(const struct inet_frag_queue *q, + const void *arg); void (*constructor)(struct inet_frag_queue *q, - void *arg); + const void *arg); void (*destructor)(struct inet_frag_queue *); void (*skb_free)(struct sk_buff *); void (*frag_expire)(unsigned long data); + struct kmem_cache *frags_cachep; + const char *frags_cache_name; }; -void inet_frags_init(struct inet_frags *); +int inet_frags_init(struct inet_frags *); void inet_frags_fini(struct inet_frags *); void inet_frags_init_net(struct netns_frags *nf); void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f); void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f); -void inet_frag_destroy(struct inet_frag_queue *q, - struct inet_frags *f, int *work); -int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f, bool force); +void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f); struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, - struct inet_frags *f, void *key, unsigned int hash) - __releases(&f->lock); + struct inet_frags *f, void *key, unsigned int hash); + void inet_frag_maybe_warn_overflow(struct inet_frag_queue *q, const char *prefix); static inline void inet_frag_put(struct inet_frag_queue *q, struct inet_frags *f) { if (atomic_dec_and_test(&q->refcnt)) - inet_frag_destroy(q, f, NULL); + inet_frag_destroy(q, f); } /* Memory Tracking Functions. */ @@ -131,9 +154,9 @@ static inline void init_frag_mem_limit(struct netns_frags *nf) percpu_counter_init(&nf->mem, 0); } -static inline int sum_frag_mem_limit(struct netns_frags *nf) +static inline unsigned int sum_frag_mem_limit(struct netns_frags *nf) { - int res; + unsigned int res; local_bh_disable(); res = percpu_counter_sum_positive(&nf->mem); @@ -142,31 +165,6 @@ static inline int sum_frag_mem_limit(struct netns_frags *nf) return res; } -static inline void inet_frag_lru_move(struct inet_frag_queue *q) -{ - spin_lock(&q->net->lru_lock); - if (!list_empty(&q->lru_list)) - list_move_tail(&q->lru_list, &q->net->lru_list); - spin_unlock(&q->net->lru_lock); -} - -static inline void inet_frag_lru_del(struct inet_frag_queue *q) -{ - spin_lock(&q->net->lru_lock); - list_del_init(&q->lru_list); - q->net->nqueues--; - spin_unlock(&q->net->lru_lock); -} - -static inline void inet_frag_lru_add(struct netns_frags *nf, - struct inet_frag_queue *q) -{ - spin_lock(&nf->lru_lock); - list_add_tail(&q->lru_list, &nf->lru_list); - q->net->nqueues++; - spin_unlock(&nf->lru_lock); -} - /* RFC 3168 support : * We want to check ECN values of all fragments, do detect invalid combinations. * In ipq->ecn, we store the OR value of each ip4_frag_ecn() fragment value. diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index 1bdb47715def..dd1950a7e273 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -292,12 +292,12 @@ static inline struct sock *inet_lookup_listener(struct net *net, #define INET_ADDR_COOKIE(__name, __saddr, __daddr) \ const __addrpair __name = (__force __addrpair) ( \ (((__force __u64)(__be32)(__saddr)) << 32) | \ - ((__force __u64)(__be32)(__daddr))); + ((__force __u64)(__be32)(__daddr))) #else /* __LITTLE_ENDIAN */ #define INET_ADDR_COOKIE(__name, __saddr, __daddr) \ const __addrpair __name = (__force __addrpair) ( \ (((__force __u64)(__be32)(__daddr)) << 32) | \ - ((__force __u64)(__be32)(__saddr))); + ((__force __u64)(__be32)(__saddr))) #endif /* __BIG_ENDIAN */ #define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif) \ (((__sk)->sk_portpair == (__ports)) && \ @@ -306,7 +306,9 @@ static inline struct sock *inet_lookup_listener(struct net *net, ((__sk)->sk_bound_dev_if == (__dif))) && \ net_eq(sock_net(__sk), (__net))) #else /* 32-bit arch */ -#define INET_ADDR_COOKIE(__name, __saddr, __daddr) +#define INET_ADDR_COOKIE(__name, __saddr, __daddr) \ + const int __name __deprecated __attribute__((unused)) + #define INET_MATCH(__sk, __net, __cookie, __saddr, __daddr, __ports, __dif) \ (((__sk)->sk_portpair == (__ports)) && \ ((__sk)->sk_daddr == (__saddr)) && \ diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index 1833c3f389ee..a829b77523cf 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -88,8 +88,11 @@ 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; }; static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk) @@ -97,6 +100,15 @@ static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk) return (struct inet_request_sock *)sk; } +static inline u32 inet_request_mark(struct sock *sk, struct sk_buff *skb) +{ + if (!sk->sk_mark && sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept) { + return skb->mark; + } else { + return sk->sk_mark; + } +} + struct inet_cork { unsigned int flags; __be32 addr; diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h index 61474ea02152..6c566034e26d 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/inetpeer.h b/include/net/inetpeer.h index 058271bde27a..01d590ee5e7e 100644 --- a/include/net/inetpeer.h +++ b/include/net/inetpeer.h @@ -41,14 +41,13 @@ struct inet_peer { struct rcu_head gc_rcu; }; /* - * Once inet_peer is queued for deletion (refcnt == -1), following fields - * are not available: rid, ip_id_count + * Once inet_peer is queued for deletion (refcnt == -1), following field + * is not available: rid * We can share memory with rcu_head to help keep inet_peer small. */ union { struct { atomic_t rid; /* Frag reception counter */ - atomic_t ip_id_count; /* IP ID for the next packet */ }; struct rcu_head rcu; struct inet_peer *gc_next; @@ -165,21 +164,11 @@ bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout); void inetpeer_invalidate_tree(struct inet_peer_base *); /* - * temporary check to make sure we dont access rid, ip_id_count, tcp_ts, + * temporary check to make sure we dont access rid, tcp_ts, * tcp_ts_stamp if no refcount is taken on inet_peer */ static inline void inet_peer_refcheck(const struct inet_peer *p) { WARN_ON_ONCE(atomic_read(&p->refcnt) <= 0); } - - -/* can be called with or without local BH being disabled */ -static inline int inet_getid(struct inet_peer *p, int more) -{ - more++; - inet_peer_refcheck(p); - return atomic_add_return(more, &p->ip_id_count) - more; -} - #endif /* _NET_INETPEER_H */ diff --git a/include/net/ip.h b/include/net/ip.h index 3ec2b0fb9d83..db4a771b9ef3 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; @@ -196,35 +197,37 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr, #define NET_ADD_STATS_BH(net, field, adnd) SNMP_ADD_STATS_BH((net)->mib.net_statistics, field, adnd) #define NET_ADD_STATS_USER(net, field, adnd) SNMP_ADD_STATS_USER((net)->mib.net_statistics, field, adnd) -unsigned long snmp_fold_field(void __percpu *mib[], int offt); +unsigned long snmp_fold_field(void __percpu *mib, int offt); #if BITS_PER_LONG==32 -u64 snmp_fold_field64(void __percpu *mib[], int offt, size_t sync_off); +u64 snmp_fold_field64(void __percpu *mib, int offt, size_t sync_off); #else -static inline u64 snmp_fold_field64(void __percpu *mib[], int offt, size_t syncp_off) +static inline u64 snmp_fold_field64(void __percpu *mib, int offt, size_t syncp_off) { return snmp_fold_field(mib, offt); } #endif -int snmp_mib_init(void __percpu *ptr[2], size_t mibsize, size_t align); -static inline void snmp_mib_free(void __percpu *ptr[SNMP_ARRAY_SZ]) -{ - int i; +void inet_get_local_port_range(struct net *net, int *low, int *high); - BUG_ON(ptr == NULL); - for (i = 0; i < SNMP_ARRAY_SZ; i++) { - free_percpu(ptr[i]); - ptr[i] = NULL; - } +#ifdef CONFIG_SYSCTL +static inline int inet_is_local_reserved_port(struct net *net, int port) +{ + if (!net->ipv4.sysctl_local_reserved_ports) + return 0; + return test_bit(port, net->ipv4.sysctl_local_reserved_ports); } -void inet_get_local_port_range(struct net *net, int *low, int *high); +static inline bool sysctl_dev_name_is_allowed(const char *name) +{ + return strcmp(name, "default") != 0 && strcmp(name, "all") != 0; +} -extern unsigned long *sysctl_local_reserved_ports; -static inline int inet_is_reserved_local_port(int port) +#else +static inline int inet_is_local_reserved_port(struct net *net, int port) { - return test_bit(port, sysctl_local_reserved_ports); + return 0; } +#endif extern int sysctl_ip_nonlocal_bind; @@ -243,6 +246,9 @@ void ipfrag_init(void); void ip_static_sysctl_init(void); +#define IP4_REPLY_MARK(net, mark) \ + ((net)->ipv4.sysctl_fwmark_reflect ? (mark) : 0) + static inline bool ip_is_fragment(const struct iphdr *iph) { return (iph->frag_off & htons(IP_MF | IP_OFFSET)) != 0; @@ -281,7 +287,7 @@ static inline bool ip_sk_use_pmtu(const struct sock *sk) return inet_sk(sk)->pmtudisc < IP_PMTUDISC_PROBE; } -static inline bool ip_sk_local_df(const struct sock *sk) +static inline bool ip_sk_ignore_df(const struct sock *sk) { return inet_sk(sk)->pmtudisc < IP_PMTUDISC_DO || inet_sk(sk)->pmtudisc == IP_PMTUDISC_OMIT; @@ -310,36 +316,52 @@ static inline unsigned int ip_skb_dst_mtu(const struct sk_buff *skb) } } -void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more); +u32 ip_idents_reserve(u32 hash, int segs); +void __ip_select_ident(struct iphdr *iph, int segs); -static inline void ip_select_ident(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk) +static inline void ip_select_ident_segs(struct sk_buff *skb, struct sock *sk, int segs) { struct iphdr *iph = ip_hdr(skb); - if ((iph->frag_off & htons(IP_DF)) && !skb->local_df) { + if ((iph->frag_off & htons(IP_DF)) && !skb->ignore_df) { /* This is only to work around buggy Windows95/2000 * VJ compression implementations. If the ID field * does not change, they drop every other packet in * a TCP stream using header compression. */ - iph->id = (sk && inet_sk(sk)->inet_daddr) ? - htons(inet_sk(sk)->inet_id++) : 0; - } else - __ip_select_ident(iph, dst, 0); + if (sk && inet_sk(sk)->inet_daddr) { + iph->id = htons(inet_sk(sk)->inet_id); + inet_sk(sk)->inet_id += segs; + } else { + iph->id = 0; + } + } else { + __ip_select_ident(iph, segs); + } } -static inline void ip_select_ident_more(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk, int more) +static inline void ip_select_ident(struct sk_buff *skb, struct sock *sk) { - struct iphdr *iph = ip_hdr(skb); + ip_select_ident_segs(skb, sk, 1); +} - if ((iph->frag_off & htons(IP_DF)) && !skb->local_df) { - if (sk && inet_sk(sk)->inet_daddr) { - iph->id = htons(inet_sk(sk)->inet_id); - inet_sk(sk)->inet_id += 1 + more; - } else - iph->id = 0; - } else - __ip_select_ident(iph, dst, more); +static inline __wsum inet_compute_pseudo(struct sk_buff *skb, int proto) +{ + return csum_tcpudp_nofold(ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, + 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); } /* @@ -470,7 +492,6 @@ static inline struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user) } #endif int ip_frag_mem(struct net *net); -int ip_frag_nqueues(struct net *net); /* * Functions provided by ip_forward.c diff --git a/include/net/ip6_checksum.h b/include/net/ip6_checksum.h index 9e3c540c1b11..55236cb71174 100644 --- a/include/net/ip6_checksum.h +++ b/include/net/ip6_checksum.h @@ -41,6 +41,13 @@ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, __wsum csum); #endif +static inline __wsum ip6_compute_pseudo(struct sk_buff *skb, int proto) +{ + return ~csum_unfold(csum_ipv6_magic(&ipv6_hdr(skb)->saddr, + &ipv6_hdr(skb)->daddr, + skb->len, proto, 0)); +} + static __inline__ __sum16 tcp_v6_check(int len, const struct in6_addr *saddr, const struct in6_addr *daddr, @@ -75,5 +82,17 @@ static inline void tcp_v6_send_check(struct sock *sk, struct sk_buff *skb) } #endif +static inline __sum16 udp_v6_check(int len, + const struct in6_addr *saddr, + const struct in6_addr *daddr, + __wsum base) +{ + return csum_ipv6_magic(saddr, daddr, len, IPPROTO_UDP, base); +} + +void udp6_set_csum(bool nocheck, struct sk_buff *skb, + const struct in6_addr *saddr, + const struct in6_addr *daddr, int len); + int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh, int proto); #endif diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 216cecce65e9..1d09b46c1e48 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -186,7 +186,7 @@ static inline bool ip6_sk_accept_pmtu(const struct sock *sk) inet6_sk(sk)->pmtudisc != IPV6_PMTUDISC_OMIT; } -static inline bool ip6_sk_local_df(const struct sock *sk) +static inline bool ip6_sk_ignore_df(const struct sock *sk) { return inet6_sk(sk)->pmtudisc < IPV6_PMTUDISC_DO || inet6_sk(sk)->pmtudisc == IPV6_PMTUDISC_OMIT; diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index a4daf9eb8562..8dd8cab88b87 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -40,6 +40,7 @@ struct ip_tunnel_prl_entry { struct ip_tunnel_dst { struct dst_entry __rcu *dst; + __be32 saddr; }; struct ip_tunnel { diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 5679d927562b..624a8a54806d 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -1204,7 +1204,7 @@ static inline bool __ip_vs_conn_get(struct ip_vs_conn *cp) /* put back the conn without restarting its timer */ static inline void __ip_vs_conn_put(struct ip_vs_conn *cp) { - smp_mb__before_atomic_dec(); + smp_mb__before_atomic(); atomic_dec(&cp->refcnt); } void ip_vs_conn_put(struct ip_vs_conn *cp); @@ -1408,7 +1408,7 @@ static inline void ip_vs_dest_hold(struct ip_vs_dest *dest) static inline void ip_vs_dest_put(struct ip_vs_dest *dest) { - smp_mb__before_atomic_dec(); + smp_mb__before_atomic(); atomic_dec(&dest->refcnt); } diff --git a/include/net/ipv6.h b/include/net/ipv6.h index d640925bc454..a2db816e8461 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 @@ -113,6 +114,9 @@ struct frag_hdr { #define IP6_MF 0x0001 #define IP6_OFFSET 0xFFF8 +#define IP6_REPLY_MARK(net, mark) \ + ((net)->ipv6.sysctl.fwmark_reflect ? (mark) : 0) + #include <net/sock.h> /* sysctls */ @@ -295,11 +299,6 @@ static inline bool ipv6_accept_ra(struct inet6_dev *idev) } #if IS_ENABLED(CONFIG_IPV6) -static inline int ip6_frag_nqueues(struct net *net) -{ - return net->ipv6.frags.nqueues; -} - static inline int ip6_frag_mem(struct net *net) { return sum_frag_mem_limit(&net->ipv6.frags); @@ -492,8 +491,8 @@ struct ip6_create_arg { u8 ecn; }; -void ip6_frag_init(struct inet_frag_queue *q, void *a); -bool ip6_frag_match(struct inet_frag_queue *q, void *a); +void ip6_frag_init(struct inet_frag_queue *q, const void *a); +bool ip6_frag_match(const struct inet_frag_queue *q, const void *a); /* * Equivalent of ipv4 struct ip @@ -554,24 +553,29 @@ static inline u32 __ipv6_addr_jhash(const struct in6_addr *a, const u32 initval) static inline bool ipv6_addr_loopback(const struct in6_addr *a) { #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 - const unsigned long *ul = (const unsigned long *)a; + const __be64 *be = (const __be64 *)a; - return (ul[0] | (ul[1] ^ cpu_to_be64(1))) == 0UL; + return (be[0] | (be[1] ^ cpu_to_be64(1))) == 0UL; #else return (a->s6_addr32[0] | a->s6_addr32[1] | - a->s6_addr32[2] | (a->s6_addr32[3] ^ htonl(1))) == 0; + a->s6_addr32[2] | (a->s6_addr32[3] ^ cpu_to_be32(1))) == 0; #endif } +/* + * Note that we must __force cast these to unsigned long to make sparse happy, + * since all of the endian-annotated types are fixed size regardless of arch. + */ static inline bool ipv6_addr_v4mapped(const struct in6_addr *a) { return ( #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64 - *(__be64 *)a | + *(unsigned long *)a | #else - (a->s6_addr32[0] | a->s6_addr32[1]) | + (__force unsigned long)(a->s6_addr32[0] | a->s6_addr32[1]) | #endif - (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0UL; + (__force unsigned long)(a->s6_addr32[2] ^ + cpu_to_be32(0x0000ffff))) == 0UL; } /* @@ -583,6 +587,11 @@ static inline bool ipv6_addr_orchid(const struct in6_addr *a) return (a->s6_addr32[0] & htonl(0xfffffff0)) == htonl(0x20010010); } +static inline bool ipv6_addr_is_multicast(const struct in6_addr *addr) +{ + return (addr->s6_addr32[0] & htonl(0xFF000000)) == htonl(0xFF000000); +} + static inline void ipv6_addr_set_v4mapped(const __be32 addr, struct in6_addr *v4mapped) { @@ -660,10 +669,66 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr)); } -void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt); - int ip6_dst_hoplimit(struct dst_entry *dst); +static inline int ip6_sk_dst_hoplimit(struct ipv6_pinfo *np, struct flowi6 *fl6, + struct dst_entry *dst) +{ + int hlimit; + + if (ipv6_addr_is_multicast(&fl6->daddr)) + hlimit = np->mcast_hops; + else + hlimit = np->hop_limit; + if (hlimit < 0) + hlimit = ip6_dst_hoplimit(dst); + 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 8248e3909fdf..dae2e24616e1 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -189,6 +189,43 @@ struct ieee80211_chanctx_conf { }; /** + * enum ieee80211_chanctx_switch_mode - channel context switch mode + * @CHANCTX_SWMODE_REASSIGN_VIF: Both old and new contexts already + * exist (and will continue to exist), but the virtual interface + * needs to be switched from one to the other. + * @CHANCTX_SWMODE_SWAP_CONTEXTS: The old context exists but will stop + * to exist with this call, the new context doesn't exist but + * will be active after this call, the virtual interface switches + * from the old to the new (note that the driver may of course + * implement this as an on-the-fly chandef switch of the existing + * hardware context, but the mac80211 pointer for the old context + * will cease to exist and only the new one will later be used + * for changes/removal.) + */ +enum ieee80211_chanctx_switch_mode { + CHANCTX_SWMODE_REASSIGN_VIF, + CHANCTX_SWMODE_SWAP_CONTEXTS, +}; + +/** + * struct ieee80211_vif_chanctx_switch - vif chanctx switch information + * + * This is structure is used to pass information about a vif that + * needs to switch from one chanctx to another. The + * &ieee80211_chanctx_switch_mode defines how the switch should be + * done. + * + * @vif: the vif that should be switched from old_ctx to new_ctx + * @old_ctx: the old context to which the vif was assigned + * @new_ctx: the new context to which the vif must be assigned + */ +struct ieee80211_vif_chanctx_switch { + struct ieee80211_vif *vif; + struct ieee80211_chanctx_conf *old_ctx; + struct ieee80211_chanctx_conf *new_ctx; +}; + +/** * enum ieee80211_bss_change - BSS change notification flags * * These flags are used with the bss_info_changed() callback @@ -717,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; @@ -1113,7 +1155,9 @@ enum ieee80211_vif_flags { * @addr: address of this interface * @p2p: indicates whether this AP or STA interface is a p2p * interface, i.e. a GO or p2p-sta respectively - * @csa_active: marks whether a channel switch is going on + * @csa_active: marks whether a channel switch is going on. Internally it is + * write-protected by sdata_lock and local->mtx so holding either is fine + * for read access. * @driver_flags: flags/capabilities the driver has for this interface, * these need to be set (or cleared) when the interface is added * or, if supported by the driver, the interface type is changed @@ -1202,14 +1246,18 @@ struct ieee80211_vif *wdev_to_ieee80211_vif(struct wireless_dev *wdev); * fall back to software crypto. Note that this flag deals only with * RX, if your crypto engine can't deal with TX you can also set the * %IEEE80211_KEY_FLAG_SW_MGMT_TX flag to encrypt such frames in SW. + * @IEEE80211_KEY_FLAG_GENERATE_IV_MGMT: This flag should be set by the + * driver for a CCMP key to indicate that is requires IV generation + * only for managment frames (MFP). */ enum ieee80211_key_flags { - IEEE80211_KEY_FLAG_GENERATE_IV = 1<<1, - IEEE80211_KEY_FLAG_GENERATE_MMIC= 1<<2, - IEEE80211_KEY_FLAG_PAIRWISE = 1<<3, - IEEE80211_KEY_FLAG_SW_MGMT_TX = 1<<4, - IEEE80211_KEY_FLAG_PUT_IV_SPACE = 1<<5, - IEEE80211_KEY_FLAG_RX_MGMT = 1<<6, + IEEE80211_KEY_FLAG_GENERATE_IV_MGMT = BIT(0), + IEEE80211_KEY_FLAG_GENERATE_IV = BIT(1), + IEEE80211_KEY_FLAG_GENERATE_MMIC = BIT(2), + IEEE80211_KEY_FLAG_PAIRWISE = BIT(3), + IEEE80211_KEY_FLAG_SW_MGMT_TX = BIT(4), + IEEE80211_KEY_FLAG_PUT_IV_SPACE = BIT(5), + IEEE80211_KEY_FLAG_RX_MGMT = BIT(6), }; /** @@ -1370,6 +1418,7 @@ struct ieee80211_sta_rates { * the station moves to associated state. * @smps_mode: current SMPS mode (off, static or dynamic) * @rates: rate control selection table + * @tdls: indicates whether the STA is a TDLS peer */ struct ieee80211_sta { u32 supp_rates[IEEE80211_NUM_BANDS]; @@ -1384,6 +1433,7 @@ struct ieee80211_sta { enum ieee80211_sta_rx_bandwidth bandwidth; enum ieee80211_smps_mode smps_mode; struct ieee80211_sta_rates __rcu *rates; + bool tdls; /* must be last */ u8 drv_priv[0] __aligned(sizeof(void *)); @@ -1555,6 +1605,9 @@ struct ieee80211_tx_control { * for a single active channel while using channel contexts. When support * is not enabled the default action is to disconnect when getting the * CSA frame. + * + * @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, @@ -1586,6 +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, + /* bit 29 unused */ + IEEE80211_SINGLE_HW_SCAN_ON_ALL_BANDS = 1<<30, }; /** @@ -1712,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 @@ -2609,6 +2677,7 @@ enum ieee80211_roc_type { * of queues to flush, which is useful if different virtual interfaces * use different hardware queues; it may also indicate all queues. * If the parameter @drop is set to %true, pending frames may be dropped. + * Note that vif can be NULL. * The callback can sleep. * * @channel_switch: Drivers that need (or want) to offload the channel @@ -2711,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 @@ -2720,6 +2798,11 @@ enum ieee80211_roc_type { * to vif. Possible use is for hw queue remapping. * @unassign_vif_chanctx: Notifies device driver about channel context being * unbound from vif. + * @switch_vif_chanctx: switch a number of vifs from one chanctx to + * another, as specified in the list of + * @ieee80211_vif_chanctx_switch passed to the driver, according + * to the mode defined in &ieee80211_chanctx_switch_mode. + * * @start_ap: Start operation on the AP interface, this is called after all the * information in bss_conf is set and beacon can be retrieved. A channel * context is bound before this is called. Note that if the driver uses @@ -2753,6 +2836,10 @@ enum ieee80211_roc_type { * information in bss_conf is set up and the beacon can be retrieved. A * channel context is bound before this is called. * @leave_ibss: Leave the IBSS again. + * + * @get_expected_throughput: extract the expected throughput towards the + * specified station. The returned value is expressed in Kbps. It returns 0 + * if the RC algorithm does not have proper data to provide. */ struct ieee80211_ops { void (*tx)(struct ieee80211_hw *hw, @@ -2803,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); @@ -2871,7 +2958,8 @@ struct ieee80211_ops { struct netlink_callback *cb, void *data, int len); #endif - void (*flush)(struct ieee80211_hw *hw, u32 queues, bool drop); + void (*flush)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, + u32 queues, bool drop); void (*channel_switch)(struct ieee80211_hw *hw, struct ieee80211_channel_switch *ch_switch); int (*set_antenna)(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); @@ -2918,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, @@ -2931,6 +3022,10 @@ struct ieee80211_ops { void (*unassign_vif_chanctx)(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_chanctx_conf *ctx); + int (*switch_vif_chanctx)(struct ieee80211_hw *hw, + struct ieee80211_vif_chanctx_switch *vifs, + int n_vifs, + enum ieee80211_chanctx_switch_mode mode); void (*restart_complete)(struct ieee80211_hw *hw); @@ -2945,6 +3040,7 @@ struct ieee80211_ops { int (*join_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); void (*leave_ibss)(struct ieee80211_hw *hw, struct ieee80211_vif *vif); + u32 (*get_expected_throughput)(struct ieee80211_sta *sta); }; /** @@ -3394,6 +3490,47 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, */ void ieee80211_report_low_ack(struct ieee80211_sta *sta, u32 num_packets); +#define IEEE80211_MAX_CSA_COUNTERS_NUM 2 + +/** + * struct ieee80211_mutable_offsets - mutable beacon offsets + * @tim_offset: position of TIM element + * @tim_length: size of TIM element + * @csa_counter_offs: array of IEEE80211_MAX_CSA_COUNTERS_NUM offsets + * to CSA counters. This array can contain zero values which + * should be ignored. + */ +struct ieee80211_mutable_offsets { + u16 tim_offset; + u16 tim_length; + + u16 csa_counter_offs[IEEE80211_MAX_CSA_COUNTERS_NUM]; +}; + +/** + * ieee80211_beacon_get_template - beacon template generation function + * @hw: pointer obtained from ieee80211_alloc_hw(). + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * @offs: &struct ieee80211_mutable_offsets pointer to struct that will + * receive the offsets that may be updated by the driver. + * + * If the driver implements beaconing modes, it must use this function to + * obtain the beacon template. + * + * This function should be used if the beacon frames are generated by the + * device, and then the driver must use the returned beacon as the template + * The driver or the device are responsible to update the DTIM and, when + * applicable, the CSA count. + * + * The driver is responsible for freeing the returned skb. + * + * Return: The beacon template. %NULL on error. + */ +struct sk_buff * +ieee80211_beacon_get_template(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + struct ieee80211_mutable_offsets *offs); + /** * ieee80211_beacon_get_tim - beacon generation function * @hw: pointer obtained from ieee80211_alloc_hw(). @@ -3405,16 +3542,12 @@ void ieee80211_report_low_ack(struct ieee80211_sta *sta, u32 num_packets); * Set to 0 if invalid (in non-AP modes). * * If the driver implements beaconing modes, it must use this function to - * obtain the beacon frame/template. + * obtain the beacon frame. * * If the beacon frames are generated by the host system (i.e., not in * hardware/firmware), the driver uses this function to get each beacon - * frame from mac80211 -- it is responsible for calling this function - * before the beacon is needed (e.g. based on hardware interrupt). - * - * If the beacon frames are generated by the device, then the driver - * must use the returned beacon as the template and change the TIM IE - * according to the current DTIM parameters/TIM bitmap. + * frame from mac80211 -- it is responsible for calling this function exactly + * once before the beacon is needed (e.g. based on hardware interrupt). * * The driver is responsible for freeing the returned skb. * @@ -3440,6 +3573,20 @@ static inline struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, } /** + * ieee80211_csa_update_counter - request mac80211 to decrement the csa counter + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * + * The csa counter should be updated after each beacon transmission. + * This function is called implicitly when + * ieee80211_beacon_get/ieee80211_beacon_get_tim are called, however if the + * beacon frames are generated by the device, the driver should call this + * function after each beacon transmission to sync mac80211's csa counters. + * + * Return: new csa counter value + */ +u8 ieee80211_csa_update_counter(struct ieee80211_vif *vif); + +/** * ieee80211_csa_finish - notify mac80211 about channel switch * @vif: &struct ieee80211_vif pointer from the add_interface callback. * @@ -4405,6 +4552,40 @@ void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap, */ void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn); +/** + * ieee80211_start_rx_ba_session_offl - start a Rx BA session + * + * Some device drivers may offload part of the Rx aggregation flow including + * AddBa/DelBa negotiation but may otherwise be incapable of full Rx + * reordering. + * + * Create structures responsible for reordering so device drivers may call here + * when they complete AddBa negotiation. + * + * @vif: &struct ieee80211_vif pointer from the add_interface callback + * @addr: station mac address + * @tid: the rx tid + */ +void ieee80211_start_rx_ba_session_offl(struct ieee80211_vif *vif, + const u8 *addr, u16 tid); + +/** + * ieee80211_stop_rx_ba_session_offl - stop a Rx BA session + * + * Some device drivers may offload part of the Rx aggregation flow including + * AddBa/DelBa negotiation but may otherwise be incapable of full Rx + * reordering. + * + * Destroy structures responsible for reordering so device drivers may call here + * when they complete DelBa negotiation. + * + * @vif: &struct ieee80211_vif pointer from the add_interface callback + * @addr: station mac address + * @tid: the rx tid + */ +void ieee80211_stop_rx_ba_session_offl(struct ieee80211_vif *vif, + const u8 *addr, u16 tid); + /* Rate control API */ /** @@ -4467,6 +4648,8 @@ struct rate_control_ops { void (*add_sta_debugfs)(void *priv, void *priv_sta, struct dentry *dir); void (*remove_sta_debugfs)(void *priv, void *priv_sta); + + u32 (*get_expected_throughput)(void *priv_sta); }; static inline int rate_supported(struct ieee80211_sta *sta, @@ -4576,7 +4759,9 @@ conf_is_ht40(struct ieee80211_conf *conf) static inline bool conf_is_ht(struct ieee80211_conf *conf) { - return conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT; + return (conf->chandef.width != NL80211_CHAN_WIDTH_5) && + (conf->chandef.width != NL80211_CHAN_WIDTH_10) && + (conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT); } static inline enum nl80211_iftype @@ -4692,4 +4877,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 a591053cae63..2e67cdd19cdc 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/neighbour.h b/include/net/neighbour.h index 7277caf3743d..47f425464f84 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -203,7 +203,6 @@ struct neigh_table { void (*proxy_redo)(struct sk_buff *skb); char *id; struct neigh_parms parms; - /* HACK. gc_* should follow parms without a gap! */ int gc_interval; int gc_thresh1; int gc_thresh2; diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index 5f9eb260990f..361d26077196 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h @@ -373,6 +373,14 @@ static inline void rt_genid_bump_ipv6(struct net *net) } #endif +#if IS_ENABLED(CONFIG_IEEE802154_6LOWPAN) +static inline struct netns_ieee802154_lowpan * +net_ieee802154_lowpan(struct net *net) +{ + return &net->ieee802154_lowpan; +} +#endif + /* For callers who don't really care about whether it's IPv4 or IPv6 */ static inline void rt_genid_bump_all(struct net *net) { diff --git a/include/net/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h index 0e3d08e4b1d3..57c880378443 100644 --- a/include/net/netfilter/nf_conntrack_ecache.h +++ b/include/net/netfilter/nf_conntrack_ecache.h @@ -18,7 +18,6 @@ struct nf_conntrack_ecache { u16 ctmask; /* bitmask of ct events to be delivered */ u16 expmask; /* bitmask of expect events to be delivered */ u32 portid; /* netlink portid of destroyer */ - struct timer_list timeout; }; static inline struct nf_conntrack_ecache * @@ -216,8 +215,23 @@ void nf_conntrack_ecache_pernet_fini(struct net *net); int nf_conntrack_ecache_init(void); void nf_conntrack_ecache_fini(void); -#else /* CONFIG_NF_CONNTRACK_EVENTS */ +static inline void nf_conntrack_ecache_delayed_work(struct net *net) +{ + if (!delayed_work_pending(&net->ct.ecache_dwork)) { + schedule_delayed_work(&net->ct.ecache_dwork, HZ); + net->ct.ecache_dwork_pending = true; + } +} + +static inline void nf_conntrack_ecache_work(struct net *net) +{ + if (net->ct.ecache_dwork_pending) { + net->ct.ecache_dwork_pending = false; + mod_delayed_work(system_wq, &net->ct.ecache_dwork, 0); + } +} +#else /* CONFIG_NF_CONNTRACK_EVENTS */ static inline void nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct) {} static inline int nf_conntrack_eventmask_report(unsigned int eventmask, @@ -255,6 +269,14 @@ static inline int nf_conntrack_ecache_init(void) static inline void nf_conntrack_ecache_fini(void) { } + +static inline void nf_conntrack_ecache_delayed_work(struct net *net) +{ +} + +static inline void nf_conntrack_ecache_work(struct net *net) +{ +} #endif /* CONFIG_NF_CONNTRACK_EVENTS */ #endif /*_NF_CONNTRACK_ECACHE_H*/ diff --git a/include/net/netfilter/nf_log.h b/include/net/netfilter/nf_log.h index 99eac12d040b..534e1f2ac4fc 100644 --- a/include/net/netfilter/nf_log.h +++ b/include/net/netfilter/nf_log.h @@ -12,8 +12,11 @@ #define NF_LOG_UID 0x08 /* Log UID owning local socket */ #define NF_LOG_MASK 0x0f -#define NF_LOG_TYPE_LOG 0x01 -#define NF_LOG_TYPE_ULOG 0x02 +enum nf_log_type { + NF_LOG_TYPE_LOG = 0, + NF_LOG_TYPE_ULOG, + NF_LOG_TYPE_MAX +}; struct nf_loginfo { u_int8_t type; @@ -40,10 +43,10 @@ typedef void nf_logfn(struct net *net, const char *prefix); struct nf_logger { - struct module *me; - nf_logfn *logfn; - char *name; - struct list_head list[NFPROTO_NUMPROTO]; + char *name; + enum nf_log_type type; + nf_logfn *logfn; + struct module *me; }; /* Function to register/unregister log function. */ @@ -58,6 +61,13 @@ int nf_log_bind_pf(struct net *net, u_int8_t pf, const struct nf_logger *logger); void nf_log_unbind_pf(struct net *net, u_int8_t pf); +int nf_logger_find_get(int pf, enum nf_log_type type); +void nf_logger_put(int pf, enum nf_log_type type); +void nf_logger_request_module(int pf, enum nf_log_type type); + +#define MODULE_ALIAS_NF_LOGGER(family, type) \ + MODULE_ALIAS("nf-logger-" __stringify(family) "-" __stringify(type)) + /* Calls the registered backend logging function */ __printf(8, 9) void nf_log_packet(struct net *net, @@ -69,4 +79,24 @@ void nf_log_packet(struct net *net, const struct nf_loginfo *li, const char *fmt, ...); +struct nf_log_buf; + +struct nf_log_buf *nf_log_buf_open(void); +__printf(2, 3) int nf_log_buf_add(struct nf_log_buf *m, const char *f, ...); +void nf_log_buf_close(struct nf_log_buf *m); + +/* common logging functions */ +int nf_log_dump_udp_header(struct nf_log_buf *m, const struct sk_buff *skb, + u8 proto, int fragment, unsigned int offset); +int nf_log_dump_tcp_header(struct nf_log_buf *m, const struct sk_buff *skb, + u8 proto, int fragment, unsigned int offset, + unsigned int logflags); +void nf_log_dump_sk_uid_gid(struct nf_log_buf *m, struct sock *sk); +void nf_log_dump_packet_common(struct nf_log_buf *m, u_int8_t pf, + unsigned int hooknum, const struct sk_buff *skb, + const struct net_device *in, + const struct net_device *out, + const struct nf_loginfo *loginfo, + const char *prefix); + #endif /* _NF_LOG_H */ diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h index 07eaaf604092..a71dd333ac68 100644 --- a/include/net/netfilter/nf_nat.h +++ b/include/net/netfilter/nf_nat.h @@ -48,6 +48,8 @@ unsigned int nf_nat_setup_info(struct nf_conn *ct, extern unsigned int nf_nat_alloc_null_binding(struct nf_conn *ct, unsigned int hooknum); +struct nf_conn_nat *nf_ct_nat_ext_add(struct nf_conn *ct); + /* Is this tuple already taken? (not by us)*/ int nf_nat_used_tuple(const struct nf_conntrack_tuple *tuple, const struct nf_conn *ignored_conntrack); diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index e6bc14d8fa9a..c4d86198d3d6 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -6,6 +6,7 @@ #include <linux/netfilter/nfnetlink.h> #include <linux/netfilter/x_tables.h> #include <linux/netfilter/nf_tables.h> +#include <linux/u64_stats_sync.h> #include <net/netlink.h> #define NFT_JUMP_STACK_SIZE 16 @@ -72,21 +73,23 @@ static inline void nft_data_debug(const struct nft_data *data) * struct nft_ctx - nf_tables rule/set context * * @net: net namespace - * @skb: netlink skb - * @nlh: netlink message header * @afi: address family info * @table: the table the chain is contained in * @chain: the chain the rule is contained in * @nla: netlink attributes + * @portid: netlink portID of the original message + * @seq: netlink sequence number + * @report: notify via unicast netlink message */ struct nft_ctx { struct net *net; - const struct sk_buff *skb; - const struct nlmsghdr *nlh; - const struct nft_af_info *afi; - const struct nft_table *table; - const struct nft_chain *chain; + struct nft_af_info *afi; + struct nft_table *table; + struct nft_chain *chain; const struct nlattr * const *nla; + u32 portid; + u32 seq; + bool report; }; struct nft_data_desc { @@ -146,6 +149,44 @@ struct nft_set_iter { }; /** + * struct nft_set_desc - description of set elements + * + * @klen: key length + * @dlen: data length + * @size: number of set elements + */ +struct nft_set_desc { + unsigned int klen; + unsigned int dlen; + unsigned int size; +}; + +/** + * enum nft_set_class - performance class + * + * @NFT_LOOKUP_O_1: constant, O(1) + * @NFT_LOOKUP_O_LOG_N: logarithmic, O(log N) + * @NFT_LOOKUP_O_N: linear, O(N) + */ +enum nft_set_class { + NFT_SET_CLASS_O_1, + NFT_SET_CLASS_O_LOG_N, + NFT_SET_CLASS_O_N, +}; + +/** + * struct nft_set_estimate - estimation of memory and performance + * characteristics + * + * @size: required memory + * @class: lookup performance class + */ +struct nft_set_estimate { + unsigned int size; + enum nft_set_class class; +}; + +/** * struct nft_set_ops - nf_tables set operations * * @lookup: look up an element within the set @@ -174,7 +215,11 @@ struct nft_set_ops { struct nft_set_iter *iter); unsigned int (*privsize)(const struct nlattr * const nla[]); + bool (*estimate)(const struct nft_set_desc *desc, + u32 features, + struct nft_set_estimate *est); int (*init)(const struct nft_set *set, + const struct nft_set_desc *desc, const struct nlattr * const nla[]); void (*destroy)(const struct nft_set *set); @@ -194,6 +239,8 @@ void nft_unregister_set(struct nft_set_ops *ops); * @name: name of the set * @ktype: key type (numeric type defined by userspace, not used in the kernel) * @dtype: data type (verdict or numeric type defined by userspace) + * @size: maximum set size + * @nelems: number of elements * @ops: set ops * @flags: set flags * @klen: key length @@ -206,6 +253,8 @@ struct nft_set { char name[IFNAMSIZ]; u32 ktype; u32 dtype; + u32 size; + u32 nelems; /* runtime data below here */ const struct nft_set_ops *ops ____cacheline_aligned; u16 flags; @@ -222,6 +271,8 @@ static inline void *nft_set_priv(const struct nft_set *set) struct nft_set *nf_tables_set_lookup(const struct nft_table *table, const struct nlattr *nla); +struct nft_set *nf_tables_set_lookup_byid(const struct net *net, + const struct nlattr *nla); /** * struct nft_set_binding - nf_tables set binding @@ -341,18 +392,75 @@ struct nft_rule { }; /** - * struct nft_rule_trans - nf_tables rule update in transaction + * struct nft_trans - nf_tables object update in transaction * + * @rcu_head: rcu head to defer release of transaction data * @list: used internally - * @ctx: rule context - * @rule: rule that needs to be updated + * @msg_type: message type + * @ctx: transaction context + * @data: internal information related to the transaction */ -struct nft_rule_trans { +struct nft_trans { + struct rcu_head rcu_head; struct list_head list; + int msg_type; struct nft_ctx ctx; + char data[0]; +}; + +struct nft_trans_rule { struct nft_rule *rule; }; +#define nft_trans_rule(trans) \ + (((struct nft_trans_rule *)trans->data)->rule) + +struct nft_trans_set { + struct nft_set *set; + u32 set_id; +}; + +#define nft_trans_set(trans) \ + (((struct nft_trans_set *)trans->data)->set) +#define nft_trans_set_id(trans) \ + (((struct nft_trans_set *)trans->data)->set_id) + +struct nft_trans_chain { + bool update; + char name[NFT_CHAIN_MAXNAMELEN]; + struct nft_stats __percpu *stats; + u8 policy; +}; + +#define nft_trans_chain_update(trans) \ + (((struct nft_trans_chain *)trans->data)->update) +#define nft_trans_chain_name(trans) \ + (((struct nft_trans_chain *)trans->data)->name) +#define nft_trans_chain_stats(trans) \ + (((struct nft_trans_chain *)trans->data)->stats) +#define nft_trans_chain_policy(trans) \ + (((struct nft_trans_chain *)trans->data)->policy) + +struct nft_trans_table { + bool update; + bool enable; +}; + +#define nft_trans_table_update(trans) \ + (((struct nft_trans_table *)trans->data)->update) +#define nft_trans_table_enable(trans) \ + (((struct nft_trans_table *)trans->data)->enable) + +struct nft_trans_elem { + struct nft_set *set; + struct nft_set_elem elem; +}; + +#define nft_trans_elem_set(trans) \ + (((struct nft_trans_elem *)trans->data)->set) +#define nft_trans_elem(trans) \ + (((struct nft_trans_elem *)trans->data)->elem) + static inline struct nft_expr *nft_expr_first(const struct nft_rule *rule) { return (struct nft_expr *)&rule->data[0]; @@ -385,6 +493,7 @@ static inline void *nft_userdata(const struct nft_rule *rule) enum nft_chain_flags { NFT_BASE_CHAIN = 0x1, + NFT_CHAIN_INACTIVE = 0x2, }; /** @@ -395,9 +504,9 @@ enum nft_chain_flags { * @net: net namespace that this chain belongs to * @table: table that this chain belongs to * @handle: chain handle - * @flags: bitmask of enum nft_chain_flags * @use: number of jump references to this chain * @level: length of longest path to this chain + * @flags: bitmask of enum nft_chain_flags * @name: name of the chain */ struct nft_chain { @@ -406,9 +515,9 @@ struct nft_chain { struct net *net; struct nft_table *table; u64 handle; - u8 flags; - u16 use; + u32 use; u16 level; + u8 flags; char name[NFT_CHAIN_MAXNAMELEN]; }; @@ -420,8 +529,9 @@ enum nft_chain_type { }; struct nft_stats { - u64 bytes; - u64 pkts; + u64 bytes; + u64 pkts; + struct u64_stats_sync syncp; }; #define NFT_HOOK_OPS_MAX 2 diff --git a/include/net/netfilter/nft_meta.h b/include/net/netfilter/nft_meta.h new file mode 100644 index 000000000000..0ee47c3e2e31 --- /dev/null +++ b/include/net/netfilter/nft_meta.h @@ -0,0 +1,36 @@ +#ifndef _NFT_META_H_ +#define _NFT_META_H_ + +struct nft_meta { + enum nft_meta_keys key:8; + union { + enum nft_registers dreg:8; + enum nft_registers sreg:8; + }; +}; + +extern const struct nla_policy nft_meta_policy[]; + +int nft_meta_get_init(const struct nft_ctx *ctx, + const struct nft_expr *expr, + const struct nlattr * const tb[]); + +int nft_meta_set_init(const struct nft_ctx *ctx, + const struct nft_expr *expr, + const struct nlattr * const tb[]); + +int nft_meta_get_dump(struct sk_buff *skb, + const struct nft_expr *expr); + +int nft_meta_set_dump(struct sk_buff *skb, + const struct nft_expr *expr); + +void nft_meta_get_eval(const struct nft_expr *expr, + struct nft_data data[NFT_REG_MAX + 1], + const struct nft_pktinfo *pkt); + +void nft_meta_set_eval(const struct nft_expr *expr, + struct nft_data data[NFT_REG_MAX + 1], + const struct nft_pktinfo *pkt); + +#endif diff --git a/include/net/netfilter/xt_log.h b/include/net/netfilter/xt_log.h deleted file mode 100644 index 9d9756cca013..000000000000 --- a/include/net/netfilter/xt_log.h +++ /dev/null @@ -1,54 +0,0 @@ -#define S_SIZE (1024 - (sizeof(unsigned int) + 1)) - -struct sbuff { - unsigned int count; - char buf[S_SIZE + 1]; -}; -static struct sbuff emergency, *emergency_ptr = &emergency; - -static __printf(2, 3) int sb_add(struct sbuff *m, const char *f, ...) -{ - va_list args; - int len; - - if (likely(m->count < S_SIZE)) { - va_start(args, f); - len = vsnprintf(m->buf + m->count, S_SIZE - m->count, f, args); - va_end(args); - if (likely(m->count + len < S_SIZE)) { - m->count += len; - return 0; - } - } - m->count = S_SIZE; - printk_once(KERN_ERR KBUILD_MODNAME " please increase S_SIZE\n"); - return -1; -} - -static struct sbuff *sb_open(void) -{ - struct sbuff *m = kmalloc(sizeof(*m), GFP_ATOMIC); - - if (unlikely(!m)) { - local_bh_disable(); - do { - m = xchg(&emergency_ptr, NULL); - } while (!m); - } - m->count = 0; - return m; -} - -static void sb_close(struct sbuff *m) -{ - m->buf[m->count] = 0; - printk("%s\n", m->buf); - - if (likely(m != &emergency)) - kfree(m); - else { - emergency_ptr = m; - local_bh_enable(); - } -} - diff --git a/include/net/netlink.h b/include/net/netlink.h index 2b47eaadba8f..6c1076275aaa 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -949,12 +949,12 @@ static inline int nla_put_flag(struct sk_buff *skb, int attrtype) * nla_put_msecs - Add a msecs netlink attribute to a socket buffer * @skb: socket buffer to add attribute to * @attrtype: attribute type - * @jiffies: number of msecs in jiffies + * @njiffies: number of jiffies to convert to msecs */ static inline int nla_put_msecs(struct sk_buff *skb, int attrtype, - unsigned long jiffies) + unsigned long njiffies) { - u64 tmp = jiffies_to_msecs(jiffies); + u64 tmp = jiffies_to_msecs(njiffies); return nla_put(skb, attrtype, sizeof(u64), &tmp); } diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h index 773cce308bc6..29d6a94db54d 100644 --- a/include/net/netns/conntrack.h +++ b/include/net/netns/conntrack.h @@ -4,6 +4,7 @@ #include <linux/list.h> #include <linux/list_nulls.h> #include <linux/atomic.h> +#include <linux/workqueue.h> #include <linux/netfilter/nf_conntrack_tcp.h> #include <linux/seqlock.h> @@ -73,6 +74,10 @@ struct ct_pcpu { struct netns_ct { atomic_t count; unsigned int expect_count; +#ifdef CONFIG_NF_CONNTRACK_EVENTS + struct delayed_work ecache_dwork; + bool ecache_dwork_pending; +#endif #ifdef CONFIG_SYSCTL struct ctl_table_header *sysctl_header; struct ctl_table_header *acct_sysctl_header; @@ -82,7 +87,6 @@ struct netns_ct { #endif char *slabname; unsigned int sysctl_log_invalid; /* Log invalid packets */ - unsigned int sysctl_events_retry_timeout; int sysctl_events; int sysctl_acct; int sysctl_auto_assign_helper; diff --git a/include/net/netns/ieee802154_6lowpan.h b/include/net/netns/ieee802154_6lowpan.h index 079030c853d8..e2070960bac0 100644 --- a/include/net/netns/ieee802154_6lowpan.h +++ b/include/net/netns/ieee802154_6lowpan.h @@ -16,7 +16,7 @@ struct netns_sysctl_lowpan { struct netns_ieee802154_lowpan { struct netns_sysctl_lowpan sysctl; struct netns_frags frags; - u16 max_dsize; + int max_dsize; }; #endif diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h index b2704fd0ec80..aec5e12f9f19 100644 --- a/include/net/netns/ipv4.h +++ b/include/net/netns/ipv4.h @@ -77,10 +77,17 @@ struct netns_ipv4 { int sysctl_ip_no_pmtu_disc; int sysctl_ip_fwd_use_pmtu; + int sysctl_fwmark_reflect; + int sysctl_tcp_fwmark_accept; + struct ping_group_range ping_group_range; atomic_t dev_addr_genid; +#ifdef CONFIG_SYSCTL + unsigned long *sysctl_local_reserved_ports; +#endif + #ifdef CONFIG_IP_MROUTE #ifndef CONFIG_IP_MROUTE_MULTIPLE_TABLES struct mr_table *mrt; diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h index 21edaf1f7916..eade27adecf3 100644 --- a/include/net/netns/ipv6.h +++ b/include/net/netns/ipv6.h @@ -28,8 +28,10 @@ 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; }; struct netns_ipv6 { diff --git a/include/net/netns/nftables.h b/include/net/netns/nftables.h index 26a394cb91a8..eee608b12cc9 100644 --- a/include/net/netns/nftables.h +++ b/include/net/netns/nftables.h @@ -13,8 +13,8 @@ struct netns_nftables { struct nft_af_info *inet; struct nft_af_info *arp; struct nft_af_info *bridge; + unsigned int base_seq; u8 gencursor; - u8 genctr; }; #endif diff --git a/include/net/netns/x_tables.h b/include/net/netns/x_tables.h index 02fe40f8c8fd..c24060ee411e 100644 --- a/include/net/netns/x_tables.h +++ b/include/net/netns/x_tables.h @@ -15,11 +15,5 @@ struct netns_xt { struct ebt_table *frame_filter; struct ebt_table *frame_nat; #endif -#if IS_ENABLED(CONFIG_IP_NF_TARGET_ULOG) - bool ulog_warn_deprecated; -#endif -#if IS_ENABLED(CONFIG_BRIDGE_EBT_ULOG) - bool ebt_ulog_warn_deprecated; -#endif }; #endif diff --git a/include/net/nfc/digital.h b/include/net/nfc/digital.h index 7655cfe27c34..d9a5cf7ac1c4 100644 --- a/include/net/nfc/digital.h +++ b/include/net/nfc/digital.h @@ -36,6 +36,7 @@ enum { NFC_DIGITAL_RF_TECH_212F, NFC_DIGITAL_RF_TECH_424F, NFC_DIGITAL_RF_TECH_ISO15693, + NFC_DIGITAL_RF_TECH_106B, NFC_DIGITAL_RF_TECH_LAST, }; @@ -48,6 +49,7 @@ enum { NFC_DIGITAL_FRAMING_NFCA_SHORT = 0, NFC_DIGITAL_FRAMING_NFCA_STANDARD, NFC_DIGITAL_FRAMING_NFCA_STANDARD_WITH_CRC_A, + NFC_DIGITAL_FRAMING_NFCA_ANTICOL_COMPLETE, NFC_DIGITAL_FRAMING_NFCA_T1T, NFC_DIGITAL_FRAMING_NFCA_T2T, @@ -62,6 +64,9 @@ enum { NFC_DIGITAL_FRAMING_ISO15693_INVENTORY, NFC_DIGITAL_FRAMING_ISO15693_T5T, + NFC_DIGITAL_FRAMING_NFCB, + NFC_DIGITAL_FRAMING_NFCB_T4T, + NFC_DIGITAL_FRAMING_LAST, }; @@ -122,6 +127,15 @@ typedef void (*nfc_digital_cmd_complete_t)(struct nfc_digital_dev *ddev, * the NFC-DEP ATR_REQ command through cb. The digital stack deducts the RF * tech by analyzing the SoD of the frame containing the ATR_REQ command. * This is an asynchronous function. + * @tg_listen_md: If supported, put the device in automatic listen mode with + * mode detection but without automatic anti-collision. In this mode, the + * device automatically detects the RF technology. What the actual + * RF technology is can be retrieved by calling @tg_get_rf_tech. + * The digital stack will then perform the appropriate anti-collision + * sequence. This is an asynchronous function. + * @tg_get_rf_tech: Required when @tg_listen_md is supported, unused otherwise. + * Return the RF Technology that was detected by the @tg_listen_md call. + * This is a synchronous function. * * @switch_rf: Turns device radio on or off. The stack does not call explicitly * switch_rf to turn the radio on. A call to in|tg_configure_hw must turn @@ -156,6 +170,9 @@ struct nfc_digital_ops { struct digital_tg_mdaa_params *mdaa_params, u16 timeout, nfc_digital_cmd_complete_t cb, void *arg); + int (*tg_listen_md)(struct nfc_digital_dev *ddev, u16 timeout, + nfc_digital_cmd_complete_t cb, void *arg); + int (*tg_get_rf_tech)(struct nfc_digital_dev *ddev, u8 *rf_tech); int (*switch_rf)(struct nfc_digital_dev *ddev, bool on); void (*abort_cmd)(struct nfc_digital_dev *ddev); diff --git a/include/net/nfc/hci.h b/include/net/nfc/hci.h index 03c4650b548c..7ee8f4cc610b 100644 --- a/include/net/nfc/hci.h +++ b/include/net/nfc/hci.h @@ -27,6 +27,7 @@ struct nfc_hci_dev; struct nfc_hci_ops { int (*open) (struct nfc_hci_dev *hdev); void (*close) (struct nfc_hci_dev *hdev); + int (*load_session) (struct nfc_hci_dev *hdev); int (*hci_ready) (struct nfc_hci_dev *hdev); /* * xmit must always send the complete buffer before @@ -36,6 +37,7 @@ struct nfc_hci_ops { int (*xmit) (struct nfc_hci_dev *hdev, struct sk_buff *skb); int (*start_poll) (struct nfc_hci_dev *hdev, u32 im_protocols, u32 tm_protocols); + void (*stop_poll) (struct nfc_hci_dev *hdev); int (*dep_link_up)(struct nfc_hci_dev *hdev, struct nfc_target *target, u8 comm_mode, u8 *gb, size_t gb_len); int (*dep_link_down)(struct nfc_hci_dev *hdev); diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index 2e8b40c16274..6c583e244de2 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -264,4 +264,7 @@ int nfc_add_se(struct nfc_dev *dev, u32 se_idx, u16 type); int nfc_remove_se(struct nfc_dev *dev, u32 se_idx); struct nfc_se *nfc_find_se(struct nfc_dev *dev, u32 se_idx); +void nfc_send_to_raw_sock(struct nfc_dev *dev, struct sk_buff *skb, + u8 payload_type, u8 direction); + #endif /* __NET_NFC_H */ diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index a2441fb1428f..6da46dcf1049 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h @@ -136,7 +136,7 @@ tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts, int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb, struct nlattr *rate_tlv, - struct tcf_exts *exts); + struct tcf_exts *exts, bool ovr); void tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts); void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst, struct tcf_exts *src); diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index 891d80d2c4d2..ec030cd76616 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -96,7 +96,7 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct nlattr *tab); void qdisc_put_rtab(struct qdisc_rate_table *tab); void qdisc_put_stab(struct qdisc_size_table *tab); -void qdisc_warn_nonwc(char *txt, struct Qdisc *qdisc); +void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc); int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q, struct net_device *dev, struct netdev_queue *txq, spinlock_t *root_lock); diff --git a/include/net/protocol.h b/include/net/protocol.h index a7e986b08147..d6fcc1fcdb5b 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -86,7 +86,6 @@ struct inet_protosw { struct proto *prot; const struct proto_ops *ops; - char no_check; /* checksum on rcv/xmit/none? */ unsigned char flags; /* See INET_PROTOSW_* below. */ }; #define INET_PROTOSW_REUSE 0x01 /* Are ports automatically reusable? */ diff --git a/include/net/regulatory.h b/include/net/regulatory.h index 75fc1f5a948d..259992444e80 100644 --- a/include/net/regulatory.h +++ b/include/net/regulatory.h @@ -131,6 +131,11 @@ struct regulatory_request { * all country IE information processed by the regulatory core. This will * override %REGULATORY_COUNTRY_IE_FOLLOW_POWER as all country IEs will * be ignored. + * @REGULATORY_ENABLE_RELAX_NO_IR: for devices that wish to allow the + * NO_IR relaxation, which enables transmissions on channels on which + * otherwise initiating radiation is not allowed. This will enable the + * relaxations enabled under the CFG80211_REG_RELAX_NO_IR configuration + * option */ enum ieee80211_regulatory_flags { REGULATORY_CUSTOM_REG = BIT(0), @@ -138,6 +143,7 @@ enum ieee80211_regulatory_flags { REGULATORY_DISABLE_BEACON_HINTS = BIT(2), REGULATORY_COUNTRY_IE_FOLLOW_POWER = BIT(3), REGULATORY_COUNTRY_IE_IGNORE = BIT(4), + REGULATORY_ENABLE_RELAX_NO_IR = BIT(5), }; struct ieee80211_freq_range { diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h index 72240e5ac2c4..e21b9f9653c0 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 d062f81c692f..a3cfb8ebeb53 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -199,7 +199,7 @@ struct tcf_proto_ops { int (*change)(struct net *net, struct sk_buff *, struct tcf_proto*, unsigned long, u32 handle, struct nlattr **, - unsigned long *); + unsigned long *, bool); int (*delete)(struct tcf_proto*, unsigned long); void (*walk)(struct tcf_proto*, struct tcf_walker *arg); @@ -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 4b7cd695e431..f22538e68245 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/constants.h b/include/net/sctp/constants.h index 307728f622ef..8c337cd0e1e4 100644 --- a/include/net/sctp/constants.h +++ b/include/net/sctp/constants.h @@ -311,7 +311,7 @@ typedef enum { SCTP_XMIT_OK, SCTP_XMIT_PMTU_FULL, SCTP_XMIT_RWND_FULL, - SCTP_XMIT_NAGLE_DELAY, + SCTP_XMIT_DELAY, } sctp_xmit_t; /* These are the commands for manipulating transports. */ diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 8e4de46c052e..f6e7397e799d 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -109,6 +109,7 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk, struct sctp_association *asoc); extern struct percpu_counter sctp_sockets_allocated; int sctp_asconf_mgmt(struct sctp_sock *, struct sctp_sockaddr_entry *); +struct sk_buff *sctp_skb_recv_datagram(struct sock *, int, int, int *); /* * sctp/primitive.c @@ -388,27 +389,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) { @@ -574,6 +554,8 @@ static inline void sctp_v6_map_v4(union sctp_addr *addr) static inline void sctp_v4_map_v6(union sctp_addr *addr) { addr->v6.sin6_family = AF_INET6; + addr->v6.sin6_flowinfo = 0; + addr->v6.sin6_scope_id = 0; addr->v6.sin6_port = addr->v4.sin_port; addr->v6.sin6_addr.s6_addr32[3] = addr->v4.sin_addr.s_addr; addr->v6.sin6_addr.s6_addr32[0] = 0; diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 0dfcc92600e8..4ff3f67be62c 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -207,7 +207,9 @@ struct sctp_sock { struct sctp_paddrparams paddrparam; struct sctp_event_subscribe subscribe; struct sctp_assocparams assocparams; + int user_frag; + __u32 autoclose; __u8 nodelay; __u8 disable_fragments; @@ -215,6 +217,8 @@ struct sctp_sock { __u8 frag_interleave; __u32 adaptation_ind; __u32 pd_point; + __u8 recvrcvinfo; + __u8 recvnxtinfo; atomic_t pd_mode; /* Receive to here while partial delivery is in effect. */ @@ -461,10 +465,6 @@ struct sctp_af { int saddr); void (*from_sk) (union sctp_addr *, struct sock *sk); - void (*to_sk_saddr) (union sctp_addr *, - struct sock *sk); - void (*to_sk_daddr) (union sctp_addr *, - struct sock *sk); void (*from_addr_param) (union sctp_addr *, union sctp_addr_param *, __be16 port, int iif); @@ -505,7 +505,9 @@ struct sctp_pf { int (*supported_addrs)(const struct sctp_sock *, __be16 *); struct sock *(*create_accept_sk) (struct sock *sk, struct sctp_association *asoc); - void (*addr_v4map) (struct sctp_sock *, union sctp_addr *); + int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr); + void (*to_sk_saddr)(union sctp_addr *, struct sock *sk); + void (*to_sk_daddr)(union sctp_addr *, struct sock *sk); struct sctp_af *af; }; @@ -838,10 +840,10 @@ struct sctp_transport { unsigned long sackdelay; __u32 sackfreq; - /* When was the last time (in jiffies) that we heard from this - * transport? We use this to pick new active and retran paths. + /* When was the last time that we heard from this transport? We use + * this to pick new active and retran paths. */ - unsigned long last_time_heard; + ktime_t last_time_heard; /* Last time(in jiffies) when cwnd is reduced due to the congestion * indication based on ECNE chunk. @@ -1919,7 +1921,8 @@ struct sctp_chunk *sctp_get_ecne_prepend(struct sctp_association *asoc); /* A convenience structure to parse out SCTP specific CMSGs. */ typedef struct sctp_cmsgs { struct sctp_initmsg *init; - struct sctp_sndrcvinfo *info; + struct sctp_sndrcvinfo *srinfo; + struct sctp_sndinfo *sinfo; } sctp_cmsgs_t; /* Structure for tracking memory objects */ diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h index daacb32b55b5..cccdcfd14973 100644 --- a/include/net/sctp/ulpevent.h +++ b/include/net/sctp/ulpevent.h @@ -129,7 +129,12 @@ struct sctp_ulpevent *sctp_ulpevent_make_sender_dry_event( const struct sctp_association *asoc, gfp_t gfp); void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, - struct msghdr *); + struct msghdr *); +void sctp_ulpevent_read_rcvinfo(const struct sctp_ulpevent *event, + struct msghdr *); +void sctp_ulpevent_read_nxtinfo(const struct sctp_ulpevent *event, + struct msghdr *, struct sock *sk); + __u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event); /* Is this event type enabled? */ @@ -155,10 +160,3 @@ static inline int sctp_ulpevent_is_enabled(const struct sctp_ulpevent *event, } #endif /* __sctp_ulpevent_h__ */ - - - - - - - diff --git a/include/net/secure_seq.h b/include/net/secure_seq.h index f257486f17be..3f36d45b714a 100644 --- a/include/net/secure_seq.h +++ b/include/net/secure_seq.h @@ -3,8 +3,6 @@ #include <linux/types.h> -__u32 secure_ip_id(__be32 daddr); -__u32 secure_ipv6_id(const __be32 daddr[4]); u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport); u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, __be16 dport); diff --git a/include/net/snmp.h b/include/net/snmp.h index 71596261fa99..f1f27fdbb0d5 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h @@ -116,51 +116,49 @@ struct linux_xfrm_mib { unsigned long mibs[LINUX_MIB_XFRMMAX]; }; -#define SNMP_ARRAY_SZ 1 - #define DEFINE_SNMP_STAT(type, name) \ - __typeof__(type) __percpu *name[SNMP_ARRAY_SZ] + __typeof__(type) __percpu *name #define DEFINE_SNMP_STAT_ATOMIC(type, name) \ __typeof__(type) *name #define DECLARE_SNMP_STAT(type, name) \ - extern __typeof__(type) __percpu *name[SNMP_ARRAY_SZ] + extern __typeof__(type) __percpu *name #define SNMP_INC_STATS_BH(mib, field) \ - __this_cpu_inc(mib[0]->mibs[field]) + __this_cpu_inc(mib->mibs[field]) #define SNMP_INC_STATS_USER(mib, field) \ - this_cpu_inc(mib[0]->mibs[field]) + this_cpu_inc(mib->mibs[field]) #define SNMP_INC_STATS_ATOMIC_LONG(mib, field) \ atomic_long_inc(&mib->mibs[field]) #define SNMP_INC_STATS(mib, field) \ - this_cpu_inc(mib[0]->mibs[field]) + this_cpu_inc(mib->mibs[field]) #define SNMP_DEC_STATS(mib, field) \ - this_cpu_dec(mib[0]->mibs[field]) + this_cpu_dec(mib->mibs[field]) #define SNMP_ADD_STATS_BH(mib, field, addend) \ - __this_cpu_add(mib[0]->mibs[field], addend) + __this_cpu_add(mib->mibs[field], addend) #define SNMP_ADD_STATS_USER(mib, field, addend) \ - this_cpu_add(mib[0]->mibs[field], addend) + this_cpu_add(mib->mibs[field], addend) #define SNMP_ADD_STATS(mib, field, addend) \ - this_cpu_add(mib[0]->mibs[field], addend) + this_cpu_add(mib->mibs[field], addend) /* - * Use "__typeof__(*mib[0]) *ptr" instead of "__typeof__(mib[0]) ptr" + * Use "__typeof__(*mib) *ptr" instead of "__typeof__(mib) ptr" * to make @ptr a non-percpu pointer. */ #define SNMP_UPD_PO_STATS(mib, basefield, addend) \ do { \ - __typeof__(*mib[0]->mibs) *ptr = mib[0]->mibs; \ + __typeof__(*mib->mibs) *ptr = mib->mibs; \ this_cpu_inc(ptr[basefield##PKTS]); \ this_cpu_add(ptr[basefield##OCTETS], addend); \ } while (0) #define SNMP_UPD_PO_STATS_BH(mib, basefield, addend) \ do { \ - __typeof__(*mib[0]->mibs) *ptr = mib[0]->mibs; \ + __typeof__(*mib->mibs) *ptr = mib->mibs; \ __this_cpu_inc(ptr[basefield##PKTS]); \ __this_cpu_add(ptr[basefield##OCTETS], addend); \ } while (0) @@ -170,7 +168,7 @@ struct linux_xfrm_mib { #define SNMP_ADD_STATS64_BH(mib, field, addend) \ do { \ - __typeof__(*mib[0]) *ptr = __this_cpu_ptr((mib)[0]); \ + __typeof__(*mib) *ptr = __this_cpu_ptr(mib); \ u64_stats_update_begin(&ptr->syncp); \ ptr->mibs[field] += addend; \ u64_stats_update_end(&ptr->syncp); \ @@ -191,8 +189,8 @@ struct linux_xfrm_mib { #define SNMP_INC_STATS64(mib, field) SNMP_ADD_STATS64(mib, field, 1) #define SNMP_UPD_PO_STATS64_BH(mib, basefield, addend) \ do { \ - __typeof__(*mib[0]) *ptr; \ - ptr = __this_cpu_ptr((mib)[0]); \ + __typeof__(*mib) *ptr; \ + ptr = __this_cpu_ptr(mib); \ u64_stats_update_begin(&ptr->syncp); \ ptr->mibs[basefield##PKTS]++; \ ptr->mibs[basefield##OCTETS] += addend; \ diff --git a/include/net/sock.h b/include/net/sock.h index 21569cf456ed..38805fa02e48 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -67,6 +67,7 @@ #include <linux/atomic.h> #include <net/dst.h> #include <net/checksum.h> +#include <linux/net_tstamp.h> struct cgroup; struct cgroup_subsys; @@ -181,7 +182,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; @@ -243,7 +245,8 @@ struct cg_proto; * @sk_sndbuf: size of send buffer in bytes * @sk_flags: %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE, * %SO_OOBINLINE settings, %SO_TIMESTAMPING settings - * @sk_no_check: %SO_NO_CHECK setting, whether or not checkup packets + * @sk_no_check_tx: %SO_NO_CHECK setting, set checksum in TX packets + * @sk_no_check_rx: allow zero checksum in RX packets * @sk_route_caps: route capabilities (e.g. %NETIF_F_TSO) * @sk_route_nocaps: forbidden route capabilities (e.g NETIF_F_GSO_MASK) * @sk_gso_type: GSO type (e.g. %SKB_GSO_TCPV4) @@ -271,10 +274,13 @@ 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 * @sk_stamp: time stamp of last packet received + * @sk_tsflags: SO_TIMESTAMPING socket options + * @sk_tskey: counter to disambiguate concurrent tstamp requests * @sk_socket: Identd and reporting IO signals * @sk_user_data: RPC layer private data * @sk_frag: cached page frag @@ -316,6 +322,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 @@ -344,6 +351,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; @@ -371,7 +379,8 @@ struct sock { struct sk_buff_head sk_write_queue; kmemcheck_bitfield_begin(flags); unsigned int sk_shutdown : 2, - sk_no_check : 2, + sk_no_check_tx : 1, + sk_no_check_rx : 1, sk_userlocks : 4, sk_protocol : 8, sk_type : 16; @@ -405,6 +414,8 @@ struct sock { void *sk_protinfo; struct timer_list sk_timer; ktime_t sk_stamp; + u16 sk_tsflags; + u32 sk_tskey; struct socket *sk_socket; void *sk_user_data; struct page_frag sk_frag; @@ -654,6 +665,20 @@ static inline void sk_add_bind_node(struct sock *sk, #define sk_for_each_bound(__sk, list) \ hlist_for_each_entry(__sk, list, sk_bind_node) +/** + * sk_nulls_for_each_entry_offset - iterate over a list at a given struct offset + * @tpos: the type * to use as a loop cursor. + * @pos: the &struct hlist_node to use as a loop cursor. + * @head: the head for your list. + * @offset: offset of hlist_node within the struct. + * + */ +#define sk_nulls_for_each_entry_offset(tpos, pos, head, offset) \ + for (pos = (head)->first; \ + (!is_a_nulls(pos)) && \ + ({ tpos = (typeof(*tpos) *)((void *)pos - offset); 1;}); \ + pos = pos->next) + static inline struct user_namespace *sk_user_ns(struct sock *sk) { /* Careful only use this in a context where these parameters @@ -681,13 +706,7 @@ enum sock_flags { SOCK_LOCALROUTE, /* route locally only, %SO_DONTROUTE setting */ SOCK_QUEUE_SHRUNK, /* write queue has been shrunk recently */ SOCK_MEMALLOC, /* VM depends on this socket for swapping */ - SOCK_TIMESTAMPING_TX_HARDWARE, /* %SOF_TIMESTAMPING_TX_HARDWARE */ - SOCK_TIMESTAMPING_TX_SOFTWARE, /* %SOF_TIMESTAMPING_TX_SOFTWARE */ - SOCK_TIMESTAMPING_RX_HARDWARE, /* %SOF_TIMESTAMPING_RX_HARDWARE */ SOCK_TIMESTAMPING_RX_SOFTWARE, /* %SOF_TIMESTAMPING_RX_SOFTWARE */ - SOCK_TIMESTAMPING_SOFTWARE, /* %SOF_TIMESTAMPING_SOFTWARE */ - SOCK_TIMESTAMPING_RAW_HARDWARE, /* %SOF_TIMESTAMPING_RAW_HARDWARE */ - SOCK_TIMESTAMPING_SYS_HARDWARE, /* %SOF_TIMESTAMPING_SYS_HARDWARE */ SOCK_FASYNC, /* fasync() active */ SOCK_RXQ_OVFL, SOCK_ZEROCOPY, /* buffers from userspace */ @@ -790,8 +809,7 @@ static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb) * Do not take into account this skb truesize, * to allow even a single big packet to come. */ -static inline bool sk_rcvqueues_full(const struct sock *sk, const struct sk_buff *skb, - unsigned int limit) +static inline bool sk_rcvqueues_full(const struct sock *sk, unsigned int limit) { unsigned int qsize = sk->sk_backlog.len + atomic_read(&sk->sk_rmem_alloc); @@ -802,7 +820,7 @@ static inline bool sk_rcvqueues_full(const struct sock *sk, const struct sk_buff static inline __must_check int sk_add_backlog(struct sock *sk, struct sk_buff *skb, unsigned int limit) { - if (sk_rcvqueues_full(sk, skb, limit)) + if (sk_rcvqueues_full(sk, limit)) return -ENOBUFS; __sk_add_backlog(sk, skb); @@ -1728,8 +1746,8 @@ sk_dst_get(struct sock *sk) rcu_read_lock(); dst = rcu_dereference(sk->sk_dst_cache); - if (dst) - dst_hold(dst); + if (dst && !atomic_inc_not_zero(&dst->__refcnt)) + dst = NULL; rcu_read_unlock(); return dst; } @@ -1766,9 +1784,11 @@ __sk_dst_set(struct sock *sk, struct dst_entry *dst) static inline void sk_dst_set(struct sock *sk, struct dst_entry *dst) { - spin_lock(&sk->sk_dst_lock); - __sk_dst_set(sk, dst); - spin_unlock(&sk->sk_dst_lock); + struct dst_entry *old_dst; + + sk_tx_queue_clear(sk); + old_dst = xchg((__force struct dst_entry **)&sk->sk_dst_cache, dst); + dst_release(old_dst); } static inline void @@ -1780,9 +1800,7 @@ __sk_dst_reset(struct sock *sk) static inline void sk_dst_reset(struct sock *sk) { - spin_lock(&sk->sk_dst_lock); - __sk_dst_reset(sk); - spin_unlock(&sk->sk_dst_lock); + sk_dst_set(sk, NULL); } struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie); @@ -1976,6 +1994,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 @@ -1990,6 +2016,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 @@ -2133,21 +2160,17 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) /* * generate control messages if - * - receive time stamping in software requested (SOCK_RCVTSTAMP - * or SOCK_TIMESTAMPING_RX_SOFTWARE) + * - receive time stamping in software requested * - software time stamp available and wanted - * (SOCK_TIMESTAMPING_SOFTWARE) * - hardware time stamps available and wanted - * (SOCK_TIMESTAMPING_SYS_HARDWARE or - * SOCK_TIMESTAMPING_RAW_HARDWARE) */ if (sock_flag(sk, SOCK_RCVTSTAMP) || - sock_flag(sk, SOCK_TIMESTAMPING_RX_SOFTWARE) || - (kt.tv64 && sock_flag(sk, SOCK_TIMESTAMPING_SOFTWARE)) || + (sk->sk_tsflags & SOF_TIMESTAMPING_RX_SOFTWARE) || + (kt.tv64 && + (sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE || + skb_shinfo(skb)->tx_flags & SKBTX_ANY_SW_TSTAMP)) || (hwtstamps->hwtstamp.tv64 && - sock_flag(sk, SOCK_TIMESTAMPING_RAW_HARDWARE)) || - (hwtstamps->syststamp.tv64 && - sock_flag(sk, SOCK_TIMESTAMPING_SYS_HARDWARE))) + (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE))) __sock_recv_timestamp(msg, sk, skb); else sk->sk_stamp = kt; @@ -2163,12 +2186,11 @@ static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) { #define FLAGS_TS_OR_DROPS ((1UL << SOCK_RXQ_OVFL) | \ - (1UL << SOCK_RCVTSTAMP) | \ - (1UL << SOCK_TIMESTAMPING_SOFTWARE) | \ - (1UL << SOCK_TIMESTAMPING_RAW_HARDWARE) | \ - (1UL << SOCK_TIMESTAMPING_SYS_HARDWARE)) + (1UL << SOCK_RCVTSTAMP)) +#define TSFLAGS_ANY (SOF_TIMESTAMPING_SOFTWARE | \ + SOF_TIMESTAMPING_RAW_HARDWARE) - if (sk->sk_flags & FLAGS_TS_OR_DROPS) + if (sk->sk_flags & FLAGS_TS_OR_DROPS || sk->sk_tsflags & TSFLAGS_ANY) __sock_recv_ts_and_drops(msg, sk, skb); else sk->sk_stamp = skb->tstamp; @@ -2177,11 +2199,11 @@ static inline void sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, /** * sock_tx_timestamp - checks whether the outgoing packet is to be time stamped * @sk: socket sending this packet - * @tx_flags: filled with instructions for time stamping + * @tx_flags: completed with instructions for time stamping * - * Currently only depends on SOCK_TIMESTAMPING* flags. + * Note : callers should take care of initial *tx_flags value (usually 0) */ -void sock_tx_timestamp(struct sock *sk, __u8 *tx_flags); +void sock_tx_timestamp(const struct sock *sk, __u8 *tx_flags); /** * sk_eat_skb - Release a skb if it is no longer needed diff --git a/include/net/tcp.h b/include/net/tcp.h index 87d877408188..dafa1cbc149b 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -220,8 +220,6 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); #define TFO_SERVER_ENABLE 2 #define TFO_CLIENT_NO_COOKIE 4 /* Data in SYN w/o cookie option */ -/* Process SYN data but skip cookie validation */ -#define TFO_SERVER_COOKIE_NOT_CHKED 0x100 /* Accept SYN data w/o any cookie option */ #define TFO_SERVER_COOKIE_NOT_REQD 0x200 @@ -230,10 +228,6 @@ void tcp_time_wait(struct sock *sk, int state, int timeo); */ #define TFO_SERVER_WO_SOCKOPT1 0x400 #define TFO_SERVER_WO_SOCKOPT2 0x800 -/* Always create TFO child sockets on a TFO listener even when - * cookie/data not present. (For testing purpose!) - */ -#define TFO_SERVER_ALWAYS 0x1000 extern struct inet_timewait_death_row tcp_death_row; @@ -417,7 +411,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb, bool fastopen); int tcp_child_process(struct sock *parent, struct sock *child, struct sk_buff *skb); -void tcp_enter_loss(struct sock *sk, int how); +void tcp_enter_loss(struct sock *sk); void tcp_clear_retrans(struct tcp_sock *tp); void tcp_update_metrics(struct sock *sk); void tcp_init_metrics(struct sock *sk); @@ -499,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); @@ -522,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 */ @@ -541,7 +522,7 @@ void tcp_retransmit_timer(struct sock *sk); void tcp_xmit_retransmit_queue(struct sock *); void tcp_simple_retransmit(struct sock *); int tcp_trim_head(struct sock *, struct sk_buff *, u32); -int tcp_fragment(struct sock *, struct sk_buff *, u32, unsigned int); +int tcp_fragment(struct sock *, struct sk_buff *, u32, unsigned int, gfp_t); void tcp_send_probe0(struct sock *); void tcp_send_partial(struct sock *); @@ -558,7 +539,6 @@ void tcp_send_loss_probe(struct sock *sk); bool tcp_schedule_loss_probe(struct sock *sk); /* tcp_input.c */ -void tcp_cwnd_application_limited(struct sock *sk); void tcp_resume_early_retransmit(struct sock *sk); void tcp_rearm_rto(struct sock *sk); void tcp_reset(struct sock *sk); @@ -797,7 +777,7 @@ struct tcp_congestion_ops { /* return slow start threshold (required) */ u32 (*ssthresh)(struct sock *sk); /* do new cwnd calculation (required) */ - void (*cong_avoid)(struct sock *sk, u32 ack, u32 acked, u32 in_flight); + void (*cong_avoid)(struct sock *sk, u32 ack, u32 acked); /* call before changing ca_state (optional) */ void (*set_state)(struct sock *sk, u8 new_state); /* call when cwnd event occurs (optional) */ @@ -829,7 +809,7 @@ void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w); extern struct tcp_congestion_ops tcp_init_congestion_ops; u32 tcp_reno_ssthresh(struct sock *sk); -void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 acked, u32 in_flight); +void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 acked); extern struct tcp_congestion_ops tcp_reno; static inline void tcp_set_ca_state(struct sock *sk, const u8 ca_state) @@ -948,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 @@ -975,7 +955,30 @@ static inline u32 tcp_wnd_end(const struct tcp_sock *tp) { return tp->snd_una + tp->snd_wnd; } -bool tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight); + +/* We follow the spirit of RFC2861 to validate cwnd but implement a more + * flexible approach. The RFC suggests cwnd should not be raised unless + * it was fully used previously. And that's exactly what we do in + * congestion avoidance mode. But in slow start we allow cwnd to grow + * as long as the application has used half the cwnd. + * Example : + * cwnd is 10 (IW10), but application sends 9 frames. + * We allow cwnd to reach 18 when all frames are ACKed. + * This check is safe because it's as aggressive as slow start which already + * risks 100% overshoot. The advantage is that we discourage application to + * either send more filler packets or data to artificially blow up the cwnd + * usage, and allow application-limited process to probe bw more aggressively. + */ +static inline bool tcp_is_cwnd_limited(const struct sock *sk) +{ + const struct tcp_sock *tp = tcp_sk(sk); + + /* If in slow start, ensure cwnd grows to twice what was ACKed. */ + if (tp->snd_cwnd <= tp->snd_ssthresh) + return tp->snd_cwnd < 2 * tp->max_packets_out; + + return tp->is_cwnd_limited; +} static inline void tcp_check_probe_timer(struct sock *sk) { @@ -1082,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); @@ -1090,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; @@ -1101,8 +1104,12 @@ 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, + struct sock *sk, struct dst_entry *dst); + void tcp_enter_memory_pressure(struct sock *sk); static inline int keepalive_intvl_when(const struct tcp_sock *tp) @@ -1312,8 +1319,10 @@ void tcp_free_fastopen_req(struct tcp_sock *tp); extern struct tcp_fastopen_context __rcu *tcp_fastopen_ctx; int tcp_fastopen_reset_cipher(void *key, unsigned int len); -void tcp_fastopen_cookie_gen(__be32 src, __be32 dst, - struct tcp_fastopen_cookie *foc); +bool tcp_try_fastopen(struct sock *sk, struct sk_buff *skb, + struct request_sock *req, + struct tcp_fastopen_cookie *foc, + struct dst_entry *dst); void tcp_fastopen_init_key_once(bool publish); #define TCP_FASTOPEN_KEY_LENGTH 16 @@ -1564,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 @@ -1581,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); @@ -1590,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/tso.h b/include/net/tso.h new file mode 100644 index 000000000000..47e5444f7d15 --- /dev/null +++ b/include/net/tso.h @@ -0,0 +1,20 @@ +#ifndef _TSO_H +#define _TSO_H + +#include <net/ip.h> + +struct tso_t { + int next_frag_idx; + void *data; + size_t size; + u16 ip_id; + u32 tcp_seq; +}; + +int tso_count_descs(struct sk_buff *skb); +void tso_build_hdr(struct sk_buff *skb, char *hdr, struct tso_t *tso, + int size, bool is_last); +void tso_build_data(struct sk_buff *skb, struct tso_t *tso, int size); +void tso_start(struct sk_buff *skb, struct tso_t *tso); + +#endif /* _TSO_H */ diff --git a/include/net/udp.h b/include/net/udp.h index a24f0f3e107f..70f941368ace 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -95,15 +95,6 @@ static inline struct udp_hslot *udp_hashslot2(struct udp_table *table, return &table->hash2[hash & table->mask]; } -/* Note: this must match 'valbool' in sock_setsockopt */ -#define UDP_CSUM_NOXMIT 1 - -/* Used by SunRPC/xprt layer. */ -#define UDP_CSUM_NORCV 2 - -/* Default, as per the RFC, is to always do csums. */ -#define UDP_CSUM_DEFAULT 0 - extern struct proto udp_prot; extern atomic_long_t udp_memory_allocated; @@ -120,7 +111,9 @@ struct sk_buff; */ static inline __sum16 __udp_lib_checksum_complete(struct sk_buff *skb) { - return __skb_checksum_complete_head(skb, UDP_SKB_CB(skb)->cscov); + return (UDP_SKB_CB(skb)->cscov == skb->len ? + __skb_checksum_complete(skb) : + __skb_checksum_complete_head(skb, UDP_SKB_CB(skb)->cscov)); } static inline int udp_lib_checksum_complete(struct sk_buff *skb) @@ -156,6 +149,15 @@ static inline __wsum udp_csum(struct sk_buff *skb) return csum; } +static inline __sum16 udp_v4_check(int len, __be32 saddr, + __be32 daddr, __wsum base) +{ + return csum_tcpudp_magic(saddr, daddr, len, IPPROTO_UDP, base); +} + +void udp_set_csum(bool nocheck, struct sk_buff *skb, + __be32 saddr, __be32 daddr, int len); + /* hash routines shared between UDPv4/6 and UDP-Litev4/6 */ static inline void udp_lib_hash(struct sock *sk) { @@ -174,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 000000000000..ffd69cbded35 --- /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 5deef1ae78c9..d5f59f3fc35d 100644 --- a/include/net/vxlan.h +++ b/include/net/vxlan.h @@ -24,18 +24,26 @@ struct vxlan_sock { struct udp_offload udp_offloads; }; +#define VXLAN_F_LEARN 0x01 +#define VXLAN_F_PROXY 0x02 +#define VXLAN_F_RSC 0x04 +#define VXLAN_F_L2MISS 0x08 +#define VXLAN_F_L3MISS 0x10 +#define VXLAN_F_IPV6 0x20 +#define VXLAN_F_UDP_CSUM 0x40 +#define VXLAN_F_UDP_ZERO_CSUM6_TX 0x80 +#define VXLAN_F_UDP_ZERO_CSUM6_RX 0x100 + struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port, vxlan_rcv_t *rcv, void *data, - bool no_share, bool ipv6); + bool no_share, u32 flags); void vxlan_sock_release(struct vxlan_sock *vs); int vxlan_xmit_skb(struct vxlan_sock *vs, struct rtable *rt, struct sk_buff *skb, __be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df, - __be16 src_port, __be16 dst_port, __be32 vni); - -__be16 vxlan_src_port(__u16 port_min, __u16 port_max, struct sk_buff *skb); + __be16 src_port, __be16 dst_port, __be32 vni, bool xnet); /* IP header + UDP + VXLAN + Ethernet header */ #define VXLAN_HEADROOM (20 + 8 + 8 + 14) diff --git a/include/net/wimax.h b/include/net/wimax.h index 98498e1daa06..e52ef5357e08 100644 --- a/include/net/wimax.h +++ b/include/net/wimax.h @@ -483,8 +483,8 @@ void wimax_report_rfkill_sw(struct wimax_dev *, enum wimax_rf_state); * Be sure not to modify skb->data in the middle (ie: don't use * skb_push()/skb_pull()/skb_reserve() on the skb). * - * "pipe_name" is any string, than can be interpreted as the name of - * the pipe or destinatary; the interpretation of it is driver + * "pipe_name" is any string, that can be interpreted as the name of + * the pipe or recipient; the interpretation of it is driver * specific, so the recipient can multiplex it as wished. It can be * NULL, it won't be used - an example is using a "diagnostics" tag to * send diagnostics information that a device-specific diagnostics diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 116e9c7e19cb..721e9c3b11bd 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -691,13 +691,6 @@ struct xfrm_spi_skb_cb { #define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0])) -/* Audit Information */ -struct xfrm_audit { - u32 secid; - kuid_t loginuid; - unsigned int sessionid; -}; - #ifdef CONFIG_AUDITSYSCALL static inline struct audit_buffer *xfrm_audit_start(const char *op) { @@ -713,30 +706,24 @@ static inline struct audit_buffer *xfrm_audit_start(const char *op) return audit_buf; } -static inline void xfrm_audit_helper_usrinfo(kuid_t auid, unsigned int ses, u32 secid, +static inline void xfrm_audit_helper_usrinfo(bool task_valid, struct audit_buffer *audit_buf) { - char *secctx; - u32 secctx_len; - - audit_log_format(audit_buf, " auid=%u ses=%u", - from_kuid(&init_user_ns, auid), ses); - if (secid != 0 && - security_secid_to_secctx(secid, &secctx, &secctx_len) == 0) { - audit_log_format(audit_buf, " subj=%s", secctx); - security_release_secctx(secctx, secctx_len); - } else - audit_log_task_context(audit_buf); -} - -void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, kuid_t auid, - unsigned int ses, u32 secid); -void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, kuid_t auid, - unsigned int ses, u32 secid); -void xfrm_audit_state_add(struct xfrm_state *x, int result, kuid_t auid, - unsigned int ses, u32 secid); -void xfrm_audit_state_delete(struct xfrm_state *x, int result, kuid_t auid, - unsigned int ses, u32 secid); + const unsigned int auid = from_kuid(&init_user_ns, task_valid ? + audit_get_loginuid(current) : + INVALID_UID); + const unsigned int ses = task_valid ? audit_get_sessionid(current) : + (unsigned int) -1; + + audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses); + audit_log_task_context(audit_buf); +} + +void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, bool task_valid); +void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, + bool task_valid); +void xfrm_audit_state_add(struct xfrm_state *x, int result, bool task_valid); +void xfrm_audit_state_delete(struct xfrm_state *x, int result, bool task_valid); void xfrm_audit_state_replay_overflow(struct xfrm_state *x, struct sk_buff *skb); void xfrm_audit_state_replay(struct xfrm_state *x, struct sk_buff *skb, @@ -749,22 +736,22 @@ void xfrm_audit_state_icvfail(struct xfrm_state *x, struct sk_buff *skb, #else static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result, - kuid_t auid, unsigned int ses, u32 secid) + bool task_valid) { } static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result, - kuid_t auid, unsigned int ses, u32 secid) + bool task_valid) { } static inline void xfrm_audit_state_add(struct xfrm_state *x, int result, - kuid_t auid, unsigned int ses, u32 secid) + bool task_valid) { } static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result, - kuid_t auid, unsigned int ses, u32 secid) + bool task_valid) { } @@ -1508,7 +1495,7 @@ struct xfrmk_spdinfo { struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq); int xfrm_state_delete(struct xfrm_state *x); -int xfrm_state_flush(struct net *net, u8 proto, struct xfrm_audit *audit_info); +int xfrm_state_flush(struct net *net, u8 proto, bool task_valid); void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si); void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si); u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq); @@ -1603,7 +1590,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(struct net *net, u32 mark, int *err); struct xfrm_policy *xfrm_policy_byid(struct net *net, u32 mark, u8, int dir, u32 id, int delete, int *err); -int xfrm_policy_flush(struct net *net, u8 type, struct xfrm_audit *audit_info); +int xfrm_policy_flush(struct net *net, u8 type, bool task_valid); u32 xfrm_get_acqseq(void); int verify_spi_info(u8 proto, u32 min, u32 max); int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi); |
