diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-04 09:41:05 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-11-04 09:41:05 -0800 |
| commit | b0f85fa11aefc4f3e03306b4cd47f113bd57dcba (patch) | |
| tree | 1333d36d99fde3f97210795941fc246f0ad08a75 /include/net | |
| parent | ccc9d4a6d640cbde05d519edeb727881646cf71b (diff) | |
| parent | f32bfb9a8ca083f8d148ea90ae5ba66f4831836e (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller:
Changes of note:
1) Allow to schedule ICMP packets in IPVS, from Alex Gartrell.
2) Provide FIB table ID in ipv4 route dumps just as ipv6 does, from
David Ahern.
3) Allow the user to ask for the statistics to be filtered out of
ipv4/ipv6 address netlink dumps. From Sowmini Varadhan.
4) More work to pass the network namespace context around deep into
various packet path APIs, starting with the netfilter hooks. From
Eric W Biederman.
5) Add layer 2 TX/RX checksum offloading to qeth driver, from Thomas
Richter.
6) Use usec resolution for SYN/ACK RTTs in TCP, from Yuchung Cheng.
7) Support Very High Throughput in wireless MESH code, from Bob
Copeland.
8) Allow setting the ageing_time in switchdev/rocker. From Scott
Feldman.
9) Properly autoload L2TP type modules, from Stephen Hemminger.
10) Fix and enable offload features by default in 8139cp driver, from
David Woodhouse.
11) Support both ipv4 and ipv6 sockets in a single vxlan device, from
Jiri Benc.
12) Fix CWND limiting of thin streams in TCP, from Bendik Rønning
Opstad.
13) Fix IPSEC flowcache overflows on large systems, from Steffen
Klassert.
14) Convert bridging to track VLANs using rhashtable entries rather than
a bitmap. From Nikolay Aleksandrov.
15) Make TCP listener handling completely lockless, this is a major
accomplishment. Incoming request sockets now live in the
established hash table just like any other socket too.
From Eric Dumazet.
15) Provide more bridging attributes to netlink, from Nikolay
Aleksandrov.
16) Use hash based algorithm for ipv4 multipath routing, this was very
long overdue. From Peter Nørlund.
17) Several y2038 cures, mostly avoiding timespec. From Arnd Bergmann.
18) Allow non-root execution of EBPF programs, from Alexei Starovoitov.
19) Support SO_INCOMING_CPU as setsockopt, from Eric Dumazet. This
influences the port binding selection logic used by SO_REUSEPORT.
20) Add ipv6 support to VRF, from David Ahern.
21) Add support for Mellanox Spectrum switch ASIC, from Jiri Pirko.
22) Add rtl8xxxu Realtek wireless driver, from Jes Sorensen.
23) Implement RACK loss recovery in TCP, from Yuchung Cheng.
24) Support multipath routes in MPLS, from Roopa Prabhu.
25) Fix POLLOUT notification for listening sockets in AF_UNIX, from Eric
Dumazet.
26) Add new QED Qlogic river, from Yuval Mintz, Manish Chopra, and
Sudarsana Kalluru.
27) Don't fetch timestamps on AF_UNIX sockets, from Hannes Frederic
Sowa.
28) Support ipv6 geneve tunnels, from John W Linville.
29) Add flood control support to switchdev layer, from Ido Schimmel.
30) Fix CHECKSUM_PARTIAL handling of potentially fragmented frames, from
Hannes Frederic Sowa.
31) Support persistent maps and progs in bpf, from Daniel Borkmann.
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1790 commits)
sh_eth: use DMA barriers
switchdev: respect SKIP_EOPNOTSUPP flag in case there is no recursion
net: sched: kill dead code in sch_choke.c
irda: Delete an unnecessary check before the function call "irlmp_unregister_service"
net: dsa: mv88e6xxx: include DSA ports in VLANs
net: dsa: mv88e6xxx: disable SA learning for DSA and CPU ports
net/core: fix for_each_netdev_feature
vlan: Invoke driver vlan hooks only if device is present
arcnet/com20020: add LEDS_CLASS dependency
bpf, verifier: annotate verbose printer with __printf
dp83640: Only wait for timestamps for packets with timestamping enabled.
ptp: Change ptp_class to a proper bitmask
dp83640: Prune rx timestamp list before reading from it
dp83640: Delay scheduled work.
dp83640: Include hash in timestamp/packet matching
ipv6: fix tunnel error handling
net/mlx5e: Fix LSO vlan insertion
net/mlx5e: Re-eanble client vlan TX acceleration
net/mlx5e: Return error in case mlx5e_set_features() fails
net/mlx5e: Don't allow more than max supported channels
...
Diffstat (limited to 'include/net')
72 files changed, 1650 insertions, 1231 deletions
diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h index a2f59ec98d24..cf3bc564ac03 100644 --- a/include/net/6lowpan.h +++ b/include/net/6lowpan.h @@ -56,146 +56,37 @@ #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 */ -#define UIP_PROTO_UDP 17 /* ipv6 next header value for UDP */ -#define UIP_FRAGH_LEN 8 /* ipv6 fragment header size */ +#define EUI64_ADDR_LEN 8 -/* - * ipv6 address based on mac - * second bit-flip (Universe/Local) is done according RFC2464 +#define LOWPAN_NHC_MAX_ID_LEN 1 +/* Maximum next header compression length which we currently support inclusive + * possible inline data. */ -#define is_addr_mac_addr_based(a, m) \ - ((((a)->s6_addr[8]) == (((m)[0]) ^ 0x02)) && \ - (((a)->s6_addr[9]) == (m)[1]) && \ - (((a)->s6_addr[10]) == (m)[2]) && \ - (((a)->s6_addr[11]) == (m)[3]) && \ - (((a)->s6_addr[12]) == (m)[4]) && \ - (((a)->s6_addr[13]) == (m)[5]) && \ - (((a)->s6_addr[14]) == (m)[6]) && \ - (((a)->s6_addr[15]) == (m)[7])) - -/* - * check whether we can compress the IID to 16 bits, - * it's possible for unicast adresses with first 49 bits are zero only. - */ -#define lowpan_is_iid_16_bit_compressable(a) \ - ((((a)->s6_addr16[4]) == 0) && \ - (((a)->s6_addr[10]) == 0) && \ - (((a)->s6_addr[11]) == 0xff) && \ - (((a)->s6_addr[12]) == 0xfe) && \ - (((a)->s6_addr[13]) == 0)) - -/* check whether the 112-bit gid of the multicast address is mappable to: */ - -/* 48 bits, FFXX::00XX:XXXX:XXXX */ -#define lowpan_is_mcast_addr_compressable48(a) \ - ((((a)->s6_addr16[1]) == 0) && \ - (((a)->s6_addr16[2]) == 0) && \ - (((a)->s6_addr16[3]) == 0) && \ - (((a)->s6_addr16[4]) == 0) && \ - (((a)->s6_addr[10]) == 0)) - -/* 32 bits, FFXX::00XX:XXXX */ -#define lowpan_is_mcast_addr_compressable32(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_addr[12]) == 0)) - -/* 8 bits, FF02::00XX */ -#define lowpan_is_mcast_addr_compressable8(a) \ - ((((a)->s6_addr[1]) == 2) && \ - (((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)) - -#define lowpan_is_addr_broadcast(a) \ - ((((a)[0]) == 0xFF) && \ - (((a)[1]) == 0xFF) && \ - (((a)[2]) == 0xFF) && \ - (((a)[3]) == 0xFF) && \ - (((a)[4]) == 0xFF) && \ - (((a)[5]) == 0xFF) && \ - (((a)[6]) == 0xFF) && \ - (((a)[7]) == 0xFF)) - -#define LOWPAN_DISPATCH_IPV6 0x41 /* 01000001 = 65 */ -#define LOWPAN_DISPATCH_HC1 0x42 /* 01000010 = 66 */ -#define LOWPAN_DISPATCH_IPHC 0x60 /* 011xxxxx = ... */ -#define LOWPAN_DISPATCH_FRAG1 0xc0 /* 11000xxx */ -#define LOWPAN_DISPATCH_FRAGN 0xe0 /* 11100xxx */ - -#define LOWPAN_DISPATCH_MASK 0xf8 /* 11111000 */ - -#define LOWPAN_FRAG_TIMEOUT (HZ * 60) /* time-out 60 sec */ - -#define LOWPAN_FRAG1_HEAD_SIZE 0x4 -#define LOWPAN_FRAGN_HEAD_SIZE 0x5 - -/* - * Values of fields within the IPHC encoding first byte - * (C stands for compressed and I for inline) +#define LOWPAN_NHC_MAX_HDR_LEN (sizeof(struct udphdr)) +/* Max IPHC Header len without IPv6 hdr specific inline data. + * Useful for getting the "extra" bytes we need at worst case compression. + * + * LOWPAN_IPHC + CID + LOWPAN_NHC_MAX_ID_LEN */ -#define LOWPAN_IPHC_TF 0x18 - -#define LOWPAN_IPHC_FL_C 0x10 -#define LOWPAN_IPHC_TC_C 0x08 -#define LOWPAN_IPHC_NH_C 0x04 -#define LOWPAN_IPHC_TTL_1 0x01 -#define LOWPAN_IPHC_TTL_64 0x02 -#define LOWPAN_IPHC_TTL_255 0x03 -#define LOWPAN_IPHC_TTL_I 0x00 - +#define LOWPAN_IPHC_MAX_HEADER_LEN (2 + 1 + LOWPAN_NHC_MAX_ID_LEN) +/* Maximum worst case IPHC header buffer size */ +#define LOWPAN_IPHC_MAX_HC_BUF_LEN (sizeof(struct ipv6hdr) + \ + LOWPAN_IPHC_MAX_HEADER_LEN + \ + LOWPAN_NHC_MAX_HDR_LEN) -/* Values of fields within the IPHC encoding second byte */ -#define LOWPAN_IPHC_CID 0x80 +#define LOWPAN_DISPATCH_IPV6 0x41 /* 01000001 = 65 */ +#define LOWPAN_DISPATCH_IPHC 0x60 /* 011xxxxx = ... */ +#define LOWPAN_DISPATCH_IPHC_MASK 0xe0 -#define LOWPAN_IPHC_ADDR_00 0x00 -#define LOWPAN_IPHC_ADDR_01 0x01 -#define LOWPAN_IPHC_ADDR_02 0x02 -#define LOWPAN_IPHC_ADDR_03 0x03 - -#define LOWPAN_IPHC_SAC 0x40 -#define LOWPAN_IPHC_SAM 0x30 - -#define LOWPAN_IPHC_SAM_BIT 4 - -#define LOWPAN_IPHC_M 0x08 -#define LOWPAN_IPHC_DAC 0x04 -#define LOWPAN_IPHC_DAM_00 0x00 -#define LOWPAN_IPHC_DAM_01 0x01 -#define LOWPAN_IPHC_DAM_10 0x02 -#define LOWPAN_IPHC_DAM_11 0x03 - -#define LOWPAN_IPHC_DAM_BIT 0 -/* - * LOWPAN_UDP encoding (works together with IPHC) - */ -#define LOWPAN_NHC_UDP_MASK 0xF8 -#define LOWPAN_NHC_UDP_ID 0xF0 -#define LOWPAN_NHC_UDP_CHECKSUMC 0x04 -#define LOWPAN_NHC_UDP_CHECKSUMI 0x00 - -#define LOWPAN_NHC_UDP_4BIT_PORT 0xF0B0 -#define LOWPAN_NHC_UDP_4BIT_MASK 0xFFF0 -#define LOWPAN_NHC_UDP_8BIT_PORT 0xF000 -#define LOWPAN_NHC_UDP_8BIT_MASK 0xFF00 +static inline bool lowpan_is_ipv6(u8 dispatch) +{ + return dispatch == LOWPAN_DISPATCH_IPV6; +} -/* values for port compression, _with checksum_ ie bit 5 set to 0 */ -#define LOWPAN_NHC_UDP_CS_P_00 0xF0 /* all inline */ -#define LOWPAN_NHC_UDP_CS_P_01 0xF1 /* source 16bit inline, - dest = 0xF0 + 8 bit inline */ -#define LOWPAN_NHC_UDP_CS_P_10 0xF2 /* source = 0xF0 + 8bit inline, - dest = 16 bit inline */ -#define LOWPAN_NHC_UDP_CS_P_11 0xF3 /* source & dest = 0xF0B + 4bit inline */ -#define LOWPAN_NHC_UDP_CS_C 0x04 /* checksum elided */ +static inline bool lowpan_is_iphc(u8 dispatch) +{ + return (dispatch & LOWPAN_DISPATCH_IPHC_MASK) == LOWPAN_DISPATCH_IPHC; +} #define LOWPAN_PRIV_SIZE(llpriv_size) \ (sizeof(struct lowpan_priv) + llpriv_size) @@ -218,10 +109,23 @@ struct lowpan_priv *lowpan_priv(const struct net_device *dev) return netdev_priv(dev); } +struct lowpan_802154_cb { + u16 d_tag; + unsigned int d_size; + u8 d_offset; +}; + +static inline +struct lowpan_802154_cb *lowpan_802154_cb(const struct sk_buff *skb) +{ + BUILD_BUG_ON(sizeof(struct lowpan_802154_cb) > sizeof(skb->cb)); + return (struct lowpan_802154_cb *)skb->cb; +} + #ifdef DEBUG /* print data in line */ static inline void raw_dump_inline(const char *caller, char *msg, - unsigned char *buf, int len) + const unsigned char *buf, int len) { if (msg) pr_debug("%s():%s: ", caller, msg); @@ -236,7 +140,7 @@ static inline void raw_dump_inline(const char *caller, char *msg, * ... */ static inline void raw_dump_table(const char *caller, char *msg, - unsigned char *buf, int len) + const unsigned char *buf, int len) { if (msg) pr_debug("%s():%s:\n", caller, msg); @@ -245,24 +149,25 @@ static inline void raw_dump_table(const char *caller, char *msg, } #else static inline void raw_dump_table(const char *caller, char *msg, - unsigned char *buf, int len) { } + const unsigned char *buf, int len) { } static inline void raw_dump_inline(const char *caller, char *msg, - unsigned char *buf, int len) { } + const unsigned char *buf, int len) { } #endif -static inline int lowpan_fetch_skb_u8(struct sk_buff *skb, u8 *val) -{ - if (unlikely(!pskb_may_pull(skb, 1))) - return -EINVAL; - - *val = skb->data[0]; - skb_pull(skb, 1); - - return 0; -} - -static inline bool lowpan_fetch_skb(struct sk_buff *skb, - void *data, const unsigned int len) +/** + * lowpan_fetch_skb - getting inline data from 6LoWPAN header + * + * This function will pull data from sk buffer and put it into data to + * remove the 6LoWPAN inline data. This function returns true if the + * sk buffer is too small to pull the amount of data which is specified + * by len. + * + * @skb: the buffer where the inline data should be pulled from. + * @data: destination buffer for the inline data. + * @len: amount of data which should be pulled in bytes. + */ +static inline bool lowpan_fetch_skb(struct sk_buff *skb, void *data, + unsigned int len) { if (unlikely(!pskb_may_pull(skb, len))) return true; @@ -280,129 +185,44 @@ static inline void lowpan_push_hc_data(u8 **hc_ptr, const void *data, *hc_ptr += len; } -static inline u8 lowpan_addr_mode_size(const u8 addr_mode) -{ - static const u8 addr_sizes[] = { - [LOWPAN_IPHC_ADDR_00] = 16, - [LOWPAN_IPHC_ADDR_01] = 8, - [LOWPAN_IPHC_ADDR_02] = 2, - [LOWPAN_IPHC_ADDR_03] = 0, - }; - return addr_sizes[addr_mode]; -} - -static inline u8 lowpan_next_hdr_size(const u8 h_enc, u16 *uncomp_header) -{ - u8 ret = 1; - - if ((h_enc & LOWPAN_NHC_UDP_MASK) == LOWPAN_NHC_UDP_ID) { - *uncomp_header += sizeof(struct udphdr); - - switch (h_enc & LOWPAN_NHC_UDP_CS_P_11) { - case LOWPAN_NHC_UDP_CS_P_00: - ret += 4; - break; - case LOWPAN_NHC_UDP_CS_P_01: - case LOWPAN_NHC_UDP_CS_P_10: - ret += 3; - break; - case LOWPAN_NHC_UDP_CS_P_11: - ret++; - break; - default: - break; - } - - if (!(h_enc & LOWPAN_NHC_UDP_CS_C)) - ret += 2; - } - - return ret; -} +void lowpan_netdev_setup(struct net_device *dev, enum lowpan_lltypes lltype); /** - * lowpan_uncompress_size - returns skb->len size with uncompressed header - * @skb: sk_buff with 6lowpan header inside - * @datagram_offset: optional to get the datagram_offset value + * lowpan_header_decompress - replace 6LoWPAN header with IPv6 header * - * Returns the skb->len with uncompressed header + * This function replaces the IPHC 6LoWPAN header which should be pointed at + * skb->data and skb_network_header, with the IPv6 header. + * It would be nice that the caller have the necessary headroom of IPv6 header + * and greatest Transport layer header, this would reduce the overhead for + * reallocate headroom. + * + * @skb: the buffer which should be manipulate. + * @dev: the lowpan net device pointer. + * @daddr: destination lladdr of mac header which is used for compression + * methods. + * @saddr: source lladdr of mac header which is used for compression + * methods. */ -static inline u16 -lowpan_uncompress_size(const struct sk_buff *skb, u16 *dgram_offset) -{ - u16 ret = 2, uncomp_header = sizeof(struct ipv6hdr); - u8 iphc0, iphc1, h_enc; - - iphc0 = skb_network_header(skb)[0]; - iphc1 = skb_network_header(skb)[1]; - - switch ((iphc0 & LOWPAN_IPHC_TF) >> 3) { - case 0: - ret += 4; - break; - case 1: - ret += 3; - break; - case 2: - ret++; - break; - default: - break; - } - - if (!(iphc0 & LOWPAN_IPHC_NH_C)) - ret++; - - if (!(iphc0 & 0x03)) - ret++; - - ret += lowpan_addr_mode_size((iphc1 & LOWPAN_IPHC_SAM) >> - LOWPAN_IPHC_SAM_BIT); - - if (iphc1 & LOWPAN_IPHC_M) { - switch ((iphc1 & LOWPAN_IPHC_DAM_11) >> - LOWPAN_IPHC_DAM_BIT) { - case LOWPAN_IPHC_DAM_00: - ret += 16; - break; - case LOWPAN_IPHC_DAM_01: - ret += 6; - break; - case LOWPAN_IPHC_DAM_10: - ret += 4; - break; - case LOWPAN_IPHC_DAM_11: - ret++; - break; - default: - break; - } - } else { - ret += lowpan_addr_mode_size((iphc1 & LOWPAN_IPHC_DAM_11) >> - LOWPAN_IPHC_DAM_BIT); - } - - if (iphc0 & LOWPAN_IPHC_NH_C) { - h_enc = skb_network_header(skb)[ret]; - ret += lowpan_next_hdr_size(h_enc, &uncomp_header); - } +int lowpan_header_decompress(struct sk_buff *skb, const struct net_device *dev, + const void *daddr, const void *saddr); - if (dgram_offset) - *dgram_offset = uncomp_header; - - return skb->len + uncomp_header - ret; -} - -void lowpan_netdev_setup(struct net_device *dev, enum lowpan_lltypes lltype); - -int -lowpan_header_decompress(struct sk_buff *skb, struct net_device *dev, - const u8 *saddr, const u8 saddr_type, - const u8 saddr_len, const u8 *daddr, - const u8 daddr_type, const u8 daddr_len, - u8 iphc0, u8 iphc1); -int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev, - unsigned short type, const void *_daddr, - const void *_saddr, unsigned int len); +/** + * lowpan_header_compress - replace IPv6 header with 6LoWPAN header + * + * This function replaces the IPv6 header which should be pointed at + * skb->data and skb_network_header, with the IPHC 6LoWPAN header. + * The caller need to be sure that the sk buffer is not shared and at have + * at least a headroom which is smaller or equal LOWPAN_IPHC_MAX_HEADER_LEN, + * which is the IPHC "more bytes than IPv6 header" at worst case. + * + * @skb: the buffer which should be manipulate. + * @dev: the lowpan net device pointer. + * @daddr: destination lladdr of mac header which is used for compression + * methods. + * @saddr: source lladdr of mac header which is used for compression + * methods. + */ +int lowpan_header_compress(struct sk_buff *skb, const struct net_device *dev, + const void *daddr, const void *saddr); #endif /* __6LOWPAN_H__ */ diff --git a/include/net/addrconf.h b/include/net/addrconf.h index b5474b1fcd83..78003dfb8539 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -192,8 +192,7 @@ struct ipv6_stub { int (*ipv6_dst_lookup)(struct net *net, struct sock *sk, struct dst_entry **dst, struct flowi6 *fl6); void (*udpv6_encap_enable)(void); - void (*ndisc_send_na)(struct net_device *dev, struct neighbour *neigh, - const struct in6_addr *daddr, + void (*ndisc_send_na)(struct net_device *dev, const struct in6_addr *daddr, const struct in6_addr *solicited_addr, bool router, bool solicited, bool override, bool inc_opt); struct neigh_table *nd_tbl; diff --git a/include/net/af_ieee802154.h b/include/net/af_ieee802154.h index 7d38e2ffd256..a5563d27a3eb 100644 --- a/include/net/af_ieee802154.h +++ b/include/net/af_ieee802154.h @@ -1,5 +1,5 @@ /* - * IEEE 802.15.4 inteface for userspace + * IEEE 802.15.4 interface for userspace * * Copyright 2007, 2008 Siemens AG * diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h index db639a4c5ab8..e9eb2d6791b3 100644 --- a/include/net/af_vsock.h +++ b/include/net/af_vsock.h @@ -22,6 +22,9 @@ #include "vsock_addr.h" +/* vsock-specific sock->sk_state constants */ +#define VSOCK_SS_LISTEN 255 + #define LAST_RESERVED_PORT 1023 #define vsock_sk(__sk) ((struct vsock_sock *)__sk) diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 38d8a34d3589..42844d7b154a 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h @@ -122,12 +122,28 @@ struct bt_voice { __printf(1, 2) void bt_info(const char *fmt, ...); __printf(1, 2) +void bt_warn(const char *fmt, ...); +__printf(1, 2) void bt_err(const char *fmt, ...); +__printf(1, 2) +void bt_err_ratelimited(const char *fmt, ...); #define BT_INFO(fmt, ...) bt_info(fmt "\n", ##__VA_ARGS__) +#define BT_WARN(fmt, ...) bt_warn(fmt "\n", ##__VA_ARGS__) #define BT_ERR(fmt, ...) bt_err(fmt "\n", ##__VA_ARGS__) #define BT_DBG(fmt, ...) pr_debug(fmt "\n", ##__VA_ARGS__) +#define BT_ERR_RATELIMITED(fmt, ...) bt_err_ratelimited(fmt "\n", ##__VA_ARGS__) + +#define bt_dev_info(hdev, fmt, ...) \ + BT_INFO("%s: " fmt, (hdev)->name, ##__VA_ARGS__) +#define bt_dev_warn(hdev, fmt, ...) \ + BT_WARN("%s: " fmt, (hdev)->name, ##__VA_ARGS__) +#define bt_dev_err(hdev, fmt, ...) \ + BT_ERR("%s: " fmt, (hdev)->name, ##__VA_ARGS__) +#define bt_dev_dbg(hdev, fmt, ...) \ + BT_DBG("%s: " fmt, (hdev)->name, ##__VA_ARGS__) + /* Connection and socket states */ enum { BT_CONNECTED = 1, /* Equal to TCP_ESTABLISHED to make net code happy */ @@ -280,22 +296,22 @@ typedef void (*hci_req_complete_t)(struct hci_dev *hdev, u8 status, u16 opcode); typedef void (*hci_req_complete_skb_t)(struct hci_dev *hdev, u8 status, u16 opcode, struct sk_buff *skb); -struct req_ctrl { - bool start; - u8 event; - hci_req_complete_t complete; - hci_req_complete_skb_t complete_skb; +struct hci_ctrl { + __u16 opcode; + bool req_start; + u8 req_event; + hci_req_complete_t req_complete; + hci_req_complete_skb_t req_complete_skb; }; struct bt_skb_cb { __u8 pkt_type; __u8 force_active; - __u16 opcode; __u16 expect; __u8 incoming:1; union { struct l2cap_ctrl l2cap; - struct req_ctrl req; + struct hci_ctrl hci; }; }; #define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb)) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 7ca6690355ea..0205b80cc90b 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -44,6 +44,9 @@ #define HCI_DEV_DOWN 4 #define HCI_DEV_SUSPEND 5 #define HCI_DEV_RESUME 6 +#define HCI_DEV_OPEN 7 +#define HCI_DEV_CLOSE 8 +#define HCI_DEV_SETUP 9 /* HCI notify events */ #define HCI_NOTIFY_CONN_ADD 1 @@ -168,6 +171,15 @@ enum { * during the hdev->setup vendor callback. */ HCI_QUIRK_SIMULTANEOUS_DISCOVERY, + + /* When this quirk is set, the enabling of diagnostic mode is + * not persistent over HCI Reset. Every time the controller + * is brought up it needs to be reprogrammed. + * + * This quirk can be set before hci_register_dev is called or + * during the hdev->setup vendor callback. + */ + HCI_QUIRK_NON_PERSISTENT_DIAG, }; /* HCI device flags */ @@ -238,6 +250,7 @@ enum { HCI_LE_SCAN_INTERRUPTED, HCI_DUT_MODE, + HCI_VENDOR_DIAG, HCI_FORCE_BREDR_SMP, HCI_FORCE_STATIC_ADDR, @@ -260,6 +273,7 @@ enum { #define HCI_ACLDATA_PKT 0x02 #define HCI_SCODATA_PKT 0x03 #define HCI_EVENT_PKT 0x04 +#define HCI_DIAG_PKT 0xf0 #define HCI_VENDOR_PKT 0xff /* HCI packet types */ diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 9e1a59e01fa2..1878d0a96333 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -398,6 +398,8 @@ struct hci_dev { int (*send)(struct hci_dev *hdev, struct sk_buff *skb); void (*notify)(struct hci_dev *hdev, unsigned int evt); void (*hw_error)(struct hci_dev *hdev, u8 code); + int (*post_init)(struct hci_dev *hdev); + int (*set_diag)(struct hci_dev *hdev, bool enable); int (*set_bdaddr)(struct hci_dev *hdev, const bdaddr_t *bdaddr); }; @@ -469,6 +471,7 @@ struct hci_conn { struct delayed_work auto_accept_work; struct delayed_work idle_work; struct delayed_work le_conn_timeout; + struct work_struct le_scan_cleanup; struct device dev; struct dentry *debugfs; @@ -791,6 +794,30 @@ static inline struct hci_conn *hci_conn_hash_lookup_ba(struct hci_dev *hdev, return NULL; } +static inline struct hci_conn *hci_conn_hash_lookup_le(struct hci_dev *hdev, + bdaddr_t *ba, + __u8 ba_type) +{ + struct hci_conn_hash *h = &hdev->conn_hash; + struct hci_conn *c; + + rcu_read_lock(); + + list_for_each_entry_rcu(c, &h->list, list) { + if (c->type != LE_LINK) + continue; + + if (ba_type == c->dst_type && !bacmp(&c->dst, ba)) { + rcu_read_unlock(); + return c; + } + } + + rcu_read_unlock(); + + return NULL; +} + static inline struct hci_conn *hci_conn_hash_lookup_state(struct hci_dev *hdev, __u8 type, __u16 state) { @@ -987,6 +1014,7 @@ int hci_resume_dev(struct hci_dev *hdev); int hci_reset_dev(struct hci_dev *hdev); int hci_dev_open(__u16 dev); int hci_dev_close(__u16 dev); +int hci_dev_do_close(struct hci_dev *hdev); int hci_dev_reset(__u16 dev); int hci_dev_reset_stat(__u16 dev); int hci_dev_cmd(unsigned int cmd, void __user *arg); @@ -1014,9 +1042,6 @@ void hci_conn_params_clear_disabled(struct hci_dev *hdev); struct hci_conn_params *hci_pend_le_action_lookup(struct list_head *list, bdaddr_t *addr, u8 addr_type); -struct hci_conn_params *hci_explicit_connect_lookup(struct hci_dev *hdev, - bdaddr_t *addr, - u8 addr_type); void hci_uuids_clear(struct hci_dev *hdev); @@ -1065,6 +1090,7 @@ int hci_remove_adv_instance(struct hci_dev *hdev, u8 instance); void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb); +int hci_recv_diag(struct hci_dev *hdev, struct sk_buff *skb); void hci_init_sysfs(struct hci_dev *hdev); void hci_conn_init_sysfs(struct hci_conn *conn); @@ -1348,6 +1374,9 @@ void hci_send_sco(struct hci_conn *conn, struct sk_buff *skb); void *hci_sent_cmd_data(struct hci_dev *hdev, __u16 opcode); +struct sk_buff *hci_cmd_sync(struct hci_dev *hdev, u16 opcode, u32 plen, + const void *param, u32 timeout); + /* ----- HCI Sockets ----- */ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb); void hci_send_to_channel(unsigned short channel, struct sk_buff *skb, @@ -1452,7 +1481,7 @@ void mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, void mgmt_discovering(struct hci_dev *hdev, u8 discovering); bool mgmt_powering_down(struct hci_dev *hdev); 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_irk(struct hci_dev *hdev, struct smp_irk *irk, bool persistent); 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, diff --git a/include/net/bluetooth/hci_mon.h b/include/net/bluetooth/hci_mon.h index 77d1e5764185..2b67567cf28d 100644 --- a/include/net/bluetooth/hci_mon.h +++ b/include/net/bluetooth/hci_mon.h @@ -39,6 +39,10 @@ struct hci_mon_hdr { #define HCI_MON_ACL_RX_PKT 5 #define HCI_MON_SCO_TX_PKT 6 #define HCI_MON_SCO_RX_PKT 7 +#define HCI_MON_OPEN_INDEX 8 +#define HCI_MON_CLOSE_INDEX 9 +#define HCI_MON_INDEX_INFO 10 +#define HCI_MON_VENDOR_DIAG 11 struct hci_mon_new_index { __u8 type; @@ -48,4 +52,10 @@ struct hci_mon_new_index { } __packed; #define HCI_MON_NEW_INDEX_SIZE 16 +struct hci_mon_index_info { + bdaddr_t bdaddr; + __le16 manufacturer; +} __packed; +#define HCI_MON_INDEX_INFO_SIZE 8 + #endif /* __HCI_MON_H */ diff --git a/include/net/bond_3ad.h b/include/net/bond_3ad.h index c2a40a172fcd..f1fbc3b11962 100644 --- a/include/net/bond_3ad.h +++ b/include/net/bond_3ad.h @@ -297,8 +297,7 @@ void bond_3ad_bind_slave(struct slave *slave); void bond_3ad_unbind_slave(struct slave *slave); void bond_3ad_state_machine_handler(struct work_struct *); void bond_3ad_initiate_agg_selection(struct bonding *bond, int timeout); -void bond_3ad_adapter_speed_changed(struct slave *slave); -void bond_3ad_adapter_duplex_changed(struct slave *slave); +void bond_3ad_adapter_speed_duplex_changed(struct slave *slave); void bond_3ad_handle_link_change(struct slave *slave, char link); int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info); int __bond_3ad_get_active_agg_info(struct bonding *bond, diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index f0889a247643..2c7bdb81d30c 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -5,6 +5,7 @@ * * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net> * Copyright 2013-2014 Intel Mobile Communications GmbH + * Copyright 2015 Intel Deutschland GmbH * * 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 @@ -858,6 +859,8 @@ struct station_del_parameters { /** * enum cfg80211_station_type - the type of station being modified * @CFG80211_STA_AP_CLIENT: client of an AP interface + * @CFG80211_STA_AP_CLIENT_UNASSOC: client of an AP interface that is still + * unassociated (update properties for this type of client is permitted) * @CFG80211_STA_AP_MLME_CLIENT: client of an AP interface that has * the AP MLME in the device * @CFG80211_STA_AP_STA: AP station on managed interface @@ -873,6 +876,7 @@ struct station_del_parameters { */ enum cfg80211_station_type { CFG80211_STA_AP_CLIENT, + CFG80211_STA_AP_CLIENT_UNASSOC, CFG80211_STA_AP_MLME_CLIENT, CFG80211_STA_AP_STA, CFG80211_STA_IBSS, @@ -1498,13 +1502,26 @@ struct cfg80211_match_set { }; /** + * struct cfg80211_sched_scan_plan - scan plan for scheduled scan + * + * @interval: interval between scheduled scan iterations. In seconds. + * @iterations: number of scan iterations in this scan plan. Zero means + * infinite loop. + * The last scan plan will always have this parameter set to zero, + * all other scan plans will have a finite number of iterations. + */ +struct cfg80211_sched_scan_plan { + u32 interval; + u32 iterations; +}; + +/** * struct cfg80211_sched_scan_request - scheduled scan request description * * @ssids: SSIDs to scan for (passed in the probe_reqs in active scans) * @n_ssids: number of SSIDs * @n_channels: total number of channels to scan * @scan_width: channel width for scanning - * @interval: interval between each scheduled scan cycle * @ie: optional information element(s) to add into Probe Request or %NULL * @ie_len: length of ie in octets * @flags: bit field of flags controlling operation @@ -1523,6 +1540,9 @@ struct cfg80211_match_set { * @mac_addr_mask: MAC address mask used with randomisation, bits that * are 0 in the mask should be randomised, bits that are 1 should * be taken from the @mac_addr + * @scan_plans: scan plans to be executed in this scheduled scan. Lowest + * index must be executed first. + * @n_scan_plans: number of scan plans, at least 1. * @rcu_head: RCU callback used to free the struct * @owner_nlportid: netlink portid of owner (if this should is a request * owned by a particular socket) @@ -1536,7 +1556,6 @@ struct cfg80211_sched_scan_request { int n_ssids; u32 n_channels; enum nl80211_bss_scan_width scan_width; - u32 interval; const u8 *ie; size_t ie_len; u32 flags; @@ -1544,6 +1563,8 @@ struct cfg80211_sched_scan_request { int n_match_sets; s32 min_rssi_thold; u32 delay; + struct cfg80211_sched_scan_plan *scan_plans; + int n_scan_plans; u8 mac_addr[ETH_ALEN] __aligned(2); u8 mac_addr_mask[ETH_ALEN] __aligned(2); @@ -1573,6 +1594,26 @@ enum cfg80211_signal_type { }; /** + * struct cfg80211_inform_bss - BSS inform data + * @chan: channel the frame was received on + * @scan_width: scan width that was used + * @signal: signal strength value, according to the wiphy's + * signal type + * @boottime_ns: timestamp (CLOCK_BOOTTIME) when the information was + * received; should match the time when the frame was actually + * received by the device (not just by the host, in case it was + * buffered on the device) and be accurate to about 10ms. + * If the frame isn't buffered, just passing the return value of + * ktime_get_boot_ns() is likely appropriate. + */ +struct cfg80211_inform_bss { + struct ieee80211_channel *chan; + enum nl80211_bss_scan_width scan_width; + s32 signal; + u64 boottime_ns; +}; + +/** * struct cfg80211_bss_ie_data - BSS entry IE data * @tsf: TSF contained in the frame that carried these IEs * @rcu_head: internal use, for freeing @@ -2358,6 +2399,10 @@ struct cfg80211_qos_map { * @set_power_mgmt: Configure WLAN power management. A timeout value of -1 * allows the driver to adjust the dynamic ps timeout value. * @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold. + * After configuration, the driver should (soon) send an event indicating + * the current level is above/below the configured threshold; this may + * need some care when the configuration is changed (without first being + * disabled.) * @set_cqm_txe_config: Configure connection quality monitor TX error * thresholds. * @sched_scan_start: Tell the driver to start a scheduled scan. @@ -2971,12 +3016,21 @@ enum wiphy_vendor_command_flags { * @doit: callback for the operation, note that wdev is %NULL if the * flags didn't ask for a wdev and non-%NULL otherwise; the data * pointer may be %NULL if userspace provided no data at all + * @dumpit: dump callback, for transferring bigger/multiple items. The + * @storage points to cb->args[5], ie. is preserved over the multiple + * dumpit calls. + * It's recommended to not have the same sub command with both @doit and + * @dumpit, so that userspace can assume certain ones are get and others + * are used with dump requests. */ struct wiphy_vendor_command { struct nl80211_vendor_cmd_info info; u32 flags; int (*doit)(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); + int (*dumpit)(struct wiphy *wiphy, struct wireless_dev *wdev, + struct sk_buff *skb, const void *data, int data_len, + unsigned long *storage); }; /** @@ -3044,6 +3098,12 @@ struct wiphy_vendor_command { * include fixed IEs like supported rates * @max_sched_scan_ie_len: same as max_scan_ie_len, but for scheduled * scans + * @max_sched_scan_plans: maximum number of scan plans (scan interval and number + * of iterations) for scheduled scan supported by the device. + * @max_sched_scan_plan_interval: maximum interval (in seconds) for a + * single scan plan supported by the device. + * @max_sched_scan_plan_iterations: maximum number of iterations for a single + * scan plan supported by the device. * @coverage_class: current coverage class * @fw_version: firmware version for ethtool reporting * @hw_version: hardware version for ethtool reporting @@ -3151,6 +3211,9 @@ struct wiphy { u8 max_match_sets; u16 max_scan_ie_len; u16 max_sched_scan_ie_len; + u32 max_sched_scan_plans; + u32 max_sched_scan_plan_interval; + u32 max_sched_scan_plan_iterations; int n_cipher_suites; const u32 *cipher_suites; @@ -3946,14 +4009,11 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy); void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy); /** - * cfg80211_inform_bss_width_frame - inform cfg80211 of a received BSS frame - * + * cfg80211_inform_bss_frame_data - inform cfg80211 of a received BSS frame * @wiphy: the wiphy reporting the BSS - * @rx_channel: The channel the frame was received on - * @scan_width: width of the control channel + * @data: the BSS metadata * @mgmt: the management frame (probe response or beacon) * @len: length of the management frame - * @signal: the signal strength, type depends on the wiphy's signal_type * @gfp: context flags * * This informs cfg80211 that BSS information was found and @@ -3963,11 +4023,26 @@ void cfg80211_sched_scan_stopped_rtnl(struct wiphy *wiphy); * Or %NULL on error. */ struct cfg80211_bss * __must_check +cfg80211_inform_bss_frame_data(struct wiphy *wiphy, + struct cfg80211_inform_bss *data, + struct ieee80211_mgmt *mgmt, size_t len, + gfp_t gfp); + +static inline struct cfg80211_bss * __must_check cfg80211_inform_bss_width_frame(struct wiphy *wiphy, struct ieee80211_channel *rx_channel, enum nl80211_bss_scan_width scan_width, struct ieee80211_mgmt *mgmt, size_t len, - s32 signal, gfp_t gfp); + s32 signal, gfp_t gfp) +{ + struct cfg80211_inform_bss data = { + .chan = rx_channel, + .scan_width = scan_width, + .signal = signal, + }; + + return cfg80211_inform_bss_frame_data(wiphy, &data, mgmt, len, gfp); +} static inline struct cfg80211_bss * __must_check cfg80211_inform_bss_frame(struct wiphy *wiphy, @@ -3975,9 +4050,13 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy, struct ieee80211_mgmt *mgmt, size_t len, s32 signal, gfp_t gfp) { - return cfg80211_inform_bss_width_frame(wiphy, rx_channel, - NL80211_BSS_CHAN_WIDTH_20, - mgmt, len, signal, gfp); + struct cfg80211_inform_bss data = { + .chan = rx_channel, + .scan_width = NL80211_BSS_CHAN_WIDTH_20, + .signal = signal, + }; + + return cfg80211_inform_bss_frame_data(wiphy, &data, mgmt, len, gfp); } /** @@ -3994,11 +4073,10 @@ enum cfg80211_bss_frame_type { }; /** - * cfg80211_inform_bss_width - inform cfg80211 of a new BSS + * cfg80211_inform_bss_data - inform cfg80211 of a new BSS * * @wiphy: the wiphy reporting the BSS - * @rx_channel: The channel the frame was received on - * @scan_width: width of the control channel + * @data: the BSS metadata * @ftype: frame type (if known) * @bssid: the BSSID of the BSS * @tsf: the TSF sent by the peer in the beacon/probe response (or 0) @@ -4006,7 +4084,6 @@ enum cfg80211_bss_frame_type { * @beacon_interval: the beacon interval announced by the peer * @ie: additional IEs sent by the peer * @ielen: length of the additional IEs - * @signal: the signal strength, type depends on the wiphy's signal_type * @gfp: context flags * * This informs cfg80211 that BSS information was found and @@ -4016,13 +4093,32 @@ enum cfg80211_bss_frame_type { * Or %NULL on error. */ struct cfg80211_bss * __must_check +cfg80211_inform_bss_data(struct wiphy *wiphy, + struct cfg80211_inform_bss *data, + enum cfg80211_bss_frame_type ftype, + const u8 *bssid, u64 tsf, u16 capability, + u16 beacon_interval, const u8 *ie, size_t ielen, + gfp_t gfp); + +static inline struct cfg80211_bss * __must_check cfg80211_inform_bss_width(struct wiphy *wiphy, struct ieee80211_channel *rx_channel, enum nl80211_bss_scan_width scan_width, enum cfg80211_bss_frame_type ftype, const u8 *bssid, u64 tsf, u16 capability, u16 beacon_interval, const u8 *ie, size_t ielen, - s32 signal, gfp_t gfp); + s32 signal, gfp_t gfp) +{ + struct cfg80211_inform_bss data = { + .chan = rx_channel, + .scan_width = scan_width, + .signal = signal, + }; + + return cfg80211_inform_bss_data(wiphy, &data, ftype, bssid, tsf, + capability, beacon_interval, ie, ielen, + gfp); +} static inline struct cfg80211_bss * __must_check cfg80211_inform_bss(struct wiphy *wiphy, @@ -4032,11 +4128,15 @@ cfg80211_inform_bss(struct wiphy *wiphy, u16 beacon_interval, const u8 *ie, size_t ielen, s32 signal, gfp_t gfp) { - return cfg80211_inform_bss_width(wiphy, rx_channel, - NL80211_BSS_CHAN_WIDTH_20, ftype, - bssid, tsf, capability, - beacon_interval, ie, ielen, signal, - gfp); + struct cfg80211_inform_bss data = { + .chan = rx_channel, + .scan_width = NL80211_BSS_CHAN_WIDTH_20, + .signal = signal, + }; + + return cfg80211_inform_bss_data(wiphy, &data, ftype, bssid, tsf, + capability, beacon_interval, ie, ielen, + gfp); } struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy, diff --git a/include/net/cfg802154.h b/include/net/cfg802154.h index 76b1ffaea863..171cd76558fb 100644 --- a/include/net/cfg802154.h +++ b/include/net/cfg802154.h @@ -27,6 +27,16 @@ struct wpan_phy; struct wpan_phy_cca; +#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL +struct ieee802154_llsec_device_key; +struct ieee802154_llsec_seclevel; +struct ieee802154_llsec_params; +struct ieee802154_llsec_device; +struct ieee802154_llsec_table; +struct ieee802154_llsec_key_id; +struct ieee802154_llsec_key; +#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */ + struct cfg802154_ops { struct net_device * (*add_virtual_intf_deprecated)(struct wpan_phy *wpan_phy, const char *name, @@ -65,6 +75,51 @@ struct cfg802154_ops { struct wpan_dev *wpan_dev, bool mode); int (*set_ackreq_default)(struct wpan_phy *wpan_phy, struct wpan_dev *wpan_dev, bool ackreq); +#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL + void (*get_llsec_table)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, + struct ieee802154_llsec_table **table); + void (*lock_llsec_table)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev); + void (*unlock_llsec_table)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev); + /* TODO remove locking/get table callbacks, this is part of the + * nl802154 interface and should be accessible from ieee802154 layer. + */ + int (*get_llsec_params)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, + struct ieee802154_llsec_params *params); + int (*set_llsec_params)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, + const struct ieee802154_llsec_params *params, + int changed); + int (*add_llsec_key)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, + const struct ieee802154_llsec_key_id *id, + const struct ieee802154_llsec_key *key); + int (*del_llsec_key)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, + const struct ieee802154_llsec_key_id *id); + int (*add_seclevel)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, + const struct ieee802154_llsec_seclevel *sl); + int (*del_seclevel)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, + const struct ieee802154_llsec_seclevel *sl); + int (*add_device)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, + const struct ieee802154_llsec_device *dev); + int (*del_device)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, __le64 extended_addr); + int (*add_devkey)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, + __le64 extended_addr, + const struct ieee802154_llsec_device_key *key); + int (*del_devkey)(struct wpan_phy *wpan_phy, + struct wpan_dev *wpan_dev, + __le64 extended_addr, + const struct ieee802154_llsec_device_key *key); +#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */ }; static inline bool @@ -167,6 +222,102 @@ struct wpan_phy { char priv[0] __aligned(NETDEV_ALIGN); }; +struct ieee802154_addr { + u8 mode; + __le16 pan_id; + union { + __le16 short_addr; + __le64 extended_addr; + }; +}; + +struct ieee802154_llsec_key_id { + u8 mode; + u8 id; + union { + struct ieee802154_addr device_addr; + __le32 short_source; + __le64 extended_source; + }; +}; + +#define IEEE802154_LLSEC_KEY_SIZE 16 + +struct ieee802154_llsec_key { + u8 frame_types; + u32 cmd_frame_ids; + /* TODO replace with NL802154_KEY_SIZE */ + 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_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; +}; + +struct ieee802154_llsec_seclevel { + struct list_head list; + + u8 frame_type; + u8 cmd_frame_id; + bool device_override; + u32 sec_levels; +}; + +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_device_key { + struct list_head list; + + struct ieee802154_llsec_key_id key_id; + u32 frame_counter; +}; + +struct wpan_dev_header_ops { + /* TODO create callback currently assumes ieee802154_mac_cb inside + * skb->cb. This should be changed to give these information as + * parameter. + */ + int (*create)(struct sk_buff *skb, struct net_device *dev, + const struct ieee802154_addr *daddr, + const struct ieee802154_addr *saddr, + unsigned int len); +}; + struct wpan_dev { struct wpan_phy *wpan_phy; int iftype; @@ -175,6 +326,8 @@ struct wpan_dev { struct list_head list; struct net_device *netdev; + const struct wpan_dev_header_ops *header_ops; + /* lowpan interface, set when the wpan_dev belongs to one lowpan_dev */ struct net_device *lowpan_dev; @@ -205,6 +358,17 @@ struct wpan_dev { #define to_phy(_dev) container_of(_dev, struct wpan_phy, dev) +static inline int +wpan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, + const struct ieee802154_addr *daddr, + const struct ieee802154_addr *saddr, + unsigned int len) +{ + struct wpan_dev *wpan_dev = dev->ieee802154_ptr; + + return wpan_dev->header_ops->create(skb, dev, daddr, saddr, len); +} + struct wpan_phy * wpan_phy_new(const struct cfg802154_ops *ops, size_t priv_size); static inline void wpan_phy_set_dev(struct wpan_phy *phy, struct device *dev) diff --git a/include/net/dn_neigh.h b/include/net/dn_neigh.h index d0424269313f..5e902fc3f4eb 100644 --- a/include/net/dn_neigh.h +++ b/include/net/dn_neigh.h @@ -18,11 +18,11 @@ struct dn_neigh { void dn_neigh_init(void); void dn_neigh_cleanup(void); -int dn_neigh_router_hello(struct sock *sk, struct sk_buff *skb); -int dn_neigh_endnode_hello(struct sock *sk, struct sk_buff *skb); +int dn_neigh_router_hello(struct net *net, struct sock *sk, struct sk_buff *skb); +int dn_neigh_endnode_hello(struct net *net, struct sock *sk, struct sk_buff *skb); void dn_neigh_pointopoint_hello(struct sk_buff *skb); int dn_neigh_elist(struct net_device *dev, unsigned char *ptr, int n); -int dn_to_neigh_output(struct sock *sk, struct sk_buff *skb); +int dn_to_neigh_output(struct net *net, struct sock *sk, struct sk_buff *skb); extern struct neigh_table dn_neigh_table; diff --git a/include/net/dsa.h b/include/net/dsa.h index b34d812bc5d0..82a4c6011173 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -197,6 +197,11 @@ static inline u8 dsa_upstream_port(struct dsa_switch *ds) return ds->pd->rtable[dst->cpu_switch]; } +struct switchdev_trans; +struct switchdev_obj; +struct switchdev_obj_port_fdb; +struct switchdev_obj_port_vlan; + struct dsa_switch_driver { struct list_head list; @@ -305,24 +310,32 @@ struct dsa_switch_driver { /* * VLAN support */ + int (*port_vlan_prepare)(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan, + struct switchdev_trans *trans); + int (*port_vlan_add)(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan, + struct switchdev_trans *trans); + int (*port_vlan_del)(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan); int (*port_pvid_get)(struct dsa_switch *ds, int port, u16 *pvid); - int (*port_pvid_set)(struct dsa_switch *ds, int port, u16 pvid); - int (*port_vlan_add)(struct dsa_switch *ds, int port, u16 vid, - bool untagged); - int (*port_vlan_del)(struct dsa_switch *ds, int port, u16 vid); int (*vlan_getnext)(struct dsa_switch *ds, u16 *vid, unsigned long *ports, unsigned long *untagged); /* * Forwarding database */ + int (*port_fdb_prepare)(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_fdb *fdb, + struct switchdev_trans *trans); int (*port_fdb_add)(struct dsa_switch *ds, int port, - const unsigned char *addr, u16 vid); + const struct switchdev_obj_port_fdb *fdb, + struct switchdev_trans *trans); int (*port_fdb_del)(struct dsa_switch *ds, int port, - const unsigned char *addr, u16 vid); - int (*port_fdb_getnext)(struct dsa_switch *ds, int port, - unsigned char *addr, u16 *vid, - bool *is_static); + const struct switchdev_obj_port_fdb *fdb); + int (*port_fdb_dump)(struct dsa_switch *ds, int port, + struct switchdev_obj_port_fdb *fdb, + int (*cb)(struct switchdev_obj *obj)); }; void register_switch_driver(struct dsa_switch_driver *type); diff --git a/include/net/dst.h b/include/net/dst.h index 9261d928303d..1279f9b09791 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -45,7 +45,7 @@ struct dst_entry { void *__pad1; #endif int (*input)(struct sk_buff *); - int (*output)(struct sock *sk, struct sk_buff *skb); + int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb); unsigned short flags; #define DST_HOST 0x0001 @@ -365,10 +365,10 @@ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev, __skb_tunnel_rx(skb, dev, net); } -int dst_discard_sk(struct sock *sk, struct sk_buff *skb); +int dst_discard_out(struct net *net, struct sock *sk, struct sk_buff *skb); static inline int dst_discard(struct sk_buff *skb) { - return dst_discard_sk(skb->sk, skb); + return dst_discard_out(&init_net, skb->sk, skb); } void *dst_alloc(struct dst_ops *ops, struct net_device *dev, int initial_ref, int initial_obsolete, unsigned short flags); @@ -454,13 +454,9 @@ static inline void dst_set_expires(struct dst_entry *dst, int timeout) } /* Output packet to network from transport. */ -static inline int dst_output_sk(struct sock *sk, struct sk_buff *skb) +static inline int dst_output(struct net *net, struct sock *sk, struct sk_buff *skb) { - return skb_dst(skb)->output(sk, skb); -} -static inline int dst_output(struct sk_buff *skb) -{ - return dst_output_sk(skb->sk, skb); + return skb_dst(skb)->output(net, sk, skb); } /* Input packet from network to transport. */ @@ -489,7 +485,8 @@ struct flowi; #ifndef CONFIG_XFRM static inline struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, - const struct flowi *fl, struct sock *sk, + const struct flowi *fl, + const struct sock *sk, int flags) { return dst_orig; @@ -498,7 +495,7 @@ static inline struct dst_entry *xfrm_lookup(struct net *net, static inline struct dst_entry *xfrm_lookup_route(struct net *net, struct dst_entry *dst_orig, const struct flowi *fl, - struct sock *sk, + const struct sock *sk, int flags) { return dst_orig; @@ -511,11 +508,11 @@ static inline struct xfrm_state *dst_xfrm(const struct dst_entry *dst) #else struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, - const struct flowi *fl, struct sock *sk, + const struct flowi *fl, const struct sock *sk, int flags); struct dst_entry *xfrm_lookup_route(struct net *net, struct dst_entry *dst_orig, - const struct flowi *fl, struct sock *sk, + const struct flowi *fl, const struct sock *sk, int flags); /* skb attached with this dst needs transformation if dst->xfrm is valid */ diff --git a/include/net/dst_ops.h b/include/net/dst_ops.h index d64253914a6a..a0d443ca16fc 100644 --- a/include/net/dst_ops.h +++ b/include/net/dst_ops.h @@ -9,6 +9,7 @@ struct kmem_cachep; struct net_device; struct sk_buff; struct sock; +struct net; struct dst_ops { unsigned short family; @@ -28,7 +29,7 @@ struct dst_ops { struct sk_buff *skb, u32 mtu); void (*redirect)(struct dst_entry *dst, struct sock *sk, struct sk_buff *skb); - int (*local_out)(struct sk_buff *skb); + int (*local_out)(struct net *net, struct sock *sk, struct sk_buff *skb); struct neighbour * (*neigh_lookup)(const struct dst_entry *dst, struct sk_buff *skb, const void *daddr); diff --git a/include/net/ethoc.h b/include/net/ethoc.h index 2a2d6bb34eb8..bb7f467da7fc 100644 --- a/include/net/ethoc.h +++ b/include/net/ethoc.h @@ -17,6 +17,7 @@ struct ethoc_platform_data { u8 hwaddr[IFHWADDRLEN]; s8 phy_id; u32 eth_clkfreq; + bool big_endian; }; #endif /* !LINUX_NET_ETHOC_H */ diff --git a/include/net/flow.h b/include/net/flow.h index 9b85db85f13c..83969eebebf3 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -34,7 +34,7 @@ struct flowi_common { __u8 flowic_flags; #define FLOWI_FLAG_ANYSRC 0x01 #define FLOWI_FLAG_KNOWN_NH 0x02 -#define FLOWI_FLAG_VRFSRC 0x04 +#define FLOWI_FLAG_L3MDEV_SRC 0x04 #define FLOWI_FLAG_SKIP_NH_OIF 0x08 __u32 flowic_secid; struct flowi_tunnel flowic_tun_key; diff --git a/include/net/genetlink.h b/include/net/genetlink.h index a9af1cc8c1bc..1b6b6dcb018d 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h @@ -183,9 +183,8 @@ _genl_register_family_with_ops_grps(struct genl_family *family, (grps), ARRAY_SIZE(grps)) int genl_unregister_family(struct genl_family *family); -void genl_notify(struct genl_family *family, - struct sk_buff *skb, struct net *net, u32 portid, - u32 group, struct nlmsghdr *nlh, gfp_t flags); +void genl_notify(struct genl_family *family, struct sk_buff *skb, + struct genl_info *info, u32 group, gfp_t flags); struct sk_buff *genlmsg_new_unicast(size_t payload, struct genl_info *info, gfp_t flags); diff --git a/include/net/ieee802154_netdev.h b/include/net/ieee802154_netdev.h index 2c10a9f0c6d9..a62a051a3a2f 100644 --- a/include/net/ieee802154_netdev.h +++ b/include/net/ieee802154_netdev.h @@ -50,15 +50,6 @@ struct ieee802154_sechdr { }; }; -struct ieee802154_addr { - u8 mode; - __le16 pan_id; - union { - __le16 short_addr; - __le64 extended_addr; - }; -}; - struct ieee802154_hdr_fc { #if defined(__LITTLE_ENDIAN_BITFIELD) u16 type:3, @@ -99,7 +90,7 @@ struct ieee802154_hdr { * hdr->fc will be ignored. this includes the INTRA_PAN bit and the frame * version, if SECEN is set. */ -int ieee802154_hdr_push(struct sk_buff *skb, const struct ieee802154_hdr *hdr); +int ieee802154_hdr_push(struct sk_buff *skb, struct ieee802154_hdr *hdr); /* pulls the entire 802.15.4 header off of the skb, including the security * header, and performs pan id decompression @@ -243,38 +234,6 @@ static inline struct ieee802154_mac_cb *mac_cb_init(struct sk_buff *skb) return mac_cb(skb); } -#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, @@ -283,49 +242,6 @@ enum { __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 #define IEEE802154_MAC_SCAN_PASSIVE 2 diff --git a/include/net/inet6_connection_sock.h b/include/net/inet6_connection_sock.h index 6d539e4e5ba7..064cfbe639d0 100644 --- a/include/net/inet6_connection_sock.h +++ b/include/net/inet6_connection_sock.h @@ -25,17 +25,8 @@ struct sockaddr; int inet6_csk_bind_conflict(const struct sock *sk, const struct inet_bind_bucket *tb, bool relax); -struct dst_entry *inet6_csk_route_req(struct sock *sk, struct flowi6 *fl6, - const struct request_sock *req); - -struct request_sock *inet6_csk_search_req(struct sock *sk, - const __be16 rport, - const struct in6_addr *raddr, - const struct in6_addr *laddr, - const int iif); - -void inet6_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req, - const unsigned long timeout); +struct dst_entry *inet6_csk_route_req(const struct sock *sk, struct flowi6 *fl6, + const struct request_sock *req, u8 proto); void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr); diff --git a/include/net/inet_common.h b/include/net/inet_common.h index 279f83591971..109e3ee9108c 100644 --- a/include/net/inet_common.h +++ b/include/net/inet_common.h @@ -41,7 +41,8 @@ int inet_recv_error(struct sock *sk, struct msghdr *msg, int len, static inline void inet_ctl_sock_destroy(struct sock *sk) { - sock_release(sk->sk_socket); + if (sk) + sock_release(sk->sk_socket); } #endif diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index 0320bbb7d7b5..481fe1c9044c 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -41,9 +41,11 @@ struct inet_connection_sock_af_ops { int (*rebuild_header)(struct sock *sk); void (*sk_rx_dst_set)(struct sock *sk, const struct sk_buff *skb); int (*conn_request)(struct sock *sk, struct sk_buff *skb); - struct sock *(*syn_recv_sock)(struct sock *sk, struct sk_buff *skb, + struct sock *(*syn_recv_sock)(const struct sock *sk, struct sk_buff *skb, struct request_sock *req, - struct dst_entry *dst); + struct dst_entry *dst, + struct request_sock *req_unhash, + bool *own_req); u16 net_header_len; u16 net_frag_header_len; u16 sockaddr_len; @@ -258,31 +260,25 @@ inet_csk_rto_backoff(const struct inet_connection_sock *icsk, struct sock *inet_csk_accept(struct sock *sk, int flags, int *err); -struct request_sock *inet_csk_search_req(struct sock *sk, - const __be16 rport, - const __be32 raddr, - const __be32 laddr); int inet_csk_bind_conflict(const struct sock *sk, const struct inet_bind_bucket *tb, bool relax); int inet_csk_get_port(struct sock *sk, unsigned short snum); -struct dst_entry *inet_csk_route_req(struct sock *sk, struct flowi4 *fl4, +struct dst_entry *inet_csk_route_req(const struct sock *sk, struct flowi4 *fl4, const struct request_sock *req); -struct dst_entry *inet_csk_route_child_sock(struct sock *sk, struct sock *newsk, +struct dst_entry *inet_csk_route_child_sock(const struct sock *sk, + struct sock *newsk, const struct request_sock *req); -static inline void inet_csk_reqsk_queue_add(struct sock *sk, - struct request_sock *req, - struct sock *child) -{ - reqsk_queue_add(&inet_csk(sk)->icsk_accept_queue, req, sk, child); -} - +void inet_csk_reqsk_queue_add(struct sock *sk, struct request_sock *req, + struct sock *child); void inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req, unsigned long timeout); +struct sock *inet_csk_complete_hashdance(struct sock *sk, struct sock *child, + struct request_sock *req, + bool own_req); -static inline void inet_csk_reqsk_queue_added(struct sock *sk, - const unsigned long timeout) +static inline void inet_csk_reqsk_queue_added(struct sock *sk) { reqsk_queue_added(&inet_csk(sk)->icsk_accept_queue); } @@ -299,10 +295,11 @@ static inline int inet_csk_reqsk_queue_young(const struct sock *sk) static inline int inet_csk_reqsk_queue_is_full(const struct sock *sk) { - return reqsk_queue_is_full(&inet_csk(sk)->icsk_accept_queue); + return inet_csk_reqsk_queue_len(sk) >= sk->sk_max_ack_backlog; } void inet_csk_reqsk_queue_drop(struct sock *sk, struct request_sock *req); +void inet_csk_reqsk_queue_drop_and_put(struct sock *sk, struct request_sock *req); void inet_csk_destroy_sock(struct sock *sk); void inet_csk_prepare_forced_close(struct sock *sk); @@ -316,7 +313,7 @@ static inline unsigned int inet_csk_listen_poll(const struct sock *sk) (POLLIN | POLLRDNORM) : 0; } -int inet_csk_listen_start(struct sock *sk, const int nr_table_entries); +int inet_csk_listen_start(struct sock *sk, int backlog); void inet_csk_listen_stop(struct sock *sk); void inet_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr); diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h index 53eead2da743..ac42bbb37b2d 100644 --- a/include/net/inet_frag.h +++ b/include/net/inet_frag.h @@ -108,7 +108,15 @@ 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); +static inline int inet_frags_init_net(struct netns_frags *nf) +{ + return percpu_counter_init(&nf->mem, 0, GFP_KERNEL); +} +static inline void inet_frags_uninit_net(struct netns_frags *nf) +{ + percpu_counter_destroy(&nf->mem); +} + 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); @@ -154,11 +162,6 @@ static inline void add_frag_mem_limit(struct netns_frags *nf, int i) __percpu_counter_add(&nf->mem, i, frag_percpu_counter_batch); } -static inline void init_frag_mem_limit(struct netns_frags *nf) -{ - percpu_counter_init(&nf->mem, 0, GFP_KERNEL); -} - static inline unsigned int sum_frag_mem_limit(struct netns_frags *nf) { unsigned int res; diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h index b07d126694a7..de2e3ade6102 100644 --- a/include/net/inet_hashtables.h +++ b/include/net/inet_hashtables.h @@ -199,13 +199,14 @@ static inline int inet_sk_listen_hashfn(const struct sock *sk) } /* Caller must disable local BH processing. */ -int __inet_inherit_port(struct sock *sk, struct sock *child); +int __inet_inherit_port(const struct sock *sk, struct sock *child); void inet_put_port(struct sock *sk); void inet_hashinfo_init(struct inet_hashinfo *h); -void __inet_hash_nolisten(struct sock *sk, struct sock *osk); +bool inet_ehash_insert(struct sock *sk, struct sock *osk); +bool inet_ehash_nolisten(struct sock *sk, struct sock *osk); void __inet_hash(struct sock *sk, struct sock *osk); void inet_hash(struct sock *sk); void inet_unhash(struct sock *sk); diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index 47eb67b08abd..f5bf7310e334 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h @@ -245,7 +245,8 @@ static inline unsigned int __inet_ehashfn(const __be32 laddr, } struct request_sock *inet_reqsk_alloc(const struct request_sock_ops *ops, - struct sock *sk_listener); + struct sock *sk_listener, + bool attach_listener); static inline __u8 inet_sk_flowi_flags(const struct sock *sk) { diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h index fc1937698625..c9b3eb70f340 100644 --- a/include/net/inet_timewait_sock.h +++ b/include/net/inet_timewait_sock.h @@ -70,6 +70,7 @@ struct inet_timewait_sock { #define tw_dport __tw_common.skc_dport #define tw_num __tw_common.skc_num #define tw_cookie __tw_common.skc_cookie +#define tw_dr __tw_common.skc_tw_dr int tw_timeout; volatile unsigned char tw_substate; @@ -88,7 +89,6 @@ struct inet_timewait_sock { kmemcheck_bitfield_end(flags); struct timer_list tw_timer; struct inet_bind_bucket *tw_tb; - struct inet_timewait_death_row *tw_dr; }; #define tw_tclass tw_tos diff --git a/include/net/ip.h b/include/net/ip.h index 9b9ca2839399..1a98f1ca1638 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -100,24 +100,20 @@ int igmp_mc_init(void); * Functions provided by ip.c */ -int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk, +int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk, __be32 saddr, __be32 daddr, struct ip_options_rcu *opt); int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev); int ip_local_deliver(struct sk_buff *skb); int ip_mr_input(struct sk_buff *skb); -int ip_output(struct sock *sk, struct sk_buff *skb); -int ip_mc_output(struct sock *sk, struct sk_buff *skb); -int ip_do_fragment(struct sock *sk, struct sk_buff *skb, - int (*output)(struct sock *, struct sk_buff *)); +int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb); +int ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb); +int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, + int (*output)(struct net *, struct sock *, struct sk_buff *)); void ip_send_check(struct iphdr *ip); -int __ip_local_out(struct sk_buff *skb); -int ip_local_out_sk(struct sock *sk, struct sk_buff *skb); -static inline int ip_local_out(struct sk_buff *skb) -{ - return ip_local_out_sk(skb->sk, skb); -} +int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb); +int ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb); int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl); void ip_init(void); @@ -282,10 +278,12 @@ int ip_decrease_ttl(struct iphdr *iph) } static inline -int ip_dont_fragment(struct sock *sk, struct dst_entry *dst) +int ip_dont_fragment(const struct sock *sk, const struct dst_entry *dst) { - return inet_sk(sk)->pmtudisc == IP_PMTUDISC_DO || - (inet_sk(sk)->pmtudisc == IP_PMTUDISC_WANT && + u8 pmtudisc = READ_ONCE(inet_sk(sk)->pmtudisc); + + return pmtudisc == IP_PMTUDISC_DO || + (pmtudisc == IP_PMTUDISC_WANT && !(dst_metric_locked(dst, RTAX_MTU))); } @@ -321,12 +319,15 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst, static inline unsigned int ip_skb_dst_mtu(const struct sk_buff *skb) { - if (!skb->sk || ip_sk_use_pmtu(skb->sk)) { + struct sock *sk = skb->sk; + + if (!sk || !sk_fullsock(sk) || ip_sk_use_pmtu(sk)) { bool forwarding = IPCB(skb)->flags & IPSKB_FORWARDED; + return ip_dst_mtu_maybe_forward(skb_dst(skb), forwarding); - } else { - return min(skb_dst(skb)->dev->mtu, IP_MAX_MTU); } + + return min(skb_dst(skb)->dev->mtu, IP_MAX_MTU); } u32 ip_idents_reserve(u32 hash, int segs); @@ -505,11 +506,11 @@ static inline bool ip_defrag_user_in_between(u32 user, return user >= lower_bond && user <= upper_bond; } -int ip_defrag(struct sk_buff *skb, u32 user); +int ip_defrag(struct net *net, struct sk_buff *skb, u32 user); #ifdef CONFIG_INET -struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user); +struct sk_buff *ip_check_defrag(struct net *net, struct sk_buff *skb, u32 user); #else -static inline struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user) +static inline struct sk_buff *ip_check_defrag(struct net *net, struct sk_buff *skb, u32 user) { return skb; } diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 297629aadb19..2bfb2ad2fab1 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -173,8 +173,8 @@ static inline bool ipv6_anycast_destination(const struct dst_entry *dst, ipv6_addr_equal(&rt->rt6i_dst.addr, daddr)); } -int ip6_fragment(struct sock *sk, struct sk_buff *skb, - int (*output)(struct sock *, struct sk_buff *)); +int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, + int (*output)(struct net *, struct sock *, struct sk_buff *)); static inline int ip6_skb_dst_mtu(struct sk_buff *skb) { diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h index fa915fa0f703..aaee6fa02cf1 100644 --- a/include/net/ip6_tunnel.h +++ b/include/net/ip6_tunnel.h @@ -87,7 +87,7 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb, int pkt_len, err; pkt_len = skb->len - skb_inner_network_offset(skb); - err = ip6_local_out_sk(sk, skb); + err = ip6_local_out(dev_net(skb_dst(skb)->dev), sk, skb); if (net_xmit_eval(err) == 0) { struct pcpu_sw_netstats *tstats = this_cpu_ptr(dev->tstats); diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 727d6e9a9685..9f4df68105ab 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -79,7 +79,7 @@ struct fib_nh { unsigned char nh_scope; #ifdef CONFIG_IP_ROUTE_MULTIPATH int nh_weight; - int nh_power; + atomic_t nh_upper_bound; #endif #ifdef CONFIG_IP_ROUTE_CLASSID __u32 nh_tclassid; @@ -118,7 +118,7 @@ struct fib_info { #define fib_advmss fib_metrics[RTAX_ADVMSS-1] int fib_nhs; #ifdef CONFIG_IP_ROUTE_MULTIPATH - int fib_power; + int fib_weight; #endif struct rcu_head rcu; struct fib_nh fib_nh[0]; @@ -317,10 +317,20 @@ void fib_flush_external(struct net *net); /* Exported by fib_semantics.c */ int ip_fib_check_default(__be32 gw, struct net_device *dev); -int fib_sync_down_dev(struct net_device *dev, unsigned long event); +int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force); int fib_sync_down_addr(struct net *net, __be32 local); int fib_sync_up(struct net_device *dev, unsigned int nh_flags); -void fib_select_multipath(struct fib_result *res); + +extern u32 fib_multipath_secret __read_mostly; + +static inline int fib_multipath_hash(__be32 saddr, __be32 daddr) +{ + return jhash_2words(saddr, daddr, fib_multipath_secret) >> 1; +} + +void fib_select_multipath(struct fib_result *res, int hash); +void fib_select_path(struct net *net, struct fib_result *res, + struct flowi4 *fl4, int mp_hash); /* Exported by fib_trie.c */ void fib_trie_init(void); diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 9b9ca87a4210..0816c872b689 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -29,65 +29,15 @@ #endif #include <net/net_namespace.h> /* Netw namespace */ +#define IP_VS_HDR_INVERSE 1 +#define IP_VS_HDR_ICMP 2 + /* Generic access of ipvs struct */ static inline struct netns_ipvs *net_ipvs(struct net* net) { return net->ipvs; } -/* Get net ptr from skb in traffic cases - * use skb_sknet when call is from userland (ioctl or netlink) - */ -static inline struct net *skb_net(const struct sk_buff *skb) -{ -#ifdef CONFIG_NET_NS -#ifdef CONFIG_IP_VS_DEBUG - /* - * This is used for debug only. - * Start with the most likely hit - * End with BUG - */ - if (likely(skb->dev && dev_net(skb->dev))) - return dev_net(skb->dev); - if (skb_dst(skb) && skb_dst(skb)->dev) - return dev_net(skb_dst(skb)->dev); - WARN(skb->sk, "Maybe skb_sknet should be used in %s() at line:%d\n", - __func__, __LINE__); - if (likely(skb->sk && sock_net(skb->sk))) - return sock_net(skb->sk); - pr_err("There is no net ptr to find in the skb in %s() line:%d\n", - __func__, __LINE__); - BUG(); -#else - return dev_net(skb->dev ? : skb_dst(skb)->dev); -#endif -#else - return &init_net; -#endif -} - -static inline struct net *skb_sknet(const struct sk_buff *skb) -{ -#ifdef CONFIG_NET_NS -#ifdef CONFIG_IP_VS_DEBUG - /* Start with the most likely hit */ - if (likely(skb->sk && sock_net(skb->sk))) - return sock_net(skb->sk); - WARN(skb->dev, "Maybe skb_net should be used instead in %s() line:%d\n", - __func__, __LINE__); - if (likely(skb->dev && dev_net(skb->dev))) - return dev_net(skb->dev); - pr_err("There is no net ptr to find in the skb in %s() line:%d\n", - __func__, __LINE__); - BUG(); -#else - return sock_net(skb->sk); -#endif -#else - return &init_net; -#endif -} - /* This one needed for single_open_net since net is stored directly in * private not as a struct i.e. seq_file_net can't be used. */ @@ -104,6 +54,8 @@ static inline struct net *seq_file_single_net(struct seq_file *seq) extern int ip_vs_conn_tab_size; struct ip_vs_iphdr { + int hdr_flags; /* ipvs flags */ + __u32 off; /* Where IP or IPv4 header starts */ __u32 len; /* IPv4 simply where L4 starts * IPv6 where L4 Transport Header starts */ __u16 fragoffs; /* IPv6 fragment offset, 0 if first frag (or not frag)*/ @@ -120,48 +72,89 @@ static inline void *frag_safe_skb_hp(const struct sk_buff *skb, int offset, return skb_header_pointer(skb, offset, len, buffer); } -static inline void -ip_vs_fill_ip4hdr(const void *nh, struct ip_vs_iphdr *iphdr) -{ - const struct iphdr *iph = nh; - - iphdr->len = iph->ihl * 4; - iphdr->fragoffs = 0; - iphdr->protocol = iph->protocol; - iphdr->saddr.ip = iph->saddr; - iphdr->daddr.ip = iph->daddr; -} - /* This function handles filling *ip_vs_iphdr, both for IPv4 and IPv6. * IPv6 requires some extra work, as finding proper header position, * depend on the IPv6 extension headers. */ -static inline void -ip_vs_fill_iph_skb(int af, const struct sk_buff *skb, struct ip_vs_iphdr *iphdr) +static inline int +ip_vs_fill_iph_skb_off(int af, const struct sk_buff *skb, int offset, + int hdr_flags, struct ip_vs_iphdr *iphdr) { + iphdr->hdr_flags = hdr_flags; + iphdr->off = offset; + #ifdef CONFIG_IP_VS_IPV6 if (af == AF_INET6) { - const struct ipv6hdr *iph = - (struct ipv6hdr *)skb_network_header(skb); + struct ipv6hdr _iph; + const struct ipv6hdr *iph = skb_header_pointer( + skb, offset, sizeof(_iph), &_iph); + if (!iph) + return 0; + iphdr->saddr.in6 = iph->saddr; iphdr->daddr.in6 = iph->daddr; /* ipv6_find_hdr() updates len, flags */ - iphdr->len = 0; + iphdr->len = offset; iphdr->flags = 0; iphdr->protocol = ipv6_find_hdr(skb, &iphdr->len, -1, &iphdr->fragoffs, &iphdr->flags); + if (iphdr->protocol < 0) + return 0; } else #endif { - const struct iphdr *iph = - (struct iphdr *)skb_network_header(skb); - iphdr->len = iph->ihl * 4; + struct iphdr _iph; + const struct iphdr *iph = skb_header_pointer( + skb, offset, sizeof(_iph), &_iph); + if (!iph) + return 0; + + iphdr->len = offset + iph->ihl * 4; iphdr->fragoffs = 0; iphdr->protocol = iph->protocol; iphdr->saddr.ip = iph->saddr; iphdr->daddr.ip = iph->daddr; } + + return 1; +} + +static inline int +ip_vs_fill_iph_skb_icmp(int af, const struct sk_buff *skb, int offset, + bool inverse, struct ip_vs_iphdr *iphdr) +{ + int hdr_flags = IP_VS_HDR_ICMP; + + if (inverse) + hdr_flags |= IP_VS_HDR_INVERSE; + + return ip_vs_fill_iph_skb_off(af, skb, offset, hdr_flags, iphdr); +} + +static inline int +ip_vs_fill_iph_skb(int af, const struct sk_buff *skb, bool inverse, + struct ip_vs_iphdr *iphdr) +{ + int hdr_flags = 0; + + if (inverse) + hdr_flags |= IP_VS_HDR_INVERSE; + + return ip_vs_fill_iph_skb_off(af, skb, skb_network_offset(skb), + hdr_flags, iphdr); +} + +static inline bool +ip_vs_iph_inverse(const struct ip_vs_iphdr *iph) +{ + return !!(iph->hdr_flags & IP_VS_HDR_INVERSE); +} + +static inline bool +ip_vs_iph_icmp(const struct ip_vs_iphdr *iph) +{ + return !!(iph->hdr_flags & IP_VS_HDR_ICMP); } static inline void ip_vs_addr_copy(int af, union nf_inet_addr *dst, @@ -437,26 +430,27 @@ struct ip_vs_protocol { void (*exit)(struct ip_vs_protocol *pp); - int (*init_netns)(struct net *net, struct ip_vs_proto_data *pd); + int (*init_netns)(struct netns_ipvs *ipvs, struct ip_vs_proto_data *pd); - void (*exit_netns)(struct net *net, struct ip_vs_proto_data *pd); + void (*exit_netns)(struct netns_ipvs *ipvs, struct ip_vs_proto_data *pd); - int (*conn_schedule)(int af, struct sk_buff *skb, + int (*conn_schedule)(struct netns_ipvs *ipvs, + int af, struct sk_buff *skb, struct ip_vs_proto_data *pd, int *verdict, struct ip_vs_conn **cpp, struct ip_vs_iphdr *iph); struct ip_vs_conn * - (*conn_in_get)(int af, + (*conn_in_get)(struct netns_ipvs *ipvs, + int af, const struct sk_buff *skb, - const struct ip_vs_iphdr *iph, - int inverse); + const struct ip_vs_iphdr *iph); struct ip_vs_conn * - (*conn_out_get)(int af, + (*conn_out_get)(struct netns_ipvs *ipvs, + int af, const struct sk_buff *skb, - const struct ip_vs_iphdr *iph, - int inverse); + const struct ip_vs_iphdr *iph); int (*snat_handler)(struct sk_buff *skb, struct ip_vs_protocol *pp, struct ip_vs_conn *cp, struct ip_vs_iphdr *iph); @@ -473,9 +467,9 @@ struct ip_vs_protocol { const struct sk_buff *skb, struct ip_vs_proto_data *pd); - int (*register_app)(struct net *net, struct ip_vs_app *inc); + int (*register_app)(struct netns_ipvs *ipvs, struct ip_vs_app *inc); - void (*unregister_app)(struct net *net, struct ip_vs_app *inc); + void (*unregister_app)(struct netns_ipvs *ipvs, struct ip_vs_app *inc); int (*app_conn_bind)(struct ip_vs_conn *cp); @@ -497,11 +491,11 @@ struct ip_vs_proto_data { }; struct ip_vs_protocol *ip_vs_proto_get(unsigned short proto); -struct ip_vs_proto_data *ip_vs_proto_data_get(struct net *net, +struct ip_vs_proto_data *ip_vs_proto_data_get(struct netns_ipvs *ipvs, unsigned short proto); struct ip_vs_conn_param { - struct net *net; + struct netns_ipvs *ipvs; const union nf_inet_addr *caddr; const union nf_inet_addr *vaddr; __be16 cport; @@ -528,9 +522,7 @@ struct ip_vs_conn { volatile __u32 flags; /* status flags */ __u16 protocol; /* Which protocol (TCP/UDP) */ __u16 daf; /* Address family of the dest */ -#ifdef CONFIG_NET_NS - struct net *net; /* Name space */ -#endif + struct netns_ipvs *ipvs; /* counter and timer */ atomic_t refcnt; /* reference count */ @@ -577,33 +569,6 @@ struct ip_vs_conn { struct rcu_head rcu_head; }; -/* To save some memory in conn table when name space is disabled. */ -static inline struct net *ip_vs_conn_net(const struct ip_vs_conn *cp) -{ -#ifdef CONFIG_NET_NS - return cp->net; -#else - return &init_net; -#endif -} - -static inline void ip_vs_conn_net_set(struct ip_vs_conn *cp, struct net *net) -{ -#ifdef CONFIG_NET_NS - cp->net = net; -#endif -} - -static inline int ip_vs_conn_net_eq(const struct ip_vs_conn *cp, - struct net *net) -{ -#ifdef CONFIG_NET_NS - return cp->net == net; -#else - return 1; -#endif -} - /* Extended internal versions of struct ip_vs_service_user and ip_vs_dest_user * for IPv6 support. * @@ -663,7 +628,7 @@ struct ip_vs_service { unsigned int flags; /* service status flags */ unsigned int timeout; /* persistent timeout in ticks */ __be32 netmask; /* grouping granularity, mask/plen */ - struct net *net; + struct netns_ipvs *ipvs; struct list_head destinations; /* real server d-linked list */ __u32 num_dests; /* number of servers */ @@ -953,6 +918,8 @@ struct netns_ipvs { int sysctl_pmtu_disc; int sysctl_backup_only; int sysctl_conn_reuse_mode; + int sysctl_schedule_icmp; + int sysctl_ignore_tunneled; /* ip_vs_lblc */ int sysctl_lblc_expiration; @@ -1071,6 +1038,21 @@ static inline int sysctl_conn_reuse_mode(struct netns_ipvs *ipvs) return ipvs->sysctl_conn_reuse_mode; } +static inline int sysctl_schedule_icmp(struct netns_ipvs *ipvs) +{ + return ipvs->sysctl_schedule_icmp; +} + +static inline int sysctl_ignore_tunneled(struct netns_ipvs *ipvs) +{ + return ipvs->sysctl_ignore_tunneled; +} + +static inline int sysctl_cache_bypass(struct netns_ipvs *ipvs) +{ + return ipvs->sysctl_cache_bypass; +} + #else static inline int sysctl_sync_threshold(struct netns_ipvs *ipvs) @@ -1143,6 +1125,21 @@ static inline int sysctl_conn_reuse_mode(struct netns_ipvs *ipvs) return 1; } +static inline int sysctl_schedule_icmp(struct netns_ipvs *ipvs) +{ + return 0; +} + +static inline int sysctl_ignore_tunneled(struct netns_ipvs *ipvs) +{ + return 0; +} + +static inline int sysctl_cache_bypass(struct netns_ipvs *ipvs) +{ + return 0; +} + #endif /* IPVS core functions @@ -1164,14 +1161,14 @@ enum { IP_VS_DIR_LAST, }; -static inline void ip_vs_conn_fill_param(struct net *net, int af, int protocol, +static inline void ip_vs_conn_fill_param(struct netns_ipvs *ipvs, int af, int protocol, const union nf_inet_addr *caddr, __be16 cport, const union nf_inet_addr *vaddr, __be16 vport, struct ip_vs_conn_param *p) { - p->net = net; + p->ipvs = ipvs; p->af = af; p->protocol = protocol; p->caddr = caddr; @@ -1185,15 +1182,15 @@ static inline void ip_vs_conn_fill_param(struct net *net, int af, int protocol, struct ip_vs_conn *ip_vs_conn_in_get(const struct ip_vs_conn_param *p); struct ip_vs_conn *ip_vs_ct_in_get(const struct ip_vs_conn_param *p); -struct ip_vs_conn * ip_vs_conn_in_get_proto(int af, const struct sk_buff *skb, - const struct ip_vs_iphdr *iph, - int inverse); +struct ip_vs_conn * ip_vs_conn_in_get_proto(struct netns_ipvs *ipvs, int af, + const struct sk_buff *skb, + const struct ip_vs_iphdr *iph); struct ip_vs_conn *ip_vs_conn_out_get(const struct ip_vs_conn_param *p); -struct ip_vs_conn * ip_vs_conn_out_get_proto(int af, const struct sk_buff *skb, - const struct ip_vs_iphdr *iph, - int inverse); +struct ip_vs_conn * ip_vs_conn_out_get_proto(struct netns_ipvs *ipvs, int af, + const struct sk_buff *skb, + const struct ip_vs_iphdr *iph); /* Get reference to gain full access to conn. * By default, RCU read-side critical sections have access only to @@ -1221,9 +1218,9 @@ void ip_vs_conn_expire_now(struct ip_vs_conn *cp); const char *ip_vs_state_name(__u16 proto, int state); -void ip_vs_tcp_conn_listen(struct net *net, struct ip_vs_conn *cp); +void ip_vs_tcp_conn_listen(struct ip_vs_conn *cp); int ip_vs_check_template(struct ip_vs_conn *ct); -void ip_vs_random_dropentry(struct net *net); +void ip_vs_random_dropentry(struct netns_ipvs *ipvs); int ip_vs_conn_init(void); void ip_vs_conn_cleanup(void); @@ -1288,29 +1285,29 @@ ip_vs_control_add(struct ip_vs_conn *cp, struct ip_vs_conn *ctl_cp) } /* IPVS netns init & cleanup functions */ -int ip_vs_estimator_net_init(struct net *net); -int ip_vs_control_net_init(struct net *net); -int ip_vs_protocol_net_init(struct net *net); -int ip_vs_app_net_init(struct net *net); -int ip_vs_conn_net_init(struct net *net); -int ip_vs_sync_net_init(struct net *net); -void ip_vs_conn_net_cleanup(struct net *net); -void ip_vs_app_net_cleanup(struct net *net); -void ip_vs_protocol_net_cleanup(struct net *net); -void ip_vs_control_net_cleanup(struct net *net); -void ip_vs_estimator_net_cleanup(struct net *net); -void ip_vs_sync_net_cleanup(struct net *net); -void ip_vs_service_net_cleanup(struct net *net); +int ip_vs_estimator_net_init(struct netns_ipvs *ipvs); +int ip_vs_control_net_init(struct netns_ipvs *ipvs); +int ip_vs_protocol_net_init(struct netns_ipvs *ipvs); +int ip_vs_app_net_init(struct netns_ipvs *ipvs); +int ip_vs_conn_net_init(struct netns_ipvs *ipvs); +int ip_vs_sync_net_init(struct netns_ipvs *ipvs); +void ip_vs_conn_net_cleanup(struct netns_ipvs *ipvs); +void ip_vs_app_net_cleanup(struct netns_ipvs *ipvs); +void ip_vs_protocol_net_cleanup(struct netns_ipvs *ipvs); +void ip_vs_control_net_cleanup(struct netns_ipvs *ipvs); +void ip_vs_estimator_net_cleanup(struct netns_ipvs *ipvs); +void ip_vs_sync_net_cleanup(struct netns_ipvs *ipvs); +void ip_vs_service_net_cleanup(struct netns_ipvs *ipvs); /* IPVS application functions * (from ip_vs_app.c) */ #define IP_VS_APP_MAX_PORTS 8 -struct ip_vs_app *register_ip_vs_app(struct net *net, struct ip_vs_app *app); -void unregister_ip_vs_app(struct net *net, struct ip_vs_app *app); +struct ip_vs_app *register_ip_vs_app(struct netns_ipvs *ipvs, struct ip_vs_app *app); +void unregister_ip_vs_app(struct netns_ipvs *ipvs, struct ip_vs_app *app); int ip_vs_bind_app(struct ip_vs_conn *cp, struct ip_vs_protocol *pp); void ip_vs_unbind_app(struct ip_vs_conn *cp); -int register_ip_vs_app_inc(struct net *net, struct ip_vs_app *app, __u16 proto, +int register_ip_vs_app_inc(struct netns_ipvs *ipvs, struct ip_vs_app *app, __u16 proto, __u16 port); int ip_vs_app_inc_get(struct ip_vs_app *inc); void ip_vs_app_inc_put(struct ip_vs_app *inc); @@ -1375,10 +1372,10 @@ extern struct ip_vs_stats ip_vs_stats; extern int sysctl_ip_vs_sync_ver; struct ip_vs_service * -ip_vs_service_find(struct net *net, int af, __u32 fwmark, __u16 protocol, +ip_vs_service_find(struct netns_ipvs *ipvs, int af, __u32 fwmark, __u16 protocol, const union nf_inet_addr *vaddr, __be16 vport); -bool ip_vs_has_real_service(struct net *net, int af, __u16 protocol, +bool ip_vs_has_real_service(struct netns_ipvs *ipvs, int af, __u16 protocol, const union nf_inet_addr *daddr, __be16 dport); int ip_vs_use_count_inc(void); @@ -1388,7 +1385,7 @@ void ip_vs_unregister_nl_ioctl(void); int ip_vs_control_init(void); void ip_vs_control_cleanup(void); struct ip_vs_dest * -ip_vs_find_dest(struct net *net, int svc_af, int dest_af, +ip_vs_find_dest(struct netns_ipvs *ipvs, int svc_af, int dest_af, const union nf_inet_addr *daddr, __be16 dport, const union nf_inet_addr *vaddr, __be16 vport, __u16 protocol, __u32 fwmark, __u32 flags); @@ -1414,14 +1411,14 @@ static inline void ip_vs_dest_put_and_free(struct ip_vs_dest *dest) /* IPVS sync daemon data and function prototypes * (from ip_vs_sync.c) */ -int start_sync_thread(struct net *net, struct ipvs_sync_daemon_cfg *cfg, +int start_sync_thread(struct netns_ipvs *ipvs, struct ipvs_sync_daemon_cfg *cfg, int state); -int stop_sync_thread(struct net *net, int state); -void ip_vs_sync_conn(struct net *net, struct ip_vs_conn *cp, int pkts); +int stop_sync_thread(struct netns_ipvs *ipvs, int state); +void ip_vs_sync_conn(struct netns_ipvs *ipvs, struct ip_vs_conn *cp, int pkts); /* IPVS rate estimator prototypes (from ip_vs_est.c) */ -void ip_vs_start_estimator(struct net *net, struct ip_vs_stats *stats); -void ip_vs_stop_estimator(struct net *net, struct ip_vs_stats *stats); +void ip_vs_start_estimator(struct netns_ipvs *ipvs, struct ip_vs_stats *stats); +void ip_vs_stop_estimator(struct netns_ipvs *ipvs, struct ip_vs_stats *stats); void ip_vs_zero_estimator(struct ip_vs_stats *stats); void ip_vs_read_estimator(struct ip_vs_kstats *dst, struct ip_vs_stats *stats); diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 711cca428cc8..e1a10b0ac0b0 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -807,12 +807,12 @@ static inline u8 ip6_tclass(__be32 flowinfo) int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev); -int ip6_rcv_finish(struct sock *sk, struct sk_buff *skb); +int ip6_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb); /* * upper-layer output functions */ -int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6, +int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6, struct ipv6_txoptions *opt, int tclass); int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr); @@ -849,7 +849,7 @@ static inline struct sk_buff *ip6_finish_skb(struct sock *sk) int ip6_dst_lookup(struct net *net, struct sock *sk, struct dst_entry **dst, struct flowi6 *fl6); -struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6, +struct dst_entry *ip6_dst_lookup_flow(const struct sock *sk, struct flowi6 *fl6, const struct in6_addr *final_dst); struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6, const struct in6_addr *final_dst); @@ -860,14 +860,13 @@ struct dst_entry *ip6_blackhole_route(struct net *net, * skb processing functions */ -int ip6_output(struct sock *sk, struct sk_buff *skb); +int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb); int ip6_forward(struct sk_buff *skb); int ip6_input(struct sk_buff *skb); int ip6_mc_input(struct sk_buff *skb); -int __ip6_local_out(struct sk_buff *skb); -int ip6_local_out_sk(struct sock *sk, struct sk_buff *skb); -int ip6_local_out(struct sk_buff *skb); +int __ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb); +int ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb); /* * Extension header (options) processing diff --git a/include/net/iucv/iucv.h b/include/net/iucv/iucv.h index 0894ced31957..b867b0cf79e8 100644 --- a/include/net/iucv/iucv.h +++ b/include/net/iucv/iucv.h @@ -141,14 +141,14 @@ struct iucv_handler { * called is the order of the registration of the iucv handlers * to the base code. */ - int (*path_pending)(struct iucv_path *, u8 ipvmid[8], u8 ipuser[16]); + int (*path_pending)(struct iucv_path *, u8 *ipvmid, u8 *ipuser); /* * The path_complete function is called after an iucv interrupt * type 0x02 has been received for a path that has been established * for this handler with iucv_path_connect and got accepted by the * peer with iucv_path_accept. */ - void (*path_complete)(struct iucv_path *, u8 ipuser[16]); + void (*path_complete)(struct iucv_path *, u8 *ipuser); /* * The path_severed function is called after an iucv interrupt * type 0x03 has been received. The communication peer shutdown @@ -156,20 +156,20 @@ struct iucv_handler { * remaining messages can be received until a iucv_path_sever * shuts down the other end of the path as well. */ - void (*path_severed)(struct iucv_path *, u8 ipuser[16]); + void (*path_severed)(struct iucv_path *, u8 *ipuser); /* * The path_quiesced function is called after an icuv interrupt * type 0x04 has been received. The communication peer has quiesced * the path. Delivery of messages is stopped until iucv_path_resume * has been called. */ - void (*path_quiesced)(struct iucv_path *, u8 ipuser[16]); + void (*path_quiesced)(struct iucv_path *, u8 *ipuser); /* * The path_resumed function is called after an icuv interrupt * type 0x05 has been received. The communication peer has resumed * the path. */ - void (*path_resumed)(struct iucv_path *, u8 ipuser[16]); + void (*path_resumed)(struct iucv_path *, u8 *ipuser); /* * The message_pending function is called after an icuv interrupt * type 0x06 or type 0x07 has been received. A new message is @@ -256,7 +256,7 @@ static inline void iucv_path_free(struct iucv_path *path) * Returns the result of the CP IUCV call. */ int iucv_path_accept(struct iucv_path *path, struct iucv_handler *handler, - u8 userdata[16], void *private); + u8 *userdata, void *private); /** * iucv_path_connect @@ -274,7 +274,7 @@ int iucv_path_accept(struct iucv_path *path, struct iucv_handler *handler, * Returns the result of the CP IUCV call. */ int iucv_path_connect(struct iucv_path *path, struct iucv_handler *handler, - u8 userid[8], u8 system[8], u8 userdata[16], + u8 *userid, u8 *system, u8 *userdata, void *private); /** @@ -287,7 +287,7 @@ int iucv_path_connect(struct iucv_path *path, struct iucv_handler *handler, * * Returns the result from the CP IUCV call. */ -int iucv_path_quiesce(struct iucv_path *path, u8 userdata[16]); +int iucv_path_quiesce(struct iucv_path *path, u8 *userdata); /** * iucv_path_resume: @@ -299,7 +299,7 @@ int iucv_path_quiesce(struct iucv_path *path, u8 userdata[16]); * * Returns the result from the CP IUCV call. */ -int iucv_path_resume(struct iucv_path *path, u8 userdata[16]); +int iucv_path_resume(struct iucv_path *path, u8 *userdata); /** * iucv_path_sever @@ -310,7 +310,7 @@ int iucv_path_resume(struct iucv_path *path, u8 userdata[16]); * * Returns the result from the CP IUCV call. */ -int iucv_path_sever(struct iucv_path *path, u8 userdata[16]); +int iucv_path_sever(struct iucv_path *path, u8 *userdata); /** * iucv_message_purge diff --git a/include/net/l3mdev.h b/include/net/l3mdev.h new file mode 100644 index 000000000000..774d85b2d5d9 --- /dev/null +++ b/include/net/l3mdev.h @@ -0,0 +1,222 @@ +/* + * include/net/l3mdev.h - L3 master device API + * Copyright (c) 2015 Cumulus Networks + * Copyright (c) 2015 David Ahern <dsa@cumulusnetworks.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#ifndef _NET_L3MDEV_H_ +#define _NET_L3MDEV_H_ + +/** + * struct l3mdev_ops - l3mdev operations + * + * @l3mdev_fib_table: Get FIB table id to use for lookups + * + * @l3mdev_get_rtable: Get cached IPv4 rtable (dst_entry) for device + * + * @l3mdev_get_saddr: Get source address for a flow + * + * @l3mdev_get_rt6_dst: Get cached IPv6 rt6_info (dst_entry) for device + */ + +struct l3mdev_ops { + u32 (*l3mdev_fib_table)(const struct net_device *dev); + + /* IPv4 ops */ + struct rtable * (*l3mdev_get_rtable)(const struct net_device *dev, + const struct flowi4 *fl4); + void (*l3mdev_get_saddr)(struct net_device *dev, + struct flowi4 *fl4); + + /* IPv6 ops */ + struct dst_entry * (*l3mdev_get_rt6_dst)(const struct net_device *dev, + const struct flowi6 *fl6); +}; + +#ifdef CONFIG_NET_L3_MASTER_DEV + +int l3mdev_master_ifindex_rcu(struct net_device *dev); +static inline int l3mdev_master_ifindex(struct net_device *dev) +{ + int ifindex; + + rcu_read_lock(); + ifindex = l3mdev_master_ifindex_rcu(dev); + rcu_read_unlock(); + + return ifindex; +} + +/* get index of an interface to use for FIB lookups. For devices + * enslaved to an L3 master device FIB lookups are based on the + * master index + */ +static inline int l3mdev_fib_oif_rcu(struct net_device *dev) +{ + return l3mdev_master_ifindex_rcu(dev) ? : dev->ifindex; +} + +static inline int l3mdev_fib_oif(struct net_device *dev) +{ + int oif; + + rcu_read_lock(); + oif = l3mdev_fib_oif_rcu(dev); + rcu_read_unlock(); + + return oif; +} + +u32 l3mdev_fib_table_rcu(const struct net_device *dev); +u32 l3mdev_fib_table_by_index(struct net *net, int ifindex); +static inline u32 l3mdev_fib_table(const struct net_device *dev) +{ + u32 tb_id; + + rcu_read_lock(); + tb_id = l3mdev_fib_table_rcu(dev); + rcu_read_unlock(); + + return tb_id; +} + +static inline struct rtable *l3mdev_get_rtable(const struct net_device *dev, + const struct flowi4 *fl4) +{ + if (netif_is_l3_master(dev) && dev->l3mdev_ops->l3mdev_get_rtable) + return dev->l3mdev_ops->l3mdev_get_rtable(dev, fl4); + + return NULL; +} + +static inline bool netif_index_is_l3_master(struct net *net, int ifindex) +{ + struct net_device *dev; + bool rc = false; + + if (ifindex == 0) + return false; + + rcu_read_lock(); + + dev = dev_get_by_index_rcu(net, ifindex); + if (dev) + rc = netif_is_l3_master(dev); + + rcu_read_unlock(); + + return rc; +} + +static inline void l3mdev_get_saddr(struct net *net, int ifindex, + struct flowi4 *fl4) +{ + struct net_device *dev; + + if (ifindex) { + + rcu_read_lock(); + + dev = dev_get_by_index_rcu(net, ifindex); + if (dev && netif_is_l3_master(dev) && + dev->l3mdev_ops->l3mdev_get_saddr) { + dev->l3mdev_ops->l3mdev_get_saddr(dev, fl4); + } + + rcu_read_unlock(); + } +} + +static inline struct dst_entry *l3mdev_get_rt6_dst(const struct net_device *dev, + const struct flowi6 *fl6) +{ + if (netif_is_l3_master(dev) && dev->l3mdev_ops->l3mdev_get_rt6_dst) + return dev->l3mdev_ops->l3mdev_get_rt6_dst(dev, fl6); + + return NULL; +} + +static inline +struct dst_entry *l3mdev_rt6_dst_by_oif(struct net *net, + const struct flowi6 *fl6) +{ + struct dst_entry *dst = NULL; + struct net_device *dev; + + dev = dev_get_by_index(net, fl6->flowi6_oif); + if (dev) { + dst = l3mdev_get_rt6_dst(dev, fl6); + dev_put(dev); + } + + return dst; +} + +#else + +static inline int l3mdev_master_ifindex_rcu(struct net_device *dev) +{ + return 0; +} +static inline int l3mdev_master_ifindex(struct net_device *dev) +{ + return 0; +} + +static inline int l3mdev_fib_oif_rcu(struct net_device *dev) +{ + return dev ? dev->ifindex : 0; +} +static inline int l3mdev_fib_oif(struct net_device *dev) +{ + return dev ? dev->ifindex : 0; +} + +static inline u32 l3mdev_fib_table_rcu(const struct net_device *dev) +{ + return 0; +} +static inline u32 l3mdev_fib_table(const struct net_device *dev) +{ + return 0; +} +static inline u32 l3mdev_fib_table_by_index(struct net *net, int ifindex) +{ + return 0; +} + +static inline struct rtable *l3mdev_get_rtable(const struct net_device *dev, + const struct flowi4 *fl4) +{ + return NULL; +} + +static inline bool netif_index_is_l3_master(struct net *net, int ifindex) +{ + return false; +} + +static inline void l3mdev_get_saddr(struct net *net, int ifindex, + struct flowi4 *fl4) +{ +} + +static inline +struct dst_entry *l3mdev_get_rt6_dst(const struct net_device *dev, + const struct flowi6 *fl6) +{ + return NULL; +} +static inline +struct dst_entry *l3mdev_rt6_dst_by_oif(struct net *net, + const struct flowi6 *fl6) +{ + return NULL; +} +#endif + +#endif /* _NET_L3MDEV_H_ */ diff --git a/include/net/lwtunnel.h b/include/net/lwtunnel.h index fce0e35e74d0..66350ce3e955 100644 --- a/include/net/lwtunnel.h +++ b/include/net/lwtunnel.h @@ -18,7 +18,7 @@ struct lwtunnel_state { __u16 type; __u16 flags; atomic_t refcnt; - int (*orig_output)(struct sock *sk, struct sk_buff *skb); + int (*orig_output)(struct net *net, struct sock *sk, struct sk_buff *skb); int (*orig_input)(struct sk_buff *); int len; __u8 data[0]; @@ -28,7 +28,7 @@ struct lwtunnel_encap_ops { int (*build_state)(struct net_device *dev, struct nlattr *encap, unsigned int family, const void *cfg, struct lwtunnel_state **ts); - int (*output)(struct sock *sk, struct sk_buff *skb); + int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb); int (*input)(struct sk_buff *skb); int (*fill_encap)(struct sk_buff *skb, struct lwtunnel_state *lwtstate); @@ -88,7 +88,7 @@ int lwtunnel_fill_encap(struct sk_buff *skb, int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate); struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len); int lwtunnel_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b); -int lwtunnel_output(struct sock *sk, struct sk_buff *skb); +int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb); int lwtunnel_input(struct sk_buff *skb); #else @@ -160,7 +160,7 @@ static inline int lwtunnel_cmp_encap(struct lwtunnel_state *a, return 0; } -static inline int lwtunnel_output(struct sock *sk, struct sk_buff *skb) +static inline int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb) { return -EOPNOTSUPP; } diff --git a/include/net/mac80211.h b/include/net/mac80211.h index bfc569498bfa..82045fca388b 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -5,6 +5,7 @@ * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net> * Copyright 2013-2014 Intel Mobile Communications GmbH + * Copyright (C) 2015 Intel Deutschland GmbH * * 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 @@ -481,7 +482,9 @@ struct ieee80211_event { * Note that with TDLS this can be the case (channel is HT, protection must * be used from this field) even when the BSS association isn't using HT. * @cqm_rssi_thold: Connection quality monitor RSSI threshold, a zero value - * implies disabled + * implies disabled. As with the cfg80211 callback, a change here should + * cause an event to be sent indicating where the current value is in + * relation to the newly configured threshold. * @cqm_rssi_hyst: Connection quality monitor RSSI hysteresis * @arp_addr_list: List of IPv4 addresses for hardware ARP filtering. The * may filter ARP queries targeted for other addresses than listed here. @@ -1240,11 +1243,6 @@ enum ieee80211_smps_mode { * @flags: configuration flags defined above * * @listen_interval: listen interval in units of beacon interval - * @max_sleep_period: the maximum number of beacon intervals to sleep for - * before checking the beacon for a TIM bit (managed mode only); this - * value will be only achievable between DTIM frames, the hardware - * needs to check for the multicast traffic bit in DTIM beacons. - * This variable is valid only when the CONF_PS flag is set. * @ps_dtim_period: The DTIM period of the AP we're connected to, for use * in power saving. Power saving will not be enabled until a beacon * has been received and the DTIM period is known. @@ -1274,7 +1272,6 @@ enum ieee80211_smps_mode { struct ieee80211_conf { u32 flags; int power_level, dynamic_ps_timeout; - int max_sleep_period; u16 listen_interval; u8 ps_dtim_period; @@ -1360,6 +1357,8 @@ enum ieee80211_vif_flags { * @debugfs_dir: debugfs dentry, can be used by drivers to create own per * interface debug files. Note that it will be NULL for the virtual * monitor interface (if that is requested.) + * @probe_req_reg: probe requests should be reported to mac80211 for this + * interface. * @drv_priv: data area for driver use, will always be aligned to * sizeof(void *). * @txq: the multicast data TX queue (if driver uses the TXQ abstraction) @@ -1384,6 +1383,8 @@ struct ieee80211_vif { struct dentry *debugfs_dir; #endif + unsigned int probe_req_reg; + /* must be last */ u8 drv_priv[0] __aligned(sizeof(void *)); }; @@ -1494,10 +1495,8 @@ enum ieee80211_key_flags { * - Temporal Authenticator Rx MIC Key (64 bits) * @icv_len: The ICV length for this key type * @iv_len: The IV length for this key type - * @drv_priv: pointer for driver use */ struct ieee80211_key_conf { - void *drv_priv; atomic64_t tx_pn; u32 cipher; u8 icv_len; @@ -1680,6 +1679,7 @@ struct ieee80211_sta_rates { * @tdls: indicates whether the STA is a TDLS peer * @tdls_initiator: indicates the STA is an initiator of the TDLS link. Only * valid if the STA is a TDLS peer in the first place. + * @mfp: indicates whether the STA uses management frame protection or not. * @txq: per-TID data TX queues (if driver uses the TXQ abstraction) */ struct ieee80211_sta { @@ -1697,6 +1697,7 @@ struct ieee80211_sta { struct ieee80211_sta_rates __rcu *rates; bool tdls; bool tdls_initiator; + bool mfp; struct ieee80211_txq *txq[IEEE80211_NUM_TIDS]; @@ -1894,6 +1895,12 @@ struct ieee80211_txq { * @IEEE80211_HW_TDLS_WIDER_BW: The device/driver supports wider bandwidth * than then BSS bandwidth for a TDLS link on the base channel. * + * @IEEE80211_HW_SUPPORTS_AMSDU_IN_AMPDU: The driver supports receiving A-MSDUs + * within A-MPDU. + * + * @IEEE80211_HW_BEACON_TX_STATUS: The device/driver provides TX status + * for sent beacons. + * * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays */ enum ieee80211_hw_flags { @@ -1927,6 +1934,8 @@ enum ieee80211_hw_flags { IEEE80211_HW_SUPPORTS_CLONED_SKBS, IEEE80211_HW_SINGLE_SCAN_ON_ALL_BANDS, IEEE80211_HW_TDLS_WIDER_BW, + IEEE80211_HW_SUPPORTS_AMSDU_IN_AMPDU, + IEEE80211_HW_BEACON_TX_STATUS, /* keep last, obviously */ NUM_IEEE80211_HW_FLAGS @@ -2827,6 +2836,13 @@ enum ieee80211_reconfig_type { * See the section "Frame filtering" for more information. * This callback must be implemented and can sleep. * + * @config_iface_filter: Configure the interface's RX filter. + * This callback is optional and is used to configure which frames + * should be passed to mac80211. The filter_flags is the combination + * of FIF_* flags. The changed_flags is a bit mask that indicates + * which flags are changed. + * This callback can sleep. + * * @set_tim: Set TIM bit. mac80211 calls this function when a TIM bit * must be set or cleared for a given STA. Must be atomic. * @@ -3016,6 +3032,9 @@ enum ieee80211_reconfig_type { * buffer size of 8. Correct ways to retransmit #1 would be: * - TX: 1 or 18 or 81 * Even "189" would be wrong since 1 could be lost again. + * The @amsdu parameter is valid when the action is set to + * %IEEE80211_AMPDU_TX_OPERATIONAL and indicates the peer's ability + * to receive A-MSDU within A-MPDU. * * Returns a negative error code on failure. * The callback can sleep. @@ -3153,18 +3172,24 @@ enum ieee80211_reconfig_type { * The callback is optional and can sleep. * * @add_chanctx: Notifies device driver about new channel context creation. + * This callback may sleep. * @remove_chanctx: Notifies device driver about channel context destruction. + * This callback may sleep. * @change_chanctx: Notifies device driver about channel context changes that * may happen when combining different virtual interfaces on the same * channel context with different settings + * This callback may sleep. * @assign_vif_chanctx: Notifies device driver about channel context being bound * to vif. Possible use is for hw queue remapping. + * This callback may sleep. * @unassign_vif_chanctx: Notifies device driver about channel context being * unbound from vif. + * This callback may sleep. * @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. + * This callback may sleep. * * @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 @@ -3266,6 +3291,10 @@ struct ieee80211_ops { unsigned int changed_flags, unsigned int *total_flags, u64 multicast); + void (*config_iface_filter)(struct ieee80211_hw *hw, + struct ieee80211_vif *vif, + unsigned int filter_flags, + unsigned int changed_flags); int (*set_tim)(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set); int (*set_key)(struct ieee80211_hw *hw, enum set_key_cmd cmd, @@ -3349,7 +3378,7 @@ struct ieee80211_ops { struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, struct ieee80211_sta *sta, u16 tid, u16 *ssn, - u8 buf_size); + u8 buf_size, bool amsdu); int (*get_survey)(struct ieee80211_hw *hw, int idx, struct survey_info *survey); void (*rfkill_poll)(struct ieee80211_hw *hw); diff --git a/include/net/mac802154.h b/include/net/mac802154.h index b7f99615224b..da574bbdc333 100644 --- a/include/net/mac802154.h +++ b/include/net/mac802154.h @@ -23,14 +23,6 @@ #include <net/cfg802154.h> -/* General MAC frame format: - * 2 bytes: Frame Control - * 1 byte: Sequence Number - * 20 bytes: Addressing fields - * 14 bytes: Auxiliary Security Header - */ -#define MAC802154_FRAME_HARD_HEADER_LEN (2 + 1 + 20 + 14) - /** * enum ieee802154_hw_addr_filt_flags - hardware address filtering flags * @@ -250,6 +242,21 @@ struct ieee802154_ops { }; /** + * ieee802154_get_fc_from_skb - get the frame control field from an skb + * @skb: skb where the frame control field will be get from + */ +static inline __le16 ieee802154_get_fc_from_skb(const struct sk_buff *skb) +{ + /* return some invalid fc on failure */ + if (unlikely(skb->len < 2)) { + WARN_ON(1); + return cpu_to_le16(0); + } + + return (__force __le16)__get_unaligned_memmove16(skb_mac_header(skb)); +} + +/** * ieee802154_be64_to_le64 - copies and convert be64 to le64 * @le64_dst: le64 destination pointer * @be64_src: be64 source pointer @@ -270,6 +277,16 @@ static inline void ieee802154_le64_to_be64(void *be64_dst, const void *le64_src) } /** + * ieee802154_le16_to_be16 - copies and convert le16 to be16 + * @be16_dst: be16 destination pointer + * @le16_src: le16 source pointer + */ +static inline void ieee802154_le16_to_be16(void *be16_dst, const void *le16_src) +{ + __put_unaligned_memmove16(swab16p(le16_src), be16_dst); +} + +/** * ieee802154_alloc_hw - Allocate a new hardware device * * This must be called once for each hardware device. The returned pointer diff --git a/include/net/mpls_iptunnel.h b/include/net/mpls_iptunnel.h index 4757997f76ed..179253f9dcfd 100644 --- a/include/net/mpls_iptunnel.h +++ b/include/net/mpls_iptunnel.h @@ -18,7 +18,7 @@ struct mpls_iptunnel_encap { u32 label[MAX_NEW_LABELS]; - u32 labels; + u8 labels; }; static inline struct mpls_iptunnel_encap *mpls_lwtunnel_encap(struct lwtunnel_state *lwtstate) diff --git a/include/net/ndisc.h b/include/net/ndisc.h index aba5695fadb0..bf3937431030 100644 --- a/include/net/ndisc.h +++ b/include/net/ndisc.h @@ -180,15 +180,13 @@ void ndisc_cleanup(void); int ndisc_rcv(struct sk_buff *skb); -void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh, - const struct in6_addr *solicit, +void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit, const struct in6_addr *daddr, const struct in6_addr *saddr, struct sk_buff *oskb); void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr, const struct in6_addr *daddr); -void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, - const struct in6_addr *daddr, +void ndisc_send_na(struct net_device *dev, const struct in6_addr *daddr, const struct in6_addr *solicited_addr, bool router, bool solicited, bool override, bool inc_opt); diff --git a/include/net/netfilter/br_netfilter.h b/include/net/netfilter/br_netfilter.h index d4c6b5f30acd..e8d1448425a7 100644 --- a/include/net/netfilter/br_netfilter.h +++ b/include/net/netfilter/br_netfilter.h @@ -31,7 +31,7 @@ static inline void nf_bridge_push_encap_header(struct sk_buff *skb) skb->network_header -= len; } -int br_nf_pre_routing_finish_bridge(struct sock *sk, struct sk_buff *skb); +int br_nf_pre_routing_finish_bridge(struct net *net, struct sock *sk, struct sk_buff *skb); static inline struct rtable *bridge_parent_rtable(const struct net_device *dev) { @@ -45,12 +45,12 @@ struct net_device *setup_pre_routing(struct sk_buff *skb); void br_netfilter_enable(void); #if IS_ENABLED(CONFIG_IPV6) -int br_validate_ipv6(struct sk_buff *skb); -unsigned int br_nf_pre_routing_ipv6(const struct nf_hook_ops *ops, +int br_validate_ipv6(struct net *net, struct sk_buff *skb); +unsigned int br_nf_pre_routing_ipv6(void *priv, struct sk_buff *skb, const struct nf_hook_state *state); #else -static inline int br_validate_ipv6(struct sk_buff *skb) +static inline int br_validate_ipv6(struct net *net, struct sk_buff *skb) { return -1; } diff --git a/include/net/netfilter/ipv4/nf_dup_ipv4.h b/include/net/netfilter/ipv4/nf_dup_ipv4.h index 42008f10dfc4..0a14733e8b82 100644 --- a/include/net/netfilter/ipv4/nf_dup_ipv4.h +++ b/include/net/netfilter/ipv4/nf_dup_ipv4.h @@ -1,7 +1,7 @@ #ifndef _NF_DUP_IPV4_H_ #define _NF_DUP_IPV4_H_ -void nf_dup_ipv4(struct sk_buff *skb, unsigned int hooknum, +void nf_dup_ipv4(struct net *net, struct sk_buff *skb, unsigned int hooknum, const struct in_addr *gw, int oif); #endif /* _NF_DUP_IPV4_H_ */ diff --git a/include/net/netfilter/ipv4/nf_reject.h b/include/net/netfilter/ipv4/nf_reject.h index 77862c3645f0..df7ecd806aba 100644 --- a/include/net/netfilter/ipv4/nf_reject.h +++ b/include/net/netfilter/ipv4/nf_reject.h @@ -6,7 +6,7 @@ #include <net/icmp.h> void nf_send_unreach(struct sk_buff *skb_in, int code, int hook); -void nf_send_reset(struct sk_buff *oldskb, int hook); +void nf_send_reset(struct net *net, struct sk_buff *oldskb, int hook); const struct tcphdr *nf_reject_ip_tcphdr_get(struct sk_buff *oldskb, struct tcphdr *_oth, int hook); diff --git a/include/net/netfilter/ipv6/nf_defrag_ipv6.h b/include/net/netfilter/ipv6/nf_defrag_ipv6.h index 27666d8a0bd0..fb7da5bb76cc 100644 --- a/include/net/netfilter/ipv6/nf_defrag_ipv6.h +++ b/include/net/netfilter/ipv6/nf_defrag_ipv6.h @@ -5,7 +5,7 @@ void nf_defrag_ipv6_enable(void); int nf_ct_frag6_init(void); void nf_ct_frag6_cleanup(void); -struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user); +struct sk_buff *nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user); void nf_ct_frag6_consume_orig(struct sk_buff *skb); struct inet_frags_ctl; diff --git a/include/net/netfilter/ipv6/nf_dup_ipv6.h b/include/net/netfilter/ipv6/nf_dup_ipv6.h index ed6bd66fa5a0..fa6237b382a3 100644 --- a/include/net/netfilter/ipv6/nf_dup_ipv6.h +++ b/include/net/netfilter/ipv6/nf_dup_ipv6.h @@ -1,7 +1,7 @@ #ifndef _NF_DUP_IPV6_H_ #define _NF_DUP_IPV6_H_ -void nf_dup_ipv6(struct sk_buff *skb, unsigned int hooknum, +void nf_dup_ipv6(struct net *net, struct sk_buff *skb, unsigned int hooknum, const struct in6_addr *gw, int oif); #endif /* _NF_DUP_IPV6_H_ */ diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index e8ad46834df8..fde4068eec0b 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h @@ -183,15 +183,12 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls); void nf_ct_free_hashtable(void *hash, unsigned int size); -struct nf_conntrack_tuple_hash * -__nf_conntrack_find(struct net *net, u16 zone, - const struct nf_conntrack_tuple *tuple); - int nf_conntrack_hash_check_insert(struct nf_conn *ct); bool nf_ct_delete(struct nf_conn *ct, u32 pid, int report); bool nf_ct_get_tuplepr(const struct sk_buff *skb, unsigned int nhoff, - u_int16_t l3num, struct nf_conntrack_tuple *tuple); + u_int16_t l3num, struct net *net, + struct nf_conntrack_tuple *tuple); bool nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse, const struct nf_conntrack_tuple *orig); diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h index c03f9c42b3cd..788ef58a66b9 100644 --- a/include/net/netfilter/nf_conntrack_core.h +++ b/include/net/netfilter/nf_conntrack_core.h @@ -41,6 +41,7 @@ void nf_conntrack_cleanup_end(void); bool nf_ct_get_tuple(const struct sk_buff *skb, unsigned int nhoff, unsigned int dataoff, u_int16_t l3num, u_int8_t protonum, + struct net *net, struct nf_conntrack_tuple *tuple, const struct nf_conntrack_l3proto *l3proto, const struct nf_conntrack_l4proto *l4proto); diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h index 1f7061313d54..956d8a6ac069 100644 --- a/include/net/netfilter/nf_conntrack_l4proto.h +++ b/include/net/netfilter/nf_conntrack_l4proto.h @@ -26,7 +26,7 @@ struct nf_conntrack_l4proto { /* Try to fill in the third arg: dataoff is offset past network protocol hdr. Return true if possible. */ bool (*pkt_to_tuple)(const struct sk_buff *skb, unsigned int dataoff, - struct nf_conntrack_tuple *tuple); + struct net *net, struct nf_conntrack_tuple *tuple); /* Invert the per-proto part of the tuple: ie. turn xmit into reply. * Some packets can't be inverted: return 0 in that case. diff --git a/include/net/netfilter/nf_conntrack_timeout.h b/include/net/netfilter/nf_conntrack_timeout.h index 62308713dd7f..f72be38860a7 100644 --- a/include/net/netfilter/nf_conntrack_timeout.h +++ b/include/net/netfilter/nf_conntrack_timeout.h @@ -20,10 +20,20 @@ struct ctnl_timeout { }; struct nf_conn_timeout { - struct ctnl_timeout *timeout; + struct ctnl_timeout __rcu *timeout; }; -#define NF_CT_TIMEOUT_EXT_DATA(__t) (unsigned int *) &((__t)->timeout->data) +static inline unsigned int * +nf_ct_timeout_data(struct nf_conn_timeout *t) +{ + struct ctnl_timeout *timeout; + + timeout = rcu_dereference(t->timeout); + if (timeout == NULL) + return NULL; + + return (unsigned int *)timeout->data; +} static inline struct nf_conn_timeout *nf_ct_timeout_find(const struct nf_conn *ct) @@ -47,7 +57,7 @@ struct nf_conn_timeout *nf_ct_timeout_ext_add(struct nf_conn *ct, if (timeout_ext == NULL) return NULL; - timeout_ext->timeout = timeout; + rcu_assign_pointer(timeout_ext->timeout, timeout); return timeout_ext; #else @@ -64,10 +74,13 @@ nf_ct_timeout_lookup(struct net *net, struct nf_conn *ct, unsigned int *timeouts; timeout_ext = nf_ct_timeout_find(ct); - if (timeout_ext) - timeouts = NF_CT_TIMEOUT_EXT_DATA(timeout_ext); - else + if (timeout_ext) { + timeouts = nf_ct_timeout_data(timeout_ext); + if (unlikely(!timeouts)) + timeouts = l4proto->get_timeouts(net); + } else { timeouts = l4proto->get_timeouts(net); + } return timeouts; #else diff --git a/include/net/netfilter/nf_nat_core.h b/include/net/netfilter/nf_nat_core.h index fbfd1ba4254e..186c54138f35 100644 --- a/include/net/netfilter/nf_nat_core.h +++ b/include/net/netfilter/nf_nat_core.h @@ -10,7 +10,7 @@ unsigned int nf_nat_packet(struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned int hooknum, struct sk_buff *skb); -int nf_xfrm_me_harder(struct sk_buff *skb, unsigned int family); +int nf_xfrm_me_harder(struct net *net, struct sk_buff *skb, unsigned int family); static inline int nf_nat_initialized(struct nf_conn *ct, enum nf_nat_manip_type manip) diff --git a/include/net/netfilter/nf_nat_l3proto.h b/include/net/netfilter/nf_nat_l3proto.h index a3127325f624..aef3e5fc9fd9 100644 --- a/include/net/netfilter/nf_nat_l3proto.h +++ b/include/net/netfilter/nf_nat_l3proto.h @@ -43,31 +43,31 @@ int nf_nat_icmp_reply_translation(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned int hooknum); -unsigned int nf_nat_ipv4_in(const struct nf_hook_ops *ops, struct sk_buff *skb, +unsigned int nf_nat_ipv4_in(void *priv, struct sk_buff *skb, const struct nf_hook_state *state, - unsigned int (*do_chain)(const struct nf_hook_ops *ops, + unsigned int (*do_chain)(void *priv, struct sk_buff *skb, const struct nf_hook_state *state, struct nf_conn *ct)); -unsigned int nf_nat_ipv4_out(const struct nf_hook_ops *ops, struct sk_buff *skb, +unsigned int nf_nat_ipv4_out(void *priv, struct sk_buff *skb, const struct nf_hook_state *state, - unsigned int (*do_chain)(const struct nf_hook_ops *ops, + unsigned int (*do_chain)(void *priv, struct sk_buff *skb, const struct nf_hook_state *state, struct nf_conn *ct)); -unsigned int nf_nat_ipv4_local_fn(const struct nf_hook_ops *ops, +unsigned int nf_nat_ipv4_local_fn(void *priv, struct sk_buff *skb, const struct nf_hook_state *state, - unsigned int (*do_chain)(const struct nf_hook_ops *ops, + unsigned int (*do_chain)(void *priv, struct sk_buff *skb, const struct nf_hook_state *state, struct nf_conn *ct)); -unsigned int nf_nat_ipv4_fn(const struct nf_hook_ops *ops, struct sk_buff *skb, +unsigned int nf_nat_ipv4_fn(void *priv, struct sk_buff *skb, const struct nf_hook_state *state, - unsigned int (*do_chain)(const struct nf_hook_ops *ops, + unsigned int (*do_chain)(void *priv, struct sk_buff *skb, const struct nf_hook_state *state, struct nf_conn *ct)); @@ -76,31 +76,31 @@ int nf_nat_icmpv6_reply_translation(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo, unsigned int hooknum, unsigned int hdrlen); -unsigned int nf_nat_ipv6_in(const struct nf_hook_ops *ops, struct sk_buff *skb, +unsigned int nf_nat_ipv6_in(void *priv, struct sk_buff *skb, const struct nf_hook_state *state, - unsigned int (*do_chain)(const struct nf_hook_ops *ops, + unsigned int (*do_chain)(void *priv, struct sk_buff *skb, const struct nf_hook_state *state, struct nf_conn *ct)); -unsigned int nf_nat_ipv6_out(const struct nf_hook_ops *ops, struct sk_buff *skb, +unsigned int nf_nat_ipv6_out(void *priv, struct sk_buff *skb, const struct nf_hook_state *state, - unsigned int (*do_chain)(const struct nf_hook_ops *ops, + unsigned int (*do_chain)(void *priv, struct sk_buff *skb, const struct nf_hook_state *state, struct nf_conn *ct)); -unsigned int nf_nat_ipv6_local_fn(const struct nf_hook_ops *ops, +unsigned int nf_nat_ipv6_local_fn(void *priv, struct sk_buff *skb, const struct nf_hook_state *state, - unsigned int (*do_chain)(const struct nf_hook_ops *ops, + unsigned int (*do_chain)(void *priv, struct sk_buff *skb, const struct nf_hook_state *state, struct nf_conn *ct)); -unsigned int nf_nat_ipv6_fn(const struct nf_hook_ops *ops, struct sk_buff *skb, +unsigned int nf_nat_ipv6_fn(void *priv, struct sk_buff *skb, const struct nf_hook_state *state, - unsigned int (*do_chain)(const struct nf_hook_ops *ops, + unsigned int (*do_chain)(void *priv, struct sk_buff *skb, const struct nf_hook_state *state, struct nf_conn *ct)); diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h index e8635854a55b..9c5638ad872e 100644 --- a/include/net/netfilter/nf_queue.h +++ b/include/net/netfilter/nf_queue.h @@ -32,7 +32,7 @@ void nf_register_queue_handler(const struct nf_queue_handler *qh); void nf_unregister_queue_handler(void); void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict); -bool nf_queue_entry_get_refs(struct nf_queue_entry *entry); +void nf_queue_entry_get_refs(struct nf_queue_entry *entry); void nf_queue_entry_release_refs(struct nf_queue_entry *entry); static inline void init_hashrandom(u32 *jhash_initval) diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h index aa8bee72c9d3..c9149cc0a02d 100644 --- a/include/net/netfilter/nf_tables.h +++ b/include/net/netfilter/nf_tables.h @@ -14,9 +14,11 @@ struct nft_pktinfo { struct sk_buff *skb; + struct net *net; const struct net_device *in; const struct net_device *out; - const struct nf_hook_ops *ops; + u8 pf; + u8 hook; u8 nhoff; u8 thoff; u8 tprot; @@ -25,16 +27,15 @@ struct nft_pktinfo { }; static inline void nft_set_pktinfo(struct nft_pktinfo *pkt, - const struct nf_hook_ops *ops, struct sk_buff *skb, const struct nf_hook_state *state) { pkt->skb = skb; + pkt->net = pkt->xt.net = state->net; pkt->in = pkt->xt.in = state->in; pkt->out = pkt->xt.out = state->out; - pkt->ops = ops; - pkt->xt.hooknum = ops->hooknum; - pkt->xt.family = ops->pf; + pkt->hook = pkt->xt.hooknum = state->hook; + pkt->pf = pkt->xt.family = state->pf; } /** @@ -815,8 +816,7 @@ int nft_register_basechain(struct nft_base_chain *basechain, void nft_unregister_basechain(struct nft_base_chain *basechain, unsigned int hook_nops); -unsigned int nft_do_chain(struct nft_pktinfo *pkt, - const struct nf_hook_ops *ops); +unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv); /** * struct nft_table - nf_tables table diff --git a/include/net/netfilter/nf_tables_ipv4.h b/include/net/netfilter/nf_tables_ipv4.h index 2df7f96902ee..ca6ef6bf775e 100644 --- a/include/net/netfilter/nf_tables_ipv4.h +++ b/include/net/netfilter/nf_tables_ipv4.h @@ -6,13 +6,12 @@ static inline void nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt, - const struct nf_hook_ops *ops, struct sk_buff *skb, const struct nf_hook_state *state) { struct iphdr *ip; - nft_set_pktinfo(pkt, ops, skb, state); + nft_set_pktinfo(pkt, skb, state); ip = ip_hdr(pkt->skb); pkt->tprot = ip->protocol; diff --git a/include/net/netfilter/nf_tables_ipv6.h b/include/net/netfilter/nf_tables_ipv6.h index 97db2e3a5e65..8ad39a6a5fe1 100644 --- a/include/net/netfilter/nf_tables_ipv6.h +++ b/include/net/netfilter/nf_tables_ipv6.h @@ -6,14 +6,13 @@ static inline int nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt, - const struct nf_hook_ops *ops, struct sk_buff *skb, const struct nf_hook_state *state) { int protohdr, thoff = 0; unsigned short frag_off; - nft_set_pktinfo(pkt, ops, skb, state); + nft_set_pktinfo(pkt, skb, state); protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, NULL); /* If malformed, drop it */ diff --git a/include/net/netfilter/nfnetlink_queue.h b/include/net/netfilter/nfnetlink_queue.h deleted file mode 100644 index aff88ba91391..000000000000 --- a/include/net/netfilter/nfnetlink_queue.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef _NET_NFNL_QUEUE_H_ -#define _NET_NFNL_QUEUE_H_ - -#include <linux/netfilter/nf_conntrack_common.h> - -struct nf_conn; - -#ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT -struct nf_conn *nfqnl_ct_get(struct sk_buff *entskb, size_t *size, - enum ip_conntrack_info *ctinfo); -struct nf_conn *nfqnl_ct_parse(const struct sk_buff *skb, - const struct nlattr *attr, - enum ip_conntrack_info *ctinfo); -int nfqnl_ct_put(struct sk_buff *skb, struct nf_conn *ct, - enum ip_conntrack_info ctinfo); -void nfqnl_ct_seq_adjust(struct sk_buff *skb, struct nf_conn *ct, - enum ip_conntrack_info ctinfo, int diff); -int nfqnl_attach_expect(struct nf_conn *ct, const struct nlattr *attr, - u32 portid, u32 report); -#else -inline struct nf_conn * -nfqnl_ct_get(struct sk_buff *entskb, size_t *size, enum ip_conntrack_info *ctinfo) -{ - return NULL; -} - -inline struct nf_conn *nfqnl_ct_parse(const struct sk_buff *skb, - const struct nlattr *attr, - enum ip_conntrack_info *ctinfo) -{ - return NULL; -} - -inline int -nfqnl_ct_put(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info ctinfo) -{ - return 0; -} - -inline void nfqnl_ct_seq_adjust(struct sk_buff *skb, struct nf_conn *ct, - enum ip_conntrack_info ctinfo, int diff) -{ -} - -inline int nfqnl_attach_expect(struct nf_conn *ct, const struct nlattr *attr, - u32 portid, u32 report) -{ - return 0; -} -#endif /* NF_CONNTRACK */ -#endif diff --git a/include/net/netlink.h b/include/net/netlink.h index 2a5dbcc90d1c..0e3172751755 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -1004,6 +1004,15 @@ static inline __be32 nla_get_be32(const struct nlattr *nla) } /** + * nla_get_le32 - return payload of __le32 attribute + * @nla: __le32 netlink attribute + */ +static inline __le32 nla_get_le32(const struct nlattr *nla) +{ + return *(__le32 *) nla_data(nla); +} + +/** * nla_get_u16 - return payload of u16 attribute * @nla: u16 netlink attribute */ @@ -1066,6 +1075,15 @@ static inline __be64 nla_get_be64(const struct nlattr *nla) } /** + * nla_get_le64 - return payload of __le64 attribute + * @nla: __le64 netlink attribute + */ +static inline __le64 nla_get_le64(const struct nlattr *nla) +{ + return *(__le64 *) nla_data(nla); +} + +/** * nla_get_s32 - return payload of s32 attribute * @nla: s32 netlink attribute */ diff --git a/include/net/nfc/nci.h b/include/net/nfc/nci.h index 75d2e1880059..707e3ab816c2 100644 --- a/include/net/nfc/nci.h +++ b/include/net/nfc/nci.h @@ -35,6 +35,7 @@ #define NCI_MAX_NUM_RF_CONFIGS 10 #define NCI_MAX_NUM_CONN 10 #define NCI_MAX_PARAM_LEN 251 +#define NCI_MAX_PAYLOAD_SIZE 255 #define NCI_MAX_PACKET_SIZE 258 /* NCI Status Codes */ @@ -315,6 +316,8 @@ struct nci_nfcee_mode_set_cmd { __u8 nfcee_mode; } __packed; +#define NCI_OP_CORE_GET_CONFIG_CMD nci_opcode_pack(NCI_GID_CORE, 0x03) + /* ----------------------- */ /* ---- NCI Responses ---- */ /* ----------------------- */ @@ -375,6 +378,9 @@ struct nci_nfcee_discover_rsp { } __packed; #define NCI_OP_NFCEE_MODE_SET_RSP nci_opcode_pack(NCI_GID_NFCEE_MGMT, 0x01) + +#define NCI_OP_CORE_GET_CONFIG_RSP nci_opcode_pack(NCI_GID_CORE, 0x03) + /* --------------------------- */ /* ---- NCI Notifications ---- */ /* --------------------------- */ @@ -528,4 +534,6 @@ struct nci_nfcee_discover_ntf { struct nci_nfcee_information_tlv information_tlv; } __packed; +#define NCI_OP_CORE_RESET_NTF nci_opcode_pack(NCI_GID_CORE, 0x00) + #endif /* __NCI_H */ diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h index d0d0f1e53bb9..57ce24fb0047 100644 --- a/include/net/nfc/nci_core.h +++ b/include/net/nfc/nci_core.h @@ -67,7 +67,7 @@ enum nci_state { struct nci_dev; -struct nci_prop_ops { +struct nci_driver_ops { __u16 opcode; int (*rsp)(struct nci_dev *dev, struct sk_buff *skb); int (*ntf)(struct nci_dev *dev, struct sk_buff *skb); @@ -94,8 +94,11 @@ struct nci_ops { void (*hci_cmd_received)(struct nci_dev *ndev, u8 pipe, u8 cmd, struct sk_buff *skb); - struct nci_prop_ops *prop_ops; + struct nci_driver_ops *prop_ops; size_t n_prop_ops; + + struct nci_driver_ops *core_ops; + size_t n_core_ops; }; #define NCI_MAX_SUPPORTED_RF_INTERFACES 4 @@ -125,6 +128,8 @@ struct nci_conn_info { /* Gates */ #define NCI_HCI_ADMIN_GATE 0x00 +#define NCI_HCI_LOOPBACK_GATE 0x04 +#define NCI_HCI_IDENTITY_MGMT_GATE 0x05 #define NCI_HCI_LINK_MGMT_GATE 0x06 /* Pipes */ @@ -278,10 +283,12 @@ int nci_request(struct nci_dev *ndev, unsigned long opt), unsigned long opt, __u32 timeout); int nci_prop_cmd(struct nci_dev *ndev, __u8 oid, size_t len, __u8 *payload); +int nci_core_cmd(struct nci_dev *ndev, __u16 opcode, size_t len, __u8 *payload); int nci_core_reset(struct nci_dev *ndev); int nci_core_init(struct nci_dev *ndev); int nci_recv_frame(struct nci_dev *ndev, struct sk_buff *skb); +int nci_send_frame(struct nci_dev *ndev, struct sk_buff *skb); int nci_set_config(struct nci_dev *ndev, __u8 id, size_t len, __u8 *val); int nci_nfcee_discover(struct nci_dev *ndev, u8 action); @@ -305,6 +312,7 @@ int nci_hci_set_param(struct nci_dev *ndev, u8 gate, u8 idx, const u8 *param, size_t param_len); int nci_hci_get_param(struct nci_dev *ndev, u8 gate, u8 idx, struct sk_buff **skb); +int nci_hci_clear_all_pipes(struct nci_dev *ndev); int nci_hci_dev_session_init(struct nci_dev *ndev); static inline struct sk_buff *nci_skb_alloc(struct nci_dev *ndev, @@ -348,9 +356,14 @@ int nci_prop_rsp_packet(struct nci_dev *ndev, __u16 opcode, struct sk_buff *skb); int nci_prop_ntf_packet(struct nci_dev *ndev, __u16 opcode, struct sk_buff *skb); +int nci_core_rsp_packet(struct nci_dev *ndev, __u16 opcode, + struct sk_buff *skb); +int nci_core_ntf_packet(struct nci_dev *ndev, __u16 opcode, + struct sk_buff *skb); void nci_rx_data_packet(struct nci_dev *ndev, struct sk_buff *skb); int nci_send_cmd(struct nci_dev *ndev, __u16 opcode, __u8 plen, void *payload); int nci_send_data(struct nci_dev *ndev, __u8 conn_id, struct sk_buff *skb); +int nci_conn_max_data_pkt_payload_size(struct nci_dev *ndev, __u8 conn_id); void nci_data_exchange_complete(struct nci_dev *ndev, struct sk_buff *skb, __u8 conn_id, int err); void nci_hci_data_received_cb(void *context, struct sk_buff *skb, int err); @@ -365,6 +378,7 @@ void nci_clear_target_list(struct nci_dev *ndev); void nci_req_complete(struct nci_dev *ndev, int result); struct nci_conn_info *nci_get_conn_info_by_conn_id(struct nci_dev *ndev, int conn_id); +int nci_get_conn_info_by_id(struct nci_dev *ndev, u8 id); /* ----- NCI status code ----- */ int nci_to_errno(__u8 code); @@ -380,6 +394,12 @@ struct nci_spi { unsigned int xfer_udelay; /* microseconds delay between transactions */ + + unsigned int xfer_speed_hz; /* + * SPI clock frequency + * 0 => default clock + */ + u8 acknowledge_mode; struct completion req_completion; diff --git a/include/net/nfc/nfc.h b/include/net/nfc/nfc.h index 30afc9a6718c..dcfcfc9c00bf 100644 --- a/include/net/nfc/nfc.h +++ b/include/net/nfc/nfc.h @@ -68,7 +68,7 @@ struct nfc_ops { int (*activate_target)(struct nfc_dev *dev, struct nfc_target *target, u32 protocol); void (*deactivate_target)(struct nfc_dev *dev, - struct nfc_target *target); + struct nfc_target *target, u8 mode); int (*im_transceive)(struct nfc_dev *dev, struct nfc_target *target, struct sk_buff *skb, data_exchange_cb_t cb, void *cb_context); diff --git a/include/net/nl802154.h b/include/net/nl802154.h index cf2713d8b975..32cb3e591e07 100644 --- a/include/net/nl802154.h +++ b/include/net/nl802154.h @@ -56,6 +56,22 @@ enum nl802154_commands { /* add new commands above here */ +#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL + NL802154_CMD_SET_SEC_PARAMS, + NL802154_CMD_GET_SEC_KEY, /* can dump */ + NL802154_CMD_NEW_SEC_KEY, + NL802154_CMD_DEL_SEC_KEY, + NL802154_CMD_GET_SEC_DEV, /* can dump */ + NL802154_CMD_NEW_SEC_DEV, + NL802154_CMD_DEL_SEC_DEV, + NL802154_CMD_GET_SEC_DEVKEY, /* can dump */ + NL802154_CMD_NEW_SEC_DEVKEY, + NL802154_CMD_DEL_SEC_DEVKEY, + NL802154_CMD_GET_SEC_LEVEL, /* can dump */ + NL802154_CMD_NEW_SEC_LEVEL, + NL802154_CMD_DEL_SEC_LEVEL, +#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */ + /* used to define NL802154_CMD_MAX below */ __NL802154_CMD_AFTER_LAST, NL802154_CMD_MAX = __NL802154_CMD_AFTER_LAST - 1 @@ -110,6 +126,18 @@ enum nl802154_attrs { /* add attributes here, update the policy in nl802154.c */ +#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL + NL802154_ATTR_SEC_ENABLED, + NL802154_ATTR_SEC_OUT_LEVEL, + NL802154_ATTR_SEC_OUT_KEY_ID, + NL802154_ATTR_SEC_FRAME_COUNTER, + + NL802154_ATTR_SEC_LEVEL, + NL802154_ATTR_SEC_DEVICE, + NL802154_ATTR_SEC_DEVKEY, + NL802154_ATTR_SEC_KEY, +#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */ + __NL802154_ATTR_AFTER_LAST, NL802154_ATTR_MAX = __NL802154_ATTR_AFTER_LAST - 1 }; @@ -247,4 +275,167 @@ enum nl802154_supported_bool_states { NL802154_SUPPORTED_BOOL_MAX = __NL802154_SUPPORTED_BOOL_AFTER_LAST - 1 }; +#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL + +enum nl802154_dev_addr_modes { + NL802154_DEV_ADDR_NONE, + __NL802154_DEV_ADDR_INVALID, + NL802154_DEV_ADDR_SHORT, + NL802154_DEV_ADDR_EXTENDED, + + /* keep last */ + __NL802154_DEV_ADDR_AFTER_LAST, + NL802154_DEV_ADDR_MAX = __NL802154_DEV_ADDR_AFTER_LAST - 1 +}; + +enum nl802154_dev_addr_attrs { + NL802154_DEV_ADDR_ATTR_UNSPEC, + + NL802154_DEV_ADDR_ATTR_PAN_ID, + NL802154_DEV_ADDR_ATTR_MODE, + NL802154_DEV_ADDR_ATTR_SHORT, + NL802154_DEV_ADDR_ATTR_EXTENDED, + + /* keep last */ + __NL802154_DEV_ADDR_ATTR_AFTER_LAST, + NL802154_DEV_ADDR_ATTR_MAX = __NL802154_DEV_ADDR_ATTR_AFTER_LAST - 1 +}; + +enum nl802154_key_id_modes { + NL802154_KEY_ID_MODE_IMPLICIT, + NL802154_KEY_ID_MODE_INDEX, + NL802154_KEY_ID_MODE_INDEX_SHORT, + NL802154_KEY_ID_MODE_INDEX_EXTENDED, + + /* keep last */ + __NL802154_KEY_ID_MODE_AFTER_LAST, + NL802154_KEY_ID_MODE_MAX = __NL802154_KEY_ID_MODE_AFTER_LAST - 1 +}; + +enum nl802154_key_id_attrs { + NL802154_KEY_ID_ATTR_UNSPEC, + + NL802154_KEY_ID_ATTR_MODE, + NL802154_KEY_ID_ATTR_INDEX, + NL802154_KEY_ID_ATTR_IMPLICIT, + NL802154_KEY_ID_ATTR_SOURCE_SHORT, + NL802154_KEY_ID_ATTR_SOURCE_EXTENDED, + + /* keep last */ + __NL802154_KEY_ID_ATTR_AFTER_LAST, + NL802154_KEY_ID_ATTR_MAX = __NL802154_KEY_ID_ATTR_AFTER_LAST - 1 +}; + +enum nl802154_seclevels { + NL802154_SECLEVEL_NONE, + NL802154_SECLEVEL_MIC32, + NL802154_SECLEVEL_MIC64, + NL802154_SECLEVEL_MIC128, + NL802154_SECLEVEL_ENC, + NL802154_SECLEVEL_ENC_MIC32, + NL802154_SECLEVEL_ENC_MIC64, + NL802154_SECLEVEL_ENC_MIC128, + + /* keep last */ + __NL802154_SECLEVEL_AFTER_LAST, + NL802154_SECLEVEL_MAX = __NL802154_SECLEVEL_AFTER_LAST - 1 +}; + +enum nl802154_frames { + NL802154_FRAME_BEACON, + NL802154_FRAME_DATA, + NL802154_FRAME_ACK, + NL802154_FRAME_CMD, + + /* keep last */ + __NL802154_FRAME_AFTER_LAST, + NL802154_FRAME_MAX = __NL802154_FRAME_AFTER_LAST - 1 +}; + +enum nl802154_cmd_frames { + __NL802154_CMD_FRAME_INVALID, + NL802154_CMD_FRAME_ASSOC_REQUEST, + NL802154_CMD_FRAME_ASSOC_RESPONSE, + NL802154_CMD_FRAME_DISASSOC_NOTIFY, + NL802154_CMD_FRAME_DATA_REQUEST, + NL802154_CMD_FRAME_PAN_ID_CONFLICT_NOTIFY, + NL802154_CMD_FRAME_ORPHAN_NOTIFY, + NL802154_CMD_FRAME_BEACON_REQUEST, + NL802154_CMD_FRAME_COORD_REALIGNMENT, + NL802154_CMD_FRAME_GTS_REQUEST, + + /* keep last */ + __NL802154_CMD_FRAME_AFTER_LAST, + NL802154_CMD_FRAME_MAX = __NL802154_CMD_FRAME_AFTER_LAST - 1 +}; + +enum nl802154_seclevel_attrs { + NL802154_SECLEVEL_ATTR_UNSPEC, + + NL802154_SECLEVEL_ATTR_LEVELS, + NL802154_SECLEVEL_ATTR_FRAME, + NL802154_SECLEVEL_ATTR_CMD_FRAME, + NL802154_SECLEVEL_ATTR_DEV_OVERRIDE, + + /* keep last */ + __NL802154_SECLEVEL_ATTR_AFTER_LAST, + NL802154_SECLEVEL_ATTR_MAX = __NL802154_SECLEVEL_ATTR_AFTER_LAST - 1 +}; + +/* TODO what is this? couldn't find in mib */ +enum { + NL802154_DEVKEY_IGNORE, + NL802154_DEVKEY_RESTRICT, + NL802154_DEVKEY_RECORD, + + /* keep last */ + __NL802154_DEVKEY_AFTER_LAST, + NL802154_DEVKEY_MAX = __NL802154_DEVKEY_AFTER_LAST - 1 +}; + +enum nl802154_dev { + NL802154_DEV_ATTR_UNSPEC, + + NL802154_DEV_ATTR_FRAME_COUNTER, + NL802154_DEV_ATTR_PAN_ID, + NL802154_DEV_ATTR_SHORT_ADDR, + NL802154_DEV_ATTR_EXTENDED_ADDR, + NL802154_DEV_ATTR_SECLEVEL_EXEMPT, + NL802154_DEV_ATTR_KEY_MODE, + + /* keep last */ + __NL802154_DEV_ATTR_AFTER_LAST, + NL802154_DEV_ATTR_MAX = __NL802154_DEV_ATTR_AFTER_LAST - 1 +}; + +enum nl802154_devkey { + NL802154_DEVKEY_ATTR_UNSPEC, + + NL802154_DEVKEY_ATTR_FRAME_COUNTER, + NL802154_DEVKEY_ATTR_EXTENDED_ADDR, + NL802154_DEVKEY_ATTR_ID, + + /* keep last */ + __NL802154_DEVKEY_ATTR_AFTER_LAST, + NL802154_DEVKEY_ATTR_MAX = __NL802154_DEVKEY_ATTR_AFTER_LAST - 1 +}; + +enum nl802154_key { + NL802154_KEY_ATTR_UNSPEC, + + NL802154_KEY_ATTR_ID, + NL802154_KEY_ATTR_USAGE_FRAMES, + NL802154_KEY_ATTR_USAGE_CMDS, + NL802154_KEY_ATTR_BYTES, + + /* keep last */ + __NL802154_KEY_ATTR_AFTER_LAST, + NL802154_KEY_ATTR_MAX = __NL802154_KEY_ATTR_AFTER_LAST - 1 +}; + +#define NL802154_KEY_SIZE 16 +#define NL802154_CMD_FRAME_NR_IDS 256 + +#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */ + #endif /* __NL802154_H */ diff --git a/include/net/request_sock.h b/include/net/request_sock.h index 87935cad2f7b..a0dde04eb178 100644 --- a/include/net/request_sock.h +++ b/include/net/request_sock.h @@ -32,17 +32,17 @@ struct request_sock_ops { int obj_size; struct kmem_cache *slab; char *slab_name; - int (*rtx_syn_ack)(struct sock *sk, + int (*rtx_syn_ack)(const struct sock *sk, struct request_sock *req); - void (*send_ack)(struct sock *sk, struct sk_buff *skb, + void (*send_ack)(const struct sock *sk, struct sk_buff *skb, struct request_sock *req); - void (*send_reset)(struct sock *sk, + void (*send_reset)(const struct sock *sk, struct sk_buff *skb); void (*destructor)(struct request_sock *req); void (*syn_ack_timeout)(const struct request_sock *req); }; -int inet_rtx_syn_ack(struct sock *parent, struct request_sock *req); +int inet_rtx_syn_ack(const struct sock *parent, struct request_sock *req); /* struct request_sock - mini sock to represent a connection request */ @@ -50,16 +50,15 @@ struct request_sock { struct sock_common __req_common; #define rsk_refcnt __req_common.skc_refcnt #define rsk_hash __req_common.skc_hash +#define rsk_listener __req_common.skc_listener +#define rsk_window_clamp __req_common.skc_window_clamp +#define rsk_rcv_wnd __req_common.skc_rcv_wnd struct request_sock *dl_next; - struct sock *rsk_listener; u16 mss; u8 num_retrans; /* number of retransmits */ u8 cookie_ts:1; /* syncookie: encode tcpopts in timestamp */ u8 num_timeout:7; /* number of timeouts */ - /* The following two fields can be easily recomputed I think -AK */ - u32 window_clamp; /* window clamp at creation time */ - u32 rcv_wnd; /* rcv_wnd offered first time */ u32 ts_recent; struct timer_list rsk_timer; const struct request_sock_ops *rsk_ops; @@ -69,15 +68,35 @@ struct request_sock { u32 peer_secid; }; +static inline struct request_sock *inet_reqsk(struct sock *sk) +{ + return (struct request_sock *)sk; +} + +static inline struct sock *req_to_sk(struct request_sock *req) +{ + return (struct sock *)req; +} + static inline struct request_sock * -reqsk_alloc(const struct request_sock_ops *ops, struct sock *sk_listener) +reqsk_alloc(const struct request_sock_ops *ops, struct sock *sk_listener, + bool attach_listener) { - struct request_sock *req = kmem_cache_alloc(ops->slab, GFP_ATOMIC); + struct request_sock *req; + + req = kmem_cache_alloc(ops->slab, GFP_ATOMIC | __GFP_NOWARN); if (req) { req->rsk_ops = ops; - sock_hold(sk_listener); - req->rsk_listener = sk_listener; + if (attach_listener) { + sock_hold(sk_listener); + req->rsk_listener = sk_listener; + } else { + req->rsk_listener = NULL; + } + req_to_sk(req)->sk_prot = sk_listener->sk_prot; + sk_node_init(&req_to_sk(req)->sk_node); + sk_tx_queue_clear(req_to_sk(req)); req->saved_syn = NULL; /* Following is temporary. It is coupled with debugging * helpers in reqsk_put() & reqsk_free() @@ -87,16 +106,6 @@ reqsk_alloc(const struct request_sock_ops *ops, struct sock *sk_listener) return req; } -static inline struct request_sock *inet_reqsk(struct sock *sk) -{ - return (struct request_sock *)sk; -} - -static inline struct sock *req_to_sk(struct request_sock *req) -{ - return (struct sock *)req; -} - static inline void reqsk_free(struct request_sock *req) { /* temporary debugging */ @@ -117,26 +126,6 @@ static inline void reqsk_put(struct request_sock *req) extern int sysctl_max_syn_backlog; -/** struct listen_sock - listen state - * - * @max_qlen_log - log_2 of maximal queued SYNs/REQUESTs - */ -struct listen_sock { - int qlen_inc; /* protected by listener lock */ - int young_inc;/* protected by listener lock */ - - /* following fields can be updated by timer */ - atomic_t qlen_dec; /* qlen = qlen_inc - qlen_dec */ - atomic_t young_dec; - - u8 max_qlen_log ____cacheline_aligned_in_smp; - u8 synflood_warned; - /* 2 bytes hole, try to use */ - u32 hash_rnd; - u32 nr_table_entries; - struct request_sock *syn_table[0]; -}; - /* * For a TCP Fast Open listener - * lock - protects the access to all the reqsk, which is co-owned by @@ -170,127 +159,72 @@ struct fastopen_queue { * @rskq_accept_head - FIFO head of established children * @rskq_accept_tail - FIFO tail of established children * @rskq_defer_accept - User waits for some data after accept() - * @syn_wait_lock - serializer - * - * %syn_wait_lock is necessary only to avoid proc interface having to grab the main - * lock sock while browsing the listening hash (otherwise it's deadlock prone). * */ struct request_sock_queue { + spinlock_t rskq_lock; + u8 rskq_defer_accept; + + u32 synflood_warned; + atomic_t qlen; + atomic_t young; + struct request_sock *rskq_accept_head; struct request_sock *rskq_accept_tail; - u8 rskq_defer_accept; - struct listen_sock *listen_opt; - struct fastopen_queue *fastopenq; /* This is non-NULL iff TFO has been - * enabled on this listener. Check - * max_qlen != 0 in fastopen_queue - * to determine if TFO is enabled - * right at this moment. + struct fastopen_queue fastopenq; /* Check max_qlen != 0 to determine + * if TFO is enabled. */ - - /* temporary alignment, our goal is to get rid of this lock */ - spinlock_t syn_wait_lock ____cacheline_aligned_in_smp; }; -int reqsk_queue_alloc(struct request_sock_queue *queue, - unsigned int nr_table_entries); +void reqsk_queue_alloc(struct request_sock_queue *queue); -void __reqsk_queue_destroy(struct request_sock_queue *queue); -void reqsk_queue_destroy(struct request_sock_queue *queue); void reqsk_fastopen_remove(struct sock *sk, struct request_sock *req, bool reset); -static inline struct request_sock * - reqsk_queue_yank_acceptq(struct request_sock_queue *queue) -{ - struct request_sock *req = queue->rskq_accept_head; - - queue->rskq_accept_head = NULL; - return req; -} - -static inline int reqsk_queue_empty(struct request_sock_queue *queue) +static inline bool reqsk_queue_empty(const struct request_sock_queue *queue) { return queue->rskq_accept_head == NULL; } -static inline void reqsk_queue_add(struct request_sock_queue *queue, - struct request_sock *req, - struct sock *parent, - struct sock *child) +static inline struct request_sock *reqsk_queue_remove(struct request_sock_queue *queue, + struct sock *parent) { - req->sk = child; - sk_acceptq_added(parent); - - if (queue->rskq_accept_head == NULL) - queue->rskq_accept_head = req; - else - queue->rskq_accept_tail->dl_next = req; - - queue->rskq_accept_tail = req; - req->dl_next = NULL; -} - -static inline struct request_sock *reqsk_queue_remove(struct request_sock_queue *queue) -{ - struct request_sock *req = queue->rskq_accept_head; - - WARN_ON(req == NULL); - - queue->rskq_accept_head = req->dl_next; - if (queue->rskq_accept_head == NULL) - queue->rskq_accept_tail = NULL; + struct request_sock *req; + spin_lock_bh(&queue->rskq_lock); + req = queue->rskq_accept_head; + if (req) { + sk_acceptq_removed(parent); + queue->rskq_accept_head = req->dl_next; + if (queue->rskq_accept_head == NULL) + queue->rskq_accept_tail = NULL; + } + spin_unlock_bh(&queue->rskq_lock); return req; } static inline void reqsk_queue_removed(struct request_sock_queue *queue, const struct request_sock *req) { - struct listen_sock *lopt = queue->listen_opt; - if (req->num_timeout == 0) - atomic_inc(&lopt->young_dec); - atomic_inc(&lopt->qlen_dec); + atomic_dec(&queue->young); + atomic_dec(&queue->qlen); } static inline void reqsk_queue_added(struct request_sock_queue *queue) { - struct listen_sock *lopt = queue->listen_opt; - - lopt->young_inc++; - lopt->qlen_inc++; -} - -static inline int listen_sock_qlen(const struct listen_sock *lopt) -{ - return lopt->qlen_inc - atomic_read(&lopt->qlen_dec); -} - -static inline int listen_sock_young(const struct listen_sock *lopt) -{ - return lopt->young_inc - atomic_read(&lopt->young_dec); + atomic_inc(&queue->young); + atomic_inc(&queue->qlen); } static inline int reqsk_queue_len(const struct request_sock_queue *queue) { - const struct listen_sock *lopt = queue->listen_opt; - - return lopt ? listen_sock_qlen(lopt) : 0; + return atomic_read(&queue->qlen); } static inline int reqsk_queue_len_young(const struct request_sock_queue *queue) { - return listen_sock_young(queue->listen_opt); + return atomic_read(&queue->young); } -static inline int reqsk_queue_is_full(const struct request_sock_queue *queue) -{ - return reqsk_queue_len(queue) >> queue->listen_opt->max_qlen_log; -} - -void reqsk_queue_hash_req(struct request_sock_queue *queue, - u32 hash, struct request_sock *req, - unsigned long timeout); - #endif /* _REQUEST_SOCK_H */ diff --git a/include/net/route.h b/include/net/route.h index f46af256880c..ee81307863d5 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -28,6 +28,8 @@ #include <net/inetpeer.h> #include <net/flow.h> #include <net/inet_sock.h> +#include <net/ip_fib.h> +#include <net/l3mdev.h> #include <linux/in_route.h> #include <linux/rtnetlink.h> #include <linux/rcupdate.h> @@ -64,6 +66,8 @@ struct rtable { /* Miscellaneous cached information */ u32 rt_pmtu; + u32 rt_table_id; + struct list_head rt_uncached; struct uncached_list *rt_uncached_list; }; @@ -110,9 +114,17 @@ struct in_device; int ip_rt_init(void); void rt_cache_flush(struct net *net); void rt_flush_dev(struct net_device *dev); -struct rtable *__ip_route_output_key(struct net *, struct flowi4 *flp); +struct rtable *__ip_route_output_key_hash(struct net *, struct flowi4 *flp, + int mp_hash); + +static inline struct rtable *__ip_route_output_key(struct net *net, + struct flowi4 *flp) +{ + return __ip_route_output_key_hash(net, flp, -1); +} + struct rtable *ip_route_output_flow(struct net *, struct flowi4 *flp, - struct sock *sk); + const struct sock *sk); struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_orig); @@ -254,9 +266,6 @@ static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst, __be32 if (inet_sk(sk)->transparent) flow_flags |= FLOWI_FLAG_ANYSRC; - if (netif_index_is_vrf(sock_net(sk), oif)) - flow_flags |= FLOWI_FLAG_VRFSRC | FLOWI_FLAG_SKIP_NH_OIF; - flowi4_init_output(fl4, oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE, protocol, flow_flags, dst, src, dport, sport); } @@ -273,6 +282,10 @@ static inline struct rtable *ip_route_connect(struct flowi4 *fl4, ip_route_connect_init(fl4, dst, src, tos, oif, protocol, sport, dport, sk); + if (!src && oif) { + l3mdev_get_saddr(net, oif, fl4); + src = fl4->saddr; + } if (!dst || !src) { rt = __ip_route_output_key(net, fl4); if (IS_ERR(rt)) diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h index 18fdb98185ab..2f87c1ba13de 100644 --- a/include/net/rtnetlink.h +++ b/include/net/rtnetlink.h @@ -122,8 +122,10 @@ struct rtnl_af_ops { int family; int (*fill_link_af)(struct sk_buff *skb, - const struct net_device *dev); - size_t (*get_link_af_size)(const struct net_device *dev); + const struct net_device *dev, + u32 ext_filter_mask); + size_t (*get_link_af_size)(const struct net_device *dev, + u32 ext_filter_mask); int (*validate_link_af)(const struct net_device *dev, const struct nlattr *attr); diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 444faa89a55f..4c79ce8c1f92 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -251,7 +251,7 @@ struct tcf_proto { struct qdisc_skb_cb { unsigned int pkt_len; u16 slave_dev_queue_mapping; - u16 _pad; + u16 tc_classid; #define QDISC_CB_PRIV_LEN 20 unsigned char data[QDISC_CB_PRIV_LEN]; }; @@ -402,6 +402,7 @@ void __qdisc_calculate_pkt_len(struct sk_buff *skb, const struct qdisc_size_table *stab); bool tcf_destroy(struct tcf_proto *tp, bool force); void tcf_destroy_chain(struct tcf_proto __rcu **fl); +int skb_do_redirect(struct sk_buff *); /* Reset all TX qdiscs greater then index of a device. */ static inline void qdisc_reset_all_tx_gt(struct net_device *dev, unsigned int i) diff --git a/include/net/sock.h b/include/net/sock.h index e23717013a4e..f570e75e3da9 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -150,6 +150,10 @@ typedef __u64 __bitwise __addrpair; * @skc_node: main hash linkage for various protocol lookup tables * @skc_nulls_node: main hash linkage for TCP/UDP/UDP-Lite protocol * @skc_tx_queue_mapping: tx queue number for this connection + * @skc_flags: place holder for sk_flags + * %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE, + * %SO_OOBINLINE settings, %SO_TIMESTAMPING settings + * @skc_incoming_cpu: record/match cpu processing incoming packets * @skc_refcnt: reference count * * This is the minimal network layer representation of sockets, the header @@ -200,6 +204,16 @@ struct sock_common { atomic64_t skc_cookie; + /* following fields are padding to force + * offset(struct sock, sk_refcnt) == 128 on 64bit arches + * assuming IPV6 is enabled. We use this padding differently + * for different kind of 'sockets' + */ + union { + unsigned long skc_flags; + struct sock *skc_listener; /* request_sock */ + struct inet_timewait_death_row *skc_tw_dr; /* inet_timewait_sock */ + }; /* * fields between dontcopy_begin/dontcopy_end * are not copied in sock_copy() @@ -212,9 +226,20 @@ struct sock_common { struct hlist_nulls_node skc_nulls_node; }; int skc_tx_queue_mapping; + union { + int skc_incoming_cpu; + u32 skc_rcv_wnd; + u32 skc_tw_rcv_nxt; /* struct tcp_timewait_sock */ + }; + atomic_t skc_refcnt; /* private: */ int skc_dontcopy_end[0]; + union { + u32 skc_rxhash; + u32 skc_window_clamp; + u32 skc_tw_snd_nxt; /* struct tcp_timewait_sock */ + }; /* public: */ }; @@ -243,8 +268,6 @@ struct cg_proto; * @sk_pacing_rate: Pacing rate (if supported by transport/packet scheduler) * @sk_max_pacing_rate: Maximum pacing rate (%SO_MAX_PACING_RATE) * @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_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) @@ -273,8 +296,6 @@ struct cg_proto; * @sk_rcvlowat: %SO_RCVLOWAT setting * @sk_rcvtimeo: %SO_RCVTIMEO setting * @sk_sndtimeo: %SO_SNDTIMEO setting - * @sk_rxhash: flow hash received from netif layer - * @sk_incoming_cpu: record cpu processing incoming packets * @sk_txhash: computed flow hash for use on transmit * @sk_filter: socket filtering instructions * @sk_timer: sock cleanup timer @@ -331,6 +352,9 @@ struct sock { #define sk_v6_daddr __sk_common.skc_v6_daddr #define sk_v6_rcv_saddr __sk_common.skc_v6_rcv_saddr #define sk_cookie __sk_common.skc_cookie +#define sk_incoming_cpu __sk_common.skc_incoming_cpu +#define sk_flags __sk_common.skc_flags +#define sk_rxhash __sk_common.skc_rxhash socket_lock_t sk_lock; struct sk_buff_head sk_receive_queue; @@ -350,14 +374,6 @@ struct sock { } sk_backlog; #define sk_rmem_alloc sk_backlog.rmem_alloc int sk_forward_alloc; -#ifdef CONFIG_RPS - __u32 sk_rxhash; -#endif - u16 sk_incoming_cpu; - /* 16bit hole - * Warned : sk_incoming_cpu can be set from softirq, - * Do not use this hole without fully understanding possible issues. - */ __u32 sk_txhash; #ifdef CONFIG_NET_RX_BUSY_POLL @@ -373,7 +389,6 @@ struct sock { #ifdef CONFIG_XFRM struct xfrm_policy *sk_policy[2]; #endif - unsigned long sk_flags; struct dst_entry *sk_rx_dst; struct dst_entry __rcu *sk_dst_cache; spinlock_t sk_dst_lock; @@ -759,7 +774,7 @@ static inline int sk_memalloc_socks(void) #endif -static inline gfp_t sk_gfp_atomic(struct sock *sk, gfp_t gfp_mask) +static inline gfp_t sk_gfp_atomic(const struct sock *sk, gfp_t gfp_mask) { return GFP_ATOMIC | (sk->sk_allocation & __GFP_MEMALLOC); } @@ -1522,6 +1537,13 @@ void sock_kfree_s(struct sock *sk, void *mem, int size); void sock_kzfree_s(struct sock *sk, void *mem, int size); void sk_send_sigurg(struct sock *sk); +struct sockcm_cookie { + u32 mark; +}; + +int sock_cmsg_send(struct sock *sk, struct msghdr *msg, + struct sockcm_cookie *sockc); + /* * Functions to fill in entries in struct proto_ops when a protocol * does not implement a particular function. @@ -1662,12 +1684,16 @@ static inline void sock_graft(struct sock *sk, struct socket *parent) kuid_t sock_i_uid(struct sock *sk); unsigned long sock_i_ino(struct sock *sk); -static inline void sk_set_txhash(struct sock *sk) +static inline u32 net_tx_rndhash(void) { - sk->sk_txhash = prandom_u32(); + u32 v = prandom_u32(); + + return v ?: 1; +} - if (unlikely(!sk->sk_txhash)) - sk->sk_txhash = 1; +static inline void sk_set_txhash(struct sock *sk) +{ + sk->sk_txhash = net_tx_rndhash(); } static inline void sk_rethink_txhash(struct sock *sk) @@ -1925,6 +1951,8 @@ static inline void skb_set_hash_from_sk(struct sk_buff *skb, struct sock *sk) } } +void skb_set_owner_w(struct sk_buff *skb, struct sock *sk); + /* * Queue a received datagram if it will fit. Stream and sequenced * protocols can't normally use this as they need to fit buffers in @@ -1933,21 +1961,6 @@ static inline void skb_set_hash_from_sk(struct sk_buff *skb, struct sock *sk) * Inlined as it's very short and called for pretty much every * packet ever received. */ - -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 - * all in-flight packets are completed - */ - atomic_add(skb->truesize, &sk->sk_wmem_alloc); -} - static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk) { skb_orphan(skb); @@ -2205,6 +2218,14 @@ static inline bool sk_fullsock(const struct sock *sk) return (1 << sk->sk_state) & ~(TCPF_TIME_WAIT | TCPF_NEW_SYN_RECV); } +/* This helper checks if a socket is a LISTEN or NEW_SYN_RECV + * SYNACK messages can be attached to either ones (depending on SYNCOOKIE) + */ +static inline bool sk_listener(const struct sock *sk) +{ + return (1 << sk->sk_state) & (TCPF_LISTEN | TCPF_NEW_SYN_RECV); +} + void sock_enable_timestamp(struct sock *sk, int flag); int sock_get_timestamp(struct sock *, struct timeval __user *); int sock_get_timestampns(struct sock *, struct timespec __user *); diff --git a/include/net/switchdev.h b/include/net/switchdev.h index 319baab3b48e..bc865e244efe 100644 --- a/include/net/switchdev.h +++ b/include/net/switchdev.h @@ -1,6 +1,6 @@ /* * include/net/switchdev.h - Switch device API - * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us> + * Copyright (c) 2014-2015 Jiri Pirko <jiri@resnulli.us> * Copyright (c) 2014-2015 Scott Feldman <sfeldma@gmail.com> * * This program is free software; you can redistribute it and/or modify @@ -13,70 +13,109 @@ #include <linux/netdevice.h> #include <linux/notifier.h> +#include <linux/list.h> +#include <net/ip_fib.h> #define SWITCHDEV_F_NO_RECURSE BIT(0) +#define SWITCHDEV_F_SKIP_EOPNOTSUPP BIT(1) +#define SWITCHDEV_F_DEFER BIT(2) -enum switchdev_trans { - SWITCHDEV_TRANS_NONE, - SWITCHDEV_TRANS_PREPARE, - SWITCHDEV_TRANS_ABORT, - SWITCHDEV_TRANS_COMMIT, +struct switchdev_trans_item { + struct list_head list; + void *data; + void (*destructor)(const void *data); }; +struct switchdev_trans { + struct list_head item_list; + bool ph_prepare; +}; + +static inline bool switchdev_trans_ph_prepare(struct switchdev_trans *trans) +{ + return trans && trans->ph_prepare; +} + +static inline bool switchdev_trans_ph_commit(struct switchdev_trans *trans) +{ + return trans && !trans->ph_prepare; +} + enum switchdev_attr_id { - SWITCHDEV_ATTR_UNDEFINED, - SWITCHDEV_ATTR_PORT_PARENT_ID, - SWITCHDEV_ATTR_PORT_STP_STATE, - SWITCHDEV_ATTR_PORT_BRIDGE_FLAGS, + SWITCHDEV_ATTR_ID_UNDEFINED, + SWITCHDEV_ATTR_ID_PORT_PARENT_ID, + SWITCHDEV_ATTR_ID_PORT_STP_STATE, + SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS, + SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME, }; struct switchdev_attr { enum switchdev_attr_id id; - enum switchdev_trans trans; u32 flags; union { struct netdev_phys_item_id ppid; /* PORT_PARENT_ID */ u8 stp_state; /* PORT_STP_STATE */ unsigned long brport_flags; /* PORT_BRIDGE_FLAGS */ + u32 ageing_time; /* BRIDGE_AGEING_TIME */ } u; }; -struct fib_info; - enum switchdev_obj_id { - SWITCHDEV_OBJ_UNDEFINED, - SWITCHDEV_OBJ_PORT_VLAN, - SWITCHDEV_OBJ_IPV4_FIB, - SWITCHDEV_OBJ_PORT_FDB, + SWITCHDEV_OBJ_ID_UNDEFINED, + SWITCHDEV_OBJ_ID_PORT_VLAN, + SWITCHDEV_OBJ_ID_IPV4_FIB, + SWITCHDEV_OBJ_ID_PORT_FDB, }; struct switchdev_obj { enum switchdev_obj_id id; - enum switchdev_trans trans; - int (*cb)(struct net_device *dev, struct switchdev_obj *obj); - union { - struct switchdev_obj_vlan { /* PORT_VLAN */ - u16 flags; - u16 vid_begin; - u16 vid_end; - } vlan; - struct switchdev_obj_ipv4_fib { /* IPV4_FIB */ - u32 dst; - int dst_len; - struct fib_info *fi; - u8 tos; - u8 type; - u32 nlflags; - u32 tb_id; - } ipv4_fib; - struct switchdev_obj_fdb { /* PORT_FDB */ - const unsigned char *addr; - u16 vid; - u16 ndm_state; - } fdb; - } u; + u32 flags; }; +/* SWITCHDEV_OBJ_ID_PORT_VLAN */ +struct switchdev_obj_port_vlan { + struct switchdev_obj obj; + u16 flags; + u16 vid_begin; + u16 vid_end; +}; + +#define SWITCHDEV_OBJ_PORT_VLAN(obj) \ + container_of(obj, struct switchdev_obj_port_vlan, obj) + +/* SWITCHDEV_OBJ_ID_IPV4_FIB */ +struct switchdev_obj_ipv4_fib { + struct switchdev_obj obj; + u32 dst; + int dst_len; + struct fib_info fi; + u8 tos; + u8 type; + u32 nlflags; + u32 tb_id; +}; + +#define SWITCHDEV_OBJ_IPV4_FIB(obj) \ + container_of(obj, struct switchdev_obj_ipv4_fib, obj) + +/* SWITCHDEV_OBJ_ID_PORT_FDB */ +struct switchdev_obj_port_fdb { + struct switchdev_obj obj; + unsigned char addr[ETH_ALEN]; + u16 vid; + u16 ndm_state; +}; + +#define SWITCHDEV_OBJ_PORT_FDB(obj) \ + container_of(obj, struct switchdev_obj_port_fdb, obj) + +void switchdev_trans_item_enqueue(struct switchdev_trans *trans, + void *data, void (*destructor)(void const *), + struct switchdev_trans_item *tritem); +void *switchdev_trans_item_dequeue(struct switchdev_trans *trans); + +typedef int switchdev_obj_dump_cb_t(struct switchdev_obj *obj); + /** * struct switchdev_ops - switchdev operations * @@ -84,23 +123,26 @@ struct switchdev_obj { * * @switchdev_port_attr_set: Set a port attribute (see switchdev_attr). * - * @switchdev_port_obj_add: Add an object to port (see switchdev_obj). + * @switchdev_port_obj_add: Add an object to port (see switchdev_obj_*). * - * @switchdev_port_obj_del: Delete an object from port (see switchdev_obj). + * @switchdev_port_obj_del: Delete an object from port (see switchdev_obj_*). * - * @switchdev_port_obj_dump: Dump port objects (see switchdev_obj). + * @switchdev_port_obj_dump: Dump port objects (see switchdev_obj_*). */ struct switchdev_ops { int (*switchdev_port_attr_get)(struct net_device *dev, struct switchdev_attr *attr); int (*switchdev_port_attr_set)(struct net_device *dev, - struct switchdev_attr *attr); + const struct switchdev_attr *attr, + struct switchdev_trans *trans); int (*switchdev_port_obj_add)(struct net_device *dev, - struct switchdev_obj *obj); + const struct switchdev_obj *obj, + struct switchdev_trans *trans); int (*switchdev_port_obj_del)(struct net_device *dev, - struct switchdev_obj *obj); + const struct switchdev_obj *obj); int (*switchdev_port_obj_dump)(struct net_device *dev, - struct switchdev_obj *obj); + struct switchdev_obj *obj, + switchdev_obj_dump_cb_t *cb); }; enum switchdev_notifier_type { @@ -126,13 +168,17 @@ switchdev_notifier_info_to_dev(const struct switchdev_notifier_info *info) #ifdef CONFIG_NET_SWITCHDEV +void switchdev_deferred_process(void); int switchdev_port_attr_get(struct net_device *dev, struct switchdev_attr *attr); int switchdev_port_attr_set(struct net_device *dev, - struct switchdev_attr *attr); -int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj); -int switchdev_port_obj_del(struct net_device *dev, struct switchdev_obj *obj); -int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj); + const struct switchdev_attr *attr); +int switchdev_port_obj_add(struct net_device *dev, + const struct switchdev_obj *obj); +int switchdev_port_obj_del(struct net_device *dev, + const struct switchdev_obj *obj); +int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj, + switchdev_obj_dump_cb_t *cb); int register_switchdev_notifier(struct notifier_block *nb); int unregister_switchdev_notifier(struct notifier_block *nb); int call_switchdev_notifiers(unsigned long val, struct net_device *dev, @@ -164,6 +210,10 @@ void switchdev_port_fwd_mark_set(struct net_device *dev, #else +static inline void switchdev_deferred_process(void) +{ +} + static inline int switchdev_port_attr_get(struct net_device *dev, struct switchdev_attr *attr) { @@ -171,25 +221,26 @@ static inline int switchdev_port_attr_get(struct net_device *dev, } static inline int switchdev_port_attr_set(struct net_device *dev, - struct switchdev_attr *attr) + const struct switchdev_attr *attr) { return -EOPNOTSUPP; } static inline int switchdev_port_obj_add(struct net_device *dev, - struct switchdev_obj *obj) + const struct switchdev_obj *obj) { return -EOPNOTSUPP; } static inline int switchdev_port_obj_del(struct net_device *dev, - struct switchdev_obj *obj) + const struct switchdev_obj *obj) { return -EOPNOTSUPP; } static inline int switchdev_port_obj_dump(struct net_device *dev, - struct switchdev_obj *obj) + const struct switchdev_obj *obj, + switchdev_obj_dump_cb_t *cb) { return -EOPNOTSUPP; } diff --git a/include/net/tc_act/tc_connmark.h b/include/net/tc_act/tc_connmark.h index 5c1104c2e24f..02caa406611b 100644 --- a/include/net/tc_act/tc_connmark.h +++ b/include/net/tc_act/tc_connmark.h @@ -5,6 +5,7 @@ struct tcf_connmark_info { struct tcf_common common; + struct net *net; u16 zone; }; diff --git a/include/net/tcp.h b/include/net/tcp.h index 0cab28cd43a9..f80e74c5ad18 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -279,6 +279,7 @@ extern int sysctl_tcp_limit_output_bytes; extern int sysctl_tcp_challenge_ack_limit; extern unsigned int sysctl_tcp_notsent_lowat; extern int sysctl_tcp_min_tso_segs; +extern int sysctl_tcp_min_rtt_wlen; extern int sysctl_tcp_autocorking; extern int sysctl_tcp_invalid_ratelimit; extern int sysctl_tcp_pacing_ss_ratio; @@ -365,8 +366,7 @@ void tcp_wfree(struct sk_buff *skb); void tcp_write_timer_handler(struct sock *sk); void tcp_delack_timer_handler(struct sock *sk); int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg); -int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, - const struct tcphdr *th, unsigned int len); +int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb); void tcp_rcv_established(struct sock *sk, struct sk_buff *skb, const struct tcphdr *th, unsigned int len); void tcp_rcv_space_adjust(struct sock *sk); @@ -451,19 +451,22 @@ void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb); void tcp_v4_mtu_reduced(struct sock *sk); void tcp_req_err(struct sock *sk, u32 seq); int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb); -struct sock *tcp_create_openreq_child(struct sock *sk, +struct sock *tcp_create_openreq_child(const struct sock *sk, struct request_sock *req, struct sk_buff *skb); void tcp_ca_openreq_child(struct sock *sk, const struct dst_entry *dst); -struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, +struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb, struct request_sock *req, - struct dst_entry *dst); + struct dst_entry *dst, + struct request_sock *req_unhash, + bool *own_req); int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb); int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len); int tcp_connect(struct sock *sk); -struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, +struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst, struct request_sock *req, - struct tcp_fastopen_cookie *foc); + struct tcp_fastopen_cookie *foc, + bool attach_req); int tcp_disconnect(struct sock *sk, int flags); void tcp_finish_connect(struct sock *sk, struct sk_buff *skb); @@ -492,8 +495,9 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb); /* syncookies: remember time of last synqueue overflow * But do not dirty this field too often (once per second is enough) + * It is racy as we do not hold a lock, but race is very minor. */ -static inline void tcp_synq_overflow(struct sock *sk) +static inline void tcp_synq_overflow(const struct sock *sk) { unsigned long last_overflow = tcp_sk(sk)->rx_opt.ts_recent_stamp; unsigned long now = jiffies; @@ -520,8 +524,7 @@ 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, const struct sk_buff *skb, - __u16 *mss); +__u32 cookie_v4_init_sequence(const struct sk_buff *skb, __u16 *mss); __u32 cookie_init_timestamp(struct request_sock *req); bool cookie_timestamp_decode(struct tcp_options_received *opt); bool cookie_ecn_ok(const struct tcp_options_received *opt, @@ -534,8 +537,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb); 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); +__u32 cookie_v6_init_sequence(const struct sk_buff *skb, __u16 *mss); #endif /* tcp_output.c */ @@ -565,7 +567,9 @@ bool tcp_schedule_loss_probe(struct sock *sk); /* tcp_input.c */ void tcp_resume_early_retransmit(struct sock *sk); void tcp_rearm_rto(struct sock *sk); +void tcp_synack_rtt_meas(struct sock *sk, struct request_sock *req); void tcp_reset(struct sock *sk); +void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, struct sk_buff *skb); /* tcp_timer.c */ void tcp_init_xmit_timers(struct sock *); @@ -671,6 +675,12 @@ static inline bool tcp_ca_dst_locked(const struct dst_entry *dst) return dst_metric_locked(dst, RTAX_CC_ALGO); } +/* Minimum RTT in usec. ~0 means not available. */ +static inline u32 tcp_min_rtt(const struct tcp_sock *tp) +{ + return tp->rtt_min[0].rtt; +} + /* Compute the actual receive window we are currently advertising. * Rcv_nxt can be after the window if our peer push more data * than the offered window. @@ -1206,7 +1216,8 @@ static inline int tcp_full_space(const struct sock *sk) } extern void tcp_openreq_init_rwin(struct request_sock *req, - struct sock *sk, struct dst_entry *dst); + const struct sock *sk_listener, + const struct dst_entry *dst); void tcp_enter_memory_pressure(struct sock *sk); @@ -1370,16 +1381,16 @@ int tcp_md5_do_add(struct sock *sk, const union tcp_md5_addr *addr, int family, const u8 *newkey, u8 newkeylen, gfp_t gfp); int tcp_md5_do_del(struct sock *sk, const union tcp_md5_addr *addr, int family); -struct tcp_md5sig_key *tcp_v4_md5_lookup(struct sock *sk, +struct tcp_md5sig_key *tcp_v4_md5_lookup(const struct sock *sk, const struct sock *addr_sk); #ifdef CONFIG_TCP_MD5SIG -struct tcp_md5sig_key *tcp_md5_do_lookup(struct sock *sk, +struct tcp_md5sig_key *tcp_md5_do_lookup(const struct sock *sk, const union tcp_md5_addr *addr, int family); #define tcp_twsk_md5_key(twsk) ((twsk)->tw_md5_key) #else -static inline struct tcp_md5sig_key *tcp_md5_do_lookup(struct sock *sk, +static inline struct tcp_md5sig_key *tcp_md5_do_lookup(const struct sock *sk, const union tcp_md5_addr *addr, int family) { @@ -1420,10 +1431,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); -bool tcp_try_fastopen(struct sock *sk, struct sk_buff *skb, - struct request_sock *req, - struct tcp_fastopen_cookie *foc, - struct dst_entry *dst); +struct sock *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 @@ -1618,7 +1629,6 @@ static inline bool tcp_stream_is_thin(struct tcp_sock *tp) /* /proc */ enum tcp_seq_states { TCP_SEQ_STATE_LISTENING, - TCP_SEQ_STATE_OPENREQ, TCP_SEQ_STATE_ESTABLISHED, }; @@ -1637,7 +1647,6 @@ struct tcp_iter_state { enum tcp_seq_states state; struct sock *syn_wait_sk; int bucket, offset, sbucket, num; - kuid_t uid; loff_t last_pos; }; @@ -1674,7 +1683,7 @@ int tcp4_proc_init(void); void tcp4_proc_exit(void); #endif -int tcp_rtx_synack(struct sock *sk, struct request_sock *req); +int tcp_rtx_synack(const 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); @@ -1682,7 +1691,7 @@ int tcp_conn_request(struct request_sock_ops *rsk_ops, /* TCP af-specific functions */ struct tcp_sock_af_ops { #ifdef CONFIG_TCP_MD5SIG - struct tcp_md5sig_key *(*md5_lookup) (struct sock *sk, + struct tcp_md5sig_key *(*md5_lookup) (const struct sock *sk, const struct sock *addr_sk); int (*calc_md5_hash)(char *location, const struct tcp_md5sig_key *md5, @@ -1697,40 +1706,42 @@ struct tcp_sock_af_ops { struct tcp_request_sock_ops { u16 mss_clamp; #ifdef CONFIG_TCP_MD5SIG - struct tcp_md5sig_key *(*req_md5_lookup)(struct sock *sk, + struct tcp_md5sig_key *(*req_md5_lookup)(const struct sock *sk, const struct sock *addr_sk); int (*calc_md5_hash) (char *location, const struct tcp_md5sig_key *md5, const struct sock *sk, const struct sk_buff *skb); #endif - void (*init_req)(struct request_sock *req, struct sock *sk, + void (*init_req)(struct request_sock *req, + const struct sock *sk_listener, struct sk_buff *skb); #ifdef CONFIG_SYN_COOKIES - __u32 (*cookie_init_seq)(struct sock *sk, const struct sk_buff *skb, + __u32 (*cookie_init_seq)(const struct sk_buff *skb, __u16 *mss); #endif - struct dst_entry *(*route_req)(struct sock *sk, struct flowi *fl, + struct dst_entry *(*route_req)(const 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, + int (*send_synack)(const 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); + struct tcp_fastopen_cookie *foc, + bool attach_req); }; #ifdef CONFIG_SYN_COOKIES static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops, - struct sock *sk, struct sk_buff *skb, + const struct sock *sk, struct sk_buff *skb, __u16 *mss) { - return ops->cookie_init_seq(sk, skb, mss); + tcp_synq_overflow(sk); + NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_SYNCOOKIESSENT); + return ops->cookie_init_seq(skb, mss); } #else static inline __u32 cookie_init_sequence(const struct tcp_request_sock_ops *ops, - struct sock *sk, struct sk_buff *skb, + const struct sock *sk, struct sk_buff *skb, __u16 *mss) { return 0; @@ -1742,6 +1753,19 @@ int tcpv4_offload_init(void); void tcp_v4_init(void); void tcp_init(void); +/* tcp_recovery.c */ + +/* Flags to enable various loss recovery features. See below */ +extern int sysctl_tcp_recovery; + +/* Use TCP RACK to detect (some) tail and retransmit losses */ +#define TCP_RACK_LOST_RETRANS 0x1 + +extern int tcp_rack_mark_lost(struct sock *sk); + +extern void tcp_rack_advance(struct tcp_sock *tp, + const struct skb_mstamp *xmit_time, u8 sacked); + /* * Save and compile IPv4 options, return a pointer to it */ diff --git a/include/net/tso.h b/include/net/tso.h index 47e5444f7d15..b7be852bfe9d 100644 --- a/include/net/tso.h +++ b/include/net/tso.h @@ -8,6 +8,7 @@ struct tso_t { void *data; size_t size; u16 ip_id; + bool ipv6; u32 tcp_seq; }; diff --git a/include/net/vrf.h b/include/net/vrf.h deleted file mode 100644 index 593e6094ddd4..000000000000 --- a/include/net/vrf.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * include/net/net_vrf.h - adds vrf dev structure definitions - * Copyright (c) 2015 Cumulus Networks - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - */ - -#ifndef __LINUX_NET_VRF_H -#define __LINUX_NET_VRF_H - -struct net_vrf_dev { - struct rcu_head rcu; - int ifindex; /* ifindex of master dev */ - u32 tb_id; /* table id for VRF */ -}; - -struct slave { - struct list_head list; - struct net_device *dev; -}; - -struct slave_queue { - struct list_head all_slaves; -}; - -struct net_vrf { - struct slave_queue queue; - struct rtable *rth; - u32 tb_id; -}; - - -#if IS_ENABLED(CONFIG_NET_VRF) -/* called with rcu_read_lock() */ -static inline int vrf_master_ifindex_rcu(const struct net_device *dev) -{ - struct net_vrf_dev *vrf_ptr; - int ifindex = 0; - - if (!dev) - return 0; - - if (netif_is_vrf(dev)) { - ifindex = dev->ifindex; - } else { - vrf_ptr = rcu_dereference(dev->vrf_ptr); - if (vrf_ptr) - ifindex = vrf_ptr->ifindex; - } - - return ifindex; -} - -static inline int vrf_master_ifindex(const struct net_device *dev) -{ - int ifindex; - - rcu_read_lock(); - ifindex = vrf_master_ifindex_rcu(dev); - rcu_read_unlock(); - - return ifindex; -} - -/* called with rcu_read_lock */ -static inline u32 vrf_dev_table_rcu(const struct net_device *dev) -{ - u32 tb_id = 0; - - if (dev) { - struct net_vrf_dev *vrf_ptr; - - vrf_ptr = rcu_dereference(dev->vrf_ptr); - if (vrf_ptr) - tb_id = vrf_ptr->tb_id; - } - return tb_id; -} - -static inline u32 vrf_dev_table(const struct net_device *dev) -{ - u32 tb_id; - - rcu_read_lock(); - tb_id = vrf_dev_table_rcu(dev); - rcu_read_unlock(); - - return tb_id; -} - -static inline u32 vrf_dev_table_ifindex(struct net *net, int ifindex) -{ - struct net_device *dev; - u32 tb_id = 0; - - if (!ifindex) - return 0; - - rcu_read_lock(); - - dev = dev_get_by_index_rcu(net, ifindex); - if (dev) - tb_id = vrf_dev_table_rcu(dev); - - rcu_read_unlock(); - - return tb_id; -} - -/* called with rtnl */ -static inline u32 vrf_dev_table_rtnl(const struct net_device *dev) -{ - u32 tb_id = 0; - - if (dev) { - struct net_vrf_dev *vrf_ptr; - - vrf_ptr = rtnl_dereference(dev->vrf_ptr); - if (vrf_ptr) - tb_id = vrf_ptr->tb_id; - } - return tb_id; -} - -/* caller has already checked netif_is_vrf(dev) */ -static inline struct rtable *vrf_dev_get_rth(const struct net_device *dev) -{ - struct rtable *rth = ERR_PTR(-ENETUNREACH); - struct net_vrf *vrf = netdev_priv(dev); - - if (vrf) { - rth = vrf->rth; - atomic_inc(&rth->dst.__refcnt); - } - return rth; -} - -#else -static inline int vrf_master_ifindex_rcu(const struct net_device *dev) -{ - return 0; -} - -static inline int vrf_master_ifindex(const struct net_device *dev) -{ - return 0; -} - -static inline u32 vrf_dev_table_rcu(const struct net_device *dev) -{ - return 0; -} - -static inline u32 vrf_dev_table(const struct net_device *dev) -{ - return 0; -} - -static inline u32 vrf_dev_table_ifindex(struct net *net, int ifindex) -{ - return 0; -} - -static inline u32 vrf_dev_table_rtnl(const struct net_device *dev) -{ - return 0; -} - -static inline struct rtable *vrf_dev_get_rth(const struct net_device *dev) -{ - return ERR_PTR(-ENETUNREACH); -} -#endif - -#endif /* __LINUX_NET_VRF_H */ diff --git a/include/net/vxlan.h b/include/net/vxlan.h index 480a319b4c92..c1c899c3a51b 100644 --- a/include/net/vxlan.h +++ b/include/net/vxlan.h @@ -152,7 +152,10 @@ struct vxlan_config { struct vxlan_dev { struct hlist_node hlist; /* vni hash table */ struct list_head next; /* vxlan's per namespace list */ - struct vxlan_sock *vn_sock; /* listening socket */ + struct vxlan_sock *vn4_sock; /* listening socket for IPv4 */ +#if IS_ENABLED(CONFIG_IPV6) + struct vxlan_sock *vn6_sock; /* listening socket for IPv6 */ +#endif struct net_device *dev; struct net *net; /* netns for packet i/o */ struct vxlan_rdst default_dst; /* default destination */ @@ -195,9 +198,14 @@ struct vxlan_dev { struct net_device *vxlan_dev_create(struct net *net, const char *name, u8 name_assign_type, struct vxlan_config *conf); -static inline __be16 vxlan_dev_dst_port(struct vxlan_dev *vxlan) +static inline __be16 vxlan_dev_dst_port(struct vxlan_dev *vxlan, + unsigned short family) { - return inet_sk(vxlan->vn_sock->sock->sk)->inet_sport; +#if IS_ENABLED(CONFIG_IPV6) + if (family == AF_INET6) + return inet_sk(vxlan->vn6_sock->sock->sk)->inet_sport; +#endif + return inet_sk(vxlan->vn4_sock->sock->sk)->inet_sport; } static inline netdev_features_t vxlan_features_check(struct sk_buff *skb, diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 312e3fee9ccf..4a9c21f9b4ea 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -296,8 +296,6 @@ struct xfrm_policy_afinfo { struct flowi *fl, int reverse); int (*get_tos)(const struct flowi *fl); - void (*init_dst)(struct net *net, - struct xfrm_dst *dst); int (*init_path)(struct xfrm_dst *path, struct dst_entry *dst, int nfheader_len); @@ -335,7 +333,7 @@ struct xfrm_state_afinfo { const xfrm_address_t *saddr); int (*tmpl_sort)(struct xfrm_tmpl **dst, struct xfrm_tmpl **src, int n); int (*state_sort)(struct xfrm_state **dst, struct xfrm_state **src, int n); - int (*output)(struct sock *sk, struct sk_buff *skb); + int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb); int (*output_finish)(struct sock *sk, struct sk_buff *skb); int (*extract_input)(struct xfrm_state *x, struct sk_buff *skb); @@ -1529,7 +1527,7 @@ static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi) int xfrm4_extract_output(struct xfrm_state *x, struct sk_buff *skb); int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb); -int xfrm4_output(struct sock *sk, struct sk_buff *skb); +int xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb); int xfrm4_output_finish(struct sock *sk, struct sk_buff *skb); int xfrm4_rcv_cb(struct sk_buff *skb, u8 protocol, int err); int xfrm4_protocol_register(struct xfrm4_protocol *handler, unsigned char protocol); @@ -1554,7 +1552,7 @@ __be32 xfrm6_tunnel_alloc_spi(struct net *net, xfrm_address_t *saddr); __be32 xfrm6_tunnel_spi_lookup(struct net *net, const xfrm_address_t *saddr); int xfrm6_extract_output(struct xfrm_state *x, struct sk_buff *skb); int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb); -int xfrm6_output(struct sock *sk, struct sk_buff *skb); +int xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb); int xfrm6_output_finish(struct sock *sk, struct sk_buff *skb); int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb, u8 **prevhdr); |
