aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/dt-bindings/net/ti-dp83867.h2
-rw-r--r--include/linux/i2c.h6
-rw-r--r--include/linux/if_rmnet.h55
-rw-r--r--include/linux/igmp.h2
-rw-r--r--include/linux/netfilter_ipv6.h52
-rw-r--r--include/linux/phy.h9
-rw-r--r--include/linux/phylink.h57
-rw-r--r--include/linux/platform_data/xilinx-ll-temac.h3
-rw-r--r--include/linux/qed/qed_if.h10
-rw-r--r--include/linux/qed/qed_rdma_if.h2
-rw-r--r--include/linux/rhashtable.h36
-rw-r--r--include/net/devlink.h2
-rw-r--r--include/net/dsa.h2
-rw-r--r--include/net/fib_rules.h1
-rw-r--r--include/net/inet_frag.h37
-rw-r--r--include/net/ip.h39
-rw-r--r--include/net/ip6_fib.h24
-rw-r--r--include/net/ip6_route.h4
-rw-r--r--include/net/ip_fib.h9
-rw-r--r--include/net/ipv6.h44
-rw-r--r--include/net/ipv6_stubs.h5
-rw-r--r--include/net/net_namespace.h2
-rw-r--r--include/net/netfilter/nf_conntrack.h1
-rw-r--r--include/net/netfilter/nf_conntrack_bridge.h20
-rw-r--r--include/net/netfilter/nf_conntrack_core.h3
-rw-r--r--include/net/netns/ieee802154_6lowpan.h2
-rw-r--r--include/net/netns/ipv4.h2
-rw-r--r--include/net/netns/ipv6.h4
-rw-r--r--include/net/netns/nexthop.h18
-rw-r--r--include/net/nexthop.h195
-rw-r--r--include/net/sctp/checksum.h12
-rw-r--r--include/net/tc_act/tc_ctinfo.h28
-rw-r--r--include/net/tcp.h41
-rw-r--r--include/trace/events/neigh.h49
-rw-r--r--include/uapi/linux/ethtool.h2
-rw-r--r--include/uapi/linux/nexthop.h56
-rw-r--r--include/uapi/linux/pkt_cls.h1
-rw-r--r--include/uapi/linux/rtnetlink.h10
-rw-r--r--include/uapi/linux/snmp.h1
-rw-r--r--include/uapi/linux/tc_act/tc_ctinfo.h34
-rw-r--r--include/uapi/linux/unix_diag.h2
41 files changed, 802 insertions, 82 deletions
diff --git a/include/dt-bindings/net/ti-dp83867.h b/include/dt-bindings/net/ti-dp83867.h
index 7b1656427cbe..192b79439eb7 100644
--- a/include/dt-bindings/net/ti-dp83867.h
+++ b/include/dt-bindings/net/ti-dp83867.h
@@ -56,4 +56,6 @@
#define DP83867_CLK_O_SEL_CHN_C_TCLK 0xA
#define DP83867_CLK_O_SEL_CHN_D_TCLK 0xB
#define DP83867_CLK_O_SEL_REF_CLK 0xC
+/* Special flag to indicate clock should be off */
+#define DP83867_CLK_O_SEL_OFF 0xFFFFFFFF
#endif
diff --git a/include/linux/i2c.h b/include/linux/i2c.h
index 1308126fc384..e982b8913b73 100644
--- a/include/linux/i2c.h
+++ b/include/linux/i2c.h
@@ -14,6 +14,7 @@
#ifndef _LINUX_I2C_H
#define _LINUX_I2C_H
+#include <linux/acpi.h> /* for acpi_handle */
#include <linux/mod_devicetable.h>
#include <linux/device.h> /* for struct device */
#include <linux/sched.h> /* for completion */
@@ -981,6 +982,7 @@ bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
u32 i2c_acpi_find_bus_speed(struct device *dev);
struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
struct i2c_board_info *info);
+struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle);
#else
static inline bool i2c_acpi_get_i2c_resource(struct acpi_resource *ares,
struct acpi_resource_i2c_serialbus **i2c)
@@ -996,6 +998,10 @@ static inline struct i2c_client *i2c_acpi_new_device(struct device *dev,
{
return NULL;
}
+static inline struct i2c_adapter *i2c_acpi_find_adapter_by_handle(acpi_handle handle)
+{
+ return NULL;
+}
#endif /* CONFIG_ACPI */
#endif /* _LINUX_I2C_H */
diff --git a/include/linux/if_rmnet.h b/include/linux/if_rmnet.h
new file mode 100644
index 000000000000..b4f5403383fc
--- /dev/null
+++ b/include/linux/if_rmnet.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0-only
+ * Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _LINUX_IF_RMNET_H_
+#define _LINUX_IF_RMNET_H_
+
+struct rmnet_map_header {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 pad_len:6;
+ u8 reserved_bit:1;
+ u8 cd_bit:1;
+#elif defined (__BIG_ENDIAN_BITFIELD)
+ u8 cd_bit:1;
+ u8 reserved_bit:1;
+ u8 pad_len:6;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ u8 mux_id;
+ __be16 pkt_len;
+} __aligned(1);
+
+struct rmnet_map_dl_csum_trailer {
+ u8 reserved1;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u8 valid:1;
+ u8 reserved2:7;
+#elif defined (__BIG_ENDIAN_BITFIELD)
+ u8 reserved2:7;
+ u8 valid:1;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+ u16 csum_start_offset;
+ u16 csum_length;
+ __be16 csum_value;
+} __aligned(1);
+
+struct rmnet_map_ul_csum_header {
+ __be16 csum_start_offset;
+#if defined(__LITTLE_ENDIAN_BITFIELD)
+ u16 csum_insert_offset:14;
+ u16 udp_ip4_ind:1;
+ u16 csum_enabled:1;
+#elif defined (__BIG_ENDIAN_BITFIELD)
+ u16 csum_enabled:1;
+ u16 udp_ip4_ind:1;
+ u16 csum_insert_offset:14;
+#else
+#error "Please fix <asm/byteorder.h>"
+#endif
+} __aligned(1);
+
+#endif /* !(_LINUX_IF_RMNET_H_) */
diff --git a/include/linux/igmp.h b/include/linux/igmp.h
index 9c94b2ea789c..6649cb78de4a 100644
--- a/include/linux/igmp.h
+++ b/include/linux/igmp.h
@@ -65,8 +65,8 @@ struct ip_mc_socklist {
struct ip_sf_list {
struct ip_sf_list *sf_next;
- __be32 sf_inaddr;
unsigned long sf_count[2]; /* include/exclude counts */
+ __be32 sf_inaddr;
unsigned char sf_gsresp; /* include in g & s response? */
unsigned char sf_oldin; /* change state */
unsigned char sf_crcount; /* retrans. left to send */
diff --git a/include/linux/netfilter_ipv6.h b/include/linux/netfilter_ipv6.h
index 12113e502656..3a3dc4b1f0e7 100644
--- a/include/linux/netfilter_ipv6.h
+++ b/include/linux/netfilter_ipv6.h
@@ -19,6 +19,7 @@ struct ip6_rt_info {
};
struct nf_queue_entry;
+struct nf_ct_bridge_frag_data;
/*
* Hook functions for ipv6 to allow xt_* modules to be built-in even
@@ -39,6 +40,15 @@ struct nf_ipv6_ops {
int (*fragment)(struct net *net, struct sock *sk, struct sk_buff *skb,
int (*output)(struct net *, struct sock *, struct sk_buff *));
int (*reroute)(struct sk_buff *skb, const struct nf_queue_entry *entry);
+#if IS_MODULE(CONFIG_IPV6)
+ int (*br_defrag)(struct net *net, struct sk_buff *skb, u32 user);
+ int (*br_fragment)(struct net *net, struct sock *sk,
+ struct sk_buff *skb,
+ struct nf_ct_bridge_frag_data *data,
+ int (*output)(struct net *, struct sock *sk,
+ const struct nf_ct_bridge_frag_data *data,
+ struct sk_buff *));
+#endif
};
#ifdef CONFIG_NETFILTER
@@ -86,6 +96,48 @@ static inline int nf_ip6_route(struct net *net, struct dst_entry **dst,
#endif
}
+#include <net/netfilter/ipv6/nf_defrag_ipv6.h>
+
+static inline int nf_ipv6_br_defrag(struct net *net, struct sk_buff *skb,
+ u32 user)
+{
+#if IS_MODULE(CONFIG_IPV6)
+ const struct nf_ipv6_ops *v6_ops = nf_get_ipv6_ops();
+
+ if (!v6_ops)
+ return 1;
+
+ return v6_ops->br_defrag(net, skb, user);
+#else
+ return nf_ct_frag6_gather(net, skb, user);
+#endif
+}
+
+int br_ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
+ struct nf_ct_bridge_frag_data *data,
+ int (*output)(struct net *, struct sock *sk,
+ const struct nf_ct_bridge_frag_data *data,
+ struct sk_buff *));
+
+static inline int nf_br_ip6_fragment(struct net *net, struct sock *sk,
+ struct sk_buff *skb,
+ struct nf_ct_bridge_frag_data *data,
+ int (*output)(struct net *, struct sock *sk,
+ const struct nf_ct_bridge_frag_data *data,
+ struct sk_buff *))
+{
+#if IS_MODULE(CONFIG_IPV6)
+ const struct nf_ipv6_ops *v6_ops = nf_get_ipv6_ops();
+
+ if (!v6_ops)
+ return 1;
+
+ return v6_ops->br_fragment(net, sk, skb, data, output);
+#else
+ return br_ip6_fragment(net, sk, skb, data, output);
+#endif
+}
+
int ip6_route_me_harder(struct net *net, struct sk_buff *skb);
static inline int nf_ip6_route_me_harder(struct net *net, struct sk_buff *skb)
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 073fb151b5a9..dc4b51060ebc 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -103,6 +103,7 @@ typedef enum {
PHY_INTERFACE_MODE_XAUI,
/* 10GBASE-KR, XFI, SFI - single lane 10G Serdes */
PHY_INTERFACE_MODE_10GKR,
+ PHY_INTERFACE_MODE_USXGMII,
PHY_INTERFACE_MODE_MAX,
} phy_interface_t;
@@ -178,6 +179,8 @@ static inline const char *phy_modes(phy_interface_t interface)
return "xaui";
case PHY_INTERFACE_MODE_10GKR:
return "10gbase-kr";
+ case PHY_INTERFACE_MODE_USXGMII:
+ return "usxgmii";
default:
return "unknown";
}
@@ -185,7 +188,6 @@ static inline const char *phy_modes(phy_interface_t interface)
#define PHY_INIT_TIMEOUT 100000
-#define PHY_STATE_TIME 1
#define PHY_FORCE_TIMEOUT 10
#define PHY_MAX_ADDR 32
@@ -534,6 +536,9 @@ struct phy_driver {
*/
int (*did_interrupt)(struct phy_device *phydev);
+ /* Override default interrupt handling */
+ int (*handle_interrupt)(struct phy_device *phydev);
+
/* Clears up any memory if needed */
void (*remove)(struct phy_device *phydev);
@@ -1134,6 +1139,7 @@ int phy_driver_register(struct phy_driver *new_driver, struct module *owner);
int phy_drivers_register(struct phy_driver *new_driver, int n,
struct module *owner);
void phy_state_machine(struct work_struct *work);
+void phy_queue_state_machine(struct phy_device *phydev, unsigned long jiffies);
void phy_mac_interrupt(struct phy_device *phydev);
void phy_start_machine(struct phy_device *phydev);
void phy_stop_machine(struct phy_device *phydev);
@@ -1144,6 +1150,7 @@ int phy_ethtool_ksettings_set(struct phy_device *phydev,
const struct ethtool_link_ksettings *cmd);
int phy_mii_ioctl(struct phy_device *phydev, struct ifreq *ifr, int cmd);
void phy_request_interrupt(struct phy_device *phydev);
+void phy_free_interrupt(struct phy_device *phydev);
void phy_print_status(struct phy_device *phydev);
int phy_set_max_speed(struct phy_device *phydev, u32 max_speed);
void phy_remove_link_mode(struct phy_device *phydev, u32 link_mode);
diff --git a/include/linux/phylink.h b/include/linux/phylink.h
index 6411c624f63a..0f6f65bb9d44 100644
--- a/include/linux/phylink.h
+++ b/include/linux/phylink.h
@@ -54,6 +54,21 @@ struct phylink_link_state {
unsigned int an_complete:1;
};
+enum phylink_op_type {
+ PHYLINK_NETDEV = 0,
+ PHYLINK_DEV,
+};
+
+/**
+ * struct phylink_config - PHYLINK configuration structure
+ * @dev: a pointer to a struct device associated with the MAC
+ * @type: operation type of PHYLINK instance
+ */
+struct phylink_config {
+ struct device *dev;
+ enum phylink_op_type type;
+};
+
/**
* struct phylink_mac_ops - MAC operations structure.
* @validate: Validate and update the link configuration.
@@ -66,16 +81,17 @@ struct phylink_link_state {
* The individual methods are described more fully below.
*/
struct phylink_mac_ops {
- void (*validate)(struct net_device *ndev, unsigned long *supported,
+ void (*validate)(struct phylink_config *config,
+ unsigned long *supported,
struct phylink_link_state *state);
- int (*mac_link_state)(struct net_device *ndev,
+ int (*mac_link_state)(struct phylink_config *config,
struct phylink_link_state *state);
- void (*mac_config)(struct net_device *ndev, unsigned int mode,
+ void (*mac_config)(struct phylink_config *config, unsigned int mode,
const struct phylink_link_state *state);
- void (*mac_an_restart)(struct net_device *ndev);
- void (*mac_link_down)(struct net_device *ndev, unsigned int mode,
+ void (*mac_an_restart)(struct phylink_config *config);
+ void (*mac_link_down)(struct phylink_config *config, unsigned int mode,
phy_interface_t interface);
- void (*mac_link_up)(struct net_device *ndev, unsigned int mode,
+ void (*mac_link_up)(struct phylink_config *config, unsigned int mode,
phy_interface_t interface,
struct phy_device *phy);
};
@@ -83,7 +99,7 @@ struct phylink_mac_ops {
#if 0 /* For kernel-doc purposes only. */
/**
* validate - Validate and update the link configuration
- * @ndev: a pointer to a &struct net_device for the MAC.
+ * @config: a pointer to a &struct phylink_config.
* @supported: ethtool bitmask for supported link modes.
* @state: a pointer to a &struct phylink_link_state.
*
@@ -100,12 +116,12 @@ struct phylink_mac_ops {
* based on @state->advertising and/or @state->speed and update
* @state->interface accordingly.
*/
-void validate(struct net_device *ndev, unsigned long *supported,
+void validate(struct phylink_config *config, unsigned long *supported,
struct phylink_link_state *state);
/**
* mac_link_state() - Read the current link state from the hardware
- * @ndev: a pointer to a &struct net_device for the MAC.
+ * @config: a pointer to a &struct phylink_config.
* @state: a pointer to a &struct phylink_link_state.
*
* Read the current link state from the MAC, reporting the current
@@ -114,12 +130,12 @@ void validate(struct net_device *ndev, unsigned long *supported,
* negotiation completion state in @state->an_complete, and link
* up state in @state->link.
*/
-int mac_link_state(struct net_device *ndev,
+int mac_link_state(struct phylink_config *config,
struct phylink_link_state *state);
/**
* mac_config() - configure the MAC for the selected mode and state
- * @ndev: a pointer to a &struct net_device for the MAC.
+ * @config: a pointer to a &struct phylink_config.
* @mode: one of %MLO_AN_FIXED, %MLO_AN_PHY, %MLO_AN_INBAND.
* @state: a pointer to a &struct phylink_link_state.
*
@@ -157,18 +173,18 @@ int mac_link_state(struct net_device *ndev,
* down. This "update" behaviour is critical to avoid bouncing the
* link up status.
*/
-void mac_config(struct net_device *ndev, unsigned int mode,
+void mac_config(struct phylink_config *config, unsigned int mode,
const struct phylink_link_state *state);
/**
* mac_an_restart() - restart 802.3z BaseX autonegotiation
- * @ndev: a pointer to a &struct net_device for the MAC.
+ * @config: a pointer to a &struct phylink_config.
*/
-void mac_an_restart(struct net_device *ndev);
+void mac_an_restart(struct phylink_config *config);
/**
* mac_link_down() - take the link down
- * @ndev: a pointer to a &struct net_device for the MAC.
+ * @config: a pointer to a &struct phylink_config.
* @mode: link autonegotiation mode
* @interface: link &typedef phy_interface_t mode
*
@@ -177,12 +193,12 @@ void mac_an_restart(struct net_device *ndev);
* Energy Efficient Ethernet MAC configuration. Interface type
* selection must be done in mac_config().
*/
-void mac_link_down(struct net_device *ndev, unsigned int mode,
+void mac_link_down(struct phylink_config *config, unsigned int mode,
phy_interface_t interface);
/**
* mac_link_up() - allow the link to come up
- * @ndev: a pointer to a &struct net_device for the MAC.
+ * @config: a pointer to a &struct phylink_config.
* @mode: link autonegotiation mode
* @interface: link &typedef phy_interface_t mode
* @phy: any attached phy
@@ -193,13 +209,14 @@ void mac_link_down(struct net_device *ndev, unsigned int mode,
* phy_init_eee() and perform appropriate MAC configuration for EEE.
* Interface type selection must be done in mac_config().
*/
-void mac_link_up(struct net_device *ndev, unsigned int mode,
+void mac_link_up(struct phylink_config *config, unsigned int mode,
phy_interface_t interface,
struct phy_device *phy);
#endif
-struct phylink *phylink_create(struct net_device *, struct fwnode_handle *,
- phy_interface_t iface, const struct phylink_mac_ops *ops);
+struct phylink *phylink_create(struct phylink_config *, struct fwnode_handle *,
+ phy_interface_t iface,
+ const struct phylink_mac_ops *ops);
void phylink_destroy(struct phylink *);
int phylink_connect_phy(struct phylink *, struct phy_device *);
diff --git a/include/linux/platform_data/xilinx-ll-temac.h b/include/linux/platform_data/xilinx-ll-temac.h
index 368530f98176..f4a68136afa6 100644
--- a/include/linux/platform_data/xilinx-ll-temac.h
+++ b/include/linux/platform_data/xilinx-ll-temac.h
@@ -4,6 +4,7 @@
#include <linux/if_ether.h>
#include <linux/phy.h>
+#include <linux/spinlock.h>
struct ll_temac_platform_data {
bool txcsum; /* Enable/disable TX checksum */
@@ -21,7 +22,7 @@ struct ll_temac_platform_data {
* TEMAC IP block, the same mutex should be passed here, as
* they share the same DCR bus bridge.
*/
- struct mutex *indirect_mutex;
+ spinlock_t *indirect_lock;
/* DMA channel control setup */
u8 tx_irq_timeout; /* TX Interrupt Delay Time-out */
u8 tx_irq_count; /* TX Interrupt Coalescing Threshold Count */
diff --git a/include/linux/qed/qed_if.h b/include/linux/qed/qed_if.h
index 48841e5dab90..eef02e64b422 100644
--- a/include/linux/qed/qed_if.h
+++ b/include/linux/qed/qed_if.h
@@ -907,7 +907,8 @@ struct qed_common_ops {
u32 (*sb_release)(struct qed_dev *cdev,
struct qed_sb_info *sb_info,
- u16 sb_id);
+ u16 sb_id,
+ enum qed_sb_type type);
void (*simd_handler_config)(struct qed_dev *cdev,
void *token,
@@ -1123,6 +1124,13 @@ struct qed_common_ops {
*/
int (*read_module_eeprom)(struct qed_dev *cdev,
char *buf, u8 dev_addr, u32 offset, u32 len);
+
+/**
+ * @brief get_affin_hwfn_idx
+ *
+ * @param cdev
+ */
+ u8 (*get_affin_hwfn_idx)(struct qed_dev *cdev);
};
#define MASK_FIELD(_name, _value) \
diff --git a/include/linux/qed/qed_rdma_if.h b/include/linux/qed/qed_rdma_if.h
index d15f8e4815e3..898f595ea3d6 100644
--- a/include/linux/qed/qed_rdma_if.h
+++ b/include/linux/qed/qed_rdma_if.h
@@ -670,6 +670,8 @@ struct qed_rdma_ops {
int (*ll2_set_mac_filter)(struct qed_dev *cdev,
u8 *old_mac_address, u8 *new_mac_address);
+ int (*iwarp_set_engine_affin)(struct qed_dev *cdev, bool b_reset);
+
int (*iwarp_connect)(void *rdma_cxt,
struct qed_iwarp_connect_in *iparams,
struct qed_iwarp_connect_out *oparams);
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h
index 9f8bc06d4136..beb9a9da1699 100644
--- a/include/linux/rhashtable.h
+++ b/include/linux/rhashtable.h
@@ -352,37 +352,38 @@ static inline void rht_unlock(struct bucket_table *tbl,
static inline struct rhash_head __rcu *__rht_ptr(
struct rhash_lock_head *const *bkt)
{
- return (struct rhash_head __rcu *)((unsigned long)*bkt & ~BIT(0));
+ return (struct rhash_head __rcu *)
+ ((unsigned long)*bkt & ~BIT(0) ?:
+ (unsigned long)RHT_NULLS_MARKER(bkt));
}
/*
* Where 'bkt' is a bucket and might be locked:
- * rht_ptr() dereferences that pointer and clears the lock bit.
+ * rht_ptr_rcu() dereferences that pointer and clears the lock bit.
+ * rht_ptr() dereferences in a context where the bucket is locked.
* rht_ptr_exclusive() dereferences in a context where exclusive
* access is guaranteed, such as when destroying the table.
*/
+static inline struct rhash_head *rht_ptr_rcu(
+ struct rhash_lock_head *const *bkt)
+{
+ struct rhash_head __rcu *p = __rht_ptr(bkt);
+
+ return rcu_dereference(p);
+}
+
static inline struct rhash_head *rht_ptr(
struct rhash_lock_head *const *bkt,
struct bucket_table *tbl,
unsigned int hash)
{
- struct rhash_head __rcu *p = __rht_ptr(bkt);
-
- if (!p)
- return RHT_NULLS_MARKER(bkt);
-
- return rht_dereference_bucket_rcu(p, tbl, hash);
+ return rht_dereference_bucket(__rht_ptr(bkt), tbl, hash);
}
static inline struct rhash_head *rht_ptr_exclusive(
struct rhash_lock_head *const *bkt)
{
- struct rhash_head __rcu *p = __rht_ptr(bkt);
-
- if (!p)
- return RHT_NULLS_MARKER(bkt);
-
- return rcu_dereference_protected(p, 1);
+ return rcu_dereference_protected(__rht_ptr(bkt), 1);
}
static inline void rht_assign_locked(struct rhash_lock_head **bkt,
@@ -509,7 +510,7 @@ static inline void rht_assign_unlock(struct bucket_table *tbl,
*/
#define rht_for_each_rcu(pos, tbl, hash) \
for (({barrier(); }), \
- pos = rht_ptr(rht_bucket(tbl, hash), tbl, hash); \
+ pos = rht_ptr_rcu(rht_bucket(tbl, hash)); \
!rht_is_a_nulls(pos); \
pos = rcu_dereference_raw(pos->next))
@@ -546,8 +547,7 @@ static inline void rht_assign_unlock(struct bucket_table *tbl,
*/
#define rht_for_each_entry_rcu(tpos, pos, tbl, hash, member) \
rht_for_each_entry_rcu_from(tpos, pos, \
- rht_ptr(rht_bucket(tbl, hash), \
- tbl, hash), \
+ rht_ptr_rcu(rht_bucket(tbl, hash)), \
tbl, hash, member)
/**
@@ -603,7 +603,7 @@ restart:
hash = rht_key_hashfn(ht, tbl, key, params);
bkt = rht_bucket(tbl, hash);
do {
- rht_for_each_rcu_from(he, rht_ptr(bkt, tbl, hash), tbl, hash) {
+ rht_for_each_rcu_from(he, rht_ptr_rcu(bkt), tbl, hash) {
if (params.obj_cmpfn ?
params.obj_cmpfn(&arg, rht_obj(ht, he)) :
rhashtable_compare(&arg, rht_obj(ht, he)))
diff --git a/include/net/devlink.h b/include/net/devlink.h
index 1c4adfb4195a..151eb930d329 100644
--- a/include/net/devlink.h
+++ b/include/net/devlink.h
@@ -17,6 +17,7 @@
#include <linux/list.h>
#include <linux/netdevice.h>
#include <linux/spinlock.h>
+#include <linux/workqueue.h>
#include <net/net_namespace.h>
#include <uapi/linux/devlink.h>
@@ -64,6 +65,7 @@ struct devlink_port {
enum devlink_port_type desired_type;
void *type_dev;
struct devlink_port_attrs attrs;
+ struct delayed_work type_warn_dw;
};
struct devlink_sb_pool_info {
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 685294817712..a7f36219904f 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -22,6 +22,7 @@
#include <linux/net_tstamp.h>
#include <linux/phy.h>
#include <linux/platform_data/dsa.h>
+#include <linux/phylink.h>
#include <net/devlink.h>
#include <net/switchdev.h>
@@ -193,6 +194,7 @@ struct dsa_port {
struct net_device *bridge_dev;
struct devlink_port devlink_port;
struct phylink *pl;
+ struct phylink_config pl_config;
struct work_struct xmit_work;
struct sk_buff_head xmit_queue;
diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h
index b473df5b9512..eba8465e1d86 100644
--- a/include/net/fib_rules.h
+++ b/include/net/fib_rules.h
@@ -103,6 +103,7 @@ struct fib_rule_notifier_info {
};
#define FRA_GENERIC_POLICY \
+ [FRA_UNSPEC] = { .strict_start_type = FRA_DPORT_RANGE + 1 }, \
[FRA_IIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \
[FRA_OIFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \
[FRA_PRIORITY] = { .type = NLA_U32 }, \
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index 378904ee9129..e91b79ad4e4a 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -3,19 +3,24 @@
#define __NET_FRAG_H__
#include <linux/rhashtable-types.h>
+#include <linux/completion.h>
-struct netns_frags {
+/* Per netns frag queues directory */
+struct fqdir {
/* sysctls */
long high_thresh;
long low_thresh;
int timeout;
int max_dist;
struct inet_frags *f;
+ struct net *net;
+ bool dead;
struct rhashtable rhashtable ____cacheline_aligned_in_smp;
/* Keep atomic mem on separate cachelines in structs that include it */
atomic_long_t mem ____cacheline_aligned_in_smp;
+ struct rcu_work destroy_rwork;
};
/**
@@ -24,11 +29,13 @@ struct netns_frags {
* @INET_FRAG_FIRST_IN: first fragment has arrived
* @INET_FRAG_LAST_IN: final fragment has arrived
* @INET_FRAG_COMPLETE: frag queue has been processed and is due for destruction
+ * @INET_FRAG_HASH_DEAD: inet_frag_kill() has not removed fq from rhashtable
*/
enum {
INET_FRAG_FIRST_IN = BIT(0),
INET_FRAG_LAST_IN = BIT(1),
INET_FRAG_COMPLETE = BIT(2),
+ INET_FRAG_HASH_DEAD = BIT(3),
};
struct frag_v4_compare_key {
@@ -64,7 +71,7 @@ struct frag_v6_compare_key {
* @meat: length of received fragments so far
* @flags: fragment queue flags
* @max_size: maximum received fragment size
- * @net: namespace that this frag belongs to
+ * @fqdir: pointer to struct fqdir
* @rcu: rcu head for freeing deferall
*/
struct inet_frag_queue {
@@ -84,7 +91,7 @@ struct inet_frag_queue {
int meat;
__u8 flags;
u16 max_size;
- struct netns_frags *net;
+ struct fqdir *fqdir;
struct rcu_head rcu;
};
@@ -98,21 +105,19 @@ struct inet_frags {
struct kmem_cache *frags_cachep;
const char *frags_cache_name;
struct rhashtable_params rhash_params;
+ refcount_t refcnt;
+ struct completion completion;
};
int inet_frags_init(struct inet_frags *);
void inet_frags_fini(struct inet_frags *);
-static inline int inet_frags_init_net(struct netns_frags *nf)
-{
- atomic_long_set(&nf->mem, 0);
- return rhashtable_init(&nf->rhashtable, &nf->f->rhash_params);
-}
-void inet_frags_exit_net(struct netns_frags *nf);
+int fqdir_init(struct fqdir **fqdirp, struct inet_frags *f, struct net *net);
+void fqdir_exit(struct fqdir *fqdir);
void inet_frag_kill(struct inet_frag_queue *q);
void inet_frag_destroy(struct inet_frag_queue *q);
-struct inet_frag_queue *inet_frag_find(struct netns_frags *nf, void *key);
+struct inet_frag_queue *inet_frag_find(struct fqdir *fqdir, void *key);
/* Free all skbs in the queue; return the sum of their truesizes. */
unsigned int inet_frag_rbtree_purge(struct rb_root *root);
@@ -125,19 +130,19 @@ static inline void inet_frag_put(struct inet_frag_queue *q)
/* Memory Tracking Functions. */
-static inline long frag_mem_limit(const struct netns_frags *nf)
+static inline long frag_mem_limit(const struct fqdir *fqdir)
{
- return atomic_long_read(&nf->mem);
+ return atomic_long_read(&fqdir->mem);
}
-static inline void sub_frag_mem_limit(struct netns_frags *nf, long val)
+static inline void sub_frag_mem_limit(struct fqdir *fqdir, long val)
{
- atomic_long_sub(val, &nf->mem);
+ atomic_long_sub(val, &fqdir->mem);
}
-static inline void add_frag_mem_limit(struct netns_frags *nf, long val)
+static inline void add_frag_mem_limit(struct fqdir *fqdir, long val)
{
- atomic_long_add(val, &nf->mem);
+ atomic_long_add(val, &fqdir->mem);
}
/* RFC 3168 support :
diff --git a/include/net/ip.h b/include/net/ip.h
index 2d3cce7c3e8a..029cc3fd26bd 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -165,6 +165,45 @@ int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb);
int ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb);
int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
int (*output)(struct net *, struct sock *, struct sk_buff *));
+
+struct ip_fraglist_iter {
+ struct sk_buff *frag_list;
+ struct sk_buff *frag;
+ struct iphdr *iph;
+ int offset;
+ unsigned int hlen;
+};
+
+void ip_fraglist_init(struct sk_buff *skb, struct iphdr *iph,
+ unsigned int hlen, struct ip_fraglist_iter *iter);
+void ip_fraglist_prepare(struct sk_buff *skb, struct ip_fraglist_iter *iter);
+
+static inline struct sk_buff *ip_fraglist_next(struct ip_fraglist_iter *iter)
+{
+ struct sk_buff *skb = iter->frag;
+
+ iter->frag = skb->next;
+ skb_mark_not_on_list(skb);
+
+ return skb;
+}
+
+struct ip_frag_state {
+ struct iphdr *iph;
+ unsigned int hlen;
+ unsigned int ll_rs;
+ unsigned int mtu;
+ unsigned int left;
+ int offset;
+ int ptr;
+ __be16 not_last_frag;
+};
+
+void ip_frag_init(struct sk_buff *skb, unsigned int hlen, unsigned int ll_rs,
+ unsigned int mtu, struct ip_frag_state *state);
+struct sk_buff *ip_frag_next(struct sk_buff *skb,
+ struct ip_frag_state *state);
+
void ip_send_check(struct iphdr *ip);
int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
int ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb);
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 525f701653ca..ebe5d65f97e0 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -131,6 +131,9 @@ struct fib6_nh {
#ifdef CONFIG_IPV6_ROUTER_PREF
unsigned long last_probe;
#endif
+
+ struct rt6_info * __percpu *rt6i_pcpu;
+ struct rt6_exception_bucket __rcu *rt6i_exception_bucket;
};
struct fib6_info {
@@ -156,22 +159,18 @@ struct fib6_info {
struct rt6key fib6_src;
struct rt6key fib6_prefsrc;
- struct rt6_info * __percpu *rt6i_pcpu;
- struct rt6_exception_bucket __rcu *rt6i_exception_bucket;
-
u32 fib6_metric;
u8 fib6_protocol;
u8 fib6_type;
- u8 exception_bucket_flushed:1,
- should_flush:1,
+ u8 should_flush:1,
dst_nocount:1,
dst_nopolicy:1,
dst_host:1,
fib6_destroying:1,
- unused:2;
+ unused:3;
- struct fib6_nh fib6_nh;
struct rcu_head rcu;
+ struct fib6_nh fib6_nh[0];
};
struct rt6_info {
@@ -281,7 +280,7 @@ static inline void ip6_rt_put(struct rt6_info *rt)
dst_release(&rt->dst);
}
-struct fib6_info *fib6_info_alloc(gfp_t gfp_flags);
+struct fib6_info *fib6_info_alloc(gfp_t gfp_flags, bool with_fib6_nh);
void fib6_info_destroy_rcu(struct rcu_head *head);
static inline void fib6_info_hold(struct fib6_info *f6i)
@@ -444,7 +443,7 @@ void rt6_get_prefsrc(const struct rt6_info *rt, struct in6_addr *addr)
static inline struct net_device *fib6_info_nh_dev(const struct fib6_info *f6i)
{
- return f6i->fib6_nh.fib_nh_dev;
+ return f6i->fib6_nh->fib_nh_dev;
}
int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh,
@@ -452,6 +451,12 @@ int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh,
struct netlink_ext_ack *extack);
void fib6_nh_release(struct fib6_nh *fib6_nh);
+int call_fib6_entry_notifiers(struct net *net,
+ enum fib_event_type event_type,
+ struct fib6_info *rt,
+ struct netlink_ext_ack *extack);
+void fib6_rt_update(struct net *net, struct fib6_info *rt,
+ struct nl_info *info);
void inet6_rt_notify(int event, struct fib6_info *rt, struct nl_info *info,
unsigned int flags);
@@ -485,6 +490,7 @@ int fib6_tables_dump(struct net *net, struct notifier_block *nb);
void fib6_update_sernum(struct net *net, struct fib6_info *rt);
void fib6_update_sernum_upto_root(struct net *net, struct fib6_info *rt);
+void fib6_update_sernum_stub(struct net *net, struct fib6_info *f6i);
void fib6_metric_set(struct fib6_info *f6i, int metric, u32 val);
static inline bool fib6_metric_locked(struct fib6_info *f6i, int metric)
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 4790beaa86e0..a6ce6ea856b9 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -70,7 +70,7 @@ static inline bool rt6_qualify_for_ecmp(const struct fib6_info *f6i)
{
/* the RTF_ADDRCONF flag filters out RA's */
return !(f6i->fib6_flags & RTF_ADDRCONF) &&
- f6i->fib6_nh.fib_nh_gw_family;
+ f6i->fib6_nh->fib_nh_gw_family;
}
void ip6_route_input(struct sk_buff *skb);
@@ -275,7 +275,7 @@ static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt,
static inline bool rt6_duplicate_nexthop(struct fib6_info *a, struct fib6_info *b)
{
- struct fib6_nh *nha = &a->fib6_nh, *nhb = &b->fib6_nh;
+ struct fib6_nh *nha = a->fib6_nh, *nhb = b->fib6_nh;
return nha->fib_nh_dev == nhb->fib_nh_dev &&
ipv6_addr_equal(&nha->fib_nh_gw6, &nhb->fib_nh_gw6) &&
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index d0e28f4ab099..70ba0302c8c9 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -150,6 +150,7 @@ struct fib_info {
#define fib_advmss fib_metrics->metrics[RTAX_ADVMSS-1]
int fib_nhs;
bool fib_nh_is_v6;
+ bool nh_updated;
struct rcu_head rcu;
struct fib_nh fib_nh[0];
#define fib_dev fib_nh[0].fib_nh_dev
@@ -200,7 +201,8 @@ static inline struct fib_nh_common *fib_info_nhc(struct fib_info *fi, int nhsel)
#define FIB_TABLE_HASHSZ 2
#endif
-__be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh);
+__be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh,
+ unsigned char scope);
__be32 fib_result_prefsrc(struct net *net, struct fib_result *res);
#define FIB_RES_NHC(res) ((res).nhc)
@@ -231,6 +233,7 @@ int call_fib4_notifiers(struct net *net, enum fib_event_type event_type,
int __net_init fib4_notifier_init(struct net *net);
void __net_exit fib4_notifier_exit(struct net *net);
+void fib_info_notify_update(struct net *net, struct nl_info *info);
void fib_notify(struct net *net, struct notifier_block *nb);
struct fib_table {
@@ -429,11 +432,14 @@ int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force);
int fib_sync_down_addr(struct net_device *dev, __be32 local);
int fib_sync_up(struct net_device *dev, unsigned char nh_flags);
void fib_sync_mtu(struct net_device *dev, u32 orig_mtu);
+void fib_nhc_update_mtu(struct fib_nh_common *nhc, u32 new, u32 orig);
#ifdef CONFIG_IP_ROUTE_MULTIPATH
int fib_multipath_hash(const struct net *net, const struct flowi4 *fl4,
const struct sk_buff *skb, struct flow_keys *flkeys);
#endif
+int fib_check_nh(struct net *net, struct fib_nh *nh, u32 table, u8 scope,
+ struct netlink_ext_ack *extack);
void fib_select_multipath(struct fib_result *res, int hash);
void fib_select_path(struct net *net, struct fib_result *res,
struct flowi4 *fl4, const struct sk_buff *skb);
@@ -469,6 +475,7 @@ static inline void fib_combine_itag(u32 *itag, const struct fib_result *res)
#endif
}
+void fib_flush(struct net *net);
void free_fib_info(struct fib_info *fi);
static inline void fib_info_hold(struct fib_info *fi)
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index daf80863d3a5..21bb830e9679 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -154,6 +154,50 @@ struct frag_hdr {
#define IP6_MF 0x0001
#define IP6_OFFSET 0xFFF8
+struct ip6_fraglist_iter {
+ struct ipv6hdr *tmp_hdr;
+ struct sk_buff *frag_list;
+ struct sk_buff *frag;
+ int offset;
+ unsigned int hlen;
+ __be32 frag_id;
+ u8 nexthdr;
+};
+
+int ip6_fraglist_init(struct sk_buff *skb, unsigned int hlen, u8 *prevhdr,
+ u8 nexthdr, __be32 frag_id,
+ struct ip6_fraglist_iter *iter);
+void ip6_fraglist_prepare(struct sk_buff *skb, struct ip6_fraglist_iter *iter);
+
+static inline struct sk_buff *ip6_fraglist_next(struct ip6_fraglist_iter *iter)
+{
+ struct sk_buff *skb = iter->frag;
+
+ iter->frag = skb->next;
+ skb_mark_not_on_list(skb);
+
+ return skb;
+}
+
+struct ip6_frag_state {
+ u8 *prevhdr;
+ unsigned int hlen;
+ unsigned int mtu;
+ unsigned int left;
+ int offset;
+ int ptr;
+ int hroom;
+ int troom;
+ __be32 frag_id;
+ u8 nexthdr;
+};
+
+void ip6_frag_init(struct sk_buff *skb, unsigned int hlen, unsigned int mtu,
+ unsigned short needed_tailroom, int hdr_room, u8 *prevhdr,
+ u8 nexthdr, __be32 frag_id, struct ip6_frag_state *state);
+struct sk_buff *ip6_frag_next(struct sk_buff *skb,
+ struct ip6_frag_state *state);
+
#define IP6_REPLY_MARK(net, mark) \
((net)->ipv6.sysctl.fwmark_reflect ? (mark) : 0)
diff --git a/include/net/ipv6_stubs.h b/include/net/ipv6_stubs.h
index 6c0c4fde16f8..5c93e942c50b 100644
--- a/include/net/ipv6_stubs.h
+++ b/include/net/ipv6_stubs.h
@@ -45,6 +45,11 @@ struct ipv6_stub {
struct fib6_config *cfg, gfp_t gfp_flags,
struct netlink_ext_ack *extack);
void (*fib6_nh_release)(struct fib6_nh *fib6_nh);
+ void (*fib6_update_sernum)(struct net *net, struct fib6_info *rt);
+ int (*ip6_del_rt)(struct net *net, struct fib6_info *rt);
+ void (*fib6_rt_update)(struct net *net, struct fib6_info *rt,
+ struct nl_info *info);
+
void (*udpv6_encap_enable)(void);
void (*ndisc_send_na)(struct net_device *dev, const struct in6_addr *daddr,
const struct in6_addr *solicited_addr,
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 12689ddfc24c..abb4f92456e1 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -19,6 +19,7 @@
#include <net/netns/packet.h>
#include <net/netns/ipv4.h>
#include <net/netns/ipv6.h>
+#include <net/netns/nexthop.h>
#include <net/netns/ieee802154_6lowpan.h>
#include <net/netns/sctp.h>
#include <net/netns/dccp.h>
@@ -108,6 +109,7 @@ struct net {
struct netns_mib mib;
struct netns_packet packet;
struct netns_unix unx;
+ struct netns_nexthop nexthop;
struct netns_ipv4 ipv4;
#if IS_ENABLED(CONFIG_IPV6)
struct netns_ipv6 ipv6;
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index d2bc733a2ef1..5cb19ce454d1 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -49,6 +49,7 @@ union nf_conntrack_expect_proto {
struct nf_conntrack_net {
unsigned int users4;
unsigned int users6;
+ unsigned int users_bridge;
};
#include <linux/types.h>
diff --git a/include/net/netfilter/nf_conntrack_bridge.h b/include/net/netfilter/nf_conntrack_bridge.h
new file mode 100644
index 000000000000..9a5514d5bc51
--- /dev/null
+++ b/include/net/netfilter/nf_conntrack_bridge.h
@@ -0,0 +1,20 @@
+#ifndef NF_CONNTRACK_BRIDGE_
+#define NF_CONNTRACK_BRIDGE_
+
+struct nf_ct_bridge_info {
+ struct nf_hook_ops *ops;
+ unsigned int ops_size;
+ struct module *me;
+};
+
+void nf_ct_bridge_register(struct nf_ct_bridge_info *info);
+void nf_ct_bridge_unregister(struct nf_ct_bridge_info *info);
+
+struct nf_ct_bridge_frag_data {
+ char mac[ETH_HLEN];
+ bool vlan_present;
+ u16 vlan_tci;
+ __be16 vlan_proto;
+};
+
+#endif
diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h
index ae41e92251dd..de10faf2ce91 100644
--- a/include/net/netfilter/nf_conntrack_core.h
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -64,6 +64,9 @@ static inline int nf_conntrack_confirm(struct sk_buff *skb)
return ret;
}
+unsigned int nf_confirm(struct sk_buff *skb, unsigned int protoff,
+ struct nf_conn *ct, enum ip_conntrack_info ctinfo);
+
void print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
const struct nf_conntrack_l4proto *proto);
diff --git a/include/net/netns/ieee802154_6lowpan.h b/include/net/netns/ieee802154_6lowpan.h
index 736aeac52f56..95406e1342cb 100644
--- a/include/net/netns/ieee802154_6lowpan.h
+++ b/include/net/netns/ieee802154_6lowpan.h
@@ -16,7 +16,7 @@ struct netns_sysctl_lowpan {
struct netns_ieee802154_lowpan {
struct netns_sysctl_lowpan sysctl;
- struct netns_frags frags;
+ struct fqdir *fqdir;
};
#endif
diff --git a/include/net/netns/ipv4.h b/include/net/netns/ipv4.h
index 7698460a3dd1..c07cee1e0c9e 100644
--- a/include/net/netns/ipv4.h
+++ b/include/net/netns/ipv4.h
@@ -72,7 +72,7 @@ struct netns_ipv4 {
struct inet_peer_base *peers;
struct sock * __percpu *tcp_sk;
- struct netns_frags frags;
+ struct fqdir *fqdir;
#ifdef CONFIG_NETFILTER
struct xt_table *iptable_filter;
struct xt_table *iptable_mangle;
diff --git a/include/net/netns/ipv6.h b/include/net/netns/ipv6.h
index 5e61b5a8635d..022a0fd1a5a4 100644
--- a/include/net/netns/ipv6.h
+++ b/include/net/netns/ipv6.h
@@ -58,7 +58,7 @@ struct netns_ipv6 {
struct ipv6_devconf *devconf_all;
struct ipv6_devconf *devconf_dflt;
struct inet_peer_base *peers;
- struct netns_frags frags;
+ struct fqdir *fqdir;
#ifdef CONFIG_NETFILTER
struct xt_table *ip6table_filter;
struct xt_table *ip6table_mangle;
@@ -116,7 +116,7 @@ struct netns_ipv6 {
#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
struct netns_nf_frag {
- struct netns_frags frags;
+ struct fqdir *fqdir;
};
#endif
diff --git a/include/net/netns/nexthop.h b/include/net/netns/nexthop.h
new file mode 100644
index 000000000000..c712ee5eebd9
--- /dev/null
+++ b/include/net/netns/nexthop.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * nexthops in net namespaces
+ */
+
+#ifndef __NETNS_NEXTHOP_H__
+#define __NETNS_NEXTHOP_H__
+
+#include <linux/rbtree.h>
+
+struct netns_nexthop {
+ struct rb_root rb_root; /* tree of nexthops by id */
+ struct hlist_head *devhash; /* nexthops by device */
+
+ unsigned int seq; /* protected by rtnl_mutex */
+ u32 last_id_allocated;
+};
+#endif
diff --git a/include/net/nexthop.h b/include/net/nexthop.h
new file mode 100644
index 000000000000..6e1b8f53624c
--- /dev/null
+++ b/include/net/nexthop.h
@@ -0,0 +1,195 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Generic nexthop implementation
+ *
+ * Copyright (c) 2017-19 Cumulus Networks
+ * Copyright (c) 2017-19 David Ahern <dsa@cumulusnetworks.com>
+ */
+
+#ifndef __LINUX_NEXTHOP_H
+#define __LINUX_NEXTHOP_H
+
+#include <linux/netdevice.h>
+#include <linux/types.h>
+#include <net/ip_fib.h>
+#include <net/ip6_fib.h>
+#include <net/netlink.h>
+
+#define NEXTHOP_VALID_USER_FLAGS RTNH_F_ONLINK
+
+struct nexthop;
+
+struct nh_config {
+ u32 nh_id;
+
+ u8 nh_family;
+ u8 nh_protocol;
+ u8 nh_blackhole;
+ u32 nh_flags;
+
+ int nh_ifindex;
+ struct net_device *dev;
+
+ union {
+ __be32 ipv4;
+ struct in6_addr ipv6;
+ } gw;
+
+ struct nlattr *nh_grp;
+ u16 nh_grp_type;
+
+ struct nlattr *nh_encap;
+ u16 nh_encap_type;
+
+ u32 nlflags;
+ struct nl_info nlinfo;
+};
+
+struct nh_info {
+ struct hlist_node dev_hash; /* entry on netns devhash */
+ struct nexthop *nh_parent;
+
+ u8 family;
+ bool reject_nh;
+
+ union {
+ struct fib_nh_common fib_nhc;
+ struct fib_nh fib_nh;
+ struct fib6_nh fib6_nh;
+ };
+};
+
+struct nh_grp_entry {
+ struct nexthop *nh;
+ u8 weight;
+ atomic_t upper_bound;
+
+ struct list_head nh_list;
+ struct nexthop *nh_parent; /* nexthop of group with this entry */
+};
+
+struct nh_group {
+ u16 num_nh;
+ bool mpath;
+ bool has_v4;
+ struct nh_grp_entry nh_entries[0];
+};
+
+struct nexthop {
+ struct rb_node rb_node; /* entry on netns rbtree */
+ struct list_head grp_list; /* nh group entries using this nh */
+ struct net *net;
+
+ u32 id;
+
+ u8 protocol; /* app managing this nh */
+ u8 nh_flags;
+ bool is_group;
+
+ refcount_t refcnt;
+ struct rcu_head rcu;
+
+ union {
+ struct nh_info __rcu *nh_info;
+ struct nh_group __rcu *nh_grp;
+ };
+};
+
+/* caller is holding rcu or rtnl; no reference taken to nexthop */
+struct nexthop *nexthop_find_by_id(struct net *net, u32 id);
+void nexthop_free_rcu(struct rcu_head *head);
+
+static inline bool nexthop_get(struct nexthop *nh)
+{
+ return refcount_inc_not_zero(&nh->refcnt);
+}
+
+static inline void nexthop_put(struct nexthop *nh)
+{
+ if (refcount_dec_and_test(&nh->refcnt))
+ call_rcu(&nh->rcu, nexthop_free_rcu);
+}
+
+static inline bool nexthop_is_multipath(const struct nexthop *nh)
+{
+ if (nh->is_group) {
+ struct nh_group *nh_grp;
+
+ nh_grp = rcu_dereference_rtnl(nh->nh_grp);
+ return nh_grp->mpath;
+ }
+ return false;
+}
+
+struct nexthop *nexthop_select_path(struct nexthop *nh, int hash);
+
+static inline unsigned int nexthop_num_path(const struct nexthop *nh)
+{
+ unsigned int rc = 1;
+
+ if (nexthop_is_multipath(nh)) {
+ struct nh_group *nh_grp;
+
+ nh_grp = rcu_dereference_rtnl(nh->nh_grp);
+ rc = nh_grp->num_nh;
+ } else {
+ const struct nh_info *nhi;
+
+ nhi = rcu_dereference_rtnl(nh->nh_info);
+ if (nhi->reject_nh)
+ rc = 0;
+ }
+
+ return rc;
+}
+
+static inline
+struct nexthop *nexthop_mpath_select(const struct nexthop *nh, int nhsel)
+{
+ const struct nh_group *nhg = rcu_dereference_rtnl(nh->nh_grp);
+
+ /* for_nexthops macros in fib_semantics.c grabs a pointer to
+ * the nexthop before checking nhsel
+ */
+ if (nhsel > nhg->num_nh)
+ return NULL;
+
+ return nhg->nh_entries[nhsel].nh;
+}
+
+static inline
+int nexthop_mpath_fill_node(struct sk_buff *skb, struct nexthop *nh)
+{
+ struct nh_group *nhg = rtnl_dereference(nh->nh_grp);
+ int i;
+
+ for (i = 0; i < nhg->num_nh; i++) {
+ struct nexthop *nhe = nhg->nh_entries[i].nh;
+ struct nh_info *nhi = rcu_dereference_rtnl(nhe->nh_info);
+ struct fib_nh_common *nhc = &nhi->fib_nhc;
+ int weight = nhg->nh_entries[i].weight;
+
+ if (fib_add_nexthop(skb, nhc, weight) < 0)
+ return -EMSGSIZE;
+ }
+
+ return 0;
+}
+
+/* called with rcu lock */
+static inline bool nexthop_is_blackhole(const struct nexthop *nh)
+{
+ const struct nh_info *nhi;
+
+ if (nexthop_is_multipath(nh)) {
+ if (nexthop_num_path(nh) > 1)
+ return false;
+ nh = nexthop_mpath_select(nh, 0);
+ if (!nh)
+ return false;
+ }
+
+ nhi = rcu_dereference_rtnl(nh->nh_info);
+ return nhi->reject_nh;
+}
+#endif
diff --git a/include/net/sctp/checksum.h b/include/net/sctp/checksum.h
index 314699333bec..5a9bb09f32b6 100644
--- a/include/net/sctp/checksum.h
+++ b/include/net/sctp/checksum.h
@@ -43,19 +43,21 @@ static inline __wsum sctp_csum_combine(__wsum csum, __wsum csum2,
(__force __u32)csum2, len);
}
+static const struct skb_checksum_ops sctp_csum_ops = {
+ .update = sctp_csum_update,
+ .combine = sctp_csum_combine,
+};
+
static inline __le32 sctp_compute_cksum(const struct sk_buff *skb,
unsigned int offset)
{
struct sctphdr *sh = (struct sctphdr *)(skb->data + offset);
- const struct skb_checksum_ops ops = {
- .update = sctp_csum_update,
- .combine = sctp_csum_combine,
- };
__le32 old = sh->checksum;
__wsum new;
sh->checksum = 0;
- new = ~__skb_checksum(skb, offset, skb->len - offset, ~(__wsum)0, &ops);
+ new = ~__skb_checksum(skb, offset, skb->len - offset, ~(__wsum)0,
+ &sctp_csum_ops);
sh->checksum = old;
return cpu_to_le32((__force __u32)new);
diff --git a/include/net/tc_act/tc_ctinfo.h b/include/net/tc_act/tc_ctinfo.h
new file mode 100644
index 000000000000..d6a688571672
--- /dev/null
+++ b/include/net/tc_act/tc_ctinfo.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __NET_TC_CTINFO_H
+#define __NET_TC_CTINFO_H
+
+#include <net/act_api.h>
+
+struct tcf_ctinfo_params {
+ struct rcu_head rcu;
+ struct net *net;
+ u32 dscpmask;
+ u32 dscpstatemask;
+ u32 cpmarkmask;
+ u16 zone;
+ u8 mode;
+ u8 dscpmaskshift;
+};
+
+struct tcf_ctinfo {
+ struct tc_action common;
+ struct tcf_ctinfo_params __rcu *params;
+ u64 stats_dscp_set;
+ u64 stats_dscp_error;
+ u64 stats_cpmark_set;
+};
+
+#define to_ctinfo(a) ((struct tcf_ctinfo *)a)
+
+#endif /* __NET_TC_CTINFO_H */
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 985aa5db570c..0083a14fb64f 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1614,7 +1614,8 @@ void tcp_free_fastopen_req(struct tcp_sock *tp);
void tcp_fastopen_destroy_cipher(struct sock *sk);
void tcp_fastopen_ctx_destroy(struct net *net);
int tcp_fastopen_reset_cipher(struct net *net, struct sock *sk,
- void *key, unsigned int len);
+ void *primary_key, void *backup_key,
+ unsigned int len);
void tcp_fastopen_add_skb(struct sock *sk, struct sk_buff *skb);
struct sock *tcp_try_fastopen(struct sock *sk, struct sk_buff *skb,
struct request_sock *req,
@@ -1625,11 +1626,14 @@ 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
+#define TCP_FASTOPEN_KEY_MAX 2
+#define TCP_FASTOPEN_KEY_BUF_LENGTH \
+ (TCP_FASTOPEN_KEY_LENGTH * TCP_FASTOPEN_KEY_MAX)
/* Fastopen key context */
struct tcp_fastopen_context {
- struct crypto_cipher *tfm;
- __u8 key[TCP_FASTOPEN_KEY_LENGTH];
+ struct crypto_cipher *tfm[TCP_FASTOPEN_KEY_MAX];
+ __u8 key[TCP_FASTOPEN_KEY_BUF_LENGTH];
struct rcu_head rcu;
};
@@ -1639,6 +1643,37 @@ bool tcp_fastopen_active_should_disable(struct sock *sk);
void tcp_fastopen_active_disable_ofo_check(struct sock *sk);
void tcp_fastopen_active_detect_blackhole(struct sock *sk, bool expired);
+/* Caller needs to wrap with rcu_read_(un)lock() */
+static inline
+struct tcp_fastopen_context *tcp_fastopen_get_ctx(const struct sock *sk)
+{
+ struct tcp_fastopen_context *ctx;
+
+ ctx = rcu_dereference(inet_csk(sk)->icsk_accept_queue.fastopenq.ctx);
+ if (!ctx)
+ ctx = rcu_dereference(sock_net(sk)->ipv4.tcp_fastopen_ctx);
+ return ctx;
+}
+
+static inline
+bool tcp_fastopen_cookie_match(const struct tcp_fastopen_cookie *foc,
+ const struct tcp_fastopen_cookie *orig)
+{
+ if (orig->len == TCP_FASTOPEN_COOKIE_SIZE &&
+ orig->len == foc->len &&
+ !memcmp(orig->val, foc->val, foc->len))
+ return true;
+ return false;
+}
+
+static inline
+int tcp_fastopen_context_len(const struct tcp_fastopen_context *ctx)
+{
+ if (ctx->tfm[1])
+ return 2;
+ return 1;
+}
+
/* Latencies incurred by various limits for a sender. They are
* chronograph-like stats that are mutually exclusive.
*/
diff --git a/include/trace/events/neigh.h b/include/trace/events/neigh.h
index 0bdb08557763..62bb17516713 100644
--- a/include/trace/events/neigh.h
+++ b/include/trace/events/neigh.h
@@ -20,6 +20,55 @@
{ NUD_NOARP, "noarp" }, \
{ NUD_PERMANENT, "permanent"})
+TRACE_EVENT(neigh_create,
+
+ TP_PROTO(struct neigh_table *tbl, struct net_device *dev,
+ const void *pkey, const struct neighbour *n,
+ bool exempt_from_gc),
+
+ TP_ARGS(tbl, dev, pkey, n, exempt_from_gc),
+
+ TP_STRUCT__entry(
+ __field(u32, family)
+ __dynamic_array(char, dev, IFNAMSIZ )
+ __field(int, entries)
+ __field(u8, created)
+ __field(u8, gc_exempt)
+ __array(u8, primary_key4, 4)
+ __array(u8, primary_key6, 16)
+ ),
+
+ TP_fast_assign(
+ struct in6_addr *pin6;
+ __be32 *p32;
+
+ __entry->family = tbl->family;
+ __assign_str(dev, (dev ? dev->name : "NULL"));
+ __entry->entries = atomic_read(&tbl->gc_entries);
+ __entry->created = n != NULL;
+ __entry->gc_exempt = exempt_from_gc;
+ pin6 = (struct in6_addr *)__entry->primary_key6;
+ p32 = (__be32 *)__entry->primary_key4;
+
+ if (tbl->family == AF_INET)
+ *p32 = *(__be32 *)pkey;
+ else
+ *p32 = 0;
+
+#if IS_ENABLED(CONFIG_IPV6)
+ if (tbl->family == AF_INET6) {
+ pin6 = (struct in6_addr *)__entry->primary_key6;
+ *pin6 = *(struct in6_addr *)pkey;
+ }
+#endif
+ ),
+
+ TP_printk("family %d dev %s entries %d primary_key4 %pI4 primary_key6 %pI6c created %d gc_exempt %d",
+ __entry->family, __get_str(dev), __entry->entries,
+ __entry->primary_key4, __entry->primary_key6,
+ __entry->created, __entry->gc_exempt)
+);
+
TRACE_EVENT(neigh_update,
TP_PROTO(struct neighbour *n, const u8 *lladdr, u8 new,
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index 3534ce157ae9..dd06302aa93e 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -1483,6 +1483,8 @@ enum ethtool_link_mode_bit_indices {
ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT = 64,
ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT = 65,
ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT = 66,
+ ETHTOOL_LINK_MODE_100baseT1_Full_BIT = 67,
+ ETHTOOL_LINK_MODE_1000baseT1_Full_BIT = 68,
/* must be last entry */
__ETHTOOL_LINK_MODE_MASK_NBITS
diff --git a/include/uapi/linux/nexthop.h b/include/uapi/linux/nexthop.h
new file mode 100644
index 000000000000..7b61867e9848
--- /dev/null
+++ b/include/uapi/linux/nexthop.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _UAPI_LINUX_NEXTHOP_H
+#define _UAPI_LINUX_NEXTHOP_H
+
+#include <linux/types.h>
+
+struct nhmsg {
+ unsigned char nh_family;
+ unsigned char nh_scope; /* return only */
+ unsigned char nh_protocol; /* Routing protocol that installed nh */
+ unsigned char resvd;
+ unsigned int nh_flags; /* RTNH_F flags */
+};
+
+/* entry in a nexthop group */
+struct nexthop_grp {
+ __u32 id; /* nexthop id - must exist */
+ __u8 weight; /* weight of this nexthop */
+ __u8 resvd1;
+ __u16 resvd2;
+};
+
+enum {
+ NEXTHOP_GRP_TYPE_MPATH, /* default type if not specified */
+ __NEXTHOP_GRP_TYPE_MAX,
+};
+
+#define NEXTHOP_GRP_TYPE_MAX (__NEXTHOP_GRP_TYPE_MAX - 1)
+
+enum {
+ NHA_UNSPEC,
+ NHA_ID, /* u32; id for nexthop. id == 0 means auto-assign */
+
+ NHA_GROUP, /* array of nexthop_grp */
+ NHA_GROUP_TYPE, /* u16 one of NEXTHOP_GRP_TYPE */
+ /* if NHA_GROUP attribute is added, no other attributes can be set */
+
+ NHA_BLACKHOLE, /* flag; nexthop used to blackhole packets */
+ /* if NHA_BLACKHOLE is added, OIF, GATEWAY, ENCAP can not be set */
+
+ NHA_OIF, /* u32; nexthop device */
+ NHA_GATEWAY, /* be32 (IPv4) or in6_addr (IPv6) gw address */
+ NHA_ENCAP_TYPE, /* u16; lwt encap type */
+ NHA_ENCAP, /* lwt encap data */
+
+ /* NHA_OIF can be appended to dump request to return only
+ * nexthops using given device
+ */
+ NHA_GROUPS, /* flag; only return nexthop groups in dump */
+ NHA_MASTER, /* u32; only return nexthops with given master dev */
+
+ __NHA_MAX,
+};
+
+#define NHA_MAX (__NHA_MAX - 1)
+#endif
diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
index 51a0496f78ea..a93680fc4bfa 100644
--- a/include/uapi/linux/pkt_cls.h
+++ b/include/uapi/linux/pkt_cls.h
@@ -105,6 +105,7 @@ enum tca_id {
TCA_ID_IFE = TCA_ACT_IFE,
TCA_ID_SAMPLE = TCA_ACT_SAMPLE,
/* other actions go here */
+ TCA_ID_CTINFO,
__TCA_ID_MAX = 255
};
diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index 46399367627f..ce2a623abb75 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -157,6 +157,13 @@ enum {
RTM_GETCHAIN,
#define RTM_GETCHAIN RTM_GETCHAIN
+ RTM_NEWNEXTHOP = 104,
+#define RTM_NEWNEXTHOP RTM_NEWNEXTHOP
+ RTM_DELNEXTHOP,
+#define RTM_DELNEXTHOP RTM_DELNEXTHOP
+ RTM_GETNEXTHOP,
+#define RTM_GETNEXTHOP RTM_GETNEXTHOP
+
__RTM_MAX,
#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
};
@@ -342,6 +349,7 @@ enum rtattr_type_t {
RTA_IP_PROTO,
RTA_SPORT,
RTA_DPORT,
+ RTA_NH_ID,
__RTA_MAX
};
@@ -704,6 +712,8 @@ enum rtnetlink_groups {
#define RTNLGRP_IPV4_MROUTE_R RTNLGRP_IPV4_MROUTE_R
RTNLGRP_IPV6_MROUTE_R,
#define RTNLGRP_IPV6_MROUTE_R RTNLGRP_IPV6_MROUTE_R
+ RTNLGRP_NEXTHOP,
+#define RTNLGRP_NEXTHOP RTNLGRP_NEXTHOP
__RTNLGRP_MAX
};
#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
diff --git a/include/uapi/linux/snmp.h b/include/uapi/linux/snmp.h
index 86dc24a96c90..74904e9d1b72 100644
--- a/include/uapi/linux/snmp.h
+++ b/include/uapi/linux/snmp.h
@@ -283,6 +283,7 @@ enum
LINUX_MIB_TCPACKCOMPRESSED, /* TCPAckCompressed */
LINUX_MIB_TCPZEROWINDOWDROP, /* TCPZeroWindowDrop */
LINUX_MIB_TCPRCVQDROP, /* TCPRcvQDrop */
+ LINUX_MIB_TCPFASTOPENPASSIVEALTKEY, /* TCPFastOpenPassiveAltKey */
__LINUX_MIB_MAX
};
diff --git a/include/uapi/linux/tc_act/tc_ctinfo.h b/include/uapi/linux/tc_act/tc_ctinfo.h
new file mode 100644
index 000000000000..da803e05a89b
--- /dev/null
+++ b/include/uapi/linux/tc_act/tc_ctinfo.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef __UAPI_TC_CTINFO_H
+#define __UAPI_TC_CTINFO_H
+
+#include <linux/types.h>
+#include <linux/pkt_cls.h>
+
+struct tc_ctinfo {
+ tc_gen;
+};
+
+enum {
+ TCA_CTINFO_UNSPEC,
+ TCA_CTINFO_PAD,
+ TCA_CTINFO_TM,
+ TCA_CTINFO_ACT,
+ TCA_CTINFO_ZONE,
+ TCA_CTINFO_PARMS_DSCP_MASK,
+ TCA_CTINFO_PARMS_DSCP_STATEMASK,
+ TCA_CTINFO_PARMS_CPMARK_MASK,
+ TCA_CTINFO_STATS_DSCP_SET,
+ TCA_CTINFO_STATS_DSCP_ERROR,
+ TCA_CTINFO_STATS_CPMARK_SET,
+ __TCA_CTINFO_MAX
+};
+
+#define TCA_CTINFO_MAX (__TCA_CTINFO_MAX - 1)
+
+enum {
+ CTINFO_MODE_DSCP = BIT(0),
+ CTINFO_MODE_CPMARK = BIT(1)
+};
+
+#endif
diff --git a/include/uapi/linux/unix_diag.h b/include/uapi/linux/unix_diag.h
index 5c502fdf7a42..a1988576fa8a 100644
--- a/include/uapi/linux/unix_diag.h
+++ b/include/uapi/linux/unix_diag.h
@@ -20,6 +20,7 @@ struct unix_diag_req {
#define UDIAG_SHOW_ICONS 0x00000008 /* show pending connections */
#define UDIAG_SHOW_RQLEN 0x00000010 /* show skb receive queue len */
#define UDIAG_SHOW_MEMINFO 0x00000020 /* show memory info of a socket */
+#define UDIAG_SHOW_UID 0x00000040 /* show socket's UID */
struct unix_diag_msg {
__u8 udiag_family;
@@ -40,6 +41,7 @@ enum {
UNIX_DIAG_RQLEN,
UNIX_DIAG_MEMINFO,
UNIX_DIAG_SHUTDOWN,
+ UNIX_DIAG_UID,
__UNIX_DIAG_MAX,
};