summaryrefslogtreecommitdiff
path: root/include/net
diff options
context:
space:
mode:
Diffstat (limited to 'include/net')
-rw-r--r--include/net/9p/9p.h8
-rw-r--r--include/net/9p/client.h18
-rw-r--r--include/net/act_api.h6
-rw-r--r--include/net/addrconf.h4
-rw-r--r--include/net/af_vsock.h3
-rw-r--r--include/net/arp.h16
-rw-r--r--include/net/bluetooth/bluetooth.h25
-rw-r--r--include/net/bluetooth/hci_core.h6
-rw-r--r--include/net/bonding.h2
-rw-r--r--include/net/busy_poll.h39
-rw-r--r--include/net/cfg80211.h378
-rw-r--r--include/net/checksum.h4
-rw-r--r--include/net/cipso_ipv4.h4
-rw-r--r--include/net/devlink.h2
-rw-r--r--include/net/dsa.h121
-rw-r--r--include/net/dst.h33
-rw-r--r--include/net/dst_metadata.h10
-rw-r--r--include/net/dst_ops.h11
-rw-r--r--include/net/fib_rules.h9
-rw-r--r--include/net/flow.h10
-rw-r--r--include/net/flow_dissector.h41
-rw-r--r--include/net/flowcache.h2
-rw-r--r--include/net/gen_stats.h17
-rw-r--r--include/net/genetlink.h107
-rw-r--r--include/net/gro_cells.h86
-rw-r--r--include/net/ieee80211_radiotap.h455
-rw-r--r--include/net/if_inet6.h2
-rw-r--r--include/net/ife.h51
-rw-r--r--include/net/inet6_connection_sock.h4
-rw-r--r--include/net/inet_common.h5
-rw-r--r--include/net/inet_connection_sock.h15
-rw-r--r--include/net/inet_frag.h8
-rw-r--r--include/net/inet_hashtables.h15
-rw-r--r--include/net/inet_sock.h7
-rw-r--r--include/net/inet_timewait_sock.h13
-rw-r--r--include/net/ip.h16
-rw-r--r--include/net/ip6_fib.h4
-rw-r--r--include/net/ip6_route.h5
-rw-r--r--include/net/ip_fib.h19
-rw-r--r--include/net/ip_tunnels.h11
-rw-r--r--include/net/ip_vs.h12
-rw-r--r--include/net/ipv6.h10
-rw-r--r--include/net/irda/timer.h2
-rw-r--r--include/net/iw_handler.h66
-rw-r--r--include/net/lwtunnel.h35
-rw-r--r--include/net/mac80211.h103
-rw-r--r--include/net/ndisc.h22
-rw-r--r--include/net/neighbour.h10
-rw-r--r--include/net/net_namespace.h2
-rw-r--r--include/net/netfilter/ipv4/nf_conntrack_ipv4.h10
-rw-r--r--include/net/netfilter/ipv4/nf_defrag_ipv4.h3
-rw-r--r--include/net/netfilter/ipv6/nf_conntrack_ipv6.h10
-rw-r--r--include/net/netfilter/ipv6/nf_defrag_ipv6.h3
-rw-r--r--include/net/netfilter/nf_conntrack.h23
-rw-r--r--include/net/netfilter/nf_conntrack_core.h2
-rw-r--r--include/net/netfilter/nf_conntrack_l3proto.h16
-rw-r--r--include/net/netfilter/nf_conntrack_l4proto.h22
-rw-r--r--include/net/netfilter/nf_conntrack_synproxy.h2
-rw-r--r--include/net/netfilter/nf_dup_netdev.h1
-rw-r--r--include/net/netfilter/nf_log.h10
-rw-r--r--include/net/netfilter/nf_nat_l4proto.h9
-rw-r--r--include/net/netfilter/nf_queue.h1
-rw-r--r--include/net/netfilter/nf_socket.h27
-rw-r--r--include/net/netfilter/nf_tables.h184
-rw-r--r--include/net/netfilter/nf_tables_core.h34
-rw-r--r--include/net/netfilter/nf_tables_ipv6.h6
-rw-r--r--include/net/netfilter/nft_fib.h37
-rw-r--r--include/net/netfilter/xt_rateest.h10
-rw-r--r--include/net/netlink.h13
-rw-r--r--include/net/netns/conntrack.h28
-rw-r--r--include/net/netns/generic.h16
-rw-r--r--include/net/netns/ipv4.h21
-rw-r--r--include/net/netns/ipv6.h1
-rw-r--r--include/net/netns/netfilter.h6
-rw-r--r--include/net/netns/sctp.h3
-rw-r--r--include/net/pkt_cls.h43
-rw-r--r--include/net/pkt_sched.h2
-rw-r--r--include/net/psample.h36
-rw-r--r--include/net/raw.h6
-rw-r--r--include/net/rawv6.h7
-rw-r--r--include/net/red.h4
-rw-r--r--include/net/request_sock.h4
-rw-r--r--include/net/route.h5
-rw-r--r--include/net/rtnetlink.h4
-rw-r--r--include/net/sch_generic.h24
-rw-r--r--include/net/scm.h1
-rw-r--r--include/net/sctp/constants.h7
-rw-r--r--include/net/sctp/sctp.h40
-rw-r--r--include/net/sctp/sm.h34
-rw-r--r--include/net/sctp/structs.h129
-rw-r--r--include/net/sctp/ulpevent.h4
-rw-r--r--include/net/secure_seq.h8
-rw-r--r--include/net/seg6.h62
-rw-r--r--include/net/seg6_hmac.h62
-rw-r--r--include/net/smc.h20
-rw-r--r--include/net/sock.h183
-rw-r--r--include/net/switchdev.h4
-rw-r--r--include/net/tc_act/tc_ife.h3
-rw-r--r--include/net/tc_act/tc_mirred.h6
-rw-r--r--include/net/tc_act/tc_pedit.h6
-rw-r--r--include/net/tc_act/tc_sample.h50
-rw-r--r--include/net/tc_act/tc_skbedit.h1
-rw-r--r--include/net/tc_act/tc_tunnel_key.h37
-rw-r--r--include/net/tcp.h68
-rw-r--r--include/net/udp.h21
-rw-r--r--include/net/udplite.h3
-rw-r--r--include/net/vxlan.h10
-rw-r--r--include/net/xfrm.h60
108 files changed, 2192 insertions, 1114 deletions
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h
index 27dfe85772b1..b8eb51a661e5 100644
--- a/include/net/9p/9p.h
+++ b/include/net/9p/9p.h
@@ -402,10 +402,10 @@ struct p9_wstat {
u32 atime;
u32 mtime;
u64 length;
- char *name;
- char *uid;
- char *gid;
- char *muid;
+ const char *name;
+ const char *uid;
+ const char *gid;
+ const char *muid;
char *extension; /* 9p2000.u extensions */
kuid_t n_uid; /* 9p2000.u extensions */
kgid_t n_gid; /* 9p2000.u extensions */
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index c6b97e58cf84..b582339ccef5 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -223,16 +223,16 @@ void p9_client_destroy(struct p9_client *clnt);
void p9_client_disconnect(struct p9_client *clnt);
void p9_client_begin_disconnect(struct p9_client *clnt);
struct p9_fid *p9_client_attach(struct p9_client *clnt, struct p9_fid *afid,
- char *uname, kuid_t n_uname, char *aname);
+ const char *uname, kuid_t n_uname, const char *aname);
struct p9_fid *p9_client_walk(struct p9_fid *oldfid, uint16_t nwname,
- char **wnames, int clone);
+ const unsigned char * const *wnames, int clone);
int p9_client_open(struct p9_fid *fid, int mode);
-int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode,
+int p9_client_fcreate(struct p9_fid *fid, const char *name, u32 perm, int mode,
char *extension);
-int p9_client_link(struct p9_fid *fid, struct p9_fid *oldfid, char *newname);
-int p9_client_symlink(struct p9_fid *fid, char *name, char *symname, kgid_t gid,
- struct p9_qid *qid);
-int p9_client_create_dotl(struct p9_fid *ofid, char *name, u32 flags, u32 mode,
+int p9_client_link(struct p9_fid *fid, struct p9_fid *oldfid, const char *newname);
+int p9_client_symlink(struct p9_fid *fid, const char *name, const char *symname,
+ kgid_t gid, struct p9_qid *qid);
+int p9_client_create_dotl(struct p9_fid *ofid, const char *name, u32 flags, u32 mode,
kgid_t gid, struct p9_qid *qid);
int p9_client_clunk(struct p9_fid *fid);
int p9_client_fsync(struct p9_fid *fid, int datasync);
@@ -250,9 +250,9 @@ int p9_client_setattr(struct p9_fid *fid, struct p9_iattr_dotl *attr);
struct p9_stat_dotl *p9_client_getattr_dotl(struct p9_fid *fid,
u64 request_mask);
-int p9_client_mknod_dotl(struct p9_fid *oldfid, char *name, int mode,
+int p9_client_mknod_dotl(struct p9_fid *oldfid, const char *name, int mode,
dev_t rdev, kgid_t gid, struct p9_qid *);
-int p9_client_mkdir_dotl(struct p9_fid *fid, char *name, int mode,
+int p9_client_mkdir_dotl(struct p9_fid *fid, const char *name, int mode,
kgid_t gid, struct p9_qid *);
int p9_client_lock_dotl(struct p9_fid *fid, struct p9_flock *flock, u8 *status);
int p9_client_getlock_dotl(struct p9_fid *fid, struct p9_getlock *fl);
diff --git a/include/net/act_api.h b/include/net/act_api.h
index 82f3c912a5b1..cfa2ae33da9a 100644
--- a/include/net/act_api.h
+++ b/include/net/act_api.h
@@ -36,13 +36,13 @@ struct tc_action {
struct tcf_t tcfa_tm;
struct gnet_stats_basic_packed tcfa_bstats;
struct gnet_stats_queue tcfa_qstats;
- struct gnet_stats_rate_est64 tcfa_rate_est;
+ struct net_rate_estimator __rcu *tcfa_rate_est;
spinlock_t tcfa_lock;
struct rcu_head tcfa_rcu;
struct gnet_stats_basic_cpu __percpu *cpu_bstats;
struct gnet_stats_queue __percpu *cpu_qstats;
+ struct tc_cookie *act_cookie;
};
-#define tcf_act common.tcfa_act
#define tcf_head common.tcfa_head
#define tcf_index common.tcfa_index
#define tcf_refcnt common.tcfa_refcnt
@@ -120,6 +120,8 @@ struct tc_action_ops {
int (*walk)(struct net *, struct sk_buff *,
struct netlink_callback *, int, const struct tc_action_ops *);
void (*stats_update)(struct tc_action *, u64, u32, u64);
+ int (*get_dev)(const struct tc_action *a, struct net *net,
+ struct net_device **mirred_dev);
};
struct tc_action_net {
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 8f998afc1384..17c6fd84e287 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -88,9 +88,7 @@ int __ipv6_get_lladdr(struct inet6_dev *idev, struct in6_addr *addr,
u32 banned_flags);
int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr,
u32 banned_flags);
-int ipv4_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2,
- bool match_wildcard);
-int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2,
+int inet_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2,
bool match_wildcard);
void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr);
void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr);
diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
index f2758964ce6f..f32ed9ac181a 100644
--- a/include/net/af_vsock.h
+++ b/include/net/af_vsock.h
@@ -100,6 +100,9 @@ struct vsock_transport {
void (*destruct)(struct vsock_sock *);
void (*release)(struct vsock_sock *);
+ /* Cancel all pending packets sent on vsock. */
+ int (*cancel_pkt)(struct vsock_sock *vsk);
+
/* Connections. */
int (*connect)(struct vsock_sock *);
diff --git a/include/net/arp.h b/include/net/arp.h
index 5e0f891d476c..65619a2de6f4 100644
--- a/include/net/arp.h
+++ b/include/net/arp.h
@@ -35,6 +35,22 @@ static inline struct neighbour *__ipv4_neigh_lookup(struct net_device *dev, u32
return n;
}
+static inline void __ipv4_confirm_neigh(struct net_device *dev, u32 key)
+{
+ struct neighbour *n;
+
+ rcu_read_lock_bh();
+ n = __ipv4_neigh_lookup_noref(dev, key);
+ if (n) {
+ unsigned long now = jiffies;
+
+ /* avoid dirtying neighbour */
+ if (n->confirmed != now)
+ n->confirmed = now;
+ }
+ rcu_read_unlock_bh();
+}
+
void arp_init(void);
int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg);
void arp_send(int type, int ptype, __be32 dest_ip,
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index 0a1e21d7bce1..01487192f628 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -197,7 +197,7 @@ typedef struct {
#define BDADDR_LE_PUBLIC 0x01
#define BDADDR_LE_RANDOM 0x02
-static inline bool bdaddr_type_is_valid(__u8 type)
+static inline bool bdaddr_type_is_valid(u8 type)
{
switch (type) {
case BDADDR_BREDR:
@@ -209,7 +209,7 @@ static inline bool bdaddr_type_is_valid(__u8 type)
return false;
}
-static inline bool bdaddr_type_is_le(__u8 type)
+static inline bool bdaddr_type_is_le(u8 type)
{
switch (type) {
case BDADDR_LE_PUBLIC:
@@ -279,15 +279,16 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock);
/* Skb helpers */
struct l2cap_ctrl {
- __u8 sframe:1,
+ u8 sframe:1,
poll:1,
final:1,
fcs:1,
sar:2,
super:2;
- __u16 reqseq;
- __u16 txseq;
- __u8 retries;
+
+ u16 reqseq;
+ u16 txseq;
+ u8 retries;
__le16 psm;
bdaddr_t bdaddr;
struct l2cap_chan *chan;
@@ -303,7 +304,7 @@ typedef void (*hci_req_complete_skb_t)(struct hci_dev *hdev, u8 status,
#define HCI_REQ_SKB BIT(1)
struct hci_ctrl {
- __u16 opcode;
+ u16 opcode;
u8 req_flags;
u8 req_event;
union {
@@ -313,10 +314,10 @@ struct hci_ctrl {
};
struct bt_skb_cb {
- __u8 pkt_type;
- __u8 force_active;
- __u16 expect;
- __u8 incoming:1;
+ u8 pkt_type;
+ u8 force_active;
+ u16 expect;
+ u8 incoming:1;
union {
struct l2cap_ctrl l2cap;
struct hci_ctrl hci;
@@ -366,7 +367,7 @@ out:
return NULL;
}
-int bt_to_errno(__u16 code);
+int bt_to_errno(u16 code);
void hci_sock_set_flag(struct sock *sk, int nr);
void hci_sock_clear_flag(struct sock *sk, int nr);
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 554671c81f4a..95ccc1eef558 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -26,6 +26,8 @@
#define __HCI_CORE_H
#include <linux/leds.h>
+#include <linux/rculist.h>
+
#include <net/bluetooth/hci.h>
#include <net/bluetooth/hci_sock.h>
@@ -987,7 +989,7 @@ static inline void hci_conn_drop(struct hci_conn *conn)
static inline void hci_dev_put(struct hci_dev *d)
{
BT_DBG("%s orig refcnt %d", d->name,
- atomic_read(&d->dev.kobj.kref.refcount));
+ kref_read(&d->dev.kobj.kref));
put_device(&d->dev);
}
@@ -995,7 +997,7 @@ static inline void hci_dev_put(struct hci_dev *d)
static inline struct hci_dev *hci_dev_hold(struct hci_dev *d)
{
BT_DBG("%s orig refcnt %d", d->name,
- atomic_read(&d->dev.kobj.kref.refcount));
+ kref_read(&d->dev.kobj.kref));
get_device(&d->dev);
return d;
diff --git a/include/net/bonding.h b/include/net/bonding.h
index f32f7ef8a23a..3c857778a6ca 100644
--- a/include/net/bonding.h
+++ b/include/net/bonding.h
@@ -681,7 +681,7 @@ static inline int bond_get_targets_ip(__be32 *targets, __be32 ip)
}
/* exported from bond_main.c */
-extern int bond_net_id;
+extern unsigned int bond_net_id;
extern const struct bond_parm_tbl bond_lacp_tbl[];
extern const struct bond_parm_tbl xmit_hashtype_tbl[];
extern const struct bond_parm_tbl arp_validate_tbl[];
diff --git a/include/net/busy_poll.h b/include/net/busy_poll.h
index 2fbeb1313c0f..c0452de83086 100644
--- a/include/net/busy_poll.h
+++ b/include/net/busy_poll.h
@@ -25,6 +25,8 @@
#define _LINUX_NET_BUSY_POLL_H
#include <linux/netdevice.h>
+#include <linux/sched/clock.h>
+#include <linux/sched/signal.h>
#include <net/ip.h>
#ifdef CONFIG_NET_RX_BUSY_POLL
@@ -33,10 +35,6 @@ struct napi_struct;
extern unsigned int sysctl_net_busy_read __read_mostly;
extern unsigned int sysctl_net_busy_poll __read_mostly;
-/* return values from ndo_ll_poll */
-#define LL_FLUSH_FAILED -1
-#define LL_FLUSH_BUSY -2
-
static inline bool net_busy_loop_on(void)
{
return sysctl_net_busy_poll;
@@ -58,10 +56,9 @@ static inline unsigned long busy_loop_end_time(void)
return busy_loop_us_clock() + ACCESS_ONCE(sysctl_net_busy_poll);
}
-static inline bool sk_can_busy_loop(struct sock *sk)
+static inline bool sk_can_busy_loop(const struct sock *sk)
{
- return sk->sk_ll_usec && sk->sk_napi_id &&
- !need_resched() && !signal_pending(current);
+ return sk->sk_ll_usec && sk->sk_napi_id && !signal_pending(current);
}
@@ -81,11 +78,6 @@ static inline void skb_mark_napi_id(struct sk_buff *skb,
skb->napi_id = napi->napi_id;
}
-/* used in the protocol hanlder to propagate the napi_id to the socket */
-static inline void sk_mark_napi_id(struct sock *sk, struct sk_buff *skb)
-{
- sk->sk_napi_id = skb->napi_id;
-}
#else /* CONFIG_NET_RX_BUSY_POLL */
static inline unsigned long net_busy_loop_on(void)
@@ -108,10 +100,6 @@ static inline void skb_mark_napi_id(struct sk_buff *skb,
{
}
-static inline void sk_mark_napi_id(struct sock *sk, struct sk_buff *skb)
-{
-}
-
static inline bool busy_loop_timeout(unsigned long end_time)
{
return true;
@@ -123,4 +111,23 @@ static inline bool sk_busy_loop(struct sock *sk, int nonblock)
}
#endif /* CONFIG_NET_RX_BUSY_POLL */
+
+/* used in the protocol hanlder to propagate the napi_id to the socket */
+static inline void sk_mark_napi_id(struct sock *sk, const struct sk_buff *skb)
+{
+#ifdef CONFIG_NET_RX_BUSY_POLL
+ sk->sk_napi_id = skb->napi_id;
+#endif
+}
+
+/* variant used for unconnected sockets */
+static inline void sk_mark_napi_id_once(struct sock *sk,
+ const struct sk_buff *skb)
+{
+#ifdef CONFIG_NET_RX_BUSY_POLL
+ if (!sk->sk_napi_id)
+ sk->sk_napi_id = skb->napi_id;
+#endif
+}
+
#endif /* _LINUX_NET_BUSY_POLL_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 14b51d739c3b..ead1aa6d003e 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5,7 +5,7 @@
*
* Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH
- * Copyright 2015-2016 Intel Deutschland GmbH
+ * Copyright 2015-2017 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
@@ -311,6 +311,34 @@ struct ieee80211_supported_band {
struct ieee80211_sta_vht_cap vht_cap;
};
+/**
+ * wiphy_read_of_freq_limits - read frequency limits from device tree
+ *
+ * @wiphy: the wireless device to get extra limits for
+ *
+ * Some devices may have extra limitations specified in DT. This may be useful
+ * for chipsets that normally support more bands but are limited due to board
+ * design (e.g. by antennas or external power amplifier).
+ *
+ * This function reads info from DT and uses it to *modify* channels (disable
+ * unavailable ones). It's usually a *bad* idea to use it in drivers with
+ * shared channel data as DT limitations are device specific. You should make
+ * sure to call it only if channels in wiphy are copied and can be modified
+ * without affecting other devices.
+ *
+ * As this function access device node it has to be called after set_wiphy_dev.
+ * It also modifies channels so they have to be set first.
+ * If using this helper, call it before wiphy_register().
+ */
+#ifdef CONFIG_OF
+void wiphy_read_of_freq_limits(struct wiphy *wiphy);
+#else /* CONFIG_OF */
+static inline void wiphy_read_of_freq_limits(struct wiphy *wiphy)
+{
+}
+#endif /* !CONFIG_OF */
+
+
/*
* Wireless hardware/device configuration structures and methods
*/
@@ -720,6 +748,10 @@ struct cfg80211_bitrate_mask {
* @pbss: If set, start as a PCP instead of AP. Relevant for DMG
* networks.
* @beacon_rate: bitrate to be used for beacons
+ * @ht_cap: HT capabilities (or %NULL if HT isn't enabled)
+ * @vht_cap: VHT capabilities (or %NULL if VHT isn't enabled)
+ * @ht_required: stations must support HT
+ * @vht_required: stations must support VHT
*/
struct cfg80211_ap_settings {
struct cfg80211_chan_def chandef;
@@ -740,6 +772,10 @@ struct cfg80211_ap_settings {
const struct cfg80211_acl_data *acl;
bool pbss;
struct cfg80211_bitrate_mask beacon_rate;
+
+ const struct ieee80211_ht_cap *ht_cap;
+ const struct ieee80211_vht_cap *vht_cap;
+ bool ht_required, vht_required;
};
/**
@@ -772,6 +808,30 @@ struct cfg80211_csa_settings {
};
/**
+ * struct iface_combination_params - input parameters for interface combinations
+ *
+ * Used to pass interface combination parameters
+ *
+ * @num_different_channels: the number of different channels we want
+ * to use for verification
+ * @radar_detect: a bitmap where each bit corresponds to a channel
+ * width where radar detection is needed, as in the definition of
+ * &struct ieee80211_iface_combination.@radar_detect_widths
+ * @iftype_num: array with the number of interfaces of each interface
+ * type. The index is the interface type as specified in &enum
+ * nl80211_iftype.
+ * @new_beacon_int: set this to the beacon interval of a new interface
+ * that's not operating yet, if such is to be checked as part of
+ * the verification
+ */
+struct iface_combination_params {
+ int num_different_channels;
+ u8 radar_detect;
+ int iftype_num[NUM_NL80211_IFTYPES];
+ u32 new_beacon_int;
+};
+
+/**
* enum station_parameters_apply_mask - station parameter values to apply
* @STATION_PARAM_APPLY_UAPSD: apply new uAPSD parameters (uapsd_queues, max_sp)
* @STATION_PARAM_APPLY_CAPABILITY: apply new capability
@@ -1568,6 +1628,17 @@ struct cfg80211_sched_scan_plan {
};
/**
+ * struct cfg80211_bss_select_adjust - BSS selection with RSSI adjustment.
+ *
+ * @band: band of BSS which should match for RSSI level adjustment.
+ * @delta: value of RSSI level adjustment.
+ */
+struct cfg80211_bss_select_adjust {
+ enum nl80211_band band;
+ s8 delta;
+};
+
+/**
* struct cfg80211_sched_scan_request - scheduled scan request description
*
* @ssids: SSIDs to scan for (passed in the probe_reqs in active scans)
@@ -1602,6 +1673,16 @@ struct cfg80211_sched_scan_plan {
* cycle. The driver may ignore this parameter and start
* immediately (or at any other time), if this feature is not
* supported.
+ * @relative_rssi_set: Indicates whether @relative_rssi is set or not.
+ * @relative_rssi: Relative RSSI threshold in dB to restrict scan result
+ * reporting in connected state to cases where a matching BSS is determined
+ * to have better or slightly worse RSSI than the current connected BSS.
+ * The relative RSSI threshold values are ignored in disconnected state.
+ * @rssi_adjust: delta dB of RSSI preference to be given to the BSSs that belong
+ * to the specified band while deciding whether a better BSS is reported
+ * using @relative_rssi. If delta is a negative number, the BSSs that
+ * belong to the specified band will be penalized by delta dB in relative
+ * comparisions.
*/
struct cfg80211_sched_scan_request {
struct cfg80211_ssid *ssids;
@@ -1621,6 +1702,10 @@ struct cfg80211_sched_scan_request {
u8 mac_addr[ETH_ALEN] __aligned(2);
u8 mac_addr_mask[ETH_ALEN] __aligned(2);
+ bool relative_rssi_set;
+ s8 relative_rssi;
+ struct cfg80211_bss_select_adjust rssi_adjust;
+
/* internal */
struct wiphy *wiphy;
struct net_device *dev;
@@ -1761,9 +1846,11 @@ const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie);
* @key_len: length of WEP key for shared key authentication
* @key_idx: index of WEP key for shared key authentication
* @key: WEP key for shared key authentication
- * @sae_data: Non-IE data to use with SAE or %NULL. This starts with
- * Authentication transaction sequence number field.
- * @sae_data_len: Length of sae_data buffer in octets
+ * @auth_data: Fields and elements in Authentication frames. This contains
+ * the authentication frame body (non-IE and IE data), excluding the
+ * Authentication algorithm number, i.e., starting at the Authentication
+ * transaction sequence number field.
+ * @auth_data_len: Length of auth_data buffer in octets
*/
struct cfg80211_auth_request {
struct cfg80211_bss *bss;
@@ -1772,8 +1859,8 @@ struct cfg80211_auth_request {
enum nl80211_auth_type auth_type;
const u8 *key;
u8 key_len, key_idx;
- const u8 *sae_data;
- size_t sae_data_len;
+ const u8 *auth_data;
+ size_t auth_data_len;
};
/**
@@ -1814,6 +1901,12 @@ enum cfg80211_assoc_req_flags {
* @ht_capa_mask: The bits of ht_capa which are to be used.
* @vht_capa: VHT capability override
* @vht_capa_mask: VHT capability mask indicating which fields to use
+ * @fils_kek: FILS KEK for protecting (Re)Association Request/Response frame or
+ * %NULL if FILS is not used.
+ * @fils_kek_len: Length of fils_kek in octets
+ * @fils_nonces: FILS nonces (part of AAD) for protecting (Re)Association
+ * Request/Response frame or %NULL if FILS is not used. This field starts
+ * with 16 octets of STA Nonce followed by 16 octets of AP Nonce.
*/
struct cfg80211_assoc_request {
struct cfg80211_bss *bss;
@@ -1825,6 +1918,9 @@ struct cfg80211_assoc_request {
struct ieee80211_ht_cap ht_capa;
struct ieee80211_ht_cap ht_capa_mask;
struct ieee80211_vht_cap vht_capa, vht_capa_mask;
+ const u8 *fils_kek;
+ size_t fils_kek_len;
+ const u8 *fils_nonces;
};
/**
@@ -1852,7 +1948,7 @@ struct cfg80211_deauth_request {
* struct cfg80211_disassoc_request - Disassociation request data
*
* This structure provides information needed to complete IEEE 802.11
- * disassocation.
+ * disassociation.
*
* @bss: the BSS to disassociate from
* @ie: Extra IEs to add to Disassociation frame or %NULL
@@ -1918,17 +2014,6 @@ struct cfg80211_ibss_params {
};
/**
- * struct cfg80211_bss_select_adjust - BSS selection with RSSI adjustment.
- *
- * @band: band of BSS which should match for RSSI level adjustment.
- * @delta: value of RSSI level adjustment.
- */
-struct cfg80211_bss_select_adjust {
- enum nl80211_band band;
- s8 delta;
-};
-
-/**
* struct cfg80211_bss_selection - connection parameters for BSS selection.
*
* @behaviour: requested BSS selection behaviour.
@@ -2016,6 +2101,18 @@ struct cfg80211_connect_params {
};
/**
+ * enum cfg80211_connect_params_changed - Connection parameters being updated
+ *
+ * This enum provides information of all connect parameters that
+ * have to be updated as part of update_connect_params() call.
+ *
+ * @UPDATE_ASSOC_IES: Indicates whether association request IEs are updated
+ */
+enum cfg80211_connect_params_changed {
+ UPDATE_ASSOC_IES = BIT(0),
+};
+
+/**
* enum wiphy_params_flags - set_wiphy_params bitfield values
* @WIPHY_PARAM_RETRY_SHORT: wiphy->retry_short has changed
* @WIPHY_PARAM_RETRY_LONG: wiphy->retry_long has changed
@@ -2319,11 +2416,13 @@ struct cfg80211_qos_map {
* This struct defines NAN configuration parameters
*
* @master_pref: master preference (1 - 255)
- * @dual: dual band operation mode, see &enum nl80211_nan_dual_band_conf
+ * @bands: operating bands, a bitmap of &enum nl80211_band values.
+ * For instance, for NL80211_BAND_2GHZ, bit 0 would be set
+ * (i.e. BIT(NL80211_BAND_2GHZ)).
*/
struct cfg80211_nan_conf {
u8 master_pref;
- u8 dual;
+ u8 bands;
};
/**
@@ -2331,11 +2430,11 @@ struct cfg80211_nan_conf {
* configuration
*
* @CFG80211_NAN_CONF_CHANGED_PREF: master preference
- * @CFG80211_NAN_CONF_CHANGED_DUAL: dual band operation
+ * @CFG80211_NAN_CONF_CHANGED_BANDS: operating bands
*/
enum cfg80211_nan_conf_changes {
CFG80211_NAN_CONF_CHANGED_PREF = BIT(0),
- CFG80211_NAN_CONF_CHANGED_DUAL = BIT(1),
+ CFG80211_NAN_CONF_CHANGED_BANDS = BIT(1),
};
/**
@@ -2536,9 +2635,18 @@ struct cfg80211_nan_func {
* cases, the result of roaming is indicated with a call to
* cfg80211_roamed() or cfg80211_roamed_bss().
* (invoked with the wireless_dev mutex held)
- * @disconnect: Disconnect from the BSS/ESS. Once done, call
- * cfg80211_disconnected().
+ * @update_connect_params: Update the connect parameters while connected to a
+ * BSS. The updated parameters can be used by driver/firmware for
+ * subsequent BSS selection (roaming) decisions and to form the
+ * Authentication/(Re)Association Request frames. This call does not
+ * request an immediate disassociation or reassociation with the current
+ * BSS, i.e., this impacts only subsequent (re)associations. The bits in
+ * changed are defined in &enum cfg80211_connect_params_changed.
* (invoked with the wireless_dev mutex held)
+ * @disconnect: Disconnect from the BSS/ESS or stop connection attempts if
+ * connection is in progress. Once done, call cfg80211_disconnected() in
+ * case connection was already established (invoked with the
+ * wireless_dev mutex held), otherwise call cfg80211_connect_timeout().
*
* @join_ibss: Join the specified IBSS (or create if necessary). Once done, call
* cfg80211_ibss_joined(), also call that function when changing BSSID due
@@ -2706,6 +2814,8 @@ struct cfg80211_nan_func {
* @nan_change_conf: changes NAN configuration. The changed parameters must
* be specified in @changes (using &enum cfg80211_nan_conf_changes);
* All other parameters must be ignored.
+ *
+ * @set_multicast_to_unicast: configure multicast to unicast conversion for BSS
*/
struct cfg80211_ops {
int (*suspend)(struct wiphy *wiphy, struct cfg80211_wowlan *wow);
@@ -2820,6 +2930,10 @@ struct cfg80211_ops {
int (*connect)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_connect_params *sme);
+ int (*update_connect_params)(struct wiphy *wiphy,
+ struct net_device *dev,
+ struct cfg80211_connect_params *sme,
+ u32 changed);
int (*disconnect)(struct wiphy *wiphy, struct net_device *dev,
u16 reason_code);
@@ -2982,6 +3096,10 @@ struct cfg80211_ops {
struct wireless_dev *wdev,
struct cfg80211_nan_conf *conf,
u32 changes);
+
+ int (*set_multicast_to_unicast)(struct wiphy *wiphy,
+ struct net_device *dev,
+ const bool enabled);
};
/*
@@ -3070,16 +3188,6 @@ struct ieee80211_iface_limit {
/**
* struct ieee80211_iface_combination - possible interface combination
- * @limits: limits for the given interface types
- * @n_limits: number of limitations
- * @num_different_channels: can use up to this many different channels
- * @max_interfaces: maximum number of interfaces in total allowed in this
- * group
- * @beacon_int_infra_match: In this combination, the beacon intervals
- * between infrastructure and AP types must match. This is required
- * only in special cases.
- * @radar_detect_widths: bitmap of channel widths supported for radar detection
- * @radar_detect_regions: bitmap of regions supported for radar detection
*
* With this structure the driver can describe which interface
* combinations it supports concurrently.
@@ -3138,13 +3246,61 @@ struct ieee80211_iface_limit {
*
*/
struct ieee80211_iface_combination {
+ /**
+ * @limits:
+ * limits for the given interface types
+ */
const struct ieee80211_iface_limit *limits;
+
+ /**
+ * @num_different_channels:
+ * can use up to this many different channels
+ */
u32 num_different_channels;
+
+ /**
+ * @max_interfaces:
+ * maximum number of interfaces in total allowed in this group
+ */
u16 max_interfaces;
+
+ /**
+ * @n_limits:
+ * number of limitations
+ */
u8 n_limits;
+
+ /**
+ * @beacon_int_infra_match:
+ * In this combination, the beacon intervals between infrastructure
+ * and AP types must match. This is required only in special cases.
+ */
bool beacon_int_infra_match;
+
+ /**
+ * @radar_detect_widths:
+ * bitmap of channel widths supported for radar detection
+ */
u8 radar_detect_widths;
+
+ /**
+ * @radar_detect_regions:
+ * bitmap of regions supported for radar detection
+ */
u8 radar_detect_regions;
+
+ /**
+ * @beacon_int_min_gcd:
+ * This interface combination supports different beacon intervals.
+ *
+ * = 0
+ * all beacon intervals for different interface must be same.
+ * > 0
+ * any beacon interval for the interface part of this combination AND
+ * GCD of all beacon intervals from beaconing interfaces of this
+ * combination must be greater or equal to this value.
+ */
+ u32 beacon_int_min_gcd;
};
struct ieee80211_txrx_stypes {
@@ -3442,6 +3598,10 @@ struct wiphy_iftype_ext_capab {
* attribute indices defined in &enum nl80211_bss_select_attr.
*
* @cookie_counter: unique generic cookie counter, used to identify objects.
+ * @nan_supported_bands: bands supported by the device in NAN mode, a
+ * bitmap of &enum nl80211_band values. For instance, for
+ * NL80211_BAND_2GHZ, bit 0 would be set
+ * (i.e. BIT(NL80211_BAND_2GHZ)).
*/
struct wiphy {
/* assign these fields before you register the wiphy */
@@ -3573,6 +3733,8 @@ struct wiphy {
u64 cookie_counter;
+ u8 nan_supported_bands;
+
char priv[0] __aligned(NETDEV_ALIGN);
};
@@ -3752,8 +3914,8 @@ struct cfg80211_cached_keys;
* @beacon_interval: beacon interval used on this device for transmitting
* beacons, 0 when not valid
* @address: The address for this device, valid only if @netdev is %NULL
- * @p2p_started: true if this is a P2P Device that has been started
- * @nan_started: true if this is a NAN interface that has been started
+ * @is_running: true if this is a non-netdev device that has been started, e.g.
+ * the P2P Device.
* @cac_started: true if DFS channel availability check has been started
* @cac_start_time: timestamp (jiffies) when the dfs state was entered.
* @cac_time_ms: CAC time in ms
@@ -3764,6 +3926,9 @@ struct cfg80211_cached_keys;
* @conn: (private) cfg80211 software SME connection state machine data
* @connect_keys: (private) keys to set after connection is established
* @conn_bss_type: connecting/connected BSS type
+ * @conn_owner_nlportid: (private) connection owner socket port ID
+ * @disconnect_wk: (private) auto-disconnect work
+ * @disconnect_bssid: (private) the BSSID to use for auto-disconnect
* @ibss_fixed: (private) IBSS is using fixed BSSID
* @ibss_dfs_possible: (private) IBSS may change to a DFS channel
* @event_list: (private) list for internal event processing
@@ -3785,7 +3950,7 @@ struct wireless_dev {
struct mutex mtx;
- bool use_4addr, p2p_started, nan_started;
+ bool use_4addr, is_running;
u8 address[ETH_ALEN] __aligned(sizeof(u16));
@@ -3795,6 +3960,10 @@ struct wireless_dev {
struct cfg80211_conn *conn;
struct cfg80211_cached_keys *connect_keys;
enum ieee80211_bss_type conn_bss_type;
+ u32 conn_owner_nlportid;
+
+ struct work_struct disconnect_wk;
+ u8 disconnect_bssid[ETH_ALEN];
struct list_head event_list;
spinlock_t event_lock;
@@ -3842,6 +4011,13 @@ static inline u8 *wdev_address(struct wireless_dev *wdev)
return wdev->address;
}
+static inline bool wdev_running(struct wireless_dev *wdev)
+{
+ if (wdev->netdev)
+ return netif_running(wdev->netdev);
+ return wdev->is_running;
+}
+
/**
* wdev_priv - return wiphy priv from wireless_dev
*
@@ -3875,26 +4051,15 @@ int ieee80211_channel_to_frequency(int chan, enum nl80211_band band);
*/
int ieee80211_frequency_to_channel(int freq);
-/*
- * Name indirection necessary because the ieee80211 code also has
- * a function named "ieee80211_get_channel", so if you include
- * cfg80211's header file you get cfg80211's version, if you try
- * to include both header files you'll (rightfully!) get a symbol
- * clash.
- */
-struct ieee80211_channel *__ieee80211_get_channel(struct wiphy *wiphy,
- int freq);
/**
* ieee80211_get_channel - get channel struct from wiphy for specified frequency
+ *
* @wiphy: the struct wiphy to get the channel for
* @freq: the center frequency of the channel
+ *
* Return: The channel struct from @wiphy at @freq.
*/
-static inline struct ieee80211_channel *
-ieee80211_get_channel(struct wiphy *wiphy, int freq)
-{
- return __ieee80211_get_channel(wiphy, freq);
-}
+struct ieee80211_channel *ieee80211_get_channel(struct wiphy *wiphy, int freq);
/**
* ieee80211_get_response_rate - get basic rate for a given rate
@@ -4163,6 +4328,27 @@ static inline const u8 *cfg80211_find_ie(u8 eid, const u8 *ies, int len)
}
/**
+ * cfg80211_find_ext_ie - find information element with EID Extension in data
+ *
+ * @ext_eid: element ID Extension
+ * @ies: data consisting of IEs
+ * @len: length of data
+ *
+ * Return: %NULL if the extended element ID could not be found or if
+ * the element is invalid (claims to be longer than the given
+ * data), or a pointer to the first byte of the requested
+ * element, that is the byte containing the element ID.
+ *
+ * Note: There are no checks on the element length other than
+ * having to fit into the given data.
+ */
+static inline const u8 *cfg80211_find_ext_ie(u8 ext_eid, const u8 *ies, int len)
+{
+ return cfg80211_find_ie_match(WLAN_EID_EXTENSION, ies, len,
+ &ext_eid, 1, 2);
+}
+
+/**
* cfg80211_find_vendor_ie - find vendor specific information element in data
*
* @oui: vendor OUI
@@ -4562,7 +4748,8 @@ void cfg80211_auth_timeout(struct net_device *dev, const u8 *addr);
* moves to cfg80211 in this call
* @buf: authentication frame (header + body)
* @len: length of the frame data
- * @uapsd_queues: bitmap of ACs configured to uapsd. -1 if n/a.
+ * @uapsd_queues: bitmap of queues configured for uapsd. Same format
+ * as the AC bitmap in the QoS info field
*
* After being asked to associate via cfg80211_ops::assoc() the driver must
* call either this function or cfg80211_auth_timeout().
@@ -4584,6 +4771,17 @@ void cfg80211_rx_assoc_resp(struct net_device *dev,
void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss);
/**
+ * cfg80211_abandon_assoc - notify cfg80211 of abandoned association attempt
+ * @dev: network device
+ * @bss: The BSS entry with which association was abandoned.
+ *
+ * Call this whenever - for reasons reported through other API, like deauth RX,
+ * an association attempt was abandoned.
+ * This function may sleep. The caller must hold the corresponding wdev's mutex.
+ */
+void cfg80211_abandon_assoc(struct net_device *dev, struct cfg80211_bss *bss);
+
+/**
* cfg80211_tx_mlme_mgmt - notification of transmitted deauth/disassoc frame
* @dev: network device
* @buf: 802.11 frame (header + body)
@@ -4935,20 +5133,32 @@ static inline void cfg80211_testmode_event(struct sk_buff *skb, gfp_t gfp)
* @req_ie_len: association request IEs length
* @resp_ie: association response IEs (may be %NULL)
* @resp_ie_len: assoc response IEs length
- * @status: status code, 0 for successful connection, use
- * %WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you
- * the real status code for failures.
+ * @status: status code, %WLAN_STATUS_SUCCESS for successful connection, use
+ * %WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you
+ * the real status code for failures. If this call is used to report a
+ * failure due to a timeout (e.g., not receiving an Authentication frame
+ * from the AP) instead of an explicit rejection by the AP, -1 is used to
+ * indicate that this is a failure, but without a status code.
+ * @timeout_reason is used to report the reason for the timeout in that
+ * case.
* @gfp: allocation flags
- *
- * It should be called by the underlying driver whenever connect() has
- * succeeded. This is similar to cfg80211_connect_result(), but with the
- * option of identifying the exact bss entry for the connection. Only one of
- * these functions should be called.
+ * @timeout_reason: reason for connection timeout. This is used when the
+ * connection fails due to a timeout instead of an explicit rejection from
+ * the AP. %NL80211_TIMEOUT_UNSPECIFIED is used when the timeout reason is
+ * not known. This value is used only if @status < 0 to indicate that the
+ * failure is due to a timeout and not due to explicit rejection by the AP.
+ * This value is ignored in other cases (@status >= 0).
+ *
+ * It should be called by the underlying driver once execution of the connection
+ * request from connect() has been completed. This is similar to
+ * cfg80211_connect_result(), but with the option of identifying the exact bss
+ * entry for the connection. Only one of these functions should be called.
*/
void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
struct cfg80211_bss *bss, const u8 *req_ie,
size_t req_ie_len, const u8 *resp_ie,
- size_t resp_ie_len, int status, gfp_t gfp);
+ size_t resp_ie_len, int status, gfp_t gfp,
+ enum nl80211_timeout_reason timeout_reason);
/**
* cfg80211_connect_result - notify cfg80211 of connection result
@@ -4959,13 +5169,15 @@ void cfg80211_connect_bss(struct net_device *dev, const u8 *bssid,
* @req_ie_len: association request IEs length
* @resp_ie: association response IEs (may be %NULL)
* @resp_ie_len: assoc response IEs length
- * @status: status code, 0 for successful connection, use
+ * @status: status code, %WLAN_STATUS_SUCCESS for successful connection, use
* %WLAN_STATUS_UNSPECIFIED_FAILURE if your device cannot give you
* the real status code for failures.
* @gfp: allocation flags
*
- * It should be called by the underlying driver whenever connect() has
- * succeeded.
+ * It should be called by the underlying driver once execution of the connection
+ * request from connect() has been completed. This is similar to
+ * cfg80211_connect_bss() which allows the exact bss entry to be specified. Only
+ * one of these functions should be called.
*/
static inline void
cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
@@ -4974,7 +5186,8 @@ cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
u16 status, gfp_t gfp)
{
cfg80211_connect_bss(dev, bssid, NULL, req_ie, req_ie_len, resp_ie,
- resp_ie_len, status, gfp);
+ resp_ie_len, status, gfp,
+ NL80211_TIMEOUT_UNSPECIFIED);
}
/**
@@ -4985,6 +5198,7 @@ cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
* @req_ie: association request IEs (maybe be %NULL)
* @req_ie_len: association request IEs length
* @gfp: allocation flags
+ * @timeout_reason: reason for connection timeout.
*
* It should be called by the underlying driver whenever connect() has failed
* in a sequence where no explicit authentication/association rejection was
@@ -4994,10 +5208,11 @@ cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
*/
static inline void
cfg80211_connect_timeout(struct net_device *dev, const u8 *bssid,
- const u8 *req_ie, size_t req_ie_len, gfp_t gfp)
+ const u8 *req_ie, size_t req_ie_len, gfp_t gfp,
+ enum nl80211_timeout_reason timeout_reason)
{
cfg80211_connect_bss(dev, bssid, NULL, req_ie, req_ie_len, NULL, 0, -1,
- gfp);
+ gfp, timeout_reason);
}
/**
@@ -5183,6 +5398,7 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
* cfg80211_cqm_rssi_notify - connection quality monitoring rssi event
* @dev: network device
* @rssi_event: the triggered RSSI event
+ * @rssi_level: new RSSI level value or 0 if not available
* @gfp: context flags
*
* This function is called when a configured connection quality monitoring
@@ -5190,7 +5406,7 @@ void cfg80211_mgmt_tx_status(struct wireless_dev *wdev, u64 cookie,
*/
void cfg80211_cqm_rssi_notify(struct net_device *dev,
enum nl80211_cqm_rssi_threshold_event rssi_event,
- gfp_t gfp);
+ s32 rssi_level, gfp_t gfp);
/**
* cfg80211_cqm_pktloss_notify - notify userspace about packetloss to peer
@@ -5598,36 +5814,20 @@ unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy);
* cfg80211_check_combinations - check interface combinations
*
* @wiphy: the wiphy
- * @num_different_channels: the number of different channels we want
- * to use for verification
- * @radar_detect: a bitmap where each bit corresponds to a channel
- * width where radar detection is needed, as in the definition of
- * &struct ieee80211_iface_combination.@radar_detect_widths
- * @iftype_num: array with the numbers of interfaces of each interface
- * type. The index is the interface type as specified in &enum
- * nl80211_iftype.
+ * @params: the interface combinations parameter
*
* This function can be called by the driver to check whether a
* combination of interfaces and their types are allowed according to
* the interface combinations.
*/
int cfg80211_check_combinations(struct wiphy *wiphy,
- const int num_different_channels,
- const u8 radar_detect,
- const int iftype_num[NUM_NL80211_IFTYPES]);
+ struct iface_combination_params *params);
/**
* cfg80211_iter_combinations - iterate over matching combinations
*
* @wiphy: the wiphy
- * @num_different_channels: the number of different channels we want
- * to use for verification
- * @radar_detect: a bitmap where each bit corresponds to a channel
- * width where radar detection is needed, as in the definition of
- * &struct ieee80211_iface_combination.@radar_detect_widths
- * @iftype_num: array with the numbers of interfaces of each interface
- * type. The index is the interface type as specified in &enum
- * nl80211_iftype.
+ * @params: the interface combinations parameter
* @iter: function to call for each matching combination
* @data: pointer to pass to iter function
*
@@ -5636,9 +5836,7 @@ int cfg80211_check_combinations(struct wiphy *wiphy,
* purposes.
*/
int cfg80211_iter_combinations(struct wiphy *wiphy,
- const int num_different_channels,
- const u8 radar_detect,
- const int iftype_num[NUM_NL80211_IFTYPES],
+ struct iface_combination_params *params,
void (*iter)(const struct ieee80211_iface_combination *c,
void *data),
void *data);
diff --git a/include/net/checksum.h b/include/net/checksum.h
index 5c30891e84e5..aef2b2bb6603 100644
--- a/include/net/checksum.h
+++ b/include/net/checksum.h
@@ -22,7 +22,7 @@
#include <linux/errno.h>
#include <asm/types.h>
#include <asm/byteorder.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/checksum.h>
#ifndef _HAVE_ARCH_COPY_AND_CSUM_FROM_USER
@@ -179,7 +179,7 @@ static inline __wsum remcsum_adjust(void *ptr, __wsum csum,
static inline void remcsum_unadjust(__sum16 *psum, __wsum delta)
{
- *psum = csum_fold(csum_sub(delta, *psum));
+ *psum = csum_fold(csum_sub(delta, (__force __wsum)*psum));
}
#endif
diff --git a/include/net/cipso_ipv4.h b/include/net/cipso_ipv4.h
index 3ebb168b9afc..a34b141f125f 100644
--- a/include/net/cipso_ipv4.h
+++ b/include/net/cipso_ipv4.h
@@ -309,6 +309,10 @@ static inline int cipso_v4_validate(const struct sk_buff *skb,
}
for (opt_iter = 6; opt_iter < opt_len;) {
+ if (opt_iter + 1 == opt_len) {
+ err_offset = opt_iter;
+ goto out;
+ }
tag_len = opt[opt_iter + 1];
if ((tag_len == 0) || (tag_len > (opt_len - opt_iter))) {
err_offset = opt_iter + 1;
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 211bd3c37028..d29e5fc82582 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -92,6 +92,8 @@ struct devlink_ops {
int (*eswitch_mode_get)(struct devlink *devlink, u16 *p_mode);
int (*eswitch_mode_set)(struct devlink *devlink, u16 mode);
+ int (*eswitch_inline_mode_get)(struct devlink *devlink, u8 *p_inline_mode);
+ int (*eswitch_inline_mode_set)(struct devlink *devlink, u8 inline_mode);
};
static inline void *devlink_priv(struct devlink *devlink)
diff --git a/include/net/dsa.h b/include/net/dsa.h
index b122196d5a1f..4e13e695f025 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -11,15 +11,19 @@
#ifndef __LINUX_NET_DSA_H
#define __LINUX_NET_DSA_H
+#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/list.h>
+#include <linux/notifier.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/of.h>
-#include <linux/phy.h>
-#include <linux/phy_fixed.h>
#include <linux/ethtool.h>
+struct tc_action;
+struct phy_device;
+struct fixed_phy_status;
+
enum dsa_tag_protocol {
DSA_TAG_PROTO_NONE = 0,
DSA_TAG_PROTO_DSA,
@@ -42,6 +46,11 @@ struct dsa_chip_data {
struct device *host_dev;
int sw_addr;
+ /*
+ * Reference to network devices
+ */
+ struct device *netdev[DSA_MAX_PORTS];
+
/* set to size of eeprom if supported by the switch */
int eeprom_len;
@@ -90,6 +99,9 @@ struct packet_type;
struct dsa_switch_tree {
struct list_head list;
+ /* Notifier chain for switch-wide events */
+ struct raw_notifier_head nh;
+
/* Tree identifier */
u32 tree;
@@ -124,7 +136,7 @@ struct dsa_switch_tree {
/*
* The switch and port to which the CPU is attached.
*/
- s8 cpu_switch;
+ struct dsa_switch *cpu_switch;
s8 cpu_port;
/*
@@ -139,11 +151,37 @@ struct dsa_switch_tree {
const struct dsa_device_ops *tag_ops;
};
+/* TC matchall action types, only mirroring for now */
+enum dsa_port_mall_action_type {
+ DSA_PORT_MALL_MIRROR,
+};
+
+/* TC mirroring entry */
+struct dsa_mall_mirror_tc_entry {
+ u8 to_local_port;
+ bool ingress;
+};
+
+/* TC matchall entry */
+struct dsa_mall_tc_entry {
+ struct list_head list;
+ unsigned long cookie;
+ enum dsa_port_mall_action_type type;
+ union {
+ struct dsa_mall_mirror_tc_entry mirror;
+ };
+};
+
+
struct dsa_port {
+ struct dsa_switch *ds;
+ unsigned int index;
+ const char *name;
struct net_device *netdev;
struct device_node *dn;
unsigned int ageing_time;
u8 stp_state;
+ struct net_device *bridge_dev;
};
struct dsa_switch {
@@ -155,6 +193,9 @@ struct dsa_switch {
struct dsa_switch_tree *dst;
int index;
+ /* Listener for switch fabric events */
+ struct notifier_block nb;
+
/*
* Give the switch driver somewhere to hang its private data
* structure.
@@ -169,7 +210,7 @@ struct dsa_switch {
/*
* The switch operations.
*/
- struct dsa_switch_ops *ops;
+ const struct dsa_switch_ops *ops;
/*
* An array of which element [a] indicates which port on this
@@ -178,14 +219,6 @@ struct dsa_switch {
*/
s8 rtable[DSA_MAX_SWITCHES];
-#ifdef CONFIG_NET_DSA_HWMON
- /*
- * Hardware monitoring information
- */
- char hwmon_name[IFNAMSIZ + 8];
- struct device *hwmon_dev;
-#endif
-
/*
* The lower device this switch uses to talk to the host
*/
@@ -198,13 +231,16 @@ struct dsa_switch {
u32 cpu_port_mask;
u32 enabled_port_mask;
u32 phys_mii_mask;
- struct dsa_port ports[DSA_MAX_PORTS];
struct mii_bus *slave_mii_bus;
+
+ /* Dynamically allocated ports, keep last */
+ size_t num_ports;
+ struct dsa_port ports[];
};
static inline bool dsa_is_cpu_port(struct dsa_switch *ds, int p)
{
- return !!(ds->index == ds->dst->cpu_switch && p == ds->dst->cpu_port);
+ return !!(ds == ds->dst->cpu_switch && p == ds->dst->cpu_port);
}
static inline bool dsa_is_dsa_port(struct dsa_switch *ds, int p)
@@ -227,10 +263,10 @@ static inline u8 dsa_upstream_port(struct dsa_switch *ds)
* Else return the (DSA) port number that connects to the
* switch that is one hop closer to the cpu.
*/
- if (dst->cpu_switch == ds->index)
+ if (dst->cpu_switch == ds)
return dst->cpu_port;
else
- return ds->rtable[dst->cpu_switch];
+ return ds->rtable[dst->cpu_switch->index];
}
struct switchdev_trans;
@@ -239,9 +275,17 @@ struct switchdev_obj_port_fdb;
struct switchdev_obj_port_mdb;
struct switchdev_obj_port_vlan;
-struct dsa_switch_ops {
- struct list_head list;
+#define DSA_NOTIFIER_BRIDGE_JOIN 1
+#define DSA_NOTIFIER_BRIDGE_LEAVE 2
+
+/* DSA_NOTIFIER_BRIDGE_* */
+struct dsa_notifier_bridge_info {
+ struct net_device *br;
+ int sw_index;
+ int port;
+};
+struct dsa_switch_ops {
/*
* Probing and setup.
*/
@@ -309,14 +353,6 @@ struct dsa_switch_ops {
int (*get_eee)(struct dsa_switch *ds, int port,
struct ethtool_eee *e);
-#ifdef CONFIG_NET_DSA_HWMON
- /* Hardware monitoring */
- int (*get_temp)(struct dsa_switch *ds, int *temp);
- int (*get_temp_limit)(struct dsa_switch *ds, int *temp);
- int (*set_temp_limit)(struct dsa_switch *ds, int temp);
- int (*get_temp_alarm)(struct dsa_switch *ds, bool *alarm);
-#endif
-
/* EEPROM access */
int (*get_eeprom_len)(struct dsa_switch *ds);
int (*get_eeprom)(struct dsa_switch *ds,
@@ -337,7 +373,8 @@ struct dsa_switch_ops {
int (*set_ageing_time)(struct dsa_switch *ds, unsigned int msecs);
int (*port_bridge_join)(struct dsa_switch *ds, int port,
struct net_device *bridge);
- void (*port_bridge_leave)(struct dsa_switch *ds, int port);
+ void (*port_bridge_leave)(struct dsa_switch *ds, int port,
+ struct net_device *bridge);
void (*port_stp_state_set)(struct dsa_switch *ds, int port,
u8 state);
void (*port_fast_age)(struct dsa_switch *ds, int port);
@@ -388,19 +425,43 @@ struct dsa_switch_ops {
int (*port_mdb_dump)(struct dsa_switch *ds, int port,
struct switchdev_obj_port_mdb *mdb,
int (*cb)(struct switchdev_obj *obj));
+
+ /*
+ * RXNFC
+ */
+ int (*get_rxnfc)(struct dsa_switch *ds, int port,
+ struct ethtool_rxnfc *nfc, u32 *rule_locs);
+ int (*set_rxnfc)(struct dsa_switch *ds, int port,
+ struct ethtool_rxnfc *nfc);
+
+ /*
+ * TC integration
+ */
+ int (*port_mirror_add)(struct dsa_switch *ds, int port,
+ struct dsa_mall_mirror_tc_entry *mirror,
+ bool ingress);
+ void (*port_mirror_del)(struct dsa_switch *ds, int port,
+ struct dsa_mall_mirror_tc_entry *mirror);
+};
+
+struct dsa_switch_driver {
+ struct list_head list;
+ const struct dsa_switch_ops *ops;
};
-void register_switch_driver(struct dsa_switch_ops *type);
-void unregister_switch_driver(struct dsa_switch_ops *type);
+void register_switch_driver(struct dsa_switch_driver *type);
+void unregister_switch_driver(struct dsa_switch_driver *type);
struct mii_bus *dsa_host_dev_to_mii_bus(struct device *dev);
+struct net_device *dsa_dev_to_net_device(struct device *dev);
static inline bool dsa_uses_tagged_protocol(struct dsa_switch_tree *dst)
{
return dst->rcv != NULL;
}
+struct dsa_switch *dsa_switch_alloc(struct device *dev, size_t n);
void dsa_unregister_switch(struct dsa_switch *ds);
-int dsa_register_switch(struct dsa_switch *ds, struct device_node *np);
+int dsa_register_switch(struct dsa_switch *ds, struct device *dev);
#ifdef CONFIG_PM_SLEEP
int dsa_switch_suspend(struct dsa_switch *ds);
int dsa_switch_resume(struct dsa_switch *ds);
diff --git a/include/net/dst.h b/include/net/dst.h
index 6835d224d47b..049af33da3b6 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -59,8 +59,6 @@ struct dst_entry {
#define DST_XFRM_QUEUE 0x0100
#define DST_METADATA 0x0200
- unsigned short pending_confirm;
-
short error;
/* A non-zero value of dst->obsolete forces by-hand validation
@@ -78,6 +76,8 @@ struct dst_entry {
#define DST_OBSOLETE_KILL -2
unsigned short header_len; /* more space at head required */
unsigned short trailer_len; /* space to reserve at tail */
+ unsigned short __pad3;
+
#ifdef CONFIG_IP_ROUTE_CLASSID
__u32 tclassid;
#else
@@ -440,28 +440,6 @@ static inline void dst_rcu_free(struct rcu_head *head)
static inline void dst_confirm(struct dst_entry *dst)
{
- dst->pending_confirm = 1;
-}
-
-static inline int dst_neigh_output(struct dst_entry *dst, struct neighbour *n,
- struct sk_buff *skb)
-{
- const struct hh_cache *hh;
-
- if (dst->pending_confirm) {
- unsigned long now = jiffies;
-
- dst->pending_confirm = 0;
- /* avoid dirtying neighbour */
- if (n->confirmed != now)
- n->confirmed = now;
- }
-
- hh = &n->hh;
- if ((n->nud_state & NUD_CONNECTED) && hh->hh_len)
- return neigh_hh_output(hh, skb);
- else
- return n->output(n, skb);
}
static inline struct neighbour *dst_neigh_lookup(const struct dst_entry *dst, const void *daddr)
@@ -477,6 +455,13 @@ static inline struct neighbour *dst_neigh_lookup_skb(const struct dst_entry *dst
return IS_ERR(n) ? NULL : n;
}
+static inline void dst_confirm_neigh(const struct dst_entry *dst,
+ const void *daddr)
+{
+ if (dst->ops->confirm_neigh)
+ dst->ops->confirm_neigh(dst, daddr);
+}
+
static inline void dst_link_failure(struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
diff --git a/include/net/dst_metadata.h b/include/net/dst_metadata.h
index 6965c8f68ade..701fc814d0af 100644
--- a/include/net/dst_metadata.h
+++ b/include/net/dst_metadata.h
@@ -115,6 +115,7 @@ static inline struct ip_tunnel_info *skb_tunnel_info_unclone(struct sk_buff *skb
static inline struct metadata_dst *__ip_tun_set_dst(__be32 saddr,
__be32 daddr,
__u8 tos, __u8 ttl,
+ __be16 tp_dst,
__be16 flags,
__be64 tunnel_id,
int md_size)
@@ -127,7 +128,7 @@ static inline struct metadata_dst *__ip_tun_set_dst(__be32 saddr,
ip_tunnel_key_init(&tun_dst->u.tun_info.key,
saddr, daddr, tos, ttl,
- 0, 0, 0, tunnel_id, flags);
+ 0, 0, tp_dst, tunnel_id, flags);
return tun_dst;
}
@@ -139,12 +140,13 @@ static inline struct metadata_dst *ip_tun_rx_dst(struct sk_buff *skb,
const struct iphdr *iph = ip_hdr(skb);
return __ip_tun_set_dst(iph->saddr, iph->daddr, iph->tos, iph->ttl,
- flags, tunnel_id, md_size);
+ 0, flags, tunnel_id, md_size);
}
static inline struct metadata_dst *__ipv6_tun_set_dst(const struct in6_addr *saddr,
const struct in6_addr *daddr,
__u8 tos, __u8 ttl,
+ __be16 tp_dst,
__be32 label,
__be16 flags,
__be64 tunnel_id,
@@ -162,7 +164,7 @@ static inline struct metadata_dst *__ipv6_tun_set_dst(const struct in6_addr *sad
info->key.tun_flags = flags;
info->key.tun_id = tunnel_id;
info->key.tp_src = 0;
- info->key.tp_dst = 0;
+ info->key.tp_dst = tp_dst;
info->key.u.ipv6.src = *saddr;
info->key.u.ipv6.dst = *daddr;
@@ -183,7 +185,7 @@ static inline struct metadata_dst *ipv6_tun_rx_dst(struct sk_buff *skb,
return __ipv6_tun_set_dst(&ip6h->saddr, &ip6h->daddr,
ipv6_get_dsfield(ip6h), ip6h->hop_limit,
- ip6_flowlabel(ip6h), flags, tunnel_id,
+ 0, ip6_flowlabel(ip6h), flags, tunnel_id,
md_size);
}
#endif /* __NET_DST_METADATA_H */
diff --git a/include/net/dst_ops.h b/include/net/dst_ops.h
index a0d443ca16fc..c84b3287e38b 100644
--- a/include/net/dst_ops.h
+++ b/include/net/dst_ops.h
@@ -33,6 +33,8 @@ struct dst_ops {
struct neighbour * (*neigh_lookup)(const struct dst_entry *dst,
struct sk_buff *skb,
const void *daddr);
+ void (*confirm_neigh)(const struct dst_entry *dst,
+ const void *daddr);
struct kmem_cache *kmem_cachep;
@@ -46,19 +48,12 @@ static inline int dst_entries_get_fast(struct dst_ops *dst)
static inline int dst_entries_get_slow(struct dst_ops *dst)
{
- int res;
-
- local_bh_disable();
- res = percpu_counter_sum_positive(&dst->pcpuc_entries);
- local_bh_enable();
- return res;
+ return percpu_counter_sum_positive(&dst->pcpuc_entries);
}
static inline void dst_entries_add(struct dst_ops *dst, int val)
{
- local_bh_disable();
percpu_counter_add(&dst->pcpuc_entries, val);
- local_bh_enable();
}
static inline int dst_entries_init(struct dst_ops *dst)
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index 456e4a6006ab..8dbfdf728cd8 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -8,6 +8,11 @@
#include <net/flow.h>
#include <net/rtnetlink.h>
+struct fib_kuid_range {
+ kuid_t start;
+ kuid_t end;
+};
+
struct fib_rule {
struct list_head list;
int iifindex;
@@ -30,6 +35,7 @@ struct fib_rule {
int suppress_prefixlen;
char iifname[IFNAMSIZ];
char oifname[IFNAMSIZ];
+ struct fib_kuid_range uid_range;
struct rcu_head rcu;
};
@@ -92,7 +98,8 @@ struct fib_rules_ops {
[FRA_SUPPRESS_PREFIXLEN] = { .type = NLA_U32 }, \
[FRA_SUPPRESS_IFGROUP] = { .type = NLA_U32 }, \
[FRA_GOTO] = { .type = NLA_U32 }, \
- [FRA_L3MDEV] = { .type = NLA_U8 }
+ [FRA_L3MDEV] = { .type = NLA_U8 }, \
+ [FRA_UID_RANGE] = { .len = sizeof(struct fib_rule_uid_range) }
static inline void fib_rule_get(struct fib_rule *rule)
{
diff --git a/include/net/flow.h b/include/net/flow.h
index 035aa7716967..6984f1913dc1 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -11,6 +11,7 @@
#include <linux/in6.h>
#include <linux/atomic.h>
#include <net/flow_dissector.h>
+#include <linux/uidgid.h>
/*
* ifindex generation is per-net namespace, and loopback is
@@ -37,6 +38,7 @@ struct flowi_common {
#define FLOWI_FLAG_SKIP_NH_OIF 0x04
__u32 flowic_secid;
struct flowi_tunnel flowic_tun_key;
+ kuid_t flowic_uid;
};
union flowi_uli {
@@ -74,6 +76,7 @@ struct flowi4 {
#define flowi4_flags __fl_common.flowic_flags
#define flowi4_secid __fl_common.flowic_secid
#define flowi4_tun_key __fl_common.flowic_tun_key
+#define flowi4_uid __fl_common.flowic_uid
/* (saddr,daddr) must be grouped, same order as in IP header */
__be32 saddr;
@@ -93,7 +96,8 @@ static inline void flowi4_init_output(struct flowi4 *fl4, int oif,
__u32 mark, __u8 tos, __u8 scope,
__u8 proto, __u8 flags,
__be32 daddr, __be32 saddr,
- __be16 dport, __be16 sport)
+ __be16 dport, __be16 sport,
+ kuid_t uid)
{
fl4->flowi4_oif = oif;
fl4->flowi4_iif = LOOPBACK_IFINDEX;
@@ -104,6 +108,7 @@ static inline void flowi4_init_output(struct flowi4 *fl4, int oif,
fl4->flowi4_flags = flags;
fl4->flowi4_secid = 0;
fl4->flowi4_tun_key.tun_id = 0;
+ fl4->flowi4_uid = uid;
fl4->daddr = daddr;
fl4->saddr = saddr;
fl4->fl4_dport = dport;
@@ -131,6 +136,7 @@ struct flowi6 {
#define flowi6_flags __fl_common.flowic_flags
#define flowi6_secid __fl_common.flowic_secid
#define flowi6_tun_key __fl_common.flowic_tun_key
+#define flowi6_uid __fl_common.flowic_uid
struct in6_addr daddr;
struct in6_addr saddr;
/* Note: flowi6_tos is encoded in flowlabel, too. */
@@ -176,6 +182,7 @@ struct flowi {
#define flowi_flags u.__fl_common.flowic_flags
#define flowi_secid u.__fl_common.flowic_secid
#define flowi_tun_key u.__fl_common.flowic_tun_key
+#define flowi_uid u.__fl_common.flowic_uid
} __attribute__((__aligned__(BITS_PER_LONG/8)));
static inline struct flowi *flowi4_to_flowi(struct flowi4 *fl4)
@@ -239,6 +246,7 @@ struct flow_cache_object *flow_cache_lookup(struct net *net,
void *ctx);
int flow_cache_init(struct net *net);
void flow_cache_fini(struct net *net);
+void flow_cache_hp_init(void);
void flow_cache_flush(struct net *net);
void flow_cache_flush_deferred(struct net *net);
diff --git a/include/net/flow_dissector.h b/include/net/flow_dissector.h
index d9534927d93b..ac9703018a3a 100644
--- a/include/net/flow_dissector.h
+++ b/include/net/flow_dissector.h
@@ -89,6 +89,24 @@ struct flow_dissector_key_addrs {
};
/**
+ * flow_dissector_key_arp:
+ * @ports: Operation, source and target addresses for an ARP header
+ * for Ethernet hardware addresses and IPv4 protocol addresses
+ * sip: Sender IP address
+ * tip: Target IP address
+ * op: Operation
+ * sha: Sender hardware address
+ * tpa: Target hardware address
+ */
+struct flow_dissector_key_arp {
+ __u32 sip;
+ __u32 tip;
+ __u8 op;
+ unsigned char sha[ETH_ALEN];
+ unsigned char tha[ETH_ALEN];
+};
+
+/**
* flow_dissector_key_tp_ports:
* @ports: port numbers of Transport header
* src: source port number
@@ -104,6 +122,22 @@ struct flow_dissector_key_ports {
};
};
+/**
+ * flow_dissector_key_icmp:
+ * @ports: type and code of ICMP header
+ * icmp: ICMP type (high) and code (low)
+ * type: ICMP type
+ * code: ICMP code
+ */
+struct flow_dissector_key_icmp {
+ union {
+ __be16 icmp;
+ struct {
+ u8 type;
+ u8 code;
+ };
+ };
+};
/**
* struct flow_dissector_key_eth_addrs:
@@ -122,12 +156,19 @@ enum flow_dissector_key_id {
FLOW_DISSECTOR_KEY_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
FLOW_DISSECTOR_KEY_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
FLOW_DISSECTOR_KEY_PORTS, /* struct flow_dissector_key_ports */
+ FLOW_DISSECTOR_KEY_ICMP, /* struct flow_dissector_key_icmp */
FLOW_DISSECTOR_KEY_ETH_ADDRS, /* struct flow_dissector_key_eth_addrs */
FLOW_DISSECTOR_KEY_TIPC_ADDRS, /* struct flow_dissector_key_tipc_addrs */
+ FLOW_DISSECTOR_KEY_ARP, /* struct flow_dissector_key_arp */
FLOW_DISSECTOR_KEY_VLAN, /* struct flow_dissector_key_flow_vlan */
FLOW_DISSECTOR_KEY_FLOW_LABEL, /* struct flow_dissector_key_flow_tags */
FLOW_DISSECTOR_KEY_GRE_KEYID, /* struct flow_dissector_key_keyid */
FLOW_DISSECTOR_KEY_MPLS_ENTROPY, /* struct flow_dissector_key_keyid */
+ FLOW_DISSECTOR_KEY_ENC_KEYID, /* struct flow_dissector_key_keyid */
+ FLOW_DISSECTOR_KEY_ENC_IPV4_ADDRS, /* struct flow_dissector_key_ipv4_addrs */
+ FLOW_DISSECTOR_KEY_ENC_IPV6_ADDRS, /* struct flow_dissector_key_ipv6_addrs */
+ FLOW_DISSECTOR_KEY_ENC_CONTROL, /* struct flow_dissector_key_control */
+ FLOW_DISSECTOR_KEY_ENC_PORTS, /* struct flow_dissector_key_ports */
FLOW_DISSECTOR_KEY_MAX,
};
diff --git a/include/net/flowcache.h b/include/net/flowcache.h
index c8f665ec6e0d..9caf3bfc8d2d 100644
--- a/include/net/flowcache.h
+++ b/include/net/flowcache.h
@@ -17,7 +17,7 @@ struct flow_cache_percpu {
struct flow_cache {
u32 hash_shift;
struct flow_cache_percpu __percpu *percpu;
- struct notifier_block hotcpu_notifier;
+ struct hlist_node node;
int low_watermark;
int high_watermark;
struct timer_list rnd_timer;
diff --git a/include/net/gen_stats.h b/include/net/gen_stats.h
index 231e121cc7d9..8b7aa370e7a4 100644
--- a/include/net/gen_stats.h
+++ b/include/net/gen_stats.h
@@ -11,6 +11,8 @@ struct gnet_stats_basic_cpu {
struct u64_stats_sync syncp;
};
+struct net_rate_estimator;
+
struct gnet_dump {
spinlock_t * lock;
struct sk_buff * skb;
@@ -42,8 +44,7 @@ void __gnet_stats_copy_basic(const seqcount_t *running,
struct gnet_stats_basic_cpu __percpu *cpu,
struct gnet_stats_basic_packed *b);
int gnet_stats_copy_rate_est(struct gnet_dump *d,
- const struct gnet_stats_basic_packed *b,
- struct gnet_stats_rate_est64 *r);
+ struct net_rate_estimator __rcu **ptr);
int gnet_stats_copy_queue(struct gnet_dump *d,
struct gnet_stats_queue __percpu *cpu_q,
struct gnet_stats_queue *q, __u32 qlen);
@@ -53,16 +54,16 @@ int gnet_stats_finish_copy(struct gnet_dump *d);
int gen_new_estimator(struct gnet_stats_basic_packed *bstats,
struct gnet_stats_basic_cpu __percpu *cpu_bstats,
- struct gnet_stats_rate_est64 *rate_est,
+ struct net_rate_estimator __rcu **rate_est,
spinlock_t *stats_lock,
seqcount_t *running, struct nlattr *opt);
-void gen_kill_estimator(struct gnet_stats_basic_packed *bstats,
- struct gnet_stats_rate_est64 *rate_est);
+void gen_kill_estimator(struct net_rate_estimator __rcu **ptr);
int gen_replace_estimator(struct gnet_stats_basic_packed *bstats,
struct gnet_stats_basic_cpu __percpu *cpu_bstats,
- struct gnet_stats_rate_est64 *rate_est,
+ struct net_rate_estimator __rcu **ptr,
spinlock_t *stats_lock,
seqcount_t *running, struct nlattr *opt);
-bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats,
- const struct gnet_stats_rate_est64 *rate_est);
+bool gen_estimator_active(struct net_rate_estimator __rcu **ptr);
+bool gen_estimator_read(struct net_rate_estimator __rcu **ptr,
+ struct gnet_stats_rate_est64 *sample);
#endif
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 8d4608ce8716..a34275be3600 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -20,7 +20,7 @@ struct genl_info;
/**
* struct genl_family - generic netlink family
- * @id: protocol family idenfitier
+ * @id: protocol family identifier (private)
* @hdrsize: length of user specific header in bytes
* @name: name of family
* @version: protocol version
@@ -39,16 +39,16 @@ struct genl_info;
* Note that unbind() will not be called symmetrically if the
* generic netlink family is removed while there are still open
* sockets.
- * @attrbuf: buffer to store parsed attributes
- * @family_list: family list
- * @mcgrps: multicast groups used by this family (private)
- * @n_mcgrps: number of multicast groups (private)
+ * @attrbuf: buffer to store parsed attributes (private)
+ * @mcgrps: multicast groups used by this family
+ * @n_mcgrps: number of multicast groups
* @mcgrp_offset: starting number of multicast group IDs in this family
- * @ops: the operations supported by this family (private)
- * @n_ops: number of operations supported by this family (private)
+ * (private)
+ * @ops: the operations supported by this family
+ * @n_ops: number of operations supported by this family
*/
struct genl_family {
- unsigned int id;
+ int id; /* private */
unsigned int hdrsize;
char name[GENL_NAMSIZ];
unsigned int version;
@@ -64,15 +64,16 @@ struct genl_family {
int (*mcast_bind)(struct net *net, int group);
void (*mcast_unbind)(struct net *net, int group);
struct nlattr ** attrbuf; /* private */
- const struct genl_ops * ops; /* private */
- const struct genl_multicast_group *mcgrps; /* private */
- unsigned int n_ops; /* private */
- unsigned int n_mcgrps; /* private */
+ const struct genl_ops * ops;
+ const struct genl_multicast_group *mcgrps;
+ unsigned int n_ops;
+ unsigned int n_mcgrps;
unsigned int mcgrp_offset; /* private */
- struct list_head family_list; /* private */
struct module *module;
};
+struct nlattr **genl_family_attrbuf(const struct genl_family *family);
+
/**
* struct genl_info - receiving information
* @snd_seq: sending sequence number
@@ -130,64 +131,13 @@ struct genl_ops {
u8 flags;
};
-int __genl_register_family(struct genl_family *family);
-
-static inline int genl_register_family(struct genl_family *family)
-{
- family->module = THIS_MODULE;
- return __genl_register_family(family);
-}
-
-/**
- * genl_register_family_with_ops - register a generic netlink family with ops
- * @family: generic netlink family
- * @ops: operations to be registered
- * @n_ops: number of elements to register
- *
- * Registers the specified family and operations from the specified table.
- * Only one family may be registered with the same family name or identifier.
- *
- * The family id may equal GENL_ID_GENERATE causing an unique id to
- * be automatically generated and assigned.
- *
- * Either a doit or dumpit callback must be specified for every registered
- * operation or the function will fail. Only one operation structure per
- * command identifier may be registered.
- *
- * See include/net/genetlink.h for more documenation on the operations
- * structure.
- *
- * Return 0 on success or a negative error code.
- */
-static inline int
-_genl_register_family_with_ops_grps(struct genl_family *family,
- const struct genl_ops *ops, size_t n_ops,
- const struct genl_multicast_group *mcgrps,
- size_t n_mcgrps)
-{
- family->module = THIS_MODULE;
- family->ops = ops;
- family->n_ops = n_ops;
- family->mcgrps = mcgrps;
- family->n_mcgrps = n_mcgrps;
- return __genl_register_family(family);
-}
-
-#define genl_register_family_with_ops(family, ops) \
- _genl_register_family_with_ops_grps((family), \
- (ops), ARRAY_SIZE(ops), \
- NULL, 0)
-#define genl_register_family_with_ops_groups(family, ops, grps) \
- _genl_register_family_with_ops_grps((family), \
- (ops), ARRAY_SIZE(ops), \
- (grps), ARRAY_SIZE(grps))
-
-int genl_unregister_family(struct genl_family *family);
-void genl_notify(struct genl_family *family, struct sk_buff *skb,
+int genl_register_family(struct genl_family *family);
+int genl_unregister_family(const struct genl_family *family);
+void genl_notify(const struct genl_family *family, struct sk_buff *skb,
struct genl_info *info, u32 group, gfp_t flags);
void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
- struct genl_family *family, int flags, u8 cmd);
+ const struct genl_family *family, int flags, u8 cmd);
/**
* genlmsg_nlhdr - Obtain netlink header from user specified header
@@ -196,8 +146,8 @@ void *genlmsg_put(struct sk_buff *skb, u32 portid, u32 seq,
*
* Returns pointer to netlink header.
*/
-static inline struct nlmsghdr *genlmsg_nlhdr(void *user_hdr,
- struct genl_family *family)
+static inline struct nlmsghdr *
+genlmsg_nlhdr(void *user_hdr, const struct genl_family *family)
{
return (struct nlmsghdr *)((char *)user_hdr -
family->hdrsize -
@@ -233,7 +183,7 @@ static inline int genlmsg_parse(const struct nlmsghdr *nlh,
*/
static inline void genl_dump_check_consistent(struct netlink_callback *cb,
void *user_hdr,
- struct genl_family *family)
+ const struct genl_family *family)
{
nl_dump_check_consistent(cb, genlmsg_nlhdr(user_hdr, family));
}
@@ -250,7 +200,7 @@ static inline void genl_dump_check_consistent(struct netlink_callback *cb,
*/
static inline void *genlmsg_put_reply(struct sk_buff *skb,
struct genl_info *info,
- struct genl_family *family,
+ const struct genl_family *family,
int flags, u8 cmd)
{
return genlmsg_put(skb, info->snd_portid, info->snd_seq, family,
@@ -287,7 +237,7 @@ static inline void genlmsg_cancel(struct sk_buff *skb, void *hdr)
* @group: offset of multicast group in groups array
* @flags: allocation flags
*/
-static inline int genlmsg_multicast_netns(struct genl_family *family,
+static inline int genlmsg_multicast_netns(const struct genl_family *family,
struct net *net, struct sk_buff *skb,
u32 portid, unsigned int group, gfp_t flags)
{
@@ -305,7 +255,7 @@ static inline int genlmsg_multicast_netns(struct genl_family *family,
* @group: offset of multicast group in groups array
* @flags: allocation flags
*/
-static inline int genlmsg_multicast(struct genl_family *family,
+static inline int genlmsg_multicast(const struct genl_family *family,
struct sk_buff *skb, u32 portid,
unsigned int group, gfp_t flags)
{
@@ -323,7 +273,7 @@ static inline int genlmsg_multicast(struct genl_family *family,
*
* This function must hold the RTNL or rcu_read_lock().
*/
-int genlmsg_multicast_allns(struct genl_family *family,
+int genlmsg_multicast_allns(const struct genl_family *family,
struct sk_buff *skb, u32 portid,
unsigned int group, gfp_t flags);
@@ -407,8 +357,9 @@ static inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags)
* This function returns the number of broadcast listeners that have set the
* NETLINK_RECV_NO_ENOBUFS socket option.
*/
-static inline int genl_set_err(struct genl_family *family, struct net *net,
- u32 portid, u32 group, int code)
+static inline int genl_set_err(const struct genl_family *family,
+ struct net *net, u32 portid,
+ u32 group, int code)
{
if (WARN_ON_ONCE(group >= family->n_mcgrps))
return -EINVAL;
@@ -416,7 +367,7 @@ static inline int genl_set_err(struct genl_family *family, struct net *net,
return netlink_set_err(net->genl_sock, portid, group, code);
}
-static inline int genl_has_listeners(struct genl_family *family,
+static inline int genl_has_listeners(const struct genl_family *family,
struct net *net, unsigned int group)
{
if (WARN_ON_ONCE(group >= family->n_mcgrps))
diff --git a/include/net/gro_cells.h b/include/net/gro_cells.h
index 2a1abbf8da74..fcaf8f479130 100644
--- a/include/net/gro_cells.h
+++ b/include/net/gro_cells.h
@@ -5,92 +5,14 @@
#include <linux/slab.h>
#include <linux/netdevice.h>
-struct gro_cell {
- struct sk_buff_head napi_skbs;
- struct napi_struct napi;
-};
+struct gro_cell;
struct gro_cells {
struct gro_cell __percpu *cells;
};
-static inline int gro_cells_receive(struct gro_cells *gcells, struct sk_buff *skb)
-{
- struct gro_cell *cell;
- struct net_device *dev = skb->dev;
-
- if (!gcells->cells || skb_cloned(skb) || !(dev->features & NETIF_F_GRO))
- return netif_rx(skb);
-
- cell = this_cpu_ptr(gcells->cells);
-
- if (skb_queue_len(&cell->napi_skbs) > netdev_max_backlog) {
- atomic_long_inc(&dev->rx_dropped);
- kfree_skb(skb);
- return NET_RX_DROP;
- }
-
- __skb_queue_tail(&cell->napi_skbs, skb);
- if (skb_queue_len(&cell->napi_skbs) == 1)
- napi_schedule(&cell->napi);
- return NET_RX_SUCCESS;
-}
-
-/* called under BH context */
-static inline int gro_cell_poll(struct napi_struct *napi, int budget)
-{
- struct gro_cell *cell = container_of(napi, struct gro_cell, napi);
- struct sk_buff *skb;
- int work_done = 0;
-
- while (work_done < budget) {
- skb = __skb_dequeue(&cell->napi_skbs);
- if (!skb)
- break;
- napi_gro_receive(napi, skb);
- work_done++;
- }
-
- if (work_done < budget)
- napi_complete_done(napi, work_done);
- return work_done;
-}
-
-static inline int gro_cells_init(struct gro_cells *gcells, struct net_device *dev)
-{
- int i;
-
- gcells->cells = alloc_percpu(struct gro_cell);
- if (!gcells->cells)
- return -ENOMEM;
-
- for_each_possible_cpu(i) {
- struct gro_cell *cell = per_cpu_ptr(gcells->cells, i);
-
- __skb_queue_head_init(&cell->napi_skbs);
-
- set_bit(NAPI_STATE_NO_BUSY_POLL, &cell->napi.state);
-
- netif_napi_add(dev, &cell->napi, gro_cell_poll, 64);
- napi_enable(&cell->napi);
- }
- return 0;
-}
-
-static inline void gro_cells_destroy(struct gro_cells *gcells)
-{
- int i;
-
- if (!gcells->cells)
- return;
- for_each_possible_cpu(i) {
- struct gro_cell *cell = per_cpu_ptr(gcells->cells, i);
-
- netif_napi_del(&cell->napi);
- __skb_queue_purge(&cell->napi_skbs);
- }
- free_percpu(gcells->cells);
- gcells->cells = NULL;
-}
+int gro_cells_receive(struct gro_cells *gcells, struct sk_buff *skb);
+int gro_cells_init(struct gro_cells *gcells, struct net_device *dev);
+void gro_cells_destroy(struct gro_cells *gcells);
#endif
diff --git a/include/net/ieee80211_radiotap.h b/include/net/ieee80211_radiotap.h
index ba07b9d8ed63..d91f9e7f4d71 100644
--- a/include/net/ieee80211_radiotap.h
+++ b/include/net/ieee80211_radiotap.h
@@ -1,201 +1,54 @@
/*
- * Copyright (c) 2003, 2004 David Young. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of David Young may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
- * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
- * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
- * OF SUCH DAMAGE.
- */
-
-/*
- * Modifications to fit into the linux IEEE 802.11 stack,
- * Mike Kershaw (dragorn@kismetwireless.net)
+ * Copyright (c) 2017 Intel Deutschland GmbH
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#ifndef __RADIOTAP_H
+#define __RADIOTAP_H
-#ifndef IEEE80211RADIOTAP_H
-#define IEEE80211RADIOTAP_H
-
-#include <linux/if_ether.h>
#include <linux/kernel.h>
#include <asm/unaligned.h>
-/* Base version of the radiotap packet header data */
-#define PKTHDR_RADIOTAP_VERSION 0
-
-/* A generic radio capture format is desirable. There is one for
- * Linux, but it is neither rigidly defined (there were not even
- * units given for some fields) nor easily extensible.
- *
- * I suggest the following extensible radio capture format. It is
- * based on a bitmap indicating which fields are present.
- *
- * I am trying to describe precisely what the application programmer
- * should expect in the following, and for that reason I tell the
- * units and origin of each measurement (where it applies), or else I
- * use sufficiently weaselly language ("is a monotonically nondecreasing
- * function of...") that I cannot set false expectations for lawyerly
- * readers.
- */
-
-/*
- * The radio capture header precedes the 802.11 header.
- * All data in the header is little endian on all platforms.
+/**
+ * struct ieee82011_radiotap_header - base radiotap header
*/
struct ieee80211_radiotap_header {
- u8 it_version; /* Version 0. Only increases
- * for drastic changes,
- * introduction of compatible
- * new fields does not count.
- */
- u8 it_pad;
- __le16 it_len; /* length of the whole
- * header in bytes, including
- * it_version, it_pad,
- * it_len, and data fields.
- */
- __le32 it_present; /* A bitmap telling which
- * fields are present. Set bit 31
- * (0x80000000) to extend the
- * bitmap by another 32 bits.
- * Additional extensions are made
- * by setting bit 31.
- */
+ /**
+ * @it_version: radiotap version, always 0
+ */
+ uint8_t it_version;
+
+ /**
+ * @it_pad: padding (or alignment)
+ */
+ uint8_t it_pad;
+
+ /**
+ * @it_len: overall radiotap header length
+ */
+ __le16 it_len;
+
+ /**
+ * @it_present: (first) present word
+ */
+ __le32 it_present;
} __packed;
-/* Name Data type Units
- * ---- --------- -----
- *
- * IEEE80211_RADIOTAP_TSFT __le64 microseconds
- *
- * Value in microseconds of the MAC's 64-bit 802.11 Time
- * Synchronization Function timer when the first bit of the
- * MPDU arrived at the MAC. For received frames, only.
- *
- * IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap
- *
- * Tx/Rx frequency in MHz, followed by flags (see below).
- *
- * IEEE80211_RADIOTAP_FHSS __le16 see below
- *
- * For frequency-hopping radios, the hop set (first byte)
- * and pattern (second byte).
- *
- * IEEE80211_RADIOTAP_RATE u8 500kb/s
- *
- * Tx/Rx data rate
- *
- * IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from
- * one milliwatt (dBm)
- *
- * RF signal power at the antenna, decibel difference from
- * one milliwatt.
- *
- * IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from
- * one milliwatt (dBm)
- *
- * RF noise power at the antenna, decibel difference from one
- * milliwatt.
- *
- * IEEE80211_RADIOTAP_DB_ANTSIGNAL u8 decibel (dB)
- *
- * RF signal power at the antenna, decibel difference from an
- * arbitrary, fixed reference.
- *
- * IEEE80211_RADIOTAP_DB_ANTNOISE u8 decibel (dB)
- *
- * RF noise power at the antenna, decibel difference from an
- * arbitrary, fixed reference point.
- *
- * IEEE80211_RADIOTAP_LOCK_QUALITY __le16 unitless
- *
- * Quality of Barker code lock. Unitless. Monotonically
- * nondecreasing with "better" lock strength. Called "Signal
- * Quality" in datasheets. (Is there a standard way to measure
- * this?)
- *
- * IEEE80211_RADIOTAP_TX_ATTENUATION __le16 unitless
- *
- * Transmit power expressed as unitless distance from max
- * power set at factory calibration. 0 is max power.
- * Monotonically nondecreasing with lower power levels.
- *
- * IEEE80211_RADIOTAP_DB_TX_ATTENUATION __le16 decibels (dB)
- *
- * Transmit power expressed as decibel distance from max power
- * set at factory calibration. 0 is max power. Monotonically
- * nondecreasing with lower power levels.
- *
- * IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from
- * one milliwatt (dBm)
- *
- * Transmit power expressed as dBm (decibels from a 1 milliwatt
- * reference). This is the absolute power level measured at
- * the antenna port.
- *
- * IEEE80211_RADIOTAP_FLAGS u8 bitmap
- *
- * Properties of transmitted and received frames. See flags
- * defined below.
- *
- * IEEE80211_RADIOTAP_ANTENNA u8 antenna index
- *
- * Unitless indication of the Rx/Tx antenna for this packet.
- * The first antenna is antenna 0.
- *
- * IEEE80211_RADIOTAP_RX_FLAGS __le16 bitmap
- *
- * Properties of received frames. See flags defined below.
- *
- * IEEE80211_RADIOTAP_TX_FLAGS __le16 bitmap
- *
- * Properties of transmitted frames. See flags defined below.
- *
- * IEEE80211_RADIOTAP_RTS_RETRIES u8 data
- *
- * Number of rts retries a transmitted frame used.
- *
- * IEEE80211_RADIOTAP_DATA_RETRIES u8 data
- *
- * Number of unicast retries a transmitted frame used.
- *
- * IEEE80211_RADIOTAP_MCS u8, u8, u8 unitless
- *
- * Contains a bitmap of known fields/flags, the flags, and
- * the MCS index.
- *
- * IEEE80211_RADIOTAP_AMPDU_STATUS u32, u16, u8, u8 unitless
- *
- * Contains the AMPDU information for the subframe.
- *
- * IEEE80211_RADIOTAP_VHT u16, u8, u8, u8[4], u8, u8, u16
- *
- * Contains VHT information about this frame.
- *
- * IEEE80211_RADIOTAP_TIMESTAMP u64, u16, u8, u8 variable
- *
- * Contains timestamp information for this frame.
- */
-enum ieee80211_radiotap_type {
+/* version is always 0 */
+#define PKTHDR_RADIOTAP_VERSION 0
+
+/* see the radiotap website for the descriptions */
+enum ieee80211_radiotap_presence {
IEEE80211_RADIOTAP_TSFT = 0,
IEEE80211_RADIOTAP_FLAGS = 1,
IEEE80211_RADIOTAP_RATE = 2,
@@ -214,7 +67,7 @@ enum ieee80211_radiotap_type {
IEEE80211_RADIOTAP_TX_FLAGS = 15,
IEEE80211_RADIOTAP_RTS_RETRIES = 16,
IEEE80211_RADIOTAP_DATA_RETRIES = 17,
-
+ /* 18 is XChannel, but it's not defined yet */
IEEE80211_RADIOTAP_MCS = 19,
IEEE80211_RADIOTAP_AMPDU_STATUS = 20,
IEEE80211_RADIOTAP_VHT = 21,
@@ -226,129 +79,135 @@ enum ieee80211_radiotap_type {
IEEE80211_RADIOTAP_EXT = 31
};
-/* Channel flags. */
-#define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */
-#define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */
-#define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */
-#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */
-#define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */
-#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */
-#define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */
-#define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */
-#define IEEE80211_CHAN_GSM 0x1000 /* GSM (900 MHz) */
-#define IEEE80211_CHAN_STURBO 0x2000 /* Static Turbo */
-#define IEEE80211_CHAN_HALF 0x4000 /* Half channel (10 MHz wide) */
-#define IEEE80211_CHAN_QUARTER 0x8000 /* Quarter channel (5 MHz wide) */
-
-/* For IEEE80211_RADIOTAP_FLAGS */
-#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received
- * during CFP
- */
-#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received
- * with short
- * preamble
- */
-#define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received
- * with WEP encryption
- */
-#define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received
- * with fragmentation
- */
-#define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */
-#define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between
- * 802.11 header and payload
- * (to 32-bit boundary)
- */
-#define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* bad FCS */
-
-/* For IEEE80211_RADIOTAP_RX_FLAGS */
-#define IEEE80211_RADIOTAP_F_RX_BADPLCP 0x0002 /* frame has bad PLCP */
+/* for IEEE80211_RADIOTAP_FLAGS */
+enum ieee80211_radiotap_flags {
+ IEEE80211_RADIOTAP_F_CFP = 0x01,
+ IEEE80211_RADIOTAP_F_SHORTPRE = 0x02,
+ IEEE80211_RADIOTAP_F_WEP = 0x04,
+ IEEE80211_RADIOTAP_F_FRAG = 0x08,
+ IEEE80211_RADIOTAP_F_FCS = 0x10,
+ IEEE80211_RADIOTAP_F_DATAPAD = 0x20,
+ IEEE80211_RADIOTAP_F_BADFCS = 0x40,
+};
-/* For IEEE80211_RADIOTAP_TX_FLAGS */
-#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive
- * retries */
-#define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 /* used cts 'protection' */
-#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */
-#define IEEE80211_RADIOTAP_F_TX_NOACK 0x0008 /* don't expect an ack */
+/* for IEEE80211_RADIOTAP_CHANNEL */
+enum ieee80211_radiotap_channel_flags {
+ IEEE80211_CHAN_CCK = 0x0020,
+ IEEE80211_CHAN_OFDM = 0x0040,
+ IEEE80211_CHAN_2GHZ = 0x0080,
+ IEEE80211_CHAN_5GHZ = 0x0100,
+ IEEE80211_CHAN_DYN = 0x0400,
+ IEEE80211_CHAN_HALF = 0x4000,
+ IEEE80211_CHAN_QUARTER = 0x8000,
+};
+/* for IEEE80211_RADIOTAP_RX_FLAGS */
+enum ieee80211_radiotap_rx_flags {
+ IEEE80211_RADIOTAP_F_RX_BADPLCP = 0x0002,
+};
-/* For IEEE80211_RADIOTAP_MCS */
-#define IEEE80211_RADIOTAP_MCS_HAVE_BW 0x01
-#define IEEE80211_RADIOTAP_MCS_HAVE_MCS 0x02
-#define IEEE80211_RADIOTAP_MCS_HAVE_GI 0x04
-#define IEEE80211_RADIOTAP_MCS_HAVE_FMT 0x08
-#define IEEE80211_RADIOTAP_MCS_HAVE_FEC 0x10
-#define IEEE80211_RADIOTAP_MCS_HAVE_STBC 0x20
+/* for IEEE80211_RADIOTAP_TX_FLAGS */
+enum ieee80211_radiotap_tx_flags {
+ IEEE80211_RADIOTAP_F_TX_FAIL = 0x0001,
+ IEEE80211_RADIOTAP_F_TX_CTS = 0x0002,
+ IEEE80211_RADIOTAP_F_TX_RTS = 0x0004,
+ IEEE80211_RADIOTAP_F_TX_NOACK = 0x0008,
+};
-#define IEEE80211_RADIOTAP_MCS_BW_MASK 0x03
-#define IEEE80211_RADIOTAP_MCS_BW_20 0
-#define IEEE80211_RADIOTAP_MCS_BW_40 1
-#define IEEE80211_RADIOTAP_MCS_BW_20L 2
-#define IEEE80211_RADIOTAP_MCS_BW_20U 3
-#define IEEE80211_RADIOTAP_MCS_SGI 0x04
-#define IEEE80211_RADIOTAP_MCS_FMT_GF 0x08
-#define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10
-#define IEEE80211_RADIOTAP_MCS_STBC_MASK 0x60
-#define IEEE80211_RADIOTAP_MCS_STBC_1 1
-#define IEEE80211_RADIOTAP_MCS_STBC_2 2
-#define IEEE80211_RADIOTAP_MCS_STBC_3 3
+/* for IEEE80211_RADIOTAP_MCS "have" flags */
+enum ieee80211_radiotap_mcs_have {
+ IEEE80211_RADIOTAP_MCS_HAVE_BW = 0x01,
+ IEEE80211_RADIOTAP_MCS_HAVE_MCS = 0x02,
+ IEEE80211_RADIOTAP_MCS_HAVE_GI = 0x04,
+ IEEE80211_RADIOTAP_MCS_HAVE_FMT = 0x08,
+ IEEE80211_RADIOTAP_MCS_HAVE_FEC = 0x10,
+ IEEE80211_RADIOTAP_MCS_HAVE_STBC = 0x20,
+};
-#define IEEE80211_RADIOTAP_MCS_STBC_SHIFT 5
+enum ieee80211_radiotap_mcs_flags {
+ IEEE80211_RADIOTAP_MCS_BW_MASK = 0x03,
+ IEEE80211_RADIOTAP_MCS_BW_20 = 0,
+ IEEE80211_RADIOTAP_MCS_BW_40 = 1,
+ IEEE80211_RADIOTAP_MCS_BW_20L = 2,
+ IEEE80211_RADIOTAP_MCS_BW_20U = 3,
+
+ IEEE80211_RADIOTAP_MCS_SGI = 0x04,
+ IEEE80211_RADIOTAP_MCS_FMT_GF = 0x08,
+ IEEE80211_RADIOTAP_MCS_FEC_LDPC = 0x10,
+ IEEE80211_RADIOTAP_MCS_STBC_MASK = 0x60,
+ IEEE80211_RADIOTAP_MCS_STBC_1 = 1,
+ IEEE80211_RADIOTAP_MCS_STBC_2 = 2,
+ IEEE80211_RADIOTAP_MCS_STBC_3 = 3,
+ IEEE80211_RADIOTAP_MCS_STBC_SHIFT = 5,
+};
-/* For IEEE80211_RADIOTAP_AMPDU_STATUS */
-#define IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN 0x0001
-#define IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN 0x0002
-#define IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN 0x0004
-#define IEEE80211_RADIOTAP_AMPDU_IS_LAST 0x0008
-#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR 0x0010
-#define IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN 0x0020
+/* for IEEE80211_RADIOTAP_AMPDU_STATUS */
+enum ieee80211_radiotap_ampdu_flags {
+ IEEE80211_RADIOTAP_AMPDU_REPORT_ZEROLEN = 0x0001,
+ IEEE80211_RADIOTAP_AMPDU_IS_ZEROLEN = 0x0002,
+ IEEE80211_RADIOTAP_AMPDU_LAST_KNOWN = 0x0004,
+ IEEE80211_RADIOTAP_AMPDU_IS_LAST = 0x0008,
+ IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_ERR = 0x0010,
+ IEEE80211_RADIOTAP_AMPDU_DELIM_CRC_KNOWN = 0x0020,
+};
-/* For IEEE80211_RADIOTAP_VHT */
-#define IEEE80211_RADIOTAP_VHT_KNOWN_STBC 0x0001
-#define IEEE80211_RADIOTAP_VHT_KNOWN_TXOP_PS_NA 0x0002
-#define IEEE80211_RADIOTAP_VHT_KNOWN_GI 0x0004
-#define IEEE80211_RADIOTAP_VHT_KNOWN_SGI_NSYM_DIS 0x0008
-#define IEEE80211_RADIOTAP_VHT_KNOWN_LDPC_EXTRA_OFDM_SYM 0x0010
-#define IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED 0x0020
-#define IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH 0x0040
-#define IEEE80211_RADIOTAP_VHT_KNOWN_GROUP_ID 0x0080
-#define IEEE80211_RADIOTAP_VHT_KNOWN_PARTIAL_AID 0x0100
+/* for IEEE80211_RADIOTAP_VHT */
+enum ieee80211_radiotap_vht_known {
+ IEEE80211_RADIOTAP_VHT_KNOWN_STBC = 0x0001,
+ IEEE80211_RADIOTAP_VHT_KNOWN_TXOP_PS_NA = 0x0002,
+ IEEE80211_RADIOTAP_VHT_KNOWN_GI = 0x0004,
+ IEEE80211_RADIOTAP_VHT_KNOWN_SGI_NSYM_DIS = 0x0008,
+ IEEE80211_RADIOTAP_VHT_KNOWN_LDPC_EXTRA_OFDM_SYM = 0x0010,
+ IEEE80211_RADIOTAP_VHT_KNOWN_BEAMFORMED = 0x0020,
+ IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH = 0x0040,
+ IEEE80211_RADIOTAP_VHT_KNOWN_GROUP_ID = 0x0080,
+ IEEE80211_RADIOTAP_VHT_KNOWN_PARTIAL_AID = 0x0100,
+};
-#define IEEE80211_RADIOTAP_VHT_FLAG_STBC 0x01
-#define IEEE80211_RADIOTAP_VHT_FLAG_TXOP_PS_NA 0x02
-#define IEEE80211_RADIOTAP_VHT_FLAG_SGI 0x04
-#define IEEE80211_RADIOTAP_VHT_FLAG_SGI_NSYM_M10_9 0x08
-#define IEEE80211_RADIOTAP_VHT_FLAG_LDPC_EXTRA_OFDM_SYM 0x10
-#define IEEE80211_RADIOTAP_VHT_FLAG_BEAMFORMED 0x20
+enum ieee80211_radiotap_vht_flags {
+ IEEE80211_RADIOTAP_VHT_FLAG_STBC = 0x01,
+ IEEE80211_RADIOTAP_VHT_FLAG_TXOP_PS_NA = 0x02,
+ IEEE80211_RADIOTAP_VHT_FLAG_SGI = 0x04,
+ IEEE80211_RADIOTAP_VHT_FLAG_SGI_NSYM_M10_9 = 0x08,
+ IEEE80211_RADIOTAP_VHT_FLAG_LDPC_EXTRA_OFDM_SYM = 0x10,
+ IEEE80211_RADIOTAP_VHT_FLAG_BEAMFORMED = 0x20,
+};
-#define IEEE80211_RADIOTAP_CODING_LDPC_USER0 0x01
-#define IEEE80211_RADIOTAP_CODING_LDPC_USER1 0x02
-#define IEEE80211_RADIOTAP_CODING_LDPC_USER2 0x04
-#define IEEE80211_RADIOTAP_CODING_LDPC_USER3 0x08
+enum ieee80211_radiotap_vht_coding {
+ IEEE80211_RADIOTAP_CODING_LDPC_USER0 = 0x01,
+ IEEE80211_RADIOTAP_CODING_LDPC_USER1 = 0x02,
+ IEEE80211_RADIOTAP_CODING_LDPC_USER2 = 0x04,
+ IEEE80211_RADIOTAP_CODING_LDPC_USER3 = 0x08,
+};
-/* For IEEE80211_RADIOTAP_TIMESTAMP */
-#define IEEE80211_RADIOTAP_TIMESTAMP_UNIT_MASK 0x000F
-#define IEEE80211_RADIOTAP_TIMESTAMP_UNIT_MS 0x0000
-#define IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US 0x0001
-#define IEEE80211_RADIOTAP_TIMESTAMP_UNIT_NS 0x0003
-#define IEEE80211_RADIOTAP_TIMESTAMP_SPOS_MASK 0x00F0
-#define IEEE80211_RADIOTAP_TIMESTAMP_SPOS_BEGIN_MDPU 0x0000
-#define IEEE80211_RADIOTAP_TIMESTAMP_SPOS_EO_MPDU 0x0010
-#define IEEE80211_RADIOTAP_TIMESTAMP_SPOS_EO_PPDU 0x0020
-#define IEEE80211_RADIOTAP_TIMESTAMP_SPOS_PLCP_SIG_ACQ 0x0030
-#define IEEE80211_RADIOTAP_TIMESTAMP_SPOS_UNKNOWN 0x00F0
+/* for IEEE80211_RADIOTAP_TIMESTAMP */
+enum ieee80211_radiotap_timestamp_unit_spos {
+ IEEE80211_RADIOTAP_TIMESTAMP_UNIT_MASK = 0x000F,
+ IEEE80211_RADIOTAP_TIMESTAMP_UNIT_MS = 0x0000,
+ IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US = 0x0001,
+ IEEE80211_RADIOTAP_TIMESTAMP_UNIT_NS = 0x0003,
+ IEEE80211_RADIOTAP_TIMESTAMP_SPOS_MASK = 0x00F0,
+ IEEE80211_RADIOTAP_TIMESTAMP_SPOS_BEGIN_MDPU = 0x0000,
+ IEEE80211_RADIOTAP_TIMESTAMP_SPOS_PLCP_SIG_ACQ = 0x0010,
+ IEEE80211_RADIOTAP_TIMESTAMP_SPOS_EO_PPDU = 0x0020,
+ IEEE80211_RADIOTAP_TIMESTAMP_SPOS_EO_MPDU = 0x0030,
+ IEEE80211_RADIOTAP_TIMESTAMP_SPOS_UNKNOWN = 0x00F0,
+};
-#define IEEE80211_RADIOTAP_TIMESTAMP_FLAG_64BIT 0x00
-#define IEEE80211_RADIOTAP_TIMESTAMP_FLAG_32BIT 0x01
-#define IEEE80211_RADIOTAP_TIMESTAMP_FLAG_ACCURACY 0x02
+enum ieee80211_radiotap_timestamp_flags {
+ IEEE80211_RADIOTAP_TIMESTAMP_FLAG_64BIT = 0x00,
+ IEEE80211_RADIOTAP_TIMESTAMP_FLAG_32BIT = 0x01,
+ IEEE80211_RADIOTAP_TIMESTAMP_FLAG_ACCURACY = 0x02,
+};
-/* helpers */
-static inline int ieee80211_get_radiotap_len(unsigned char *data)
+/**
+ * ieee80211_get_radiotap_len - get radiotap header length
+ */
+static inline u16 ieee80211_get_radiotap_len(const char *data)
{
- struct ieee80211_radiotap_header *hdr =
- (struct ieee80211_radiotap_header *)data;
+ struct ieee80211_radiotap_header *hdr = (void *)data;
return get_unaligned_le16(&hdr->it_len);
}
-#endif /* IEEE80211_RADIOTAP_H */
+#endif /* __RADIOTAP_H */
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index b0576cb2ab25..f656f9051aca 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -55,6 +55,7 @@ struct inet6_ifaddr {
__u8 stable_privacy_retry;
__u16 scope;
+ __u64 dad_nonce;
unsigned long cstamp; /* created timestamp */
unsigned long tstamp; /* updated timestamp */
@@ -204,7 +205,6 @@ struct inet6_dev {
__s32 rs_interval; /* in jiffies */
__u8 rs_probes;
- __u8 addr_gen_mode;
unsigned long tstamp; /* ipv6InterfaceTable update timestamp */
struct rcu_head rcu;
};
diff --git a/include/net/ife.h b/include/net/ife.h
new file mode 100644
index 000000000000..2d87d6898b0a
--- /dev/null
+++ b/include/net/ife.h
@@ -0,0 +1,51 @@
+#ifndef __NET_IFE_H
+#define __NET_IFE_H
+
+#include <linux/etherdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/module.h>
+#include <uapi/linux/ife.h>
+
+#if IS_ENABLED(CONFIG_NET_IFE)
+
+void *ife_encode(struct sk_buff *skb, u16 metalen);
+void *ife_decode(struct sk_buff *skb, u16 *metalen);
+
+void *ife_tlv_meta_decode(void *skbdata, u16 *attrtype, u16 *dlen, u16 *totlen);
+int ife_tlv_meta_encode(void *skbdata, u16 attrtype, u16 dlen,
+ const void *dval);
+
+void *ife_tlv_meta_next(void *skbdata);
+
+#else
+
+static inline void *ife_encode(struct sk_buff *skb, u16 metalen)
+{
+ return NULL;
+}
+
+static inline void *ife_decode(struct sk_buff *skb, u16 *metalen)
+{
+ return NULL;
+}
+
+static inline void *ife_tlv_meta_decode(void *skbdata, u16 *attrtype, u16 *dlen,
+ u16 *totlen)
+{
+ return NULL;
+}
+
+static inline int ife_tlv_meta_encode(void *skbdata, u16 attrtype, u16 dlen,
+ const void *dval)
+{
+ return 0;
+}
+
+static inline void *ife_tlv_meta_next(void *skbdata)
+{
+ return NULL;
+}
+
+#endif
+
+#endif /* __NET_IFE_H */
diff --git a/include/net/inet6_connection_sock.h b/include/net/inet6_connection_sock.h
index 954ad6bfb56a..8ec87b62257b 100644
--- a/include/net/inet6_connection_sock.h
+++ b/include/net/inet6_connection_sock.h
@@ -15,15 +15,11 @@
#include <linux/types.h>
-struct inet_bind_bucket;
struct request_sock;
struct sk_buff;
struct sock;
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(const struct sock *sk, struct flowi6 *fl6,
const struct request_sock *req, u8 proto);
diff --git a/include/net/inet_common.h b/include/net/inet_common.h
index 5d683428fced..f39ae697347f 100644
--- a/include/net/inet_common.h
+++ b/include/net/inet_common.h
@@ -17,10 +17,11 @@ int inet_release(struct socket *sock);
int inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
int addr_len, int flags);
int __inet_stream_connect(struct socket *sock, struct sockaddr *uaddr,
- int addr_len, int flags);
+ int addr_len, int flags, int is_sendmsg);
int inet_dgram_connect(struct socket *sock, struct sockaddr *uaddr,
int addr_len, int flags);
-int inet_accept(struct socket *sock, struct socket *newsock, int flags);
+int inet_accept(struct socket *sock, struct socket *newsock, int flags,
+ bool kern);
int inet_sendmsg(struct socket *sock, struct msghdr *msg, size_t size);
ssize_t inet_sendpage(struct socket *sock, struct page *page, int offset,
size_t size, int flags);
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index 197a30d221e9..c7a577976bec 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -62,8 +62,6 @@ struct inet_connection_sock_af_ops {
char __user *optval, int __user *optlen);
#endif
void (*addr2sockaddr)(struct sock *sk, struct sockaddr *);
- int (*bind_conflict)(const struct sock *sk,
- const struct inet_bind_bucket *tb, bool relax);
void (*mtu_reduced)(struct sock *sk);
};
@@ -143,6 +141,7 @@ struct inet_connection_sock {
#define ICSK_TIME_PROBE0 3 /* Zero window probe timer */
#define ICSK_TIME_EARLY_RETRANS 4 /* Early retransmit timer */
#define ICSK_TIME_LOSS_PROBE 5 /* Tail loss probe timer */
+#define ICSK_TIME_REO_TIMEOUT 6 /* Reordering timer */
static inline struct inet_connection_sock *inet_csk(const struct sock *sk)
{
@@ -233,7 +232,8 @@ static inline void inet_csk_reset_xmit_timer(struct sock *sk, const int what,
}
if (what == ICSK_TIME_RETRANS || what == ICSK_TIME_PROBE0 ||
- what == ICSK_TIME_EARLY_RETRANS || what == ICSK_TIME_LOSS_PROBE) {
+ what == ICSK_TIME_EARLY_RETRANS || what == ICSK_TIME_LOSS_PROBE ||
+ what == ICSK_TIME_REO_TIMEOUT) {
icsk->icsk_pending = what;
icsk->icsk_timeout = jiffies + when;
sk_reset_timer(sk, &icsk->icsk_retransmit_timer, icsk->icsk_timeout);
@@ -258,10 +258,8 @@ inet_csk_rto_backoff(const struct inet_connection_sock *icsk,
return (unsigned long)min_t(u64, when, max_when);
}
-struct sock *inet_csk_accept(struct sock *sk, int flags, int *err);
+struct sock *inet_csk_accept(struct sock *sk, int flags, int *err, bool kern);
-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(const struct sock *sk, struct flowi4 *fl4,
@@ -289,11 +287,6 @@ static inline int inet_csk_reqsk_queue_len(const struct sock *sk)
return reqsk_queue_len(&inet_csk(sk)->icsk_accept_queue);
}
-static inline int inet_csk_reqsk_queue_young(const struct sock *sk)
-{
- return reqsk_queue_len_young(&inet_csk(sk)->icsk_accept_queue);
-}
-
static inline int inet_csk_reqsk_queue_is_full(const struct sock *sk)
{
return inet_csk_reqsk_queue_len(sk) >= sk->sk_max_ack_backlog;
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index 909972aa3acd..5894730ec82a 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -164,13 +164,7 @@ static inline void add_frag_mem_limit(struct netns_frags *nf, int i)
static inline unsigned int sum_frag_mem_limit(struct netns_frags *nf)
{
- unsigned int res;
-
- local_bh_disable();
- res = percpu_counter_sum_positive(&nf->mem);
- local_bh_enable();
-
- return res;
+ return percpu_counter_sum_positive(&nf->mem);
}
/* RFC 3168 support :
diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
index 0574493e3899..1178931288cb 100644
--- a/include/net/inet_hashtables.h
+++ b/include/net/inet_hashtables.h
@@ -74,13 +74,21 @@ struct inet_ehash_bucket {
* users logged onto your box, isn't it nice to know that new data
* ports are created in O(1) time? I thought so. ;-) -DaveM
*/
+#define FASTREUSEPORT_ANY 1
+#define FASTREUSEPORT_STRICT 2
+
struct inet_bind_bucket {
possible_net_t ib_net;
unsigned short port;
signed char fastreuse;
signed char fastreuseport;
kuid_t fastuid;
- int num_owners;
+#if IS_ENABLED(CONFIG_IPV6)
+ struct in6_addr fast_v6_rcv_saddr;
+#endif
+ __be32 fast_rcv_saddr;
+ unsigned short fast_sk_family;
+ bool fast_ipv6_only;
struct hlist_node node;
struct hlist_head owners;
};
@@ -203,10 +211,7 @@ void inet_hashinfo_init(struct inet_hashinfo *h);
bool inet_ehash_insert(struct sock *sk, struct sock *osk);
bool inet_ehash_nolisten(struct sock *sk, struct sock *osk);
-int __inet_hash(struct sock *sk, struct sock *osk,
- int (*saddr_same)(const struct sock *sk1,
- const struct sock *sk2,
- bool match_wildcard));
+int __inet_hash(struct sock *sk, struct sock *osk);
int 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 236a81034fef..aa95053dfc78 100644
--- a/include/net/inet_sock.h
+++ b/include/net/inet_sock.h
@@ -206,7 +206,11 @@ struct inet_sock {
transparent:1,
mc_all:1,
nodefrag:1;
- __u8 bind_address_no_port:1;
+ __u8 bind_address_no_port:1,
+ defer_connect:1; /* Indicates that fastopen_connect is set
+ * and cookie exists so we defer connect
+ * until first data frame is written
+ */
__u8 rcv_tos;
__u8 convert_csum;
int uc_index;
@@ -228,6 +232,7 @@ struct inet_sock {
#define IP_CMSG_PASSSEC BIT(5)
#define IP_CMSG_ORIGDSTADDR BIT(6)
#define IP_CMSG_CHECKSUM BIT(7)
+#define IP_CMSG_RECVFRAGSIZE BIT(8)
/**
* sk_to_full_sk - Access to a full socket
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index c9b3eb70f340..6a75d67a30fd 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -29,16 +29,6 @@
#include <linux/atomic.h>
-struct inet_hashinfo;
-
-struct inet_timewait_death_row {
- atomic_t tw_count;
-
- struct inet_hashinfo *hashinfo ____cacheline_aligned_in_smp;
- int sysctl_tw_recycle;
- int sysctl_max_tw_buckets;
-};
-
struct inet_bind_bucket;
/*
@@ -125,8 +115,7 @@ static inline void inet_twsk_reschedule(struct inet_timewait_sock *tw, int timeo
void inet_twsk_deschedule_put(struct inet_timewait_sock *tw);
-void inet_twsk_purge(struct inet_hashinfo *hashinfo,
- struct inet_timewait_death_row *twdr, int family);
+void inet_twsk_purge(struct inet_hashinfo *hashinfo, int family);
static inline
struct net *twsk_net(const struct inet_timewait_sock *twsk)
diff --git a/include/net/ip.h b/include/net/ip.h
index d3a107850a41..bf264a8db1ce 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -178,6 +178,7 @@ struct ip_reply_arg {
/* -1 if not needed */
int bound_dev_if;
u8 tos;
+ kuid_t uid;
};
#define IP_REPLY_ARG_NOSRCCHECK 1
@@ -262,11 +263,21 @@ static inline bool sysctl_dev_name_is_allowed(const char *name)
return strcmp(name, "default") != 0 && strcmp(name, "all") != 0;
}
+static inline int inet_prot_sock(struct net *net)
+{
+ return net->ipv4.sysctl_ip_prot_sock;
+}
+
#else
static inline int inet_is_local_reserved_port(struct net *net, int port)
{
return 0;
}
+
+static inline int inet_prot_sock(struct net *net)
+{
+ return PROT_SOCK;
+}
#endif
__be32 inet_current_timestamp(void);
@@ -577,7 +588,8 @@ int ip_options_rcv_srr(struct sk_buff *skb);
*/
void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb);
-void ip_cmsg_recv_offset(struct msghdr *msg, struct sk_buff *skb, int tlen, int offset);
+void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk,
+ struct sk_buff *skb, int tlen, int offset);
int ip_cmsg_send(struct sock *sk, struct msghdr *msg,
struct ipcm_cookie *ipc, bool allow_ipv6);
int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
@@ -599,7 +611,7 @@ void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport,
static inline void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
{
- ip_cmsg_recv_offset(msg, skb, 0, 0);
+ ip_cmsg_recv_offset(msg, skb->sk, skb, 0, 0);
}
bool icmp_global_allow(void);
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index a74e2aa40ef4..c979c878df1c 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -37,7 +37,9 @@ struct fib6_config {
int fc_ifindex;
u32 fc_flags;
u32 fc_protocol;
- u32 fc_type; /* only 8 bits are used */
+ u16 fc_type; /* only 8 bits are used */
+ u16 fc_delete_all_nh : 1,
+ __unused : 15;
struct in6_addr fc_dst;
struct in6_addr fc_src;
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index f83e78d071a3..9dc2c182a263 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -140,9 +140,10 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
const struct in6_addr *gwaddr);
void ip6_update_pmtu(struct sk_buff *skb, struct net *net, __be32 mtu, int oif,
- u32 mark);
+ u32 mark, kuid_t uid);
void ip6_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, __be32 mtu);
-void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark);
+void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark,
+ kuid_t uid);
void ip6_redirect_no_header(struct sk_buff *skb, struct net *net, int oif,
u32 mark);
void ip6_sk_redirect(struct sk_buff *skb, struct sock *sk);
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index f390c3bb05c5..368bb4024b78 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -211,17 +211,26 @@ struct fib_entry_notifier_info {
u8 tos;
u8 type;
u32 tb_id;
- u32 nlflags;
+};
+
+struct fib_nh_notifier_info {
+ struct fib_notifier_info info; /* must be first */
+ struct fib_nh *fib_nh;
};
enum fib_event_type {
+ FIB_EVENT_ENTRY_REPLACE,
+ FIB_EVENT_ENTRY_APPEND,
FIB_EVENT_ENTRY_ADD,
FIB_EVENT_ENTRY_DEL,
FIB_EVENT_RULE_ADD,
FIB_EVENT_RULE_DEL,
+ FIB_EVENT_NH_ADD,
+ FIB_EVENT_NH_DEL,
};
-int register_fib_notifier(struct notifier_block *nb);
+int register_fib_notifier(struct notifier_block *nb,
+ void (*cb)(struct notifier_block *nb));
int unregister_fib_notifier(struct notifier_block *nb);
int call_fib_notifiers(struct net *net, enum fib_event_type event_type,
struct fib_notifier_info *info);
@@ -343,7 +352,6 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb);
int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
u8 tos, int oif, struct net_device *dev,
struct in_device *idev, u32 *itag);
-void fib_select_default(const struct flowi4 *flp, struct fib_result *res);
#ifdef CONFIG_IP_ROUTE_CLASSID
static inline int fib_num_tclassid_users(struct net *net)
{
@@ -397,6 +405,11 @@ static inline void fib_combine_itag(u32 *itag, const struct fib_result *res)
void free_fib_info(struct fib_info *fi);
+static inline void fib_info_hold(struct fib_info *fi)
+{
+ atomic_inc(&fi->fib_clntref);
+}
+
static inline void fib_info_put(struct fib_info *fi)
{
if (atomic_dec_and_test(&fi->fib_clntref))
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index 59557c07904b..95056796657c 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -58,6 +58,7 @@ struct ip_tunnel_key {
/* Flags for ip_tunnel_info mode. */
#define IP_TUNNEL_INFO_TX 0x01 /* represents tx tunnel parameters */
#define IP_TUNNEL_INFO_IPV6 0x02 /* key contains IPv6 addresses */
+#define IP_TUNNEL_INFO_BRIDGE 0x04 /* represents a bridged tunnel id */
/* Maximum tunnel options length. */
#define IP_TUNNEL_OPTS_MAX \
@@ -129,7 +130,7 @@ struct ip_tunnel {
#endif
struct ip_tunnel_prl_entry __rcu *prl; /* potential router list */
unsigned int prl_count; /* # of entries in PRL */
- int ip_tnl_net_id;
+ unsigned int ip_tnl_net_id;
struct gro_cells gro_cells;
bool collect_md;
bool ignore_df;
@@ -248,7 +249,7 @@ void ip_tunnel_uninit(struct net_device *dev);
void ip_tunnel_dellink(struct net_device *dev, struct list_head *head);
struct net *ip_tunnel_get_link_net(const struct net_device *dev);
int ip_tunnel_get_iflink(const struct net_device *dev);
-int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id,
+int ip_tunnel_init_net(struct net *net, unsigned int ip_tnl_net_id,
struct rtnl_link_ops *ops, char *devname);
void ip_tunnel_delete_net(struct ip_tunnel_net *itn, struct rtnl_link_ops *ops);
@@ -261,8 +262,8 @@ int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd);
int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict);
int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu);
-struct rtnl_link_stats64 *ip_tunnel_get_stats64(struct net_device *dev,
- struct rtnl_link_stats64 *tot);
+void ip_tunnel_get_stats64(struct net_device *dev,
+ struct rtnl_link_stats64 *tot);
struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn,
int link, __be16 flags,
__be32 remote, __be32 local,
@@ -275,7 +276,7 @@ int ip_tunnel_changelink(struct net_device *dev, struct nlattr *tb[],
struct ip_tunnel_parm *p);
int ip_tunnel_newlink(struct net_device *dev, struct nlattr *tb[],
struct ip_tunnel_parm *p);
-void ip_tunnel_setup(struct net_device *dev, int net_id);
+void ip_tunnel_setup(struct net_device *dev, unsigned int net_id);
struct ip_tunnel_encap_ops {
size_t (*encap_hlen)(struct ip_tunnel_encap *e);
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index cd6018a9ee24..7bdfa7d78363 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -1421,7 +1421,7 @@ static inline void ip_vs_dest_put(struct ip_vs_dest *dest)
static inline void ip_vs_dest_put_and_free(struct ip_vs_dest *dest)
{
- if (atomic_dec_return(&dest->refcnt) < 0)
+ if (atomic_dec_and_test(&dest->refcnt))
kfree(dest);
}
@@ -1554,10 +1554,12 @@ static inline void ip_vs_notrack(struct sk_buff *skb)
struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
if (!ct || !nf_ct_is_untracked(ct)) {
- nf_conntrack_put(skb->nfct);
- skb->nfct = &nf_ct_untracked_get()->ct_general;
- skb->nfctinfo = IP_CT_NEW;
- nf_conntrack_get(skb->nfct);
+ struct nf_conn *untracked;
+
+ nf_conntrack_put(&ct->ct_general);
+ untracked = nf_ct_untracked_get();
+ nf_conntrack_get(&untracked->ct_general);
+ nf_ct_set(skb, untracked, IP_CT_NEW);
}
#endif
}
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index f11ca837361b..dbf0abba33b8 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -776,6 +776,11 @@ static inline __be32 ip6_make_flowlabel(struct net *net, struct sk_buff *skb,
{
u32 hash;
+ /* @flowlabel may include more than a flow label, eg, the traffic class.
+ * Here we want only the flow label value.
+ */
+ flowlabel &= IPV6_FLOWLABEL_MASK;
+
if (flowlabel ||
net->ipv6.sysctl.auto_flowlabels == IP6_AUTO_FLOW_LABEL_OFF ||
(!autolabel &&
@@ -871,7 +876,7 @@ int ip6_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
* upper-layer output functions
*/
int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
- struct ipv6_txoptions *opt, int tclass);
+ __u32 mark, struct ipv6_txoptions *opt, int tclass);
int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr);
@@ -932,7 +937,8 @@ int ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
*/
void ipv6_push_nfrag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
- u8 *proto, struct in6_addr **daddr_p);
+ u8 *proto, struct in6_addr **daddr_p,
+ struct in6_addr *saddr);
void ipv6_push_frag_opts(struct sk_buff *skb, struct ipv6_txoptions *opt,
u8 *proto);
diff --git a/include/net/irda/timer.h b/include/net/irda/timer.h
index cb2615ccf761..d784f242cf7b 100644
--- a/include/net/irda/timer.h
+++ b/include/net/irda/timer.h
@@ -59,7 +59,7 @@ struct lap_cb;
* Slot timer must never exceed 85 ms, and must always be at least 25 ms,
* suggested to 75-85 msec by IrDA lite. This doesn't work with a lot of
* devices, and other stackes uses a lot more, so it's best we do it as well
- * (Note : this is the default value and sysctl overides it - Jean II)
+ * (Note : this is the default value and sysctl overrides it - Jean II)
*/
#define SLOT_TIMEOUT (90*HZ/1000)
diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h
index e0f4109e64c6..2509728650bd 100644
--- a/include/net/iw_handler.h
+++ b/include/net/iw_handler.h
@@ -505,25 +505,8 @@ static inline int iwe_stream_event_len_adjust(struct iw_request_info *info,
/*
* Wrapper to add an Wireless Event to a stream of events.
*/
-static inline char *
-iwe_stream_add_event(struct iw_request_info *info, char *stream, char *ends,
- struct iw_event *iwe, int event_len)
-{
- int lcp_len = iwe_stream_lcp_len(info);
-
- event_len = iwe_stream_event_len_adjust(info, event_len);
-
- /* Check if it's possible */
- if(likely((stream + event_len) < ends)) {
- iwe->len = event_len;
- /* Beware of alignement issues on 64 bits */
- memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
- memcpy(stream + lcp_len, &iwe->u,
- event_len - lcp_len);
- stream += event_len;
- }
- return stream;
-}
+char *iwe_stream_add_event(struct iw_request_info *info, char *stream,
+ char *ends, struct iw_event *iwe, int event_len);
static inline char *
iwe_stream_add_event_check(struct iw_request_info *info, char *stream,
@@ -541,26 +524,8 @@ iwe_stream_add_event_check(struct iw_request_info *info, char *stream,
* Wrapper to add an short Wireless Event containing a pointer to a
* stream of events.
*/
-static inline char *
-iwe_stream_add_point(struct iw_request_info *info, char *stream, char *ends,
- struct iw_event *iwe, char *extra)
-{
- int event_len = iwe_stream_point_len(info) + iwe->u.data.length;
- int point_len = iwe_stream_point_len(info);
- int lcp_len = iwe_stream_lcp_len(info);
-
- /* Check if it's possible */
- if(likely((stream + event_len) < ends)) {
- iwe->len = event_len;
- memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
- memcpy(stream + lcp_len,
- ((char *) &iwe->u) + IW_EV_POINT_OFF,
- IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
- memcpy(stream + point_len, extra, iwe->u.data.length);
- stream += event_len;
- }
- return stream;
-}
+char *iwe_stream_add_point(struct iw_request_info *info, char *stream,
+ char *ends, struct iw_event *iwe, char *extra);
static inline char *
iwe_stream_add_point_check(struct iw_request_info *info, char *stream,
@@ -579,25 +544,8 @@ iwe_stream_add_point_check(struct iw_request_info *info, char *stream,
* Be careful, this one is tricky to use properly :
* At the first run, you need to have (value = event + IW_EV_LCP_LEN).
*/
-static inline char *
-iwe_stream_add_value(struct iw_request_info *info, char *event, char *value,
- char *ends, struct iw_event *iwe, int event_len)
-{
- int lcp_len = iwe_stream_lcp_len(info);
-
- /* Don't duplicate LCP */
- event_len -= IW_EV_LCP_LEN;
-
- /* Check if it's possible */
- if(likely((value + event_len) < ends)) {
- /* Add new value */
- memcpy(value, &iwe->u, event_len);
- value += event_len;
- /* Patch LCP */
- iwe->len = value - event;
- memcpy(event, (char *) iwe, lcp_len);
- }
- return value;
-}
+char *iwe_stream_add_value(struct iw_request_info *info, char *event,
+ char *value, char *ends, struct iw_event *iwe,
+ int event_len);
#endif /* _IW_HANDLER_H */
diff --git a/include/net/lwtunnel.h b/include/net/lwtunnel.h
index ea3f80f58fd6..ebfe237aad7e 100644
--- a/include/net/lwtunnel.h
+++ b/include/net/lwtunnel.h
@@ -24,18 +24,19 @@ enum {
struct lwtunnel_state {
__u16 type;
__u16 flags;
+ __u16 headroom;
atomic_t refcnt;
int (*orig_output)(struct net *net, struct sock *sk, struct sk_buff *skb);
int (*orig_input)(struct sk_buff *);
- int len;
- __u16 headroom;
+ struct rcu_head rcu;
__u8 data[0];
};
struct lwtunnel_encap_ops {
- int (*build_state)(struct net_device *dev, struct nlattr *encap,
+ int (*build_state)(struct nlattr *encap,
unsigned int family, const void *cfg,
struct lwtunnel_state **ts);
+ void (*destroy_state)(struct lwtunnel_state *lws);
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,
@@ -43,13 +44,12 @@ struct lwtunnel_encap_ops {
int (*get_encap_size)(struct lwtunnel_state *lwtstate);
int (*cmp_encap)(struct lwtunnel_state *a, struct lwtunnel_state *b);
int (*xmit)(struct sk_buff *skb);
+
+ struct module *owner;
};
#ifdef CONFIG_LWTUNNEL
-static inline void lwtstate_free(struct lwtunnel_state *lws)
-{
- kfree(lws);
-}
+void lwtstate_free(struct lwtunnel_state *lws);
static inline struct lwtunnel_state *
lwtstate_get(struct lwtunnel_state *lws)
@@ -96,7 +96,8 @@ static inline bool lwtunnel_xmit_redirect(struct lwtunnel_state *lwtstate)
static inline unsigned int lwtunnel_headroom(struct lwtunnel_state *lwtstate,
unsigned int mtu)
{
- if (lwtunnel_xmit_redirect(lwtstate) && lwtstate->headroom < mtu)
+ if ((lwtunnel_xmit_redirect(lwtstate) ||
+ lwtunnel_output_redirect(lwtstate)) && lwtstate->headroom < mtu)
return lwtstate->headroom;
return 0;
@@ -106,7 +107,9 @@ int lwtunnel_encap_add_ops(const struct lwtunnel_encap_ops *op,
unsigned int num);
int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
unsigned int num);
-int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
+int lwtunnel_valid_encap_type(u16 encap_type);
+int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len);
+int lwtunnel_build_state(u16 encap_type,
struct nlattr *encap,
unsigned int family, const void *cfg,
struct lwtunnel_state **lws);
@@ -169,7 +172,19 @@ static inline int lwtunnel_encap_del_ops(const struct lwtunnel_encap_ops *op,
return -EOPNOTSUPP;
}
-static inline int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
+static inline int lwtunnel_valid_encap_type(u16 encap_type)
+{
+ return -EOPNOTSUPP;
+}
+static inline int lwtunnel_valid_encap_type_attr(struct nlattr *attr, int len)
+{
+ /* return 0 since we are not walking attr looking for
+ * RTA_ENCAP_TYPE attribute on nexthops.
+ */
+ return 0;
+}
+
+static inline int lwtunnel_build_state(u16 encap_type,
struct nlattr *encap,
unsigned int family, const void *cfg,
struct lwtunnel_state **lws)
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index e2dba93e374f..a3bab3c5ecfb 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -147,7 +147,6 @@ enum ieee80211_ac_numbers {
IEEE80211_AC_BE = 2,
IEEE80211_AC_BK = 3,
};
-#define IEEE80211_NUM_ACS 4
/**
* struct ieee80211_tx_queue_params - transmit queue configuration
@@ -1018,7 +1017,7 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
* @RX_FLAG_DECRYPTED: This frame was decrypted in hardware.
* @RX_FLAG_MMIC_STRIPPED: the Michael MIC is stripped off this frame,
* verification has been done by the hardware.
- * @RX_FLAG_IV_STRIPPED: The IV/ICV are stripped from this frame.
+ * @RX_FLAG_IV_STRIPPED: The IV and ICV are stripped from this frame.
* If this flag is set, the stack cannot do any replay detection
* hence the driver or hardware will have to do that.
* @RX_FLAG_PN_VALIDATED: Currently only valid for CCMP/GCMP frames, this
@@ -1089,6 +1088,8 @@ ieee80211_tx_info_clear_status(struct ieee80211_tx_info *info)
* @RX_FLAG_ALLOW_SAME_PN: Allow the same PN as same packet before.
* This is used for AMSDU subframes which can have the same PN as
* the first subframe.
+ * @RX_FLAG_ICV_STRIPPED: The ICV is stripped from this frame. CRC checking must
+ * be done in the hardware.
*/
enum mac80211_rx_flags {
RX_FLAG_MMIC_ERROR = BIT(0),
@@ -1124,6 +1125,7 @@ enum mac80211_rx_flags {
RX_FLAG_RADIOTAP_VENDOR_DATA = BIT(31),
RX_FLAG_MIC_STRIPPED = BIT_ULL(32),
RX_FLAG_ALLOW_SAME_PN = BIT_ULL(33),
+ RX_FLAG_ICV_STRIPPED = BIT_ULL(34),
};
#define RX_FLAG_STBC_SHIFT 26
@@ -1442,7 +1444,7 @@ enum ieee80211_vif_flags {
struct ieee80211_vif {
enum nl80211_iftype type;
struct ieee80211_bss_conf bss_conf;
- u8 addr[ETH_ALEN];
+ u8 addr[ETH_ALEN] __aligned(2);
bool p2p;
bool csa_active;
bool mu_mimo_owner;
@@ -1749,7 +1751,8 @@ struct ieee80211_sta_rates {
* @drv_priv: data area for driver use, will always be aligned to
* sizeof(void \*), size is determined in hw information.
* @uapsd_queues: bitmap of queues configured for uapsd. Only valid
- * if wme is supported.
+ * if wme is supported. The bits order is like in
+ * IEEE80211_WMM_IE_STA_QOSINFO_AC_*.
* @max_sp: max Service Period. Only valid if wme is supported.
* @bandwidth: current bandwidth the station can receive with
* @rx_nss: in HT/VHT, the maximum number of spatial streams the
@@ -1765,15 +1768,6 @@ struct ieee80211_sta_rates {
* @max_amsdu_subframes: indicates the maximal number of MSDUs in a single
* A-MSDU. Taken from the Extended Capabilities element. 0 means
* unlimited.
- * @max_amsdu_len: indicates the maximal length of an A-MSDU in bytes. This
- * field is always valid for packets with a VHT preamble. For packets
- * with a HT preamble, additional limits apply:
- * + If the skb is transmitted as part of a BA agreement, the
- * A-MSDU maximal size is min(max_amsdu_len, 4065) bytes.
- * + If the skb is not part of a BA aggreement, the A-MSDU maximal
- * size is min(max_amsdu_len, 7935) bytes.
- * Both additional HT limits must be enforced by the low level driver.
- * This is defined by the spec (IEEE 802.11-2012 section 8.3.2.2 NOTE 2).
* @support_p2p_ps: indicates whether the STA supports P2P PS mechanism or not.
* @max_rc_amsdu_len: Maximum A-MSDU size in bytes recommended by rate control.
* @txq: per-TID data TX queues (if driver uses the TXQ abstraction)
@@ -1796,6 +1790,22 @@ struct ieee80211_sta {
bool tdls_initiator;
bool mfp;
u8 max_amsdu_subframes;
+
+ /**
+ * @max_amsdu_len:
+ * indicates the maximal length of an A-MSDU in bytes.
+ * This field is always valid for packets with a VHT preamble.
+ * For packets with a HT preamble, additional limits apply:
+ *
+ * * If the skb is transmitted as part of a BA agreement, the
+ * A-MSDU maximal size is min(max_amsdu_len, 4065) bytes.
+ * * If the skb is not part of a BA aggreement, the A-MSDU maximal
+ * size is min(max_amsdu_len, 7935) bytes.
+ *
+ * Both additional HT limits must be enforced by the low level
+ * driver. This is defined by the spec (IEEE 802.11-2012 section
+ * 8.3.2.2 NOTE 2).
+ */
u16 max_amsdu_len;
bool support_p2p_ps;
u16 max_rc_amsdu_len;
@@ -2029,6 +2039,10 @@ struct ieee80211_txq {
* drivers, mac80211 packet loss mechanism will not be triggered and driver
* is completely depending on firmware event for station kickout.
*
+ * @IEEE80211_HW_SUPPORTS_TX_FRAG: Hardware does fragmentation by itself.
+ * The stack will not do fragmentation.
+ * The callback for @set_frag_threshold should be set as well.
+ *
* @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays
*/
enum ieee80211_hw_flags {
@@ -2070,6 +2084,7 @@ enum ieee80211_hw_flags {
IEEE80211_HW_TX_AMSDU,
IEEE80211_HW_TX_FRAG_LIST,
IEEE80211_HW_REPORTS_LOW_ACK,
+ IEEE80211_HW_SUPPORTS_TX_FRAG,
/* keep last, obviously */
NUM_IEEE80211_HW_FLAGS
@@ -3098,8 +3113,9 @@ enum ieee80211_reconfig_type {
* The callback must be atomic.
*
* @set_frag_threshold: Configuration of fragmentation threshold. Assign this
- * if the device does fragmentation by itself; if this callback is
- * implemented then the stack will not do fragmentation.
+ * if the device does fragmentation by itself. Note that to prevent the
+ * stack from doing fragmentation IEEE80211_HW_SUPPORTS_TX_FRAG
+ * should be set as well.
* The callback can sleep.
*
* @set_rts_threshold: Configuration of RTS threshold (if device needs it)
@@ -3194,26 +3210,6 @@ enum ieee80211_reconfig_type {
* Returns non-zero if this device sent the last beacon.
* The callback can sleep.
*
- * @ampdu_action: Perform a certain A-MPDU action
- * The RA/TID combination determines the destination and TID we want
- * the ampdu action to be performed for. The action is defined through
- * ieee80211_ampdu_mlme_action.
- * When the action is set to %IEEE80211_AMPDU_TX_OPERATIONAL the driver
- * may neither send aggregates containing more subframes than @buf_size
- * nor send aggregates in a way that lost frames would exceed the
- * buffer size. If just limiting the aggregate size, this would be
- * possible with a buf_size of 8:
- * - TX: 1.....7
- * - RX: 2....7 (lost frame #1)
- * - TX: 8..1...
- * which is invalid since #1 was now re-transmitted well past the
- * 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.
- *
- * Returns a negative error code on failure.
- * The callback can sleep.
- *
* @get_survey: Return per-channel survey information
*
* @rfkill_poll: Poll rfkill hardware state. If you need this, you also
@@ -3396,7 +3392,7 @@ enum ieee80211_reconfig_type {
* since there won't be any time to beacon before the switch anyway.
* @pre_channel_switch: This is an optional callback that is called
* before a channel switch procedure is started (ie. when a STA
- * gets a CSA or an userspace initiated channel-switch), allowing
+ * gets a CSA or a userspace initiated channel-switch), allowing
* the driver to prepare for the channel switch.
* @post_channel_switch: This is an optional callback that is called
* after a channel switch procedure is completed, allowing the
@@ -3566,6 +3562,35 @@ struct ieee80211_ops {
s64 offset);
void (*reset_tsf)(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
int (*tx_last_beacon)(struct ieee80211_hw *hw);
+
+ /**
+ * @ampdu_action:
+ * Perform a certain A-MPDU action.
+ * The RA/TID combination determines the destination and TID we want
+ * the ampdu action to be performed for. The action is defined through
+ * ieee80211_ampdu_mlme_action.
+ * When the action is set to %IEEE80211_AMPDU_TX_OPERATIONAL the driver
+ * may neither send aggregates containing more subframes than @buf_size
+ * nor send aggregates in a way that lost frames would exceed the
+ * buffer size. If just limiting the aggregate size, this would be
+ * possible with a buf_size of 8:
+ *
+ * - ``TX: 1.....7``
+ * - ``RX: 2....7`` (lost frame #1)
+ * - ``TX: 8..1...``
+ *
+ * which is invalid since #1 was now re-transmitted well past the
+ * buffer size of 8. Correct ways to retransmit #1 would be:
+ *
+ * - ``TX: 1 or``
+ * - ``TX: 18 or``
+ * - ``TX: 81``
+ *
+ * Even ``189`` would be wrong since 1 could be lost again.
+ *
+ * Returns a negative error code on failure.
+ * The callback can sleep.
+ */
int (*ampdu_action)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_ampdu_params *params);
@@ -4092,6 +4117,10 @@ void ieee80211_sta_pspoll(struct ieee80211_sta *sta);
* This must be used in conjunction with ieee80211_sta_ps_transition()
* and possibly ieee80211_sta_pspoll(); calls to all three must be
* serialized.
+ * %IEEE80211_NUM_TIDS can be passed as the tid if the tid is unknown.
+ * In this case, mac80211 will not check that this tid maps to an AC
+ * that is trigger enabled and assume that the caller did the proper
+ * checks.
*/
void ieee80211_sta_uapsd_trigger(struct ieee80211_sta *sta, u8 tid);
@@ -5249,6 +5278,7 @@ void ieee80211_resume_disconnect(struct ieee80211_vif *vif);
*
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
* @rssi_event: the RSSI trigger event type
+ * @rssi_level: new RSSI level value or 0 if not available
* @gfp: context flags
*
* When the %IEEE80211_VIF_SUPPORTS_CQM_RSSI is set, and a connection quality
@@ -5257,6 +5287,7 @@ void ieee80211_resume_disconnect(struct ieee80211_vif *vif);
*/
void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif,
enum nl80211_cqm_rssi_threshold_event rssi_event,
+ s32 rssi_level,
gfp_t gfp);
/**
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index be1fe2283254..8a0214654b6b 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -31,6 +31,7 @@ enum {
ND_OPT_PREFIX_INFO = 3, /* RFC2461 */
ND_OPT_REDIRECT_HDR = 4, /* RFC2461 */
ND_OPT_MTU = 5, /* RFC2461 */
+ ND_OPT_NONCE = 14, /* RFC7527 */
__ND_OPT_ARRAY_MAX,
ND_OPT_ROUTE_INFO = 24, /* RFC4191 */
ND_OPT_RDNSS = 25, /* RFC5006 */
@@ -121,6 +122,7 @@ struct ndisc_options {
#define nd_opts_pi_end nd_opt_array[__ND_OPT_PREFIX_INFO_END]
#define nd_opts_rh nd_opt_array[ND_OPT_REDIRECT_HDR]
#define nd_opts_mtu nd_opt_array[ND_OPT_MTU]
+#define nd_opts_nonce nd_opt_array[ND_OPT_NONCE]
#define nd_802154_opts_src_lladdr nd_802154_opt_array[ND_OPT_SOURCE_LL_ADDR]
#define nd_802154_opts_tgt_lladdr nd_802154_opt_array[ND_OPT_TARGET_LL_ADDR]
@@ -389,6 +391,23 @@ static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, cons
return n;
}
+static inline void __ipv6_confirm_neigh(struct net_device *dev,
+ const void *pkey)
+{
+ struct neighbour *n;
+
+ rcu_read_lock_bh();
+ n = __ipv6_neigh_lookup_noref(dev, pkey);
+ if (n) {
+ unsigned long now = jiffies;
+
+ /* avoid dirtying neighbour */
+ if (n->confirmed != now)
+ n->confirmed = now;
+ }
+ rcu_read_unlock_bh();
+}
+
int ndisc_init(void);
int ndisc_late_init(void);
@@ -398,7 +417,8 @@ void ndisc_cleanup(void);
int ndisc_rcv(struct sk_buff *skb);
void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit,
- const struct in6_addr *daddr, const struct in6_addr *saddr);
+ const struct in6_addr *daddr, const struct in6_addr *saddr,
+ u64 nonce);
void ndisc_send_rs(struct net_device *dev,
const struct in6_addr *saddr, const struct in6_addr *daddr);
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index 8b683841e574..5ebf69491160 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -468,6 +468,16 @@ static inline int neigh_hh_output(const struct hh_cache *hh, struct sk_buff *skb
return dev_queue_xmit(skb);
}
+static inline int neigh_output(struct neighbour *n, struct sk_buff *skb)
+{
+ const struct hh_cache *hh = &n->hh;
+
+ if ((n->nud_state & NUD_CONNECTED) && hh->hh_len)
+ return neigh_hh_output(hh, skb);
+ else
+ return n->output(n, skb);
+}
+
static inline struct neighbour *
__neigh_lookup(struct neigh_table *tbl, const void *pkey, struct net_device *dev, int creat)
{
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 0940598c002f..af8fe8a909dc 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -291,7 +291,7 @@ struct pernet_operations {
int (*init)(struct net *net);
void (*exit)(struct net *net);
void (*exit_batch)(struct list_head *net_exit_list);
- int *id;
+ unsigned int *id;
size_t size;
};
diff --git a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
index 981c327374da..6ff32815641b 100644
--- a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
+++ b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h
@@ -14,7 +14,17 @@ extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4;
extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4;
extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4;
+extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4;
extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp;
+#ifdef CONFIG_NF_CT_PROTO_DCCP
+extern struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4;
+#endif
+#ifdef CONFIG_NF_CT_PROTO_SCTP
+extern struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4;
+#endif
+#ifdef CONFIG_NF_CT_PROTO_UDPLITE
+extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4;
+#endif
int nf_conntrack_ipv4_compat_init(void);
void nf_conntrack_ipv4_compat_fini(void);
diff --git a/include/net/netfilter/ipv4/nf_defrag_ipv4.h b/include/net/netfilter/ipv4/nf_defrag_ipv4.h
index f01ef208dff6..db405f70e538 100644
--- a/include/net/netfilter/ipv4/nf_defrag_ipv4.h
+++ b/include/net/netfilter/ipv4/nf_defrag_ipv4.h
@@ -1,6 +1,7 @@
#ifndef _NF_DEFRAG_IPV4_H
#define _NF_DEFRAG_IPV4_H
-void nf_defrag_ipv4_enable(void);
+struct net;
+int nf_defrag_ipv4_enable(struct net *);
#endif /* _NF_DEFRAG_IPV4_H */
diff --git a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
index a4c993685795..c59b82456f89 100644
--- a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
+++ b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h
@@ -5,7 +5,17 @@ extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6;
extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6;
extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6;
+extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6;
extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6;
+#ifdef CONFIG_NF_CT_PROTO_DCCP
+extern struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6;
+#endif
+#ifdef CONFIG_NF_CT_PROTO_SCTP
+extern struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6;
+#endif
+#ifdef CONFIG_NF_CT_PROTO_UDPLITE
+extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6;
+#endif
#include <linux/sysctl.h>
extern struct ctl_table nf_ct_ipv6_sysctl_table[];
diff --git a/include/net/netfilter/ipv6/nf_defrag_ipv6.h b/include/net/netfilter/ipv6/nf_defrag_ipv6.h
index ddf162f7966f..7664efe37974 100644
--- a/include/net/netfilter/ipv6/nf_defrag_ipv6.h
+++ b/include/net/netfilter/ipv6/nf_defrag_ipv6.h
@@ -1,7 +1,8 @@
#ifndef _NF_DEFRAG_IPV6_H
#define _NF_DEFRAG_IPV6_H
-void nf_defrag_ipv6_enable(void);
+struct net;
+int nf_defrag_ipv6_enable(struct net *);
int nf_ct_frag6_init(void);
void nf_ct_frag6_cleanup(void);
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index d9d52c020a70..19605878da47 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -34,6 +34,7 @@ union nf_conntrack_proto {
struct ip_ct_sctp sctp;
struct ip_ct_tcp tcp;
struct nf_ct_gre gre;
+ unsigned int tmpl_padto;
};
union nf_conntrack_expect_proto {
@@ -75,7 +76,7 @@ struct nf_conn {
/* Usage count in here is 1 for hash table, 1 per skb,
* plus 1 for any connection(s) we are `master' for
*
- * Hint, SKB address this struct and refcnt via skb->nfct and
+ * Hint, SKB address this struct and refcnt via skb->_nfct and
* helpers nf_conntrack_get() and nf_conntrack_put().
* Helper nf_ct_put() equals nf_conntrack_put() by dec refcnt,
* beware nf_ct_get() is different and don't inc refcnt.
@@ -162,12 +163,16 @@ void nf_conntrack_alter_reply(struct nf_conn *ct,
int nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
const struct nf_conn *ignored_conntrack);
+#define NFCT_INFOMASK 7UL
+#define NFCT_PTRMASK ~(NFCT_INFOMASK)
+
/* Return conntrack_info and tuple hash for given skb. */
static inline struct nf_conn *
nf_ct_get(const struct sk_buff *skb, enum ip_conntrack_info *ctinfo)
{
- *ctinfo = skb->nfctinfo;
- return (struct nf_conn *)skb->nfct;
+ *ctinfo = skb->_nfct & NFCT_INFOMASK;
+
+ return (struct nf_conn *)(skb->_nfct & NFCT_PTRMASK);
}
/* decrement reference count on a conntrack */
@@ -181,6 +186,10 @@ static inline void nf_ct_put(struct nf_conn *ct)
int nf_ct_l3proto_try_module_get(unsigned short l3proto);
void nf_ct_l3proto_module_put(unsigned short l3proto);
+/* load module; enable/disable conntrack in this namespace */
+int nf_ct_netns_get(struct net *net, u8 nfproto);
+void nf_ct_netns_put(struct net *net, u8 nfproto);
+
/*
* Allocate a hashtable of hlist_head (if nulls == 0),
* or hlist_nulls_head (if nulls == 1)
@@ -235,7 +244,7 @@ extern s32 (*nf_ct_nat_offset)(const struct nf_conn *ct,
u32 seq);
/* Fake conntrack entry for untracked connections */
-DECLARE_PER_CPU(struct nf_conn, nf_conntrack_untracked);
+DECLARE_PER_CPU_ALIGNED(struct nf_conn, nf_conntrack_untracked);
static inline struct nf_conn *nf_ct_untracked_get(void)
{
return raw_cpu_ptr(&nf_conntrack_untracked);
@@ -337,6 +346,12 @@ struct nf_conn *nf_ct_tmpl_alloc(struct net *net,
gfp_t flags);
void nf_ct_tmpl_free(struct nf_conn *tmpl);
+static inline void
+nf_ct_set(struct sk_buff *skb, struct nf_conn *ct, enum ip_conntrack_info info)
+{
+ skb->_nfct = (unsigned long)ct | info;
+}
+
#define NF_CT_STAT_INC(net, count) __this_cpu_inc((net)->ct.stat->count)
#define NF_CT_STAT_INC_ATOMIC(net, count) this_cpu_inc((net)->ct.stat->count)
#define NF_CT_STAT_ADD_ATOMIC(net, count, v) this_cpu_add((net)->ct.stat->count, (v))
diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
index 62e17d1319ff..84ec7ca5f195 100644
--- a/include/net/netfilter/nf_conntrack_core.h
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -62,7 +62,7 @@ int __nf_conntrack_confirm(struct sk_buff *skb);
/* Confirm a connection: returns NF_DROP if packet must be dropped. */
static inline int nf_conntrack_confirm(struct sk_buff *skb)
{
- struct nf_conn *ct = (struct nf_conn *)skb->nfct;
+ struct nf_conn *ct = (struct nf_conn *)skb_nfct(skb);
int ret = NF_ACCEPT;
if (ct && !nf_ct_is_untracked(ct)) {
diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h
index 8992e4229da9..e01559b4d781 100644
--- a/include/net/netfilter/nf_conntrack_l3proto.h
+++ b/include/net/netfilter/nf_conntrack_l3proto.h
@@ -52,6 +52,10 @@ struct nf_conntrack_l3proto {
int (*tuple_to_nlattr)(struct sk_buff *skb,
const struct nf_conntrack_tuple *t);
+ /* Called when netns wants to use connection tracking */
+ int (*net_ns_get)(struct net *);
+ void (*net_ns_put)(struct net *);
+
/*
* Calculate size of tuple nlattr
*/
@@ -63,18 +67,24 @@ struct nf_conntrack_l3proto {
size_t nla_size;
- /* Init l3proto pernet data */
- int (*init_net)(struct net *net);
-
/* Module (if any) which this is connected to. */
struct module *me;
};
extern struct nf_conntrack_l3proto __rcu *nf_ct_l3protos[AF_MAX];
+#ifdef CONFIG_SYSCTL
/* Protocol pernet registration. */
int nf_ct_l3proto_pernet_register(struct net *net,
struct nf_conntrack_l3proto *proto);
+#else
+static inline int nf_ct_l3proto_pernet_register(struct net *n,
+ struct nf_conntrack_l3proto *p)
+{
+ return 0;
+}
+#endif
+
void nf_ct_l3proto_pernet_unregister(struct net *net,
struct nf_conntrack_l3proto *proto);
diff --git a/include/net/netfilter/nf_conntrack_l4proto.h b/include/net/netfilter/nf_conntrack_l4proto.h
index de629f1520df..85e993e278d5 100644
--- a/include/net/netfilter/nf_conntrack_l4proto.h
+++ b/include/net/netfilter/nf_conntrack_l4proto.h
@@ -55,7 +55,7 @@ struct nf_conntrack_l4proto {
void (*destroy)(struct nf_conn *ct);
int (*error)(struct net *net, struct nf_conn *tmpl, struct sk_buff *skb,
- unsigned int dataoff, enum ip_conntrack_info *ctinfo,
+ unsigned int dataoff,
u_int8_t pf, unsigned int hooknum);
/* Print out the per-protocol part of the tuple. Return like seq_* */
@@ -98,7 +98,7 @@ struct nf_conntrack_l4proto {
const struct nla_policy *nla_policy;
} ctnl_timeout;
#endif
- int *net_id;
+ unsigned int *net_id;
/* Init l4proto pernet data */
int (*init_net)(struct net *net, u_int16_t proto);
@@ -125,14 +125,24 @@ struct nf_conntrack_l4proto *nf_ct_l4proto_find_get(u_int16_t l3proto,
void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p);
/* Protocol pernet registration. */
+int nf_ct_l4proto_pernet_register_one(struct net *net,
+ struct nf_conntrack_l4proto *proto);
+void nf_ct_l4proto_pernet_unregister_one(struct net *net,
+ struct nf_conntrack_l4proto *proto);
int nf_ct_l4proto_pernet_register(struct net *net,
- struct nf_conntrack_l4proto *proto);
+ struct nf_conntrack_l4proto *proto[],
+ unsigned int num_proto);
void nf_ct_l4proto_pernet_unregister(struct net *net,
- struct nf_conntrack_l4proto *proto);
+ struct nf_conntrack_l4proto *proto[],
+ unsigned int num_proto);
/* Protocol global registration. */
-int nf_ct_l4proto_register(struct nf_conntrack_l4proto *proto);
-void nf_ct_l4proto_unregister(struct nf_conntrack_l4proto *proto);
+int nf_ct_l4proto_register_one(struct nf_conntrack_l4proto *proto);
+void nf_ct_l4proto_unregister_one(struct nf_conntrack_l4proto *proto);
+int nf_ct_l4proto_register(struct nf_conntrack_l4proto *proto[],
+ unsigned int num_proto);
+void nf_ct_l4proto_unregister(struct nf_conntrack_l4proto *proto[],
+ unsigned int num_proto);
/* Generic netlink helpers */
int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb,
diff --git a/include/net/netfilter/nf_conntrack_synproxy.h b/include/net/netfilter/nf_conntrack_synproxy.h
index e6937318546c..b0ca402c1f72 100644
--- a/include/net/netfilter/nf_conntrack_synproxy.h
+++ b/include/net/netfilter/nf_conntrack_synproxy.h
@@ -54,7 +54,7 @@ struct synproxy_net {
struct synproxy_stats __percpu *stats;
};
-extern int synproxy_net_id;
+extern unsigned int synproxy_net_id;
static inline struct synproxy_net *synproxy_pernet(struct net *net)
{
return net_generic(net, synproxy_net_id);
diff --git a/include/net/netfilter/nf_dup_netdev.h b/include/net/netfilter/nf_dup_netdev.h
index 397dcae349f9..3e919356bedf 100644
--- a/include/net/netfilter/nf_dup_netdev.h
+++ b/include/net/netfilter/nf_dup_netdev.h
@@ -2,5 +2,6 @@
#define _NF_DUP_NETDEV_H_
void nf_dup_netdev_egress(const struct nft_pktinfo *pkt, int oif);
+void nf_fwd_netdev_egress(const struct nft_pktinfo *pkt, int oif);
#endif
diff --git a/include/net/netfilter/nf_log.h b/include/net/netfilter/nf_log.h
index 309cd267be4f..42e0696f38d8 100644
--- a/include/net/netfilter/nf_log.h
+++ b/include/net/netfilter/nf_log.h
@@ -51,6 +51,9 @@ struct nf_logger {
struct module *me;
};
+/* sysctl_nf_log_all_netns - allow LOG target in all network namespaces */
+extern int sysctl_nf_log_all_netns;
+
/* Function to register/unregister log function. */
int nf_log_register(u_int8_t pf, struct nf_logger *logger);
void nf_log_unregister(struct nf_logger *logger);
@@ -109,5 +112,12 @@ void nf_log_dump_packet_common(struct nf_log_buf *m, u_int8_t pf,
const struct net_device *out,
const struct nf_loginfo *loginfo,
const char *prefix);
+void nf_log_l2packet(struct net *net, u_int8_t pf,
+ __be16 protocol,
+ unsigned int hooknum,
+ const struct sk_buff *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ const struct nf_loginfo *loginfo, const char *prefix);
#endif /* _NF_LOG_H */
diff --git a/include/net/netfilter/nf_nat_l4proto.h b/include/net/netfilter/nf_nat_l4proto.h
index 12f4cc841b6e..3923150f2a1e 100644
--- a/include/net/netfilter/nf_nat_l4proto.h
+++ b/include/net/netfilter/nf_nat_l4proto.h
@@ -54,6 +54,15 @@ extern const struct nf_nat_l4proto nf_nat_l4proto_udp;
extern const struct nf_nat_l4proto nf_nat_l4proto_icmp;
extern const struct nf_nat_l4proto nf_nat_l4proto_icmpv6;
extern const struct nf_nat_l4proto nf_nat_l4proto_unknown;
+#ifdef CONFIG_NF_NAT_PROTO_DCCP
+extern const struct nf_nat_l4proto nf_nat_l4proto_dccp;
+#endif
+#ifdef CONFIG_NF_NAT_PROTO_SCTP
+extern const struct nf_nat_l4proto nf_nat_l4proto_sctp;
+#endif
+#ifdef CONFIG_NF_NAT_PROTO_UDPLITE
+extern const struct nf_nat_l4proto nf_nat_l4proto_udplite;
+#endif
bool nf_nat_l4proto_in_range(const struct nf_conntrack_tuple *tuple,
enum nf_nat_manip_type maniptype,
diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h
index 2280cfe86c56..09948d10e38e 100644
--- a/include/net/netfilter/nf_queue.h
+++ b/include/net/netfilter/nf_queue.h
@@ -12,6 +12,7 @@ struct nf_queue_entry {
unsigned int id;
struct nf_hook_state state;
+ struct nf_hook_entry *hook;
u16 size; /* sizeof(entry) + saved route keys */
/* extra space to store route keys */
diff --git a/include/net/netfilter/nf_socket.h b/include/net/netfilter/nf_socket.h
new file mode 100644
index 000000000000..f2fc39c97d43
--- /dev/null
+++ b/include/net/netfilter/nf_socket.h
@@ -0,0 +1,27 @@
+#ifndef _NF_SOCK_H_
+#define _NF_SOCK_H_
+
+struct net_device;
+struct sk_buff;
+struct sock;
+struct net;
+
+static inline bool nf_sk_is_transparent(struct sock *sk)
+{
+ switch (sk->sk_state) {
+ case TCP_TIME_WAIT:
+ return inet_twsk(sk)->tw_transparent;
+ case TCP_NEW_SYN_RECV:
+ return inet_rsk(inet_reqsk(sk))->no_srccheck;
+ default:
+ return inet_sk(sk)->transparent;
+ }
+}
+
+struct sock *nf_sk_lookup_slow_v4(struct net *net, const struct sk_buff *skb,
+ const struct net_device *indev);
+
+struct sock *nf_sk_lookup_slow_v6(struct net *net, const struct sk_buff *skb,
+ const struct net_device *indev);
+
+#endif
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index b02af0bf5777..0136028652bd 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -14,27 +14,43 @@
struct nft_pktinfo {
struct sk_buff *skb;
- struct net *net;
- const struct net_device *in;
- const struct net_device *out;
- u8 pf;
- u8 hook;
bool tprot_set;
u8 tprot;
/* for x_tables compatibility */
struct xt_action_param xt;
};
+static inline struct net *nft_net(const struct nft_pktinfo *pkt)
+{
+ return pkt->xt.state->net;
+}
+
+static inline unsigned int nft_hook(const struct nft_pktinfo *pkt)
+{
+ return pkt->xt.state->hook;
+}
+
+static inline u8 nft_pf(const struct nft_pktinfo *pkt)
+{
+ return pkt->xt.state->pf;
+}
+
+static inline const struct net_device *nft_in(const struct nft_pktinfo *pkt)
+{
+ return pkt->xt.state->in;
+}
+
+static inline const struct net_device *nft_out(const struct nft_pktinfo *pkt)
+{
+ return pkt->xt.state->out;
+}
+
static inline void nft_set_pktinfo(struct nft_pktinfo *pkt,
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->hook = pkt->xt.hooknum = state->hook;
- pkt->pf = pkt->xt.family = state->pf;
+ pkt->xt.state = state;
}
static inline void nft_set_pktinfo_proto_unspec(struct nft_pktinfo *pkt,
@@ -87,6 +103,35 @@ struct nft_regs {
};
};
+/* Store/load an u16 or u8 integer to/from the u32 data register.
+ *
+ * Note, when using concatenations, register allocation happens at 32-bit
+ * level. So for store instruction, pad the rest part with zero to avoid
+ * garbage values.
+ */
+
+static inline void nft_reg_store16(u32 *dreg, u16 val)
+{
+ *dreg = 0;
+ *(u16 *)dreg = val;
+}
+
+static inline void nft_reg_store8(u32 *dreg, u8 val)
+{
+ *dreg = 0;
+ *(u8 *)dreg = val;
+}
+
+static inline u16 nft_reg_load16(u32 *sreg)
+{
+ return *(u16 *)sreg;
+}
+
+static inline u8 nft_reg_load8(u32 *sreg)
+{
+ return *(u8 *)sreg;
+}
+
static inline void nft_data_copy(u32 *dst, const struct nft_data *src,
unsigned int len)
{
@@ -191,9 +236,9 @@ struct nft_set_iter {
unsigned int skip;
int err;
int (*fn)(const struct nft_ctx *ctx,
- const struct nft_set *set,
+ struct nft_set *set,
const struct nft_set_iter *iter,
- const struct nft_set_elem *elem);
+ struct nft_set_elem *elem);
};
/**
@@ -227,11 +272,13 @@ enum nft_set_class {
* characteristics
*
* @size: required memory
- * @class: lookup performance class
+ * @lookup: lookup performance class
+ * @space: memory class
*/
struct nft_set_estimate {
unsigned int size;
- enum nft_set_class class;
+ enum nft_set_class lookup;
+ enum nft_set_class space;
};
struct nft_set_ext;
@@ -243,7 +290,8 @@ struct nft_expr;
* @lookup: look up an element within the set
* @insert: insert new element into set
* @activate: activate new element in the next generation
- * @deactivate: deactivate element in the next generation
+ * @deactivate: lookup for element and deactivate it in the next generation
+ * @flush: deactivate element in the next generation
* @remove: remove element from set
* @walk: iterate over all set elemeennts
* @privsize: function to return size of set private data
@@ -278,10 +326,14 @@ struct nft_set_ops {
void * (*deactivate)(const struct net *net,
const struct nft_set *set,
const struct nft_set_elem *elem);
- void (*remove)(const struct nft_set *set,
+ bool (*flush)(const struct net *net,
+ const struct nft_set *set,
+ void *priv);
+ void (*remove)(const struct net *net,
+ const struct nft_set *set,
const struct nft_set_elem *elem);
void (*walk)(const struct nft_ctx *ctx,
- const struct nft_set *set,
+ struct nft_set *set,
struct nft_set_iter *iter);
unsigned int (*privsize)(const struct nlattr * const nla[]);
@@ -310,6 +362,7 @@ void nft_unregister_set(struct nft_set_ops *ops);
* @name: name of the set
* @ktype: key type (numeric type defined by userspace, not used in the kernel)
* @dtype: data type (verdict or numeric type defined by userspace)
+ * @objtype: object type (see NFT_OBJECT_* definitions)
* @size: maximum set size
* @nelems: number of elements
* @ndeact: number of deactivated elements queued for removal
@@ -331,6 +384,7 @@ struct nft_set {
char name[NFT_SET_MAXNAMELEN];
u32 ktype;
u32 dtype;
+ u32 objtype;
u32 size;
atomic_t nelems;
u32 ndeact;
@@ -400,6 +454,7 @@ void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
* @NFT_SET_EXT_EXPIRATION: element expiration time
* @NFT_SET_EXT_USERDATA: user data associated with the element
* @NFT_SET_EXT_EXPR: expression assiociated with the element
+ * @NFT_SET_EXT_OBJREF: stateful object reference associated with element
* @NFT_SET_EXT_NUM: number of extension types
*/
enum nft_set_extensions {
@@ -410,6 +465,7 @@ enum nft_set_extensions {
NFT_SET_EXT_EXPIRATION,
NFT_SET_EXT_USERDATA,
NFT_SET_EXT_EXPR,
+ NFT_SET_EXT_OBJREF,
NFT_SET_EXT_NUM
};
@@ -538,6 +594,11 @@ static inline struct nft_set_ext *nft_set_elem_ext(const struct nft_set *set,
return elem + set->ops->elemsize;
}
+static inline struct nft_object **nft_set_ext_obj(const struct nft_set_ext *ext)
+{
+ return nft_set_ext(ext, NFT_SET_EXT_OBJREF);
+}
+
void *nft_set_elem_init(const struct nft_set *set,
const struct nft_set_ext_tmpl *tmpl,
const u32 *key, const u32 *data,
@@ -859,6 +920,7 @@ unsigned int nft_do_chain(struct nft_pktinfo *pkt, void *priv);
* @list: used internally
* @chains: chains in the table
* @sets: sets in the table
+ * @objects: stateful objects in the table
* @hgenerator: handle generator state
* @use: number of chain references to this table
* @flags: table flag (see enum nft_table_flags)
@@ -869,6 +931,7 @@ struct nft_table {
struct list_head list;
struct list_head chains;
struct list_head sets;
+ struct list_head objects;
u64 hgenerator;
u32 use;
u16 flags:14,
@@ -919,6 +982,80 @@ int nft_verdict_dump(struct sk_buff *skb, int type,
const struct nft_verdict *v);
/**
+ * struct nft_object - nf_tables stateful object
+ *
+ * @list: table stateful object list node
+ * @table: table this object belongs to
+ * @type: pointer to object type
+ * @data: pointer to object data
+ * @name: name of this stateful object
+ * @genmask: generation mask
+ * @use: number of references to this stateful object
+ * @data: object data, layout depends on type
+ */
+struct nft_object {
+ struct list_head list;
+ char name[NFT_OBJ_MAXNAMELEN];
+ struct nft_table *table;
+ u32 genmask:2,
+ use:30;
+ /* runtime data below here */
+ const struct nft_object_type *type ____cacheline_aligned;
+ unsigned char data[]
+ __attribute__((aligned(__alignof__(u64))));
+};
+
+static inline void *nft_obj_data(const struct nft_object *obj)
+{
+ return (void *)obj->data;
+}
+
+#define nft_expr_obj(expr) *((struct nft_object **)nft_expr_priv(expr))
+
+struct nft_object *nf_tables_obj_lookup(const struct nft_table *table,
+ const struct nlattr *nla, u32 objtype,
+ u8 genmask);
+
+void nft_obj_notify(struct net *net, struct nft_table *table,
+ struct nft_object *obj, u32 portid, u32 seq,
+ int event, int family, int report, gfp_t gfp);
+
+/**
+ * struct nft_object_type - stateful object type
+ *
+ * @eval: stateful object evaluation function
+ * @list: list node in list of object types
+ * @type: stateful object numeric type
+ * @size: stateful object size
+ * @owner: module owner
+ * @maxattr: maximum netlink attribute
+ * @policy: netlink attribute policy
+ * @init: initialize object from netlink attributes
+ * @destroy: release existing stateful object
+ * @dump: netlink dump stateful object
+ */
+struct nft_object_type {
+ void (*eval)(struct nft_object *obj,
+ struct nft_regs *regs,
+ const struct nft_pktinfo *pkt);
+ struct list_head list;
+ u32 type;
+ unsigned int size;
+ unsigned int maxattr;
+ struct module *owner;
+ const struct nla_policy *policy;
+ int (*init)(const struct nlattr * const tb[],
+ struct nft_object *obj);
+ void (*destroy)(struct nft_object *obj);
+ int (*dump)(struct sk_buff *skb,
+ struct nft_object *obj,
+ bool reset);
+};
+
+int nft_register_obj(struct nft_object_type *obj_type);
+void nft_unregister_obj(struct nft_object_type *obj_type);
+
+/**
* struct nft_traceinfo - nft tracing information and state
*
* @pkt: pktinfo currently processed
@@ -965,6 +1102,9 @@ void nft_trace_notify(struct nft_traceinfo *info);
#define MODULE_ALIAS_NFT_SET() \
MODULE_ALIAS("nft-set")
+#define MODULE_ALIAS_NFT_OBJ(type) \
+ MODULE_ALIAS("nft-obj-" __stringify(type))
+
/*
* The gencursor defines two generations, the currently active and the
* next one. Objects contain a bitmask of 2 bits specifying the generations
@@ -1090,10 +1230,13 @@ struct nft_trans {
struct nft_trans_rule {
struct nft_rule *rule;
+ u32 rule_id;
};
#define nft_trans_rule(trans) \
(((struct nft_trans_rule *)trans->data)->rule)
+#define nft_trans_rule_id(trans) \
+ (((struct nft_trans_rule *)trans->data)->rule_id)
struct nft_trans_set {
struct nft_set *set;
@@ -1141,4 +1284,11 @@ struct nft_trans_elem {
#define nft_trans_elem(trans) \
(((struct nft_trans_elem *)trans->data)->elem)
+struct nft_trans_obj {
+ struct nft_object *obj;
+};
+
+#define nft_trans_obj(trans) \
+ (((struct nft_trans_obj *)trans->data)->obj)
+
#endif /* _NET_NF_TABLES_H */
diff --git a/include/net/netfilter/nf_tables_core.h b/include/net/netfilter/nf_tables_core.h
index 00f4f6b1b1ba..8f690effec37 100644
--- a/include/net/netfilter/nf_tables_core.h
+++ b/include/net/netfilter/nf_tables_core.h
@@ -1,12 +1,18 @@
#ifndef _NET_NF_TABLES_CORE_H
#define _NET_NF_TABLES_CORE_H
+extern struct nft_expr_type nft_imm_type;
+extern struct nft_expr_type nft_cmp_type;
+extern struct nft_expr_type nft_lookup_type;
+extern struct nft_expr_type nft_bitwise_type;
+extern struct nft_expr_type nft_byteorder_type;
+extern struct nft_expr_type nft_payload_type;
+extern struct nft_expr_type nft_dynset_type;
+extern struct nft_expr_type nft_range_type;
+
int nf_tables_core_module_init(void);
void nf_tables_core_module_exit(void);
-int nft_immediate_module_init(void);
-void nft_immediate_module_exit(void);
-
struct nft_cmp_fast_expr {
u32 data;
enum nft_registers sreg:8;
@@ -25,24 +31,6 @@ static inline u32 nft_cmp_fast_mask(unsigned int len)
extern const struct nft_expr_ops nft_cmp_fast_ops;
-int nft_cmp_module_init(void);
-void nft_cmp_module_exit(void);
-
-int nft_range_module_init(void);
-void nft_range_module_exit(void);
-
-int nft_lookup_module_init(void);
-void nft_lookup_module_exit(void);
-
-int nft_dynset_module_init(void);
-void nft_dynset_module_exit(void);
-
-int nft_bitwise_module_init(void);
-void nft_bitwise_module_exit(void);
-
-int nft_byteorder_module_init(void);
-void nft_byteorder_module_exit(void);
-
struct nft_payload {
enum nft_payload_bases base:8;
u8 offset;
@@ -57,12 +45,10 @@ struct nft_payload_set {
enum nft_registers sreg:8;
u8 csum_type;
u8 csum_offset;
+ u8 csum_flags;
};
extern const struct nft_expr_ops nft_payload_fast_ops;
extern struct static_key_false nft_trace_enabled;
-int nft_payload_module_init(void);
-void nft_payload_module_exit(void);
-
#endif /* _NET_NF_TABLES_CORE_H */
diff --git a/include/net/netfilter/nf_tables_ipv6.h b/include/net/netfilter/nf_tables_ipv6.h
index d150b5066201..97983d1c05e4 100644
--- a/include/net/netfilter/nf_tables_ipv6.h
+++ b/include/net/netfilter/nf_tables_ipv6.h
@@ -9,12 +9,13 @@ nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
+ unsigned int flags = IP6_FH_F_AUTH;
int protohdr, thoff = 0;
unsigned short frag_off;
nft_set_pktinfo(pkt, skb, state);
- protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, NULL);
+ protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, &flags);
if (protohdr < 0) {
nft_set_pktinfo_proto_unspec(pkt, skb);
return;
@@ -32,6 +33,7 @@ __nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt,
const struct nf_hook_state *state)
{
#if IS_ENABLED(CONFIG_IPV6)
+ unsigned int flags = IP6_FH_F_AUTH;
struct ipv6hdr *ip6h, _ip6h;
unsigned int thoff = 0;
unsigned short frag_off;
@@ -50,7 +52,7 @@ __nft_set_pktinfo_ipv6_validate(struct nft_pktinfo *pkt,
if (pkt_len + sizeof(*ip6h) > skb->len)
return -1;
- protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, NULL);
+ protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, &flags);
if (protohdr < 0)
return -1;
diff --git a/include/net/netfilter/nft_fib.h b/include/net/netfilter/nft_fib.h
new file mode 100644
index 000000000000..5ceb2205e4e3
--- /dev/null
+++ b/include/net/netfilter/nft_fib.h
@@ -0,0 +1,37 @@
+#ifndef _NFT_FIB_H_
+#define _NFT_FIB_H_
+
+struct nft_fib {
+ enum nft_registers dreg:8;
+ u8 result;
+ u32 flags;
+};
+
+extern const struct nla_policy nft_fib_policy[];
+
+static inline bool
+nft_fib_is_loopback(const struct sk_buff *skb, const struct net_device *in)
+{
+ return skb->pkt_type == PACKET_LOOPBACK || in->flags & IFF_LOOPBACK;
+}
+
+int nft_fib_dump(struct sk_buff *skb, const struct nft_expr *expr);
+int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
+ const struct nlattr * const tb[]);
+int nft_fib_validate(const struct nft_ctx *ctx, const struct nft_expr *expr,
+ const struct nft_data **data);
+
+
+void nft_fib4_eval_type(const struct nft_expr *expr, struct nft_regs *regs,
+ const struct nft_pktinfo *pkt);
+void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
+ const struct nft_pktinfo *pkt);
+
+void nft_fib6_eval_type(const struct nft_expr *expr, struct nft_regs *regs,
+ const struct nft_pktinfo *pkt);
+void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
+ const struct nft_pktinfo *pkt);
+
+void nft_fib_store_result(void *reg, enum nft_fib_result r,
+ const struct nft_pktinfo *pkt, int index);
+#endif
diff --git a/include/net/netfilter/xt_rateest.h b/include/net/netfilter/xt_rateest.h
index 79f45e19f31e..130e58361f99 100644
--- a/include/net/netfilter/xt_rateest.h
+++ b/include/net/netfilter/xt_rateest.h
@@ -1,19 +1,23 @@
#ifndef _XT_RATEEST_H
#define _XT_RATEEST_H
+#include <net/gen_stats.h>
+
struct xt_rateest {
/* keep lock and bstats on same cache line to speedup xt_rateest_tg() */
struct gnet_stats_basic_packed bstats;
spinlock_t lock;
- /* keep rstats and lock on same cache line to speedup xt_rateest_mt() */
- struct gnet_stats_rate_est64 rstats;
+
/* following fields not accessed in hot path */
+ unsigned int refcnt;
struct hlist_node list;
char name[IFNAMSIZ];
- unsigned int refcnt;
struct gnet_estimator params;
struct rcu_head rcu;
+
+ /* keep this field far away to speedup xt_rateest_mt() */
+ struct net_rate_estimator __rcu *rate_est;
};
struct xt_rateest *xt_rateest_lookup(const char *name);
diff --git a/include/net/netlink.h b/include/net/netlink.h
index 254a0fc01800..b239fcd33d80 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -229,6 +229,7 @@ struct nl_info {
struct nlmsghdr *nlh;
struct net *nl_net;
u32 portid;
+ bool skip_notify;
};
int netlink_rcv_skb(struct sk_buff *skb,
@@ -713,7 +714,7 @@ static inline int nla_ok(const struct nlattr *nla, int remaining)
*/
static inline struct nlattr *nla_next(const struct nlattr *nla, int *remaining)
{
- int totlen = NLA_ALIGN(nla->nla_len);
+ unsigned int totlen = NLA_ALIGN(nla->nla_len);
*remaining -= totlen;
return (struct nlattr *) ((char *) nla + totlen);
@@ -1191,6 +1192,16 @@ static inline struct in6_addr nla_get_in6_addr(const struct nlattr *nla)
}
/**
+ * nla_memdup - duplicate attribute memory (kmemdup)
+ * @src: netlink attribute to duplicate from
+ * @gfp: GFP mask
+ */
+static inline void *nla_memdup(const struct nlattr *src, gfp_t gfp)
+{
+ return kmemdup(nla_data(src), nla_len(src), gfp);
+}
+
+/**
* nla_nest_start - Start a new level of nested attributes
* @skb: socket buffer to add attributes to
* @attrtype: attribute type of container
diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h
index e469e85de3f9..17724c62de97 100644
--- a/include/net/netns/conntrack.h
+++ b/include/net/netns/conntrack.h
@@ -6,6 +6,12 @@
#include <linux/atomic.h>
#include <linux/workqueue.h>
#include <linux/netfilter/nf_conntrack_tcp.h>
+#ifdef CONFIG_NF_CT_PROTO_DCCP
+#include <linux/netfilter/nf_conntrack_dccp.h>
+#endif
+#ifdef CONFIG_NF_CT_PROTO_SCTP
+#include <linux/netfilter/nf_conntrack_sctp.h>
+#endif
#include <linux/seqlock.h>
struct ctl_table_header;
@@ -48,12 +54,33 @@ struct nf_icmp_net {
unsigned int timeout;
};
+#ifdef CONFIG_NF_CT_PROTO_DCCP
+struct nf_dccp_net {
+ struct nf_proto_net pn;
+ int dccp_loose;
+ unsigned int dccp_timeout[CT_DCCP_MAX + 1];
+};
+#endif
+
+#ifdef CONFIG_NF_CT_PROTO_SCTP
+struct nf_sctp_net {
+ struct nf_proto_net pn;
+ unsigned int timeouts[SCTP_CONNTRACK_MAX];
+};
+#endif
+
struct nf_ip_net {
struct nf_generic_net generic;
struct nf_tcp_net tcp;
struct nf_udp_net udp;
struct nf_icmp_net icmp;
struct nf_icmp_net icmpv6;
+#ifdef CONFIG_NF_CT_PROTO_DCCP
+ struct nf_dccp_net dccp;
+#endif
+#ifdef CONFIG_NF_CT_PROTO_SCTP
+ struct nf_sctp_net sctp;
+#endif
};
struct ct_pcpu {
@@ -91,7 +118,6 @@ struct netns_ct {
struct nf_ip_net nf_ct_proto;
#if defined(CONFIG_NF_CONNTRACK_LABELS)
unsigned int labels_used;
- u8 label_words;
#endif
};
#endif
diff --git a/include/net/netns/generic.h b/include/net/netns/generic.h
index 70e158551704..f15daaa89385 100644
--- a/include/net/netns/generic.h
+++ b/include/net/netns/generic.h
@@ -25,20 +25,24 @@
*/
struct net_generic {
- unsigned int len;
- struct rcu_head rcu;
-
- void *ptr[0];
+ union {
+ struct {
+ unsigned int len;
+ struct rcu_head rcu;
+ } s;
+
+ void *ptr[0];
+ };
};
-static inline void *net_generic(const struct net *net, int id)
+static inline void *net_generic(const struct net *net, unsigned int id)
{
struct net_generic *ng;
void *ptr;
rcu_read_lock();
ng = rcu_dereference(net->gen);
- ptr = ng->ptr[id - 1];
+ ptr = ng->ptr[id];
rcu_read_unlock();
return ptr;
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 7adf4386ac8f..622d2da27135 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -27,6 +27,16 @@ struct ping_group_range {
kgid_t range[2];
};
+struct inet_hashinfo;
+
+struct inet_timewait_death_row {
+ atomic_t tw_count;
+
+ struct inet_hashinfo *hashinfo ____cacheline_aligned_in_smp;
+ int sysctl_tw_recycle;
+ int sysctl_max_tw_buckets;
+};
+
struct netns_ipv4 {
#ifdef CONFIG_SYSCTL
struct ctl_table_header *forw_hdr;
@@ -110,6 +120,13 @@ struct netns_ipv4 {
int sysctl_tcp_orphan_retries;
int sysctl_tcp_fin_timeout;
unsigned int sysctl_tcp_notsent_lowat;
+ int sysctl_tcp_tw_reuse;
+ struct inet_timewait_death_row tcp_death_row;
+ int sysctl_max_syn_backlog;
+
+#ifdef CONFIG_NET_L3_MASTER_DEV
+ int sysctl_udp_l3mdev_accept;
+#endif
int sysctl_igmp_max_memberships;
int sysctl_igmp_max_msf;
@@ -122,6 +139,7 @@ struct netns_ipv4 {
#ifdef CONFIG_SYSCTL
unsigned long *sysctl_local_reserved_ports;
+ int sysctl_ip_prot_sock;
#endif
#ifdef CONFIG_IP_MROUTE
@@ -135,6 +153,9 @@ struct netns_ipv4 {
#ifdef CONFIG_IP_ROUTE_MULTIPATH
int sysctl_fib_multipath_use_neigh;
#endif
+
+ unsigned int fib_seq; /* protected by rtnl_mutex */
+
atomic_t rt_genid;
};
#endif
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 10d0848f5b8a..de7745e2edcc 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -85,6 +85,7 @@ struct netns_ipv6 {
#endif
atomic_t dev_addr_genid;
atomic_t fib6_sernum;
+ struct seg6_pernet_data *seg6_data;
};
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
diff --git a/include/net/netns/netfilter.h b/include/net/netns/netfilter.h
index 58487b1cc99a..cea396b53a60 100644
--- a/include/net/netns/netfilter.h
+++ b/include/net/netns/netfilter.h
@@ -17,5 +17,11 @@ struct netns_nf {
struct ctl_table_header *nf_log_dir_header;
#endif
struct nf_hook_entry __rcu *hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS];
+#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4)
+ bool defrag_ipv4;
+#endif
+#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
+ bool defrag_ipv6;
+#endif
};
#endif
diff --git a/include/net/netns/sctp.h b/include/net/netns/sctp.h
index c501d67172b1..b7871d018354 100644
--- a/include/net/netns/sctp.h
+++ b/include/net/netns/sctp.h
@@ -118,6 +118,9 @@ struct netns_sctp {
/* Flag to indicate if PR-SCTP is enabled. */
int prsctp_enable;
+ /* Flag to indicate if PR-CONFIG is enabled. */
+ int reconf_enable;
+
/* Flag to idicate if SCTP-AUTH is enabled */
int auth_enable;
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index 767b03a3fe67..269fd78bb0ae 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -17,6 +17,14 @@ struct tcf_walker {
int register_tcf_proto_ops(struct tcf_proto_ops *ops);
int unregister_tcf_proto_ops(struct tcf_proto_ops *ops);
+#ifdef CONFIG_NET_CLS
+void tcf_destroy_chain(struct tcf_proto __rcu **fl);
+#else
+static inline void tcf_destroy_chain(struct tcf_proto __rcu **fl)
+{
+}
+#endif
+
static inline unsigned long
__cls_set_class(unsigned long *clp, unsigned long cl)
{
@@ -171,6 +179,8 @@ void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
struct tcf_exts *src);
int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts);
int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts);
+int tcf_exts_get_dev(struct net_device *dev, struct tcf_exts *exts,
+ struct net_device **hw_dev);
/**
* struct tcf_pkt_info - packet information
@@ -425,16 +435,14 @@ struct tc_cls_u32_offload {
};
};
-static inline bool tc_should_offload(const struct net_device *dev,
- const struct tcf_proto *tp, u32 flags)
+static inline bool tc_can_offload(const struct net_device *dev,
+ const struct tcf_proto *tp)
{
const struct Qdisc *sch = tp->q;
const struct Qdisc_class_ops *cops = sch->ops->cl_ops;
if (!(dev->features & NETIF_F_HW_TC))
return false;
- if (flags & TCA_CLS_FLAGS_SKIP_HW)
- return false;
if (!dev->netdev_ops->ndo_setup_tc)
return false;
if (cops && cops->tcf_cl_offload)
@@ -443,6 +451,19 @@ static inline bool tc_should_offload(const struct net_device *dev,
return true;
}
+static inline bool tc_skip_hw(u32 flags)
+{
+ return (flags & TCA_CLS_FLAGS_SKIP_HW) ? true : false;
+}
+
+static inline bool tc_should_offload(const struct net_device *dev,
+ const struct tcf_proto *tp, u32 flags)
+{
+ if (tc_skip_hw(flags))
+ return false;
+ return tc_can_offload(dev, tp);
+}
+
static inline bool tc_skip_sw(u32 flags)
{
return (flags & TCA_CLS_FLAGS_SKIP_SW) ? true : false;
@@ -460,6 +481,11 @@ static inline bool tc_flags_valid(u32 flags)
return true;
}
+static inline bool tc_in_hw(u32 flags)
+{
+ return (flags & TCA_CLS_FLAGS_IN_HW) ? true : false;
+}
+
enum tc_fl_command {
TC_CLSFLOWER_REPLACE,
TC_CLSFLOWER_DESTROY,
@@ -468,6 +494,7 @@ enum tc_fl_command {
struct tc_cls_flower_offload {
enum tc_fl_command command;
+ u32 prio;
unsigned long cookie;
struct flow_dissector *dissector;
struct fl_flow_key *mask;
@@ -502,4 +529,12 @@ struct tc_cls_bpf_offload {
u32 gen_flags;
};
+
+/* This structure holds cookie structure that is passed from user
+ * to the kernel for actions and classifiers
+ */
+struct tc_cookie {
+ u8 *data;
+ u32 len;
+};
#endif
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index cd334c9584e9..f1b76b8e6d2d 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -6,6 +6,8 @@
#include <linux/if_vlan.h>
#include <net/sch_generic.h>
+#define DEFAULT_TX_QUEUE_LEN 1000
+
struct qdisc_walker {
int stop;
int skip;
diff --git a/include/net/psample.h b/include/net/psample.h
new file mode 100644
index 000000000000..8888b0e1a82e
--- /dev/null
+++ b/include/net/psample.h
@@ -0,0 +1,36 @@
+#ifndef __NET_PSAMPLE_H
+#define __NET_PSAMPLE_H
+
+#include <uapi/linux/psample.h>
+#include <linux/module.h>
+#include <linux/list.h>
+
+struct psample_group {
+ struct list_head list;
+ struct net *net;
+ u32 group_num;
+ u32 refcount;
+ u32 seq;
+};
+
+struct psample_group *psample_group_get(struct net *net, u32 group_num);
+void psample_group_put(struct psample_group *group);
+
+#if IS_ENABLED(CONFIG_PSAMPLE)
+
+void psample_sample_packet(struct psample_group *group, struct sk_buff *skb,
+ u32 trunc_size, int in_ifindex, int out_ifindex,
+ u32 sample_rate);
+
+#else
+
+static inline void psample_sample_packet(struct psample_group *group,
+ struct sk_buff *skb, u32 trunc_size,
+ int in_ifindex, int out_ifindex,
+ u32 sample_rate)
+{
+}
+
+#endif
+
+#endif /* __NET_PSAMPLE_H */
diff --git a/include/net/raw.h b/include/net/raw.h
index 3e789008394d..57c33dd22ec4 100644
--- a/include/net/raw.h
+++ b/include/net/raw.h
@@ -23,6 +23,12 @@
extern struct proto raw_prot;
+extern struct raw_hashinfo raw_v4_hashinfo;
+struct sock *__raw_v4_lookup(struct net *net, struct sock *sk,
+ unsigned short num, __be32 raddr,
+ __be32 laddr, int dif);
+
+int raw_abort(struct sock *sk, int err);
void raw_icmp_error(struct sk_buff *, int, u32);
int raw_local_deliver(struct sk_buff *, int);
diff --git a/include/net/rawv6.h b/include/net/rawv6.h
index 87783dea0791..cbe4e9de1894 100644
--- a/include/net/rawv6.h
+++ b/include/net/rawv6.h
@@ -3,6 +3,13 @@
#include <net/protocol.h>
+extern struct raw_hashinfo raw_v6_hashinfo;
+struct sock *__raw_v6_lookup(struct net *net, struct sock *sk,
+ unsigned short num, const struct in6_addr *loc_addr,
+ const struct in6_addr *rmt_addr, int dif);
+
+int raw_abort(struct sock *sk, int err);
+
void raw6_icmp_error(struct sk_buff *, int nexthdr,
u8 type, u8 code, int inner_offset, __be32);
bool raw6_local_deliver(struct sk_buff *, int);
diff --git a/include/net/red.h b/include/net/red.h
index 76e0b5f922c6..208e718e16b9 100644
--- a/include/net/red.h
+++ b/include/net/red.h
@@ -207,7 +207,7 @@ static inline void red_set_parms(struct red_parms *p,
static inline int red_is_idling(const struct red_vars *v)
{
- return v->qidlestart.tv64 != 0;
+ return v->qidlestart != 0;
}
static inline void red_start_of_idle_period(struct red_vars *v)
@@ -217,7 +217,7 @@ static inline void red_start_of_idle_period(struct red_vars *v)
static inline void red_end_of_idle_period(struct red_vars *v)
{
- v->qidlestart.tv64 = 0;
+ v->qidlestart = 0;
}
static inline void red_restart(struct red_vars *v)
diff --git a/include/net/request_sock.h b/include/net/request_sock.h
index 6ebe13eb1c4c..a12a5d25b27e 100644
--- a/include/net/request_sock.h
+++ b/include/net/request_sock.h
@@ -1,7 +1,7 @@
/*
* NET Generic infrastructure for Network protocols.
*
- * Definitions for request_sock
+ * Definitions for request_sock
*
* Authors: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
*
@@ -123,8 +123,6 @@ static inline void reqsk_put(struct request_sock *req)
reqsk_free(req);
}
-extern int sysctl_max_syn_backlog;
-
/*
* For a TCP Fast Open listener -
* lock - protects the access to all the reqsk, which is co-owned by
diff --git a/include/net/route.h b/include/net/route.h
index 0429d47cad25..c0874c87c173 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -153,7 +153,7 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi
flowi4_init_output(fl4, oif, sk ? sk->sk_mark : 0, tos,
RT_SCOPE_UNIVERSE, proto,
sk ? inet_sk_flowi_flags(sk) : 0,
- daddr, saddr, dport, sport);
+ daddr, saddr, dport, sport, sock_net_uid(net, sk));
if (sk)
security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
return ip_route_output_flow(net, fl4, sk);
@@ -269,7 +269,8 @@ static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst, __be32
flow_flags |= FLOWI_FLAG_ANYSRC;
flowi4_init_output(fl4, oif, sk->sk_mark, tos, RT_SCOPE_UNIVERSE,
- protocol, flow_flags, dst, src, dport, sport);
+ protocol, flow_flags, dst, src, dport, sport,
+ sk->sk_uid);
}
static inline struct rtable *ip_route_connect(struct flowi4 *fl4,
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index 4113916cc1bb..106de5f7bf06 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -139,6 +139,10 @@ struct rtnl_af_ops {
const struct nlattr *attr);
int (*set_link_af)(struct net_device *dev,
const struct nlattr *attr);
+
+ int (*fill_stats_af)(struct sk_buff *skb,
+ const struct net_device *dev);
+ size_t (*get_stats_af_size)(const struct net_device *dev);
};
void __rtnl_af_unregister(struct rtnl_af_ops *ops);
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index e6aa0a249672..aeec4086afb2 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -76,7 +76,7 @@ struct Qdisc {
struct netdev_queue *dev_queue;
- struct gnet_stats_rate_est64 rate_est;
+ struct net_rate_estimator __rcu *rate_est;
struct gnet_stats_basic_cpu __percpu *cpu_bstats;
struct gnet_stats_queue __percpu *cpu_qstats;
@@ -405,19 +405,35 @@ struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
const struct Qdisc_ops *ops, u32 parentid);
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 *);
+static inline void skb_reset_tc(struct sk_buff *skb)
+{
+#ifdef CONFIG_NET_CLS_ACT
+ skb->tc_redirected = 0;
+#endif
+}
+
static inline bool skb_at_tc_ingress(const struct sk_buff *skb)
{
#ifdef CONFIG_NET_CLS_ACT
- return G_TC_AT(skb->tc_verd) & AT_INGRESS;
+ return skb->tc_at_ingress;
#else
return false;
#endif
}
+static inline bool skb_skip_tc_classify(struct sk_buff *skb)
+{
+#ifdef CONFIG_NET_CLS_ACT
+ if (skb->tc_skip_classify) {
+ skb->tc_skip_classify = 0;
+ return true;
+ }
+#endif
+ return false;
+}
+
/* 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/scm.h b/include/net/scm.h
index 59fa93c01d2a..142ea9e7a6d0 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -3,6 +3,7 @@
#include <linux/limits.h>
#include <linux/net.h>
+#include <linux/cred.h>
#include <linux/security.h>
#include <linux/pid.h>
#include <linux/nsproxy.h>
diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h
index 5b847e49f7e9..b07a745ab69f 100644
--- a/include/net/sctp/constants.h
+++ b/include/net/sctp/constants.h
@@ -60,11 +60,14 @@ enum { SCTP_DEFAULT_INSTREAMS = SCTP_MAX_STREAM };
#define SCTP_NUM_PRSCTP_CHUNK_TYPES 1
+#define SCTP_NUM_RECONF_CHUNK_TYPES 1
+
#define SCTP_NUM_AUTH_CHUNK_TYPES 1
#define SCTP_NUM_CHUNK_TYPES (SCTP_NUM_BASE_CHUNK_TYPES + \
SCTP_NUM_ADDIP_CHUNK_TYPES +\
SCTP_NUM_PRSCTP_CHUNK_TYPES +\
+ SCTP_NUM_RECONF_CHUNK_TYPES +\
SCTP_NUM_AUTH_CHUNK_TYPES)
/* These are the different flavours of event. */
@@ -90,6 +93,7 @@ typedef enum {
SCTP_EVENT_TIMEOUT_T4_RTO,
SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD,
SCTP_EVENT_TIMEOUT_HEARTBEAT,
+ SCTP_EVENT_TIMEOUT_RECONF,
SCTP_EVENT_TIMEOUT_SACK,
SCTP_EVENT_TIMEOUT_AUTOCLOSE,
} sctp_event_timeout_t;
@@ -113,9 +117,10 @@ typedef enum {
SCTP_PRIMITIVE_SEND,
SCTP_PRIMITIVE_REQUESTHEARTBEAT,
SCTP_PRIMITIVE_ASCONF,
+ SCTP_PRIMITIVE_RECONF,
} sctp_event_primitive_t;
-#define SCTP_EVENT_PRIMITIVE_MAX SCTP_PRIMITIVE_ASCONF
+#define SCTP_EVENT_PRIMITIVE_MAX SCTP_PRIMITIVE_RECONF
#define SCTP_NUM_PRIMITIVE_TYPES (SCTP_EVENT_PRIMITIVE_MAX + 1)
/* We define here a utility type for manipulating subtypes.
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index 31acc3f4f132..069582ee5d7f 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -69,7 +69,7 @@
#include <net/ip6_route.h>
#endif
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/page.h>
#include <net/sock.h>
#include <net/snmp.h>
@@ -141,6 +141,8 @@ int sctp_primitive_ABORT(struct net *, struct sctp_association *, void *arg);
int sctp_primitive_SEND(struct net *, struct sctp_association *, void *arg);
int sctp_primitive_REQUESTHEARTBEAT(struct net *, struct sctp_association *, void *arg);
int sctp_primitive_ASCONF(struct net *, struct sctp_association *, void *arg);
+int sctp_primitive_RECONF(struct net *net, struct sctp_association *asoc,
+ void *arg);
/*
* sctp/input.c
@@ -164,7 +166,7 @@ void sctp_backlog_migrate(struct sctp_association *assoc,
struct sock *oldsk, struct sock *newsk);
int sctp_transport_hashtable_init(void);
void sctp_transport_hashtable_destroy(void);
-void sctp_hash_transport(struct sctp_transport *t);
+int sctp_hash_transport(struct sctp_transport *t);
void sctp_unhash_transport(struct sctp_transport *t);
struct sctp_transport *sctp_addrs_lookup_transport(
struct net *net,
@@ -192,6 +194,15 @@ void sctp_remaddr_proc_exit(struct net *net);
int sctp_offload_init(void);
/*
+ * sctp/stream.c
+ */
+int sctp_send_reset_streams(struct sctp_association *asoc,
+ struct sctp_reset_streams *params);
+int sctp_send_reset_assoc(struct sctp_association *asoc);
+int sctp_send_add_streams(struct sctp_association *asoc,
+ struct sctp_add_streams *params);
+
+/*
* Module global variables
*/
@@ -283,7 +294,6 @@ extern atomic_t sctp_dbg_objcnt_chunk;
extern atomic_t sctp_dbg_objcnt_bind_addr;
extern atomic_t sctp_dbg_objcnt_bind_bucket;
extern atomic_t sctp_dbg_objcnt_addr;
-extern atomic_t sctp_dbg_objcnt_ssnmap;
extern atomic_t sctp_dbg_objcnt_datamsg;
extern atomic_t sctp_dbg_objcnt_keys;
@@ -438,10 +448,9 @@ static inline int sctp_frag_point(const struct sctp_association *asoc, int pmtu)
return frag;
}
-static inline void sctp_assoc_pending_pmtu(struct sock *sk, struct sctp_association *asoc)
+static inline void sctp_assoc_pending_pmtu(struct sctp_association *asoc)
{
-
- sctp_assoc_sync_pmtu(sk, asoc);
+ sctp_assoc_sync_pmtu(asoc);
asoc->pmtu_pending = 0;
}
@@ -586,12 +595,23 @@ static inline void sctp_v4_map_v6(union sctp_addr *addr)
*/
static inline struct dst_entry *sctp_transport_dst_check(struct sctp_transport *t)
{
- if (t->dst && !dst_check(t->dst, t->dst_cookie)) {
- dst_release(t->dst);
- t->dst = NULL;
- }
+ if (t->dst && !dst_check(t->dst, t->dst_cookie))
+ sctp_transport_dst_release(t);
return t->dst;
}
+static inline bool sctp_transport_pmtu_check(struct sctp_transport *t)
+{
+ __u32 pmtu = max_t(size_t, SCTP_TRUNC4(dst_mtu(t->dst)),
+ SCTP_DEFAULT_MINSEGMENT);
+
+ if (t->pathmtu == pmtu)
+ return true;
+
+ t->pathmtu = pmtu;
+
+ return false;
+}
+
#endif /* __net_sctp_h__ */
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index ca6c971dd74a..b6f682ec184a 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -135,6 +135,7 @@ sctp_state_fn_t sctp_sf_do_8_5_1_E_sa;
sctp_state_fn_t sctp_sf_cookie_echoed_err;
sctp_state_fn_t sctp_sf_do_asconf;
sctp_state_fn_t sctp_sf_do_asconf_ack;
+sctp_state_fn_t sctp_sf_do_reconf;
sctp_state_fn_t sctp_sf_do_9_2_reshutack;
sctp_state_fn_t sctp_sf_eat_fwd_tsn;
sctp_state_fn_t sctp_sf_eat_fwd_tsn_fast;
@@ -157,6 +158,7 @@ sctp_state_fn_t sctp_sf_error_shutdown;
sctp_state_fn_t sctp_sf_ignore_primitive;
sctp_state_fn_t sctp_sf_do_prm_requestheartbeat;
sctp_state_fn_t sctp_sf_do_prm_asconf;
+sctp_state_fn_t sctp_sf_do_prm_reconf;
/* Prototypes for other event state functions. */
sctp_state_fn_t sctp_sf_do_no_pending_tsn;
@@ -167,6 +169,7 @@ sctp_state_fn_t sctp_sf_cookie_wait_icmp_abort;
/* Prototypes for timeout event state functions. */
sctp_state_fn_t sctp_sf_do_6_3_3_rtx;
+sctp_state_fn_t sctp_sf_send_reconf;
sctp_state_fn_t sctp_sf_do_6_2_sack;
sctp_state_fn_t sctp_sf_autoclose_timer_expire;
@@ -259,10 +262,38 @@ struct sctp_chunk *sctp_make_fwdtsn(const struct sctp_association *asoc,
__u32 new_cum_tsn, size_t nstreams,
struct sctp_fwdtsn_skip *skiplist);
struct sctp_chunk *sctp_make_auth(const struct sctp_association *asoc);
-
+struct sctp_chunk *sctp_make_strreset_req(
+ const struct sctp_association *asoc,
+ __u16 stream_num, __u16 *stream_list,
+ bool out, bool in);
+struct sctp_chunk *sctp_make_strreset_tsnreq(
+ const struct sctp_association *asoc);
+struct sctp_chunk *sctp_make_strreset_addstrm(
+ const struct sctp_association *asoc,
+ __u16 out, __u16 in);
+struct sctp_chunk *sctp_make_strreset_resp(
+ const struct sctp_association *asoc,
+ __u32 result, __u32 sn);
+struct sctp_chunk *sctp_make_strreset_tsnresp(
+ struct sctp_association *asoc,
+ __u32 result, __u32 sn,
+ __u32 sender_tsn, __u32 receiver_tsn);
+bool sctp_verify_reconf(const struct sctp_association *asoc,
+ struct sctp_chunk *chunk,
+ struct sctp_paramhdr **errp);
void sctp_chunk_assign_tsn(struct sctp_chunk *);
void sctp_chunk_assign_ssn(struct sctp_chunk *);
+/* Prototypes for stream-processing functions. */
+struct sctp_chunk *sctp_process_strreset_outreq(
+ struct sctp_association *asoc,
+ union sctp_params param,
+ struct sctp_ulpevent **evp);
+struct sctp_chunk *sctp_process_strreset_inreq(
+ struct sctp_association *asoc,
+ union sctp_params param,
+ struct sctp_ulpevent **evp);
+
/* Prototypes for statetable processing. */
int sctp_do_sm(struct net *net, sctp_event_t event_type, sctp_subtype_t subtype,
@@ -275,6 +306,7 @@ int sctp_do_sm(struct net *net, sctp_event_t event_type, sctp_subtype_t subtype,
/* 2nd level prototypes */
void sctp_generate_t3_rtx_event(unsigned long peer);
void sctp_generate_heartbeat_event(unsigned long peer);
+void sctp_generate_reconf_event(unsigned long peer);
void sctp_generate_proto_unreach_event(unsigned long peer);
void sctp_ootb_pkt_free(struct sctp_packet *);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 11c3bf262a85..138f8615acf0 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -82,8 +82,8 @@ struct sctp_outq;
struct sctp_bind_addr;
struct sctp_ulpq;
struct sctp_ep_common;
-struct sctp_ssnmap;
struct crypto_shash;
+struct sctp_stream;
#include <net/sctp/tsnmap.h>
@@ -124,7 +124,7 @@ extern struct sctp_globals {
/* This is the sctp port control hash. */
struct sctp_bind_hashbucket *port_hashtable;
/* This is the hash of all transports. */
- struct rhashtable transport_hashtable;
+ struct rhltable transport_hashtable;
/* Sizes of above hashtables. */
int ep_hashsize;
@@ -375,56 +375,25 @@ typedef struct sctp_sender_hb_info {
union sctp_addr daddr;
unsigned long sent_at;
__u64 hb_nonce;
-} __packed sctp_sender_hb_info_t;
+} sctp_sender_hb_info_t;
-/*
- * RFC 2960 1.3.2 Sequenced Delivery within Streams
- *
- * The term "stream" is used in SCTP to refer to a sequence of user
- * messages that are to be delivered to the upper-layer protocol in
- * order with respect to other messages within the same stream. This is
- * in contrast to its usage in TCP, where it refers to a sequence of
- * bytes (in this document a byte is assumed to be eight bits).
- * ...
- *
- * This is the structure we use to track both our outbound and inbound
- * SSN, or Stream Sequence Numbers.
- */
-
-struct sctp_stream {
- __u16 *ssn;
- unsigned int len;
-};
-
-struct sctp_ssnmap {
- struct sctp_stream in;
- struct sctp_stream out;
-};
-
-struct sctp_ssnmap *sctp_ssnmap_new(__u16 in, __u16 out,
- gfp_t gfp);
-void sctp_ssnmap_free(struct sctp_ssnmap *map);
-void sctp_ssnmap_clear(struct sctp_ssnmap *map);
+int sctp_stream_new(struct sctp_association *asoc, gfp_t gfp);
+int sctp_stream_init(struct sctp_association *asoc, gfp_t gfp);
+void sctp_stream_free(struct sctp_stream *stream);
+void sctp_stream_clear(struct sctp_stream *stream);
/* What is the current SSN number for this stream? */
-static inline __u16 sctp_ssn_peek(struct sctp_stream *stream, __u16 id)
-{
- return stream->ssn[id];
-}
+#define sctp_ssn_peek(stream, type, sid) \
+ ((stream)->type[sid].ssn)
/* Return the next SSN number for this stream. */
-static inline __u16 sctp_ssn_next(struct sctp_stream *stream, __u16 id)
-{
- return stream->ssn[id]++;
-}
+#define sctp_ssn_next(stream, type, sid) \
+ ((stream)->type[sid].ssn++)
/* Skip over this ssn and all below. */
-static inline void sctp_ssn_skip(struct sctp_stream *stream, __u16 id,
- __u16 ssn)
-{
- stream->ssn[id] = ssn+1;
-}
-
+#define sctp_ssn_skip(stream, type, sid, ssn) \
+ ((stream)->type[sid].ssn = ssn + 1)
+
/*
* Pointers to address related SCTP functions.
* (i.e. things that depend on the address family.)
@@ -509,7 +478,8 @@ struct sctp_pf {
int (*send_verify) (struct sctp_sock *, union sctp_addr *);
int (*supported_addrs)(const struct sctp_sock *, __be16 *);
struct sock *(*create_accept_sk) (struct sock *sk,
- struct sctp_association *asoc);
+ struct sctp_association *asoc,
+ bool kern);
int (*addr_to_user)(struct sctp_sock *sk, union sctp_addr *addr);
void (*to_sk_saddr)(union sctp_addr *, struct sock *sk);
void (*to_sk_daddr)(union sctp_addr *, struct sock *sk);
@@ -530,7 +500,6 @@ struct sctp_datamsg {
/* Did the messenge fail to send? */
int send_error;
u8 send_failed:1,
- can_abandon:1, /* can chunks from this message can be abandoned. */
can_delay; /* should this message be Nagle delayed */
};
@@ -641,7 +610,6 @@ struct sctp_chunk {
#define SCTP_NEED_FRTX 0x1
#define SCTP_DONT_FRTX 0x2
__u16 rtt_in_progress:1, /* This chunk used for RTT calc? */
- resent:1, /* Has this chunk ever been resent. */
has_tsn:1, /* Does this chunk have a TSN yet? */
has_ssn:1, /* Does this chunk have a SSN yet? */
singleton:1, /* Only chunk in the packet? */
@@ -656,6 +624,7 @@ struct sctp_chunk {
fast_retransmit:2; /* Is this chunk fast retransmitted? */
};
+#define sctp_chunk_retransmitted(chunk) (chunk->sent_count > 1)
void sctp_chunk_hold(struct sctp_chunk *);
void sctp_chunk_put(struct sctp_chunk *);
int sctp_user_addto_chunk(struct sctp_chunk *chunk, int len,
@@ -723,10 +692,9 @@ struct sctp_packet {
ipfragok:1; /* So let ip fragment this packet */
};
-struct sctp_packet *sctp_packet_init(struct sctp_packet *,
- struct sctp_transport *,
- __u16 sport, __u16 dport);
-struct sctp_packet *sctp_packet_config(struct sctp_packet *, __u32 vtag, int);
+void sctp_packet_init(struct sctp_packet *, struct sctp_transport *,
+ __u16 sport, __u16 dport);
+void sctp_packet_config(struct sctp_packet *, __u32 vtag, int);
sctp_xmit_t sctp_packet_transmit_chunk(struct sctp_packet *,
struct sctp_chunk *, int, gfp_t);
sctp_xmit_t sctp_packet_append_chunk(struct sctp_packet *,
@@ -762,7 +730,7 @@ static inline int sctp_packet_empty(struct sctp_packet *packet)
struct sctp_transport {
/* A list of transports. */
struct list_head transports;
- struct rhash_head node;
+ struct rhlist_head node;
/* Reference counting. */
atomic_t refcnt;
@@ -786,6 +754,8 @@ struct sctp_transport {
/* Is the Path MTU update pending on this tranport */
pmtu_pending:1,
+ dst_pending_confirm:1, /* need to confirm neighbour */
+
/* Has this transport moved the ctsn since we last sacked */
sack_generation:1;
u32 dst_cookie;
@@ -912,6 +882,9 @@ struct sctp_transport {
/* Timer to handle ICMP proto unreachable envets */
struct timer_list proto_unreach_timer;
+ /* Timer to handler reconf chunk rtx */
+ struct timer_list reconf_timer;
+
/* Since we're using per-destination retransmission timers
* (see above), we're also using per-destination "transmitted"
* queues. This probably ought to be a private struct
@@ -970,6 +943,7 @@ void sctp_transport_pmtu(struct sctp_transport *, struct sock *sk);
void sctp_transport_free(struct sctp_transport *);
void sctp_transport_reset_t3_rtx(struct sctp_transport *);
void sctp_transport_reset_hb_timer(struct sctp_transport *);
+void sctp_transport_reset_reconf_timer(struct sctp_transport *transport);
int sctp_transport_hold(struct sctp_transport *);
void sctp_transport_put(struct sctp_transport *);
void sctp_transport_update_rto(struct sctp_transport *, __u32);
@@ -978,9 +952,11 @@ void sctp_transport_lower_cwnd(struct sctp_transport *, sctp_lower_cwnd_t);
void sctp_transport_burst_limited(struct sctp_transport *);
void sctp_transport_burst_reset(struct sctp_transport *);
unsigned long sctp_transport_timeout(struct sctp_transport *);
-void sctp_transport_reset(struct sctp_transport *);
-void sctp_transport_update_pmtu(struct sock *, struct sctp_transport *, u32);
+void sctp_transport_reset(struct sctp_transport *t);
+void sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu);
void sctp_transport_immediate_rtx(struct sctp_transport *);
+void sctp_transport_dst_release(struct sctp_transport *t);
+void sctp_transport_dst_confirm(struct sctp_transport *t);
/* This is the structure we use to queue packets as they come into
@@ -1286,7 +1262,10 @@ struct sctp_endpoint {
struct list_head endpoint_shared_keys;
__u16 active_key_id;
__u8 auth_enable:1,
- prsctp_enable:1;
+ prsctp_enable:1,
+ reconf_enable:1;
+
+ __u8 strreset_enable;
};
/* Recover the outter endpoint structure. */
@@ -1333,6 +1312,25 @@ struct sctp_inithdr_host {
__u32 initial_tsn;
};
+struct sctp_stream_out {
+ __u16 ssn;
+ __u8 state;
+};
+
+struct sctp_stream_in {
+ __u16 ssn;
+};
+
+struct sctp_stream {
+ struct sctp_stream_out *out;
+ struct sctp_stream_in *in;
+ __u16 outcnt;
+ __u16 incnt;
+};
+
+#define SCTP_STREAM_CLOSED 0x00
+#define SCTP_STREAM_OPEN 0x01
+
/* SCTP_GET_ASSOC_STATS counters */
struct sctp_priv_assoc_stats {
/* Maximum observed rto in the association during subsequent
@@ -1520,6 +1518,7 @@ struct sctp_association {
hostname_address:1, /* Peer understands DNS addresses? */
asconf_capable:1, /* Does peer support ADDIP? */
prsctp_capable:1, /* Can peer do PR-SCTP? */
+ reconf_capable:1, /* Can peer do RE-CONFIG? */
auth_capable:1; /* Is peer doing SCTP-AUTH? */
/* sack_needed : This flag indicates if the next received
@@ -1748,8 +1747,8 @@ struct sctp_association {
/* Default receive parameters */
__u32 default_rcv_context;
- /* This tracks outbound ssn for a given stream. */
- struct sctp_ssnmap *ssnmap;
+ /* Stream arrays */
+ struct sctp_stream *stream;
/* All outbound chunks go through this structure. */
struct sctp_outq outqueue;
@@ -1879,7 +1878,17 @@ struct sctp_association {
__u8 need_ecne:1, /* Need to send an ECNE Chunk? */
temp:1, /* Is it a temporary association? */
- prsctp_enable:1;
+ force_delay:1,
+ prsctp_enable:1,
+ reconf_enable:1;
+
+ __u8 strreset_enable;
+ __u8 strreset_outstanding; /* request param count on the fly */
+
+ __u32 strreset_outseq; /* Update after receiving response */
+ __u32 strreset_inseq; /* Update after receiving request */
+
+ struct sctp_chunk *strreset_chunk; /* save request chunk */
struct sctp_priv_assoc_stats stats;
@@ -1945,7 +1954,7 @@ void sctp_assoc_update(struct sctp_association *old,
__u32 sctp_association_get_next_tsn(struct sctp_association *);
-void sctp_assoc_sync_pmtu(struct sock *, struct sctp_association *);
+void sctp_assoc_sync_pmtu(struct sctp_association *asoc);
void sctp_assoc_rwnd_increase(struct sctp_association *, unsigned int);
void sctp_assoc_rwnd_decrease(struct sctp_association *, unsigned int);
void sctp_assoc_set_primary(struct sctp_association *,
diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h
index 2c098cd7e7e2..324b5965fc4d 100644
--- a/include/net/sctp/ulpevent.h
+++ b/include/net/sctp/ulpevent.h
@@ -128,6 +128,10 @@ struct sctp_ulpevent *sctp_ulpevent_make_authkey(
struct sctp_ulpevent *sctp_ulpevent_make_sender_dry_event(
const struct sctp_association *asoc, gfp_t gfp);
+struct sctp_ulpevent *sctp_ulpevent_make_stream_reset_event(
+ const struct sctp_association *asoc, __u16 flags,
+ __u16 stream_num, __u16 *stream_list, gfp_t gfp);
+
void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
struct msghdr *);
void sctp_ulpevent_read_rcvinfo(const struct sctp_ulpevent *event,
diff --git a/include/net/secure_seq.h b/include/net/secure_seq.h
index 3f36d45b714a..0caee631a836 100644
--- a/include/net/secure_seq.h
+++ b/include/net/secure_seq.h
@@ -6,10 +6,10 @@
u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
__be16 dport);
-__u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
- __be16 sport, __be16 dport);
-__u32 secure_tcpv6_sequence_number(const __be32 *saddr, const __be32 *daddr,
- __be16 sport, __be16 dport);
+u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
+ __be16 sport, __be16 dport, u32 *tsoff);
+u32 secure_tcpv6_sequence_number(const __be32 *saddr, const __be32 *daddr,
+ __be16 sport, __be16 dport, u32 *tsoff);
u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr,
__be16 sport, __be16 dport);
u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr,
diff --git a/include/net/seg6.h b/include/net/seg6.h
new file mode 100644
index 000000000000..4e0357517d79
--- /dev/null
+++ b/include/net/seg6.h
@@ -0,0 +1,62 @@
+/*
+ * SR-IPv6 implementation
+ *
+ * Author:
+ * David Lebrun <david.lebrun@uclouvain.be>
+ *
+ *
+ * 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_SEG6_H
+#define _NET_SEG6_H
+
+#include <linux/net.h>
+#include <linux/ipv6.h>
+#include <net/lwtunnel.h>
+#include <linux/seg6.h>
+#include <linux/rhashtable.h>
+
+static inline void update_csum_diff4(struct sk_buff *skb, __be32 from,
+ __be32 to)
+{
+ __be32 diff[] = { ~from, to };
+
+ skb->csum = ~csum_partial((char *)diff, sizeof(diff), ~skb->csum);
+}
+
+static inline void update_csum_diff16(struct sk_buff *skb, __be32 *from,
+ __be32 *to)
+{
+ __be32 diff[] = {
+ ~from[0], ~from[1], ~from[2], ~from[3],
+ to[0], to[1], to[2], to[3],
+ };
+
+ skb->csum = ~csum_partial((char *)diff, sizeof(diff), ~skb->csum);
+}
+
+struct seg6_pernet_data {
+ struct mutex lock;
+ struct in6_addr __rcu *tun_src;
+#ifdef CONFIG_IPV6_SEG6_HMAC
+ struct rhashtable hmac_infos;
+#endif
+};
+
+static inline struct seg6_pernet_data *seg6_pernet(struct net *net)
+{
+ return net->ipv6.seg6_data;
+}
+
+extern int seg6_init(void);
+extern void seg6_exit(void);
+extern int seg6_iptunnel_init(void);
+extern void seg6_iptunnel_exit(void);
+
+extern bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len);
+
+#endif
diff --git a/include/net/seg6_hmac.h b/include/net/seg6_hmac.h
new file mode 100644
index 000000000000..69c3a106056b
--- /dev/null
+++ b/include/net/seg6_hmac.h
@@ -0,0 +1,62 @@
+/*
+ * SR-IPv6 implementation
+ *
+ * Author:
+ * David Lebrun <david.lebrun@uclouvain.be>
+ *
+ *
+ * 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_SEG6_HMAC_H
+#define _NET_SEG6_HMAC_H
+
+#include <net/flow.h>
+#include <net/ip6_fib.h>
+#include <net/sock.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/route.h>
+#include <net/seg6.h>
+#include <linux/seg6_hmac.h>
+#include <linux/rhashtable.h>
+
+#define SEG6_HMAC_MAX_DIGESTSIZE 160
+#define SEG6_HMAC_RING_SIZE 256
+
+struct seg6_hmac_info {
+ struct rhash_head node;
+ struct rcu_head rcu;
+
+ u32 hmackeyid;
+ char secret[SEG6_HMAC_SECRET_LEN];
+ u8 slen;
+ u8 alg_id;
+};
+
+struct seg6_hmac_algo {
+ u8 alg_id;
+ char name[64];
+ struct crypto_shash * __percpu *tfms;
+ struct shash_desc * __percpu *shashs;
+};
+
+extern int seg6_hmac_compute(struct seg6_hmac_info *hinfo,
+ struct ipv6_sr_hdr *hdr, struct in6_addr *saddr,
+ u8 *output);
+extern struct seg6_hmac_info *seg6_hmac_info_lookup(struct net *net, u32 key);
+extern int seg6_hmac_info_add(struct net *net, u32 key,
+ struct seg6_hmac_info *hinfo);
+extern int seg6_hmac_info_del(struct net *net, u32 key);
+extern int seg6_push_hmac(struct net *net, struct in6_addr *saddr,
+ struct ipv6_sr_hdr *srh);
+extern bool seg6_hmac_validate_skb(struct sk_buff *skb);
+extern int seg6_hmac_init(void);
+extern void seg6_hmac_exit(void);
+extern int seg6_hmac_net_init(struct net *net);
+extern void seg6_hmac_net_exit(struct net *net);
+
+#endif
diff --git a/include/net/smc.h b/include/net/smc.h
new file mode 100644
index 000000000000..12d26358ad9f
--- /dev/null
+++ b/include/net/smc.h
@@ -0,0 +1,20 @@
+/*
+ * Shared Memory Communications over RDMA (SMC-R) and RoCE
+ *
+ * Definitions for the SMC module (socket related)
+ *
+ * Copyright IBM Corp. 2016
+ *
+ * Author(s): Ursula Braun <ubraun@linux.vnet.ibm.com>
+ */
+#ifndef _SMC_H
+#define _SMC_H
+
+struct smc_hashinfo {
+ rwlock_t lock;
+ struct hlist_head ht;
+};
+
+int smc_hash_sk(struct sock *sk);
+void smc_unhash_sk(struct sock *sk);
+#endif /* _SMC_H */
diff --git a/include/net/sock.h b/include/net/sock.h
index 92b269709b9a..03252d53975d 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -70,6 +70,7 @@
#include <net/checksum.h>
#include <net/tcp_states.h>
#include <linux/net_tstamp.h>
+#include <net/smc.h>
/*
* This structure really needs to be cleaned up.
@@ -235,10 +236,12 @@ struct sock_common {
* @sk_shutdown: mask of %SEND_SHUTDOWN and/or %RCV_SHUTDOWN
* @sk_userlocks: %SO_SNDBUF and %SO_RCVBUF settings
* @sk_lock: synchronizer
+ * @sk_kern_sock: True if sock is using kernel lock classes
* @sk_rcvbuf: size of receive buffer in bytes
* @sk_wq: sock wait queue and async head
* @sk_rx_dst: receive input route used by early demux
* @sk_dst_cache: destination cache
+ * @sk_dst_pending_confirm: need to confirm neighbour
* @sk_policy: flow policy
* @sk_receive_queue: incoming packets
* @sk_wmem_alloc: transmit queue bytes committed
@@ -343,6 +346,9 @@ struct sock {
#define sk_rxhash __sk_common.skc_rxhash
socket_lock_t sk_lock;
+ atomic_t sk_drops;
+ int sk_rcvlowat;
+ struct sk_buff_head sk_error_queue;
struct sk_buff_head sk_receive_queue;
/*
* The backlog queue is special, it is always used with
@@ -359,14 +365,13 @@ struct sock {
struct sk_buff *tail;
} sk_backlog;
#define sk_rmem_alloc sk_backlog.rmem_alloc
- int sk_forward_alloc;
- __u32 sk_txhash;
+ int sk_forward_alloc;
#ifdef CONFIG_NET_RX_BUSY_POLL
- unsigned int sk_napi_id;
unsigned int sk_ll_usec;
+ /* ===== mostly read cache line ===== */
+ unsigned int sk_napi_id;
#endif
- atomic_t sk_drops;
int sk_rcvbuf;
struct sk_filter __rcu *sk_filter;
@@ -379,18 +384,55 @@ struct sock {
#endif
struct dst_entry *sk_rx_dst;
struct dst_entry __rcu *sk_dst_cache;
- /* Note: 32bit hole on 64bit arches */
- atomic_t sk_wmem_alloc;
atomic_t sk_omem_alloc;
int sk_sndbuf;
+
+ /* ===== cache line for TX ===== */
+ int sk_wmem_queued;
+ atomic_t sk_wmem_alloc;
+ unsigned long sk_tsq_flags;
+ struct sk_buff *sk_send_head;
struct sk_buff_head sk_write_queue;
+ __s32 sk_peek_off;
+ int sk_write_pending;
+ __u32 sk_dst_pending_confirm;
+ /* Note: 32bit hole on 64bit arches */
+ long sk_sndtimeo;
+ struct timer_list sk_timer;
+ __u32 sk_priority;
+ __u32 sk_mark;
+ u32 sk_pacing_rate; /* bytes per second */
+ u32 sk_max_pacing_rate;
+ struct page_frag sk_frag;
+ netdev_features_t sk_route_caps;
+ netdev_features_t sk_route_nocaps;
+ int sk_gso_type;
+ unsigned int sk_gso_max_size;
+ gfp_t sk_allocation;
+ __u32 sk_txhash;
/*
* Because of non atomicity rules, all
* changes are protected by socket lock.
*/
+ unsigned int __sk_flags_offset[0];
+#ifdef __BIG_ENDIAN_BITFIELD
+#define SK_FL_PROTO_SHIFT 16
+#define SK_FL_PROTO_MASK 0x00ff0000
+
+#define SK_FL_TYPE_SHIFT 0
+#define SK_FL_TYPE_MASK 0x0000ffff
+#else
+#define SK_FL_PROTO_SHIFT 8
+#define SK_FL_PROTO_MASK 0x0000ff00
+
+#define SK_FL_TYPE_SHIFT 16
+#define SK_FL_TYPE_MASK 0xffff0000
+#endif
+
kmemcheck_bitfield_begin(flags);
- unsigned int sk_padding : 2,
+ unsigned int sk_padding : 1,
+ sk_kern_sock : 1,
sk_no_check_tx : 1,
sk_no_check_rx : 1,
sk_userlocks : 4,
@@ -399,41 +441,24 @@ struct sock {
#define SK_PROTOCOL_MAX U8_MAX
kmemcheck_bitfield_end(flags);
- int sk_wmem_queued;
- gfp_t sk_allocation;
- u32 sk_pacing_rate; /* bytes per second */
- u32 sk_max_pacing_rate;
- netdev_features_t sk_route_caps;
- netdev_features_t sk_route_nocaps;
- int sk_gso_type;
- unsigned int sk_gso_max_size;
u16 sk_gso_max_segs;
- int sk_rcvlowat;
unsigned long sk_lingertime;
- struct sk_buff_head sk_error_queue;
struct proto *sk_prot_creator;
rwlock_t sk_callback_lock;
int sk_err,
sk_err_soft;
u32 sk_ack_backlog;
u32 sk_max_ack_backlog;
- __u32 sk_priority;
- __u32 sk_mark;
+ kuid_t sk_uid;
struct pid *sk_peer_pid;
const struct cred *sk_peer_cred;
long sk_rcvtimeo;
- long sk_sndtimeo;
- struct timer_list sk_timer;
ktime_t sk_stamp;
u16 sk_tsflags;
u8 sk_shutdown;
u32 sk_tskey;
struct socket *sk_socket;
void *sk_user_data;
- struct page_frag sk_frag;
- struct sk_buff *sk_send_head;
- __s32 sk_peek_off;
- int sk_write_pending;
#ifdef CONFIG_SECURITY
void *sk_security;
#endif
@@ -524,8 +549,7 @@ static inline struct sock *sk_nulls_head(const struct hlist_nulls_head *head)
static inline struct sock *sk_next(const struct sock *sk)
{
- return sk->sk_node.next ?
- hlist_entry(sk->sk_node.next, struct sock, sk_node) : NULL;
+ return hlist_entry_safe(sk->sk_node.next, struct sock, sk_node);
}
static inline struct sock *sk_nulls_next(const struct sock *sk)
@@ -894,7 +918,20 @@ static inline void sock_rps_record_flow_hash(__u32 hash)
static inline void sock_rps_record_flow(const struct sock *sk)
{
#ifdef CONFIG_RPS
- sock_rps_record_flow_hash(sk->sk_rxhash);
+ if (static_key_false(&rfs_needed)) {
+ /* Reading sk->sk_rxhash might incur an expensive cache line
+ * miss.
+ *
+ * TCP_ESTABLISHED does cover almost all states where RFS
+ * might be useful, and is cheaper [1] than testing :
+ * IPv4: inet_sk(sk)->inet_daddr
+ * IPv6: ipv6_addr_any(&sk->sk_v6_daddr)
+ * OR an additional socket flag
+ * [1] : sk_state and sk_prot are in the same cache line.
+ */
+ if (sk->sk_state == TCP_ESTABLISHED)
+ sock_rps_record_flow_hash(sk->sk_rxhash);
+ }
#endif
}
@@ -914,14 +951,16 @@ static inline void sock_rps_reset_rxhash(struct sock *sk)
#endif
}
-#define sk_wait_event(__sk, __timeo, __condition) \
+#define sk_wait_event(__sk, __timeo, __condition, __wait) \
({ int __rc; \
release_sock(__sk); \
__rc = __condition; \
if (!__rc) { \
- *(__timeo) = schedule_timeout(*(__timeo)); \
+ *(__timeo) = wait_woken(__wait, \
+ TASK_INTERRUPTIBLE, \
+ *(__timeo)); \
} \
- sched_annotate_sleep(); \
+ sched_annotate_sleep(); \
lock_sock(__sk); \
__rc = __condition; \
__rc; \
@@ -952,6 +991,7 @@ struct request_sock_ops;
struct timewait_sock_ops;
struct inet_hashinfo;
struct raw_hashinfo;
+struct smc_hashinfo;
struct module;
/*
@@ -977,7 +1017,8 @@ struct proto {
int addr_len);
int (*disconnect)(struct sock *sk, int flags);
- struct sock * (*accept)(struct sock *sk, int flags, int *err);
+ struct sock * (*accept)(struct sock *sk, int flags, int *err,
+ bool kern);
int (*ioctl)(struct sock *sk, int cmd,
unsigned long arg);
@@ -990,6 +1031,7 @@ struct proto {
int (*getsockopt)(struct sock *sk, int level,
int optname, char __user *optval,
int __user *option);
+ void (*keepalive)(struct sock *sk, int valbool);
#ifdef CONFIG_COMPAT
int (*compat_setsockopt)(struct sock *sk,
int level,
@@ -1059,6 +1101,7 @@ struct proto {
struct inet_hashinfo *hashinfo;
struct udp_table *udp_table;
struct raw_hashinfo *raw_hash;
+ struct smc_hashinfo *smc_hash;
} h;
struct module *owner;
@@ -1162,11 +1205,6 @@ static inline void sk_enter_memory_pressure(struct sock *sk)
sk->sk_prot->enter_memory_pressure(sk);
}
-static inline long sk_prot_mem_limits(const struct sock *sk, int index)
-{
- return sk->sk_prot->sysctl_mem[index];
-}
-
static inline long
sk_memory_allocated(const struct sock *sk)
{
@@ -1276,14 +1314,32 @@ static inline struct inode *SOCK_INODE(struct socket *socket)
/*
* Functions for memory accounting
*/
+int __sk_mem_raise_allocated(struct sock *sk, int size, int amt, int kind);
int __sk_mem_schedule(struct sock *sk, int size, int kind);
+void __sk_mem_reduce_allocated(struct sock *sk, int amount);
void __sk_mem_reclaim(struct sock *sk, int amount);
-#define SK_MEM_QUANTUM ((int)PAGE_SIZE)
+/* We used to have PAGE_SIZE here, but systems with 64KB pages
+ * do not necessarily have 16x time more memory than 4KB ones.
+ */
+#define SK_MEM_QUANTUM 4096
#define SK_MEM_QUANTUM_SHIFT ilog2(SK_MEM_QUANTUM)
#define SK_MEM_SEND 0
#define SK_MEM_RECV 1
+/* sysctl_mem values are in pages, we convert them in SK_MEM_QUANTUM units */
+static inline long sk_prot_mem_limits(const struct sock *sk, int index)
+{
+ long val = sk->sk_prot->sysctl_mem[index];
+
+#if PAGE_SIZE > SK_MEM_QUANTUM
+ val <<= PAGE_SHIFT - SK_MEM_QUANTUM_SHIFT;
+#elif PAGE_SIZE < SK_MEM_QUANTUM
+ val >>= SK_MEM_QUANTUM_SHIFT - PAGE_SHIFT;
+#endif
+ return val;
+}
+
static inline int sk_mem_pages(int amt)
{
return (amt + SK_MEM_QUANTUM - 1) >> SK_MEM_QUANTUM_SHIFT;
@@ -1473,6 +1529,7 @@ struct sock *sk_alloc(struct net *net, int family, gfp_t priority,
void sk_free(struct sock *sk);
void sk_destruct(struct sock *sk);
struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority);
+void sk_free_unlock_clone(struct sock *sk);
struct sk_buff *sock_wmalloc(struct sock *sk, unsigned long size, int force,
gfp_t priority);
@@ -1484,7 +1541,7 @@ void sock_efree(struct sk_buff *skb);
#ifdef CONFIG_INET
void sock_edemux(struct sk_buff *skb);
#else
-#define sock_edemux(skb) sock_efree(skb)
+#define sock_edemux sock_efree
#endif
int sock_setsockopt(struct socket *sock, int level, int op,
@@ -1519,7 +1576,7 @@ int sock_cmsg_send(struct sock *sk, struct msghdr *msg,
int sock_no_bind(struct socket *, struct sockaddr *, int);
int sock_no_connect(struct socket *, struct sockaddr *, int, int);
int sock_no_socketpair(struct socket *, struct socket *);
-int sock_no_accept(struct socket *, struct socket *, int);
+int sock_no_accept(struct socket *, struct socket *, int, bool);
int sock_no_getname(struct socket *, struct sockaddr *, int *, int);
unsigned int sock_no_poll(struct file *, struct socket *,
struct poll_table_struct *);
@@ -1651,6 +1708,7 @@ static inline void sock_graft(struct sock *sk, struct socket *parent)
sk->sk_wq = parent->wq;
parent->sk = sk;
sk_set_socket(sk, parent);
+ sk->sk_uid = SOCK_INODE(parent)->i_uid;
security_sock_graft(sk, parent);
write_unlock_bh(&sk->sk_callback_lock);
}
@@ -1658,6 +1716,11 @@ 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 kuid_t sock_net_uid(const struct net *net, const struct sock *sk)
+{
+ return sk ? sk->sk_uid : make_kuid(net->user_ns, 0);
+}
+
static inline u32 net_tx_rndhash(void)
{
u32 v = prandom_u32();
@@ -1708,6 +1771,7 @@ static inline void dst_negative_advice(struct sock *sk)
if (ndst != dst) {
rcu_assign_pointer(sk->sk_dst_cache, ndst);
sk_tx_queue_clear(sk);
+ sk->sk_dst_pending_confirm = 0;
}
}
}
@@ -1718,6 +1782,7 @@ __sk_dst_set(struct sock *sk, struct dst_entry *dst)
struct dst_entry *old_dst;
sk_tx_queue_clear(sk);
+ sk->sk_dst_pending_confirm = 0;
/*
* This can be called while sk is owned by the caller only,
* with no state that can be checked in a rcu_dereference_check() cond
@@ -1733,6 +1798,7 @@ sk_dst_set(struct sock *sk, struct dst_entry *dst)
struct dst_entry *old_dst;
sk_tx_queue_clear(sk);
+ sk->sk_dst_pending_confirm = 0;
old_dst = xchg((__force struct dst_entry **)&sk->sk_dst_cache, dst);
dst_release(old_dst);
}
@@ -1753,6 +1819,26 @@ struct dst_entry *__sk_dst_check(struct sock *sk, u32 cookie);
struct dst_entry *sk_dst_check(struct sock *sk, u32 cookie);
+static inline void sk_dst_confirm(struct sock *sk)
+{
+ if (!sk->sk_dst_pending_confirm)
+ sk->sk_dst_pending_confirm = 1;
+}
+
+static inline void sock_confirm_neigh(struct sk_buff *skb, struct neighbour *n)
+{
+ if (skb_get_dst_pending_confirm(skb)) {
+ struct sock *sk = skb->sk;
+ unsigned long now = jiffies;
+
+ /* avoid dirtying neighbour */
+ if (n->confirmed != now)
+ n->confirmed = now;
+ if (sk && sk->sk_dst_pending_confirm)
+ sk->sk_dst_pending_confirm = 0;
+ }
+}
+
bool sk_mc_loop(struct sock *sk);
static inline bool sk_can_gso(const struct sock *sk)
@@ -1783,13 +1869,13 @@ static inline int skb_do_copy_data_nocache(struct sock *sk, struct sk_buff *skb,
{
if (skb->ip_summed == CHECKSUM_NONE) {
__wsum csum = 0;
- if (csum_and_copy_from_iter(to, copy, &csum, from) != copy)
+ if (!csum_and_copy_from_iter_full(to, copy, &csum, from))
return -EFAULT;
skb->csum = csum_block_add(skb->csum, csum, offset);
} else if (sk->sk_route_caps & NETIF_F_NOCACHE_COPY) {
- if (copy_from_iter_nocache(to, copy, from) != copy)
+ if (!copy_from_iter_full_nocache(to, copy, from))
return -EFAULT;
- } else if (copy_from_iter(to, copy, from) != copy)
+ } else if (!copy_from_iter_full(to, copy, from))
return -EFAULT;
return 0;
@@ -1952,6 +2038,10 @@ void sk_reset_timer(struct sock *sk, struct timer_list *timer,
void sk_stop_timer(struct sock *sk, struct timer_list *timer);
+int __sk_queue_drop_skb(struct sock *sk, struct sk_buff *skb,
+ unsigned int flags,
+ void (*destructor)(struct sock *sk,
+ struct sk_buff *skb));
int __sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
@@ -2108,7 +2198,8 @@ struct sock_skb_cb {
static inline void
sock_skb_set_dropcount(const struct sock *sk, struct sk_buff *skb)
{
- SOCK_SKB_CB(skb)->dropcount = atomic_read(&sk->sk_drops);
+ SOCK_SKB_CB(skb)->dropcount = sock_flag(sk, SOCK_RXQ_OVFL) ?
+ atomic_read(&sk->sk_drops) : 0;
}
static inline void sk_drops_add(struct sock *sk, const struct sk_buff *skb)
@@ -2137,8 +2228,8 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
*/
if (sock_flag(sk, SOCK_RCVTSTAMP) ||
(sk->sk_tsflags & SOF_TIMESTAMPING_RX_SOFTWARE) ||
- (kt.tv64 && sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) ||
- (hwtstamps->hwtstamp.tv64 &&
+ (kt && sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) ||
+ (hwtstamps->hwtstamp &&
(sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE)))
__sock_recv_timestamp(msg, sk, skb);
else
diff --git a/include/net/switchdev.h b/include/net/switchdev.h
index eba80c4fc56f..929d6af321cd 100644
--- a/include/net/switchdev.h
+++ b/include/net/switchdev.h
@@ -46,8 +46,10 @@ enum switchdev_attr_id {
SWITCHDEV_ATTR_ID_PORT_PARENT_ID,
SWITCHDEV_ATTR_ID_PORT_STP_STATE,
SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
+ SWITCHDEV_ATTR_ID_PORT_MROUTER,
SWITCHDEV_ATTR_ID_BRIDGE_AGEING_TIME,
SWITCHDEV_ATTR_ID_BRIDGE_VLAN_FILTERING,
+ SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED,
};
struct switchdev_attr {
@@ -60,8 +62,10 @@ struct switchdev_attr {
struct netdev_phys_item_id ppid; /* PORT_PARENT_ID */
u8 stp_state; /* PORT_STP_STATE */
unsigned long brport_flags; /* PORT_BRIDGE_FLAGS */
+ bool mrouter; /* PORT_MROUTER */
clock_t ageing_time; /* BRIDGE_AGEING_TIME */
bool vlan_filtering; /* BRIDGE_VLAN_FILTERING */
+ bool mc_disabled; /* MC_DISABLED */
} u;
};
diff --git a/include/net/tc_act/tc_ife.h b/include/net/tc_act/tc_ife.h
index 9fd2bea0a6e0..30ba459ddd34 100644
--- a/include/net/tc_act/tc_ife.h
+++ b/include/net/tc_act/tc_ife.h
@@ -6,7 +6,6 @@
#include <linux/rtnetlink.h>
#include <linux/module.h>
-#define IFE_METAHDRLEN 2
struct tcf_ife_info {
struct tc_action common;
u8 eth_dst[ETH_ALEN];
@@ -45,8 +44,6 @@ struct tcf_meta_ops {
int ife_get_meta_u32(struct sk_buff *skb, struct tcf_meta_info *mi);
int ife_get_meta_u16(struct sk_buff *skb, struct tcf_meta_info *mi);
-int ife_tlv_meta_encode(void *skbdata, u16 attrtype, u16 dlen,
- const void *dval);
int ife_alloc_meta_u32(struct tcf_meta_info *mi, void *metaval, gfp_t gfp);
int ife_alloc_meta_u16(struct tcf_meta_info *mi, void *metaval, gfp_t gfp);
int ife_check_meta_u32(u32 metaval, struct tcf_meta_info *mi);
diff --git a/include/net/tc_act/tc_mirred.h b/include/net/tc_act/tc_mirred.h
index 62770add15bd..604bc31e23ab 100644
--- a/include/net/tc_act/tc_mirred.h
+++ b/include/net/tc_act/tc_mirred.h
@@ -8,13 +8,13 @@ struct tcf_mirred {
struct tc_action common;
int tcfm_eaction;
int tcfm_ifindex;
- int tcfm_ok_push;
+ bool tcfm_mac_header_xmit;
struct net_device __rcu *tcfm_dev;
struct list_head tcfm_list;
};
#define to_mirred(a) ((struct tcf_mirred *)a)
-static inline bool is_tcf_mirred_redirect(const struct tc_action *a)
+static inline bool is_tcf_mirred_egress_redirect(const struct tc_action *a)
{
#ifdef CONFIG_NET_CLS_ACT
if (a->ops && a->ops->type == TCA_ACT_MIRRED)
@@ -23,7 +23,7 @@ static inline bool is_tcf_mirred_redirect(const struct tc_action *a)
return false;
}
-static inline bool is_tcf_mirred_mirror(const struct tc_action *a)
+static inline bool is_tcf_mirred_egress_mirror(const struct tc_action *a)
{
#ifdef CONFIG_NET_CLS_ACT
if (a->ops && a->ops->type == TCA_ACT_MIRRED)
diff --git a/include/net/tc_act/tc_pedit.h b/include/net/tc_act/tc_pedit.h
index 29e38d6823df..dfbd6ee0bc7c 100644
--- a/include/net/tc_act/tc_pedit.h
+++ b/include/net/tc_act/tc_pedit.h
@@ -3,11 +3,17 @@
#include <net/act_api.h>
+struct tcf_pedit_key_ex {
+ enum pedit_header_type htype;
+ enum pedit_cmd cmd;
+};
+
struct tcf_pedit {
struct tc_action common;
unsigned char tcfp_nkeys;
unsigned char tcfp_flags;
struct tc_pedit_key *tcfp_keys;
+ struct tcf_pedit_key_ex *tcfp_keys_ex;
};
#define to_pedit(a) ((struct tcf_pedit *)a)
diff --git a/include/net/tc_act/tc_sample.h b/include/net/tc_act/tc_sample.h
new file mode 100644
index 000000000000..89e9305be880
--- /dev/null
+++ b/include/net/tc_act/tc_sample.h
@@ -0,0 +1,50 @@
+#ifndef __NET_TC_SAMPLE_H
+#define __NET_TC_SAMPLE_H
+
+#include <net/act_api.h>
+#include <linux/tc_act/tc_sample.h>
+#include <net/psample.h>
+
+struct tcf_sample {
+ struct tc_action common;
+ u32 rate;
+ bool truncate;
+ u32 trunc_size;
+ struct psample_group __rcu *psample_group;
+ u32 psample_group_num;
+ struct list_head tcfm_list;
+ struct rcu_head rcu;
+};
+#define to_sample(a) ((struct tcf_sample *)a)
+
+static inline bool is_tcf_sample(const struct tc_action *a)
+{
+#ifdef CONFIG_NET_CLS_ACT
+ return a->ops && a->ops->type == TCA_ACT_SAMPLE;
+#else
+ return false;
+#endif
+}
+
+static inline __u32 tcf_sample_rate(const struct tc_action *a)
+{
+ return to_sample(a)->rate;
+}
+
+static inline bool tcf_sample_truncate(const struct tc_action *a)
+{
+ return to_sample(a)->truncate;
+}
+
+static inline int tcf_sample_trunc_size(const struct tc_action *a)
+{
+ return to_sample(a)->trunc_size;
+}
+
+static inline struct psample_group *
+tcf_sample_psample_group(const struct tc_action *a)
+{
+ return rcu_dereference(to_sample(a)->psample_group);
+}
+
+#endif /* __NET_TC_SAMPLE_H */
diff --git a/include/net/tc_act/tc_skbedit.h b/include/net/tc_act/tc_skbedit.h
index 5767e9dbcf92..19cd3d345804 100644
--- a/include/net/tc_act/tc_skbedit.h
+++ b/include/net/tc_act/tc_skbedit.h
@@ -27,6 +27,7 @@ struct tcf_skbedit {
u32 flags;
u32 priority;
u32 mark;
+ u32 mask;
u16 queue_mapping;
u16 ptype;
};
diff --git a/include/net/tc_act/tc_tunnel_key.h b/include/net/tc_act/tc_tunnel_key.h
index 253f8da6c2a6..efef0b4b1b2b 100644
--- a/include/net/tc_act/tc_tunnel_key.h
+++ b/include/net/tc_act/tc_tunnel_key.h
@@ -12,6 +12,8 @@
#define __NET_TC_TUNNEL_KEY_H
#include <net/act_api.h>
+#include <linux/tc_act/tc_tunnel_key.h>
+#include <net/dst_metadata.h>
struct tcf_tunnel_key_params {
struct rcu_head rcu;
@@ -27,4 +29,39 @@ struct tcf_tunnel_key {
#define to_tunnel_key(a) ((struct tcf_tunnel_key *)a)
+static inline bool is_tcf_tunnel_set(const struct tc_action *a)
+{
+#ifdef CONFIG_NET_CLS_ACT
+ struct tcf_tunnel_key *t = to_tunnel_key(a);
+ struct tcf_tunnel_key_params *params = rtnl_dereference(t->params);
+
+ if (a->ops && a->ops->type == TCA_ACT_TUNNEL_KEY)
+ return params->tcft_action == TCA_TUNNEL_KEY_ACT_SET;
+#endif
+ return false;
+}
+
+static inline bool is_tcf_tunnel_release(const struct tc_action *a)
+{
+#ifdef CONFIG_NET_CLS_ACT
+ struct tcf_tunnel_key *t = to_tunnel_key(a);
+ struct tcf_tunnel_key_params *params = rtnl_dereference(t->params);
+
+ if (a->ops && a->ops->type == TCA_ACT_TUNNEL_KEY)
+ return params->tcft_action == TCA_TUNNEL_KEY_ACT_RELEASE;
+#endif
+ return false;
+}
+
+static inline struct ip_tunnel_info *tcf_tunnel_info(const struct tc_action *a)
+{
+#ifdef CONFIG_NET_CLS_ACT
+ struct tcf_tunnel_key *t = to_tunnel_key(a);
+ struct tcf_tunnel_key_params *params = rtnl_dereference(t->params);
+
+ return &params->tcft_enc_metadata->u.tun_info;
+#else
+ return NULL;
+#endif
+}
#endif /* __NET_TC_TUNNEL_KEY_H */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 123979fe12bf..6ec4ea652f3f 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -143,6 +143,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo);
#define TCP_RESOURCE_PROBE_INTERVAL ((unsigned)(HZ/2U)) /* Maximal interval between probes
* for local resources.
*/
+#define TCP_REO_TIMEOUT_MIN (2000) /* Min RACK reordering timeout in usec */
#define TCP_KEEPALIVE_TIME (120*60*HZ) /* two hours */
#define TCP_KEEPALIVE_PROBES 9 /* Max of 9 keepalive probes */
@@ -231,7 +232,6 @@ void tcp_time_wait(struct sock *sk, int state, int timeo);
*/
#define TFO_SERVER_WO_SOCKOPT1 0x400
-extern struct inet_timewait_death_row tcp_death_row;
/* sysctl variables for tcp */
extern int sysctl_tcp_timestamps;
@@ -252,7 +252,6 @@ extern int sysctl_tcp_wmem[3];
extern int sysctl_tcp_rmem[3];
extern int sysctl_tcp_app_win;
extern int sysctl_tcp_adv_win_scale;
-extern int sysctl_tcp_tw_reuse;
extern int sysctl_tcp_frto;
extern int sysctl_tcp_low_latency;
extern int sysctl_tcp_nometrics_save;
@@ -263,6 +262,9 @@ extern int sysctl_tcp_slow_start_after_idle;
extern int sysctl_tcp_thin_linear_timeouts;
extern int sysctl_tcp_thin_dupack;
extern int sysctl_tcp_early_retrans;
+extern int sysctl_tcp_recovery;
+#define TCP_RACK_LOSS_DETECTION 0x1 /* Use RACK to detect losses */
+
extern int sysctl_tcp_limit_output_bytes;
extern int sysctl_tcp_challenge_ack_limit;
extern int sysctl_tcp_min_tso_segs;
@@ -399,6 +401,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
int tcp_child_process(struct sock *parent, struct sock *child,
struct sk_buff *skb);
void tcp_enter_loss(struct sock *sk);
+void tcp_cwnd_reduction(struct sock *sk, int newly_acked_sacked, int flag);
void tcp_clear_retrans(struct tcp_sock *tp);
void tcp_update_metrics(struct sock *sk);
void tcp_init_metrics(struct sock *sk);
@@ -543,6 +546,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb, int segs);
void tcp_retransmit_timer(struct sock *sk);
void tcp_xmit_retransmit_queue(struct sock *);
void tcp_simple_retransmit(struct sock *);
+void tcp_enter_recovery(struct sock *sk, bool ece_ack);
int tcp_trim_head(struct sock *, struct sk_buff *, u32);
int tcp_fragment(struct sock *, struct sk_buff *, u32, unsigned int, gfp_t);
@@ -561,7 +565,6 @@ void tcp_skb_collapse_tstamp(struct sk_buff *skb,
const struct sk_buff *next_skb);
/* 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);
@@ -958,6 +961,7 @@ u32 tcp_slow_start(struct tcp_sock *tp, u32 acked);
void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w, u32 acked);
u32 tcp_reno_ssthresh(struct sock *sk);
+u32 tcp_reno_undo_cwnd(struct sock *sk);
void tcp_reno_cong_avoid(struct sock *sk, u32 ack, u32 acked);
extern struct tcp_congestion_ops tcp_reno;
@@ -1032,23 +1036,6 @@ static inline void tcp_enable_fack(struct tcp_sock *tp)
tp->rx_opt.sack_ok |= TCP_FACK_ENABLED;
}
-/* TCP early-retransmit (ER) is similar to but more conservative than
- * the thin-dupack feature. Enable ER only if thin-dupack is disabled.
- */
-static inline void tcp_enable_early_retrans(struct tcp_sock *tp)
-{
- struct net *net = sock_net((struct sock *)tp);
-
- tp->do_early_retrans = sysctl_tcp_early_retrans &&
- sysctl_tcp_early_retrans < 4 && !sysctl_tcp_thin_dupack &&
- net->ipv4.sysctl_tcp_reordering == 3;
-}
-
-static inline void tcp_disable_early_retrans(struct tcp_sock *tp)
-{
- tp->do_early_retrans = 0;
-}
-
static inline unsigned int tcp_left_out(const struct tcp_sock *tp)
{
return tp->sacked_out + tp->lost_out;
@@ -1506,6 +1493,9 @@ struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
struct tcp_fastopen_cookie *foc,
struct dst_entry *dst);
void tcp_fastopen_init_key_once(bool publish);
+bool tcp_fastopen_cookie_check(struct sock *sk, u16 *mss,
+ struct tcp_fastopen_cookie *cookie);
+bool tcp_fastopen_defer_connect(struct sock *sk, int *err);
#define TCP_FASTOPEN_KEY_LENGTH 16
/* Fastopen key context */
@@ -1515,11 +1505,26 @@ struct tcp_fastopen_context {
struct rcu_head rcu;
};
+/* Latencies incurred by various limits for a sender. They are
+ * chronograph-like stats that are mutually exclusive.
+ */
+enum tcp_chrono {
+ TCP_CHRONO_UNSPEC,
+ TCP_CHRONO_BUSY, /* Actively sending data (non-empty write queue) */
+ TCP_CHRONO_RWND_LIMITED, /* Stalled by insufficient receive window */
+ TCP_CHRONO_SNDBUF_LIMITED, /* Stalled by insufficient send buffer */
+ __TCP_CHRONO_MAX,
+};
+
+void tcp_chrono_start(struct sock *sk, const enum tcp_chrono type);
+void tcp_chrono_stop(struct sock *sk, const enum tcp_chrono type);
+
/* write queue abstraction */
static inline void tcp_write_queue_purge(struct sock *sk)
{
struct sk_buff *skb;
+ tcp_chrono_stop(sk, TCP_CHRONO_BUSY);
while ((skb = __skb_dequeue(&sk->sk_write_queue)) != NULL)
sk_wmem_free_skb(sk, skb);
sk_mem_reclaim(sk);
@@ -1578,8 +1583,10 @@ static inline void tcp_advance_send_head(struct sock *sk, const struct sk_buff *
static inline void tcp_check_send_head(struct sock *sk, struct sk_buff *skb_unlinked)
{
- if (sk->sk_send_head == skb_unlinked)
+ if (sk->sk_send_head == skb_unlinked) {
sk->sk_send_head = NULL;
+ tcp_chrono_stop(sk, TCP_CHRONO_BUSY);
+ }
if (tcp_sk(sk)->highest_sack == skb_unlinked)
tcp_sk(sk)->highest_sack = NULL;
}
@@ -1601,6 +1608,7 @@ static inline void tcp_add_write_queue_tail(struct sock *sk, struct sk_buff *skb
/* Queue it, remembering where we must start sending. */
if (sk->sk_send_head == NULL) {
sk->sk_send_head = skb;
+ tcp_chrono_start(sk, TCP_CHRONO_BUSY);
if (tcp_sk(sk)->highest_sack == NULL)
tcp_sk(sk)->highest_sack = skb;
@@ -1808,7 +1816,7 @@ struct tcp_request_sock_ops {
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);
+ __u32 (*init_seq)(const struct sk_buff *skb, u32 *tsoff);
int (*send_synack)(const struct sock *sk, struct dst_entry *dst,
struct flowi *fl, struct request_sock *req,
struct tcp_fastopen_cookie *foc,
@@ -1839,17 +1847,11 @@ 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);
+extern void tcp_rack_mark_lost(struct sock *sk, const struct skb_mstamp *now);
+extern void tcp_rack_advance(struct tcp_sock *tp, u8 sacked, u32 end_seq,
+ const struct skb_mstamp *xmit_time,
+ const struct skb_mstamp *ack_time);
+extern void tcp_rack_reo_timeout(struct sock *sk);
/*
* Save and compile IPv4 options, return a pointer to it
diff --git a/include/net/udp.h b/include/net/udp.h
index 4948790d393d..c9d8b8e848e0 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -204,7 +204,6 @@ static inline void udp_lib_close(struct sock *sk, long timeout)
}
int udp_lib_get_port(struct sock *sk, unsigned short snum,
- int (*)(const struct sock *, const struct sock *, bool),
unsigned int hash2_nulladdr);
u32 udp_flow_hashrnd(void);
@@ -246,6 +245,25 @@ static inline __be16 udp_flow_src_port(struct net *net, struct sk_buff *skb,
}
/* net/ipv4/udp.c */
+void udp_destruct_sock(struct sock *sk);
+void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len);
+int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb);
+void udp_skb_destructor(struct sock *sk, struct sk_buff *skb);
+static inline struct sk_buff *
+__skb_recv_udp(struct sock *sk, unsigned int flags, int noblock, int *peeked,
+ int *off, int *err)
+{
+ return __skb_recv_datagram(sk, flags | (noblock ? MSG_DONTWAIT : 0),
+ udp_skb_destructor, peeked, off, err);
+}
+static inline struct sk_buff *skb_recv_udp(struct sock *sk, unsigned int flags,
+ int noblock, int *err)
+{
+ int peeked, off = 0;
+
+ return __skb_recv_udp(sk, flags, noblock, &peeked, &off, err);
+}
+
void udp_v4_early_demux(struct sk_buff *skb);
int udp_get_port(struct sock *sk, unsigned short snum,
int (*saddr_cmp)(const struct sock *,
@@ -258,6 +276,7 @@ void udp_flush_pending_frames(struct sock *sk);
void udp4_hwcsum(struct sk_buff *skb, __be32 src, __be32 dst);
int udp_rcv(struct sk_buff *skb);
int udp_ioctl(struct sock *sk, int cmd, unsigned long arg);
+int udp_init_sock(struct sock *sk);
int __udp_disconnect(struct sock *sk, int flags);
int udp_disconnect(struct sock *sk, int flags);
unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait);
diff --git a/include/net/udplite.h b/include/net/udplite.h
index 80761938b9a7..ea340524f99b 100644
--- a/include/net/udplite.h
+++ b/include/net/udplite.h
@@ -20,13 +20,14 @@ static __inline__ int udplite_getfrag(void *from, char *to, int offset,
int len, int odd, struct sk_buff *skb)
{
struct msghdr *msg = from;
- return copy_from_iter(to, len, &msg->msg_iter) != len ? -EFAULT : 0;
+ return copy_from_iter_full(to, len, &msg->msg_iter) ? 0 : -EFAULT;
}
/* Designate sk as UDP-Lite socket */
static inline int udplite_sk_init(struct sock *sk)
{
udp_sk(sk)->pcflag = UDPLITE_BIT;
+ sk->sk_destruct = udp_destruct_sock;
return 0;
}
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index 308adc4154f4..49a59202f85e 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -281,16 +281,6 @@ 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,
- unsigned short family)
-{
-#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,
netdev_features_t features)
{
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 31947b9c21d6..14d82bf16692 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -213,6 +213,8 @@ struct xfrm_state {
/* Last used time */
unsigned long lastused;
+ struct page_frag xfrag;
+
/* Reference to data common to all the instances of this
* transformer. */
const struct xfrm_type *type;
@@ -278,9 +280,7 @@ struct net_device;
struct xfrm_type;
struct xfrm_dst;
struct xfrm_policy_afinfo {
- unsigned short family;
struct dst_ops *dst_ops;
- void (*garbage_collect)(struct net *net);
struct dst_entry *(*dst_lookup)(struct net *net,
int tos, int oif,
const xfrm_address_t *saddr,
@@ -301,8 +301,8 @@ struct xfrm_policy_afinfo {
struct dst_entry *(*blackhole_route)(struct net *net, struct dst_entry *orig);
};
-int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo);
-int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo);
+int xfrm_policy_register_afinfo(const struct xfrm_policy_afinfo *afinfo, int family);
+void xfrm_policy_unregister_afinfo(const struct xfrm_policy_afinfo *afinfo);
void km_policy_notify(struct xfrm_policy *xp, int dir,
const struct km_event *c);
void km_state_notify(struct xfrm_state *x, const struct km_event *c);
@@ -343,17 +343,16 @@ struct xfrm_state_afinfo {
int xfrm_state_register_afinfo(struct xfrm_state_afinfo *afinfo);
int xfrm_state_unregister_afinfo(struct xfrm_state_afinfo *afinfo);
struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family);
-void xfrm_state_put_afinfo(struct xfrm_state_afinfo *afinfo);
+struct xfrm_state_afinfo *xfrm_state_afinfo_get_rcu(unsigned int family);
struct xfrm_input_afinfo {
unsigned int family;
- struct module *owner;
int (*callback)(struct sk_buff *skb, u8 protocol,
int err);
};
-int xfrm_input_register_afinfo(struct xfrm_input_afinfo *afinfo);
-int xfrm_input_unregister_afinfo(struct xfrm_input_afinfo *afinfo);
+int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo);
+int xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo);
void xfrm_state_delete_tunnel(struct xfrm_state *x);
@@ -499,6 +498,7 @@ struct xfrm_tmpl {
};
#define XFRM_MAX_DEPTH 6
+#define XFRM_MAX_OFFLOAD_DEPTH 1
struct xfrm_policy_walk_entry {
struct list_head all;
@@ -682,6 +682,7 @@ struct xfrm_spi_skb_cb {
unsigned int daddroff;
unsigned int family;
+ __be32 seq;
};
#define XFRM_SPI_SKB_CB(__skb) ((struct xfrm_spi_skb_cb *)&((__skb)->cb[0]))
@@ -974,10 +975,41 @@ static inline void xfrm_dst_destroy(struct xfrm_dst *xdst)
void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);
+struct xfrm_offload {
+ /* Output sequence number for replay protection on offloading. */
+ struct {
+ __u32 low;
+ __u32 hi;
+ } seq;
+
+ __u32 flags;
+#define SA_DELETE_REQ 1
+#define CRYPTO_DONE 2
+#define CRYPTO_NEXT_DONE 4
+#define CRYPTO_FALLBACK 8
+#define XFRM_GSO_SEGMENT 16
+#define XFRM_GRO 32
+
+ __u32 status;
+#define CRYPTO_SUCCESS 1
+#define CRYPTO_GENERIC_ERROR 2
+#define CRYPTO_TRANSPORT_AH_AUTH_FAILED 4
+#define CRYPTO_TRANSPORT_ESP_AUTH_FAILED 8
+#define CRYPTO_TUNNEL_AH_AUTH_FAILED 16
+#define CRYPTO_TUNNEL_ESP_AUTH_FAILED 32
+#define CRYPTO_INVALID_PACKET_SYNTAX 64
+#define CRYPTO_INVALID_PROTOCOL 128
+
+ __u8 proto;
+};
+
struct sec_path {
atomic_t refcnt;
int len;
+ int olen;
+
struct xfrm_state *xvec[XFRM_MAX_DEPTH];
+ struct xfrm_offload ovec[XFRM_MAX_OFFLOAD_DEPTH];
};
static inline int secpath_exists(struct sk_buff *skb)
@@ -1007,6 +1039,7 @@ secpath_put(struct sec_path *sp)
}
struct sec_path *secpath_dup(struct sec_path *src);
+int secpath_set(struct sk_buff *skb);
static inline void
secpath_reset(struct sk_buff *skb)
@@ -1168,6 +1201,7 @@ static inline void xfrm_sk_free_policy(struct sock *sk)
}
void xfrm_garbage_collect(struct net *net);
+void xfrm_garbage_collect_deferred(struct net *net);
#else
@@ -1519,6 +1553,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
int encap_type);
int xfrm4_transport_finish(struct sk_buff *skb, int async);
int xfrm4_rcv(struct sk_buff *skb);
+int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq);
static inline int xfrm4_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi)
{
@@ -1774,6 +1809,15 @@ static inline struct xfrm_state *xfrm_input_state(struct sk_buff *skb)
{
return skb->sp->xvec[skb->sp->len - 1];
}
+static inline struct xfrm_offload *xfrm_offload(struct sk_buff *skb)
+{
+ struct sec_path *sp = skb->sp;
+
+ if (!sp || !sp->olen || sp->len != sp->olen)
+ return NULL;
+
+ return &sp->ovec[sp->olen - 1];
+}
#endif
static inline int xfrm_mark_get(struct nlattr **attrs, struct xfrm_mark *m)