mirror of
https://github.com/Dasharo/linux.git
synced 2026-03-06 15:25:10 -08:00
Merge tag 'net-6.14-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Pull networking fixes from Paolo Abeni:
"Smaller than usual with no fixes from any subtree.
Current release - regressions:
- core: fix race of rtnl_net_lock(dev_net(dev))
Previous releases - regressions:
- core: remove the single page frag cache for good
- flow_dissector: fix handling of mixed port and port-range keys
- sched: cls_api: fix error handling causing NULL dereference
- tcp:
- adjust rcvq_space after updating scaling ratio
- drop secpath at the same time as we currently drop dst
- eth: gtp: suppress list corruption splat in gtp_net_exit_batch_rtnl().
Previous releases - always broken:
- vsock:
- fix variables initialization during resuming
- for connectible sockets allow only connected
- eth:
- geneve: fix use-after-free in geneve_find_dev()
- ibmvnic: don't reference skb after sending to VIOS"
* tag 'net-6.14-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (34 commits)
Revert "net: skb: introduce and use a single page frag cache"
net: allow small head cache usage with large MAX_SKB_FRAGS values
nfp: bpf: Add check for nfp_app_ctrl_msg_alloc()
tcp: drop secpath at the same time as we currently drop dst
net: axienet: Set mac_managed_pm
arp: switch to dev_getbyhwaddr() in arp_req_set_public()
net: Add non-RCU dev_getbyhwaddr() helper
sctp: Fix undefined behavior in left shift operation
selftests/bpf: Add a specific dst port matching
flow_dissector: Fix port range key handling in BPF conversion
selftests/net/forwarding: Add a test case for tc-flower of mixed port and port-range
flow_dissector: Fix handling of mixed port and port-range keys
geneve: Suppress list corruption splat in geneve_destroy_tunnels().
gtp: Suppress list corruption splat in gtp_net_exit_batch_rtnl().
dev: Use rtnl_net_dev_lock() in unregister_netdev().
net: Fix dev_net(dev) race in unregister_netdevice_notifier_dev_net().
net: Add net_passive_inc() and net_passive_dec().
net: pse-pd: pd692x0: Fix power limit retrieval
MAINTAINERS: trim the GVE entry
gve: set xdp redirect target only when it is available
...
This commit is contained in:
@@ -9829,8 +9829,7 @@ F: drivers/input/touchscreen/goodix*
|
||||
|
||||
GOOGLE ETHERNET DRIVERS
|
||||
M: Jeroen de Borst <jeroendb@google.com>
|
||||
M: Praveen Kaligineedi <pkaligineedi@google.com>
|
||||
R: Shailend Chand <shailend@google.com>
|
||||
M: Harshitha Ramamurthy <hramamurthy@google.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/networking/device_drivers/ethernet/google/gve.rst
|
||||
@@ -16472,6 +16471,12 @@ F: net/ethtool/cabletest.c
|
||||
F: tools/testing/selftests/drivers/net/*/ethtool*
|
||||
K: cable_test
|
||||
|
||||
NETWORKING [ETHTOOL MAC MERGE]
|
||||
M: Vladimir Oltean <vladimir.oltean@nxp.com>
|
||||
F: net/ethtool/mm.c
|
||||
F: tools/testing/selftests/drivers/net/hw/ethtool_mm.sh
|
||||
K: ethtool_mm
|
||||
|
||||
NETWORKING [GENERAL]
|
||||
M: "David S. Miller" <davem@davemloft.net>
|
||||
M: Eric Dumazet <edumazet@google.com>
|
||||
|
||||
@@ -1116,6 +1116,16 @@ static inline u32 gve_xdp_tx_start_queue_id(struct gve_priv *priv)
|
||||
return gve_xdp_tx_queue_id(priv, 0);
|
||||
}
|
||||
|
||||
static inline bool gve_supports_xdp_xmit(struct gve_priv *priv)
|
||||
{
|
||||
switch (priv->queue_format) {
|
||||
case GVE_GQI_QPL_FORMAT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* gqi napi handler defined in gve_main.c */
|
||||
int gve_napi_poll(struct napi_struct *napi, int budget);
|
||||
|
||||
|
||||
@@ -1903,6 +1903,8 @@ static void gve_turndown(struct gve_priv *priv)
|
||||
/* Stop tx queues */
|
||||
netif_tx_disable(priv->dev);
|
||||
|
||||
xdp_features_clear_redirect_target(priv->dev);
|
||||
|
||||
gve_clear_napi_enabled(priv);
|
||||
gve_clear_report_stats(priv);
|
||||
|
||||
@@ -1972,6 +1974,9 @@ static void gve_turnup(struct gve_priv *priv)
|
||||
napi_schedule(&block->napi);
|
||||
}
|
||||
|
||||
if (priv->num_xdp_queues && gve_supports_xdp_xmit(priv))
|
||||
xdp_features_set_redirect_target(priv->dev, false);
|
||||
|
||||
gve_set_napi_enabled(priv);
|
||||
}
|
||||
|
||||
@@ -2246,7 +2251,6 @@ static void gve_set_netdev_xdp_features(struct gve_priv *priv)
|
||||
if (priv->queue_format == GVE_GQI_QPL_FORMAT) {
|
||||
xdp_features = NETDEV_XDP_ACT_BASIC;
|
||||
xdp_features |= NETDEV_XDP_ACT_REDIRECT;
|
||||
xdp_features |= NETDEV_XDP_ACT_NDO_XMIT;
|
||||
xdp_features |= NETDEV_XDP_ACT_XSK_ZEROCOPY;
|
||||
} else {
|
||||
xdp_features = 0;
|
||||
|
||||
@@ -2408,6 +2408,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
|
||||
dma_addr_t data_dma_addr;
|
||||
struct netdev_queue *txq;
|
||||
unsigned long lpar_rc;
|
||||
unsigned int skblen;
|
||||
union sub_crq tx_crq;
|
||||
unsigned int offset;
|
||||
bool use_scrq_send_direct = false;
|
||||
@@ -2522,6 +2523,7 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev)
|
||||
tx_buff->skb = skb;
|
||||
tx_buff->index = bufidx;
|
||||
tx_buff->pool_index = queue_num;
|
||||
skblen = skb->len;
|
||||
|
||||
memset(&tx_crq, 0, sizeof(tx_crq));
|
||||
tx_crq.v1.first = IBMVNIC_CRQ_CMD;
|
||||
@@ -2614,7 +2616,7 @@ early_exit:
|
||||
netif_stop_subqueue(netdev, queue_num);
|
||||
}
|
||||
|
||||
tx_bytes += skb->len;
|
||||
tx_bytes += skblen;
|
||||
txq_trans_cond_update(txq);
|
||||
ret = NETDEV_TX_OK;
|
||||
goto out;
|
||||
|
||||
@@ -20,6 +20,8 @@ nfp_bpf_cmsg_alloc(struct nfp_app_bpf *bpf, unsigned int size)
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = nfp_app_ctrl_msg_alloc(bpf->app, size, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return NULL;
|
||||
skb_put(skb, size);
|
||||
|
||||
return skb;
|
||||
|
||||
@@ -2897,6 +2897,7 @@ static int axienet_probe(struct platform_device *pdev)
|
||||
|
||||
lp->phylink_config.dev = &ndev->dev;
|
||||
lp->phylink_config.type = PHYLINK_NETDEV;
|
||||
lp->phylink_config.mac_managed_pm = true;
|
||||
lp->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE |
|
||||
MAC_10FD | MAC_100FD | MAC_1000FD;
|
||||
|
||||
|
||||
@@ -1902,21 +1902,9 @@ static void geneve_destroy_tunnels(struct net *net, struct list_head *head)
|
||||
{
|
||||
struct geneve_net *gn = net_generic(net, geneve_net_id);
|
||||
struct geneve_dev *geneve, *next;
|
||||
struct net_device *dev, *aux;
|
||||
|
||||
/* gather any geneve devices that were moved into this ns */
|
||||
for_each_netdev_safe(net, dev, aux)
|
||||
if (dev->rtnl_link_ops == &geneve_link_ops)
|
||||
unregister_netdevice_queue(dev, head);
|
||||
|
||||
/* now gather any other geneve devices that were created in this ns */
|
||||
list_for_each_entry_safe(geneve, next, &gn->geneve_list, next) {
|
||||
/* If geneve->dev is in the same netns, it was already added
|
||||
* to the list by the previous loop.
|
||||
*/
|
||||
if (!net_eq(dev_net(geneve->dev), net))
|
||||
unregister_netdevice_queue(geneve->dev, head);
|
||||
}
|
||||
list_for_each_entry_safe(geneve, next, &gn->geneve_list, next)
|
||||
geneve_dellink(geneve->dev, head);
|
||||
}
|
||||
|
||||
static void __net_exit geneve_exit_batch_rtnl(struct list_head *net_list,
|
||||
|
||||
@@ -2481,11 +2481,6 @@ static void __net_exit gtp_net_exit_batch_rtnl(struct list_head *net_list,
|
||||
list_for_each_entry(net, net_list, exit_list) {
|
||||
struct gtp_net *gn = net_generic(net, gtp_net_id);
|
||||
struct gtp_dev *gtp, *gtp_next;
|
||||
struct net_device *dev;
|
||||
|
||||
for_each_netdev(net, dev)
|
||||
if (dev->rtnl_link_ops == >p_link_ops)
|
||||
gtp_dellink(dev, dev_to_kill);
|
||||
|
||||
list_for_each_entry_safe(gtp, gtp_next, &gn->gtp_dev_list, list)
|
||||
gtp_dellink(gtp->dev, dev_to_kill);
|
||||
|
||||
@@ -1047,7 +1047,7 @@ static int pd692x0_pi_get_pw_limit(struct pse_controller_dev *pcdev,
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return pd692x0_pi_get_pw_from_table(buf.data[2], buf.data[3]);
|
||||
return pd692x0_pi_get_pw_from_table(buf.data[0], buf.data[1]);
|
||||
}
|
||||
|
||||
static int pd692x0_pi_set_pw_limit(struct pse_controller_dev *pcdev,
|
||||
|
||||
@@ -220,7 +220,7 @@ static int mbim_rx_verify_nth16(struct mhi_mbim_context *mbim, struct sk_buff *s
|
||||
if (mbim->rx_seq + 1 != le16_to_cpu(nth16->wSequence) &&
|
||||
(mbim->rx_seq || le16_to_cpu(nth16->wSequence)) &&
|
||||
!(mbim->rx_seq == 0xffff && !le16_to_cpu(nth16->wSequence))) {
|
||||
net_err_ratelimited("sequence number glitch prev=%d curr=%d\n",
|
||||
net_dbg_ratelimited("sequence number glitch prev=%d curr=%d\n",
|
||||
mbim->rx_seq, le16_to_cpu(nth16->wSequence));
|
||||
}
|
||||
mbim->rx_seq = le16_to_cpu(nth16->wSequence);
|
||||
|
||||
@@ -588,6 +588,15 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ism_dev_release(struct device *dev)
|
||||
{
|
||||
struct ism_dev *ism;
|
||||
|
||||
ism = container_of(dev, struct ism_dev, dev);
|
||||
|
||||
kfree(ism);
|
||||
}
|
||||
|
||||
static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
{
|
||||
struct ism_dev *ism;
|
||||
@@ -601,6 +610,7 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
dev_set_drvdata(&pdev->dev, ism);
|
||||
ism->pdev = pdev;
|
||||
ism->dev.parent = &pdev->dev;
|
||||
ism->dev.release = ism_dev_release;
|
||||
device_initialize(&ism->dev);
|
||||
dev_set_name(&ism->dev, dev_name(&pdev->dev));
|
||||
ret = device_add(&ism->dev);
|
||||
@@ -637,7 +647,7 @@ err:
|
||||
device_del(&ism->dev);
|
||||
err_dev:
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
kfree(ism);
|
||||
put_device(&ism->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -682,7 +692,7 @@ static void ism_remove(struct pci_dev *pdev)
|
||||
pci_disable_device(pdev);
|
||||
device_del(&ism->dev);
|
||||
dev_set_drvdata(&pdev->dev, NULL);
|
||||
kfree(ism);
|
||||
put_device(&ism->dev);
|
||||
}
|
||||
|
||||
static struct pci_driver ism_driver = {
|
||||
|
||||
@@ -3275,6 +3275,8 @@ static inline struct net_device *first_net_device_rcu(struct net *net)
|
||||
}
|
||||
|
||||
int netdev_boot_setup_check(struct net_device *dev);
|
||||
struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type,
|
||||
const char *hwaddr);
|
||||
struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type,
|
||||
const char *hwaddr);
|
||||
struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type);
|
||||
@@ -4115,7 +4117,6 @@ void netif_receive_skb_list(struct list_head *head);
|
||||
gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb);
|
||||
void napi_gro_flush(struct napi_struct *napi, bool flush_old);
|
||||
struct sk_buff *napi_get_frags(struct napi_struct *napi);
|
||||
void napi_get_frags_check(struct napi_struct *napi);
|
||||
gro_result_t napi_gro_frags(struct napi_struct *napi);
|
||||
|
||||
static inline void napi_free_frags(struct napi_struct *napi)
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
#include <net/udp.h>
|
||||
#include <net/hotdata.h>
|
||||
|
||||
/* This should be increased if a protocol with a bigger head is added. */
|
||||
#define GRO_MAX_HEAD (MAX_HEADER + 128)
|
||||
|
||||
struct napi_gro_cb {
|
||||
union {
|
||||
struct {
|
||||
|
||||
@@ -297,6 +297,7 @@ static inline int check_net(const struct net *net)
|
||||
}
|
||||
|
||||
void net_drop_ns(void *);
|
||||
void net_passive_dec(struct net *net);
|
||||
|
||||
#else
|
||||
|
||||
@@ -326,8 +327,18 @@ static inline int check_net(const struct net *net)
|
||||
}
|
||||
|
||||
#define net_drop_ns NULL
|
||||
|
||||
static inline void net_passive_dec(struct net *net)
|
||||
{
|
||||
refcount_dec(&net->passive);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void net_passive_inc(struct net *net)
|
||||
{
|
||||
refcount_inc(&net->passive);
|
||||
}
|
||||
|
||||
/* Returns true if the netns initialization is completed successfully */
|
||||
static inline bool net_initialized(const struct net *net)
|
||||
{
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <net/inet_ecn.h>
|
||||
#include <net/dst.h>
|
||||
#include <net/mptcp.h>
|
||||
#include <net/xfrm.h>
|
||||
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/memcontrol.h>
|
||||
@@ -683,6 +684,19 @@ void tcp_fin(struct sock *sk);
|
||||
void tcp_check_space(struct sock *sk);
|
||||
void tcp_sack_compress_send_ack(struct sock *sk);
|
||||
|
||||
static inline void tcp_cleanup_skb(struct sk_buff *skb)
|
||||
{
|
||||
skb_dst_drop(skb);
|
||||
secpath_reset(skb);
|
||||
}
|
||||
|
||||
static inline void tcp_add_receive_queue(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
DEBUG_NET_WARN_ON_ONCE(skb_dst(skb));
|
||||
DEBUG_NET_WARN_ON_ONCE(secpath_exists(skb));
|
||||
__skb_queue_tail(&sk->sk_receive_queue, skb);
|
||||
}
|
||||
|
||||
/* tcp_timer.c */
|
||||
void tcp_init_xmit_timers(struct sock *);
|
||||
static inline void tcp_clear_xmit_timers(struct sock *sk)
|
||||
|
||||
108
net/core/dev.c
108
net/core/dev.c
@@ -1121,6 +1121,12 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool dev_addr_cmp(struct net_device *dev, unsigned short type,
|
||||
const char *ha)
|
||||
{
|
||||
return dev->type == type && !memcmp(dev->dev_addr, ha, dev->addr_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* dev_getbyhwaddr_rcu - find a device by its hardware address
|
||||
* @net: the applicable net namespace
|
||||
@@ -1129,7 +1135,7 @@ out:
|
||||
*
|
||||
* Search for an interface by MAC address. Returns NULL if the device
|
||||
* is not found or a pointer to the device.
|
||||
* The caller must hold RCU or RTNL.
|
||||
* The caller must hold RCU.
|
||||
* The returned device has not had its ref count increased
|
||||
* and the caller must therefore be careful about locking
|
||||
*
|
||||
@@ -1141,14 +1147,39 @@ struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type,
|
||||
struct net_device *dev;
|
||||
|
||||
for_each_netdev_rcu(net, dev)
|
||||
if (dev->type == type &&
|
||||
!memcmp(dev->dev_addr, ha, dev->addr_len))
|
||||
if (dev_addr_cmp(dev, type, ha))
|
||||
return dev;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(dev_getbyhwaddr_rcu);
|
||||
|
||||
/**
|
||||
* dev_getbyhwaddr() - find a device by its hardware address
|
||||
* @net: the applicable net namespace
|
||||
* @type: media type of device
|
||||
* @ha: hardware address
|
||||
*
|
||||
* Similar to dev_getbyhwaddr_rcu(), but the owner needs to hold
|
||||
* rtnl_lock.
|
||||
*
|
||||
* Context: rtnl_lock() must be held.
|
||||
* Return: pointer to the net_device, or NULL if not found
|
||||
*/
|
||||
struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type,
|
||||
const char *ha)
|
||||
{
|
||||
struct net_device *dev;
|
||||
|
||||
ASSERT_RTNL();
|
||||
for_each_netdev(net, dev)
|
||||
if (dev_addr_cmp(dev, type, ha))
|
||||
return dev;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(dev_getbyhwaddr);
|
||||
|
||||
struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type)
|
||||
{
|
||||
struct net_device *dev, *ret = NULL;
|
||||
@@ -2070,6 +2101,42 @@ static void __move_netdevice_notifier_net(struct net *src_net,
|
||||
__register_netdevice_notifier_net(dst_net, nb, true);
|
||||
}
|
||||
|
||||
static void rtnl_net_dev_lock(struct net_device *dev)
|
||||
{
|
||||
bool again;
|
||||
|
||||
do {
|
||||
struct net *net;
|
||||
|
||||
again = false;
|
||||
|
||||
/* netns might be being dismantled. */
|
||||
rcu_read_lock();
|
||||
net = dev_net_rcu(dev);
|
||||
net_passive_inc(net);
|
||||
rcu_read_unlock();
|
||||
|
||||
rtnl_net_lock(net);
|
||||
|
||||
#ifdef CONFIG_NET_NS
|
||||
/* dev might have been moved to another netns. */
|
||||
if (!net_eq(net, rcu_access_pointer(dev->nd_net.net))) {
|
||||
rtnl_net_unlock(net);
|
||||
net_passive_dec(net);
|
||||
again = true;
|
||||
}
|
||||
#endif
|
||||
} while (again);
|
||||
}
|
||||
|
||||
static void rtnl_net_dev_unlock(struct net_device *dev)
|
||||
{
|
||||
struct net *net = dev_net(dev);
|
||||
|
||||
rtnl_net_unlock(net);
|
||||
net_passive_dec(net);
|
||||
}
|
||||
|
||||
int register_netdevice_notifier_dev_net(struct net_device *dev,
|
||||
struct notifier_block *nb,
|
||||
struct netdev_net_notifier *nn)
|
||||
@@ -2077,6 +2144,11 @@ int register_netdevice_notifier_dev_net(struct net_device *dev,
|
||||
struct net *net = dev_net(dev);
|
||||
int err;
|
||||
|
||||
/* rtnl_net_lock() assumes dev is not yet published by
|
||||
* register_netdevice().
|
||||
*/
|
||||
DEBUG_NET_WARN_ON_ONCE(!list_empty(&dev->dev_list));
|
||||
|
||||
rtnl_net_lock(net);
|
||||
err = __register_netdevice_notifier_net(net, nb, false);
|
||||
if (!err) {
|
||||
@@ -2093,13 +2165,12 @@ int unregister_netdevice_notifier_dev_net(struct net_device *dev,
|
||||
struct notifier_block *nb,
|
||||
struct netdev_net_notifier *nn)
|
||||
{
|
||||
struct net *net = dev_net(dev);
|
||||
int err;
|
||||
|
||||
rtnl_net_lock(net);
|
||||
rtnl_net_dev_lock(dev);
|
||||
list_del(&nn->list);
|
||||
err = __unregister_netdevice_notifier_net(net, nb);
|
||||
rtnl_net_unlock(net);
|
||||
err = __unregister_netdevice_notifier_net(dev_net(dev), nb);
|
||||
rtnl_net_dev_unlock(dev);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -6920,6 +6991,23 @@ netif_napi_dev_list_add(struct net_device *dev, struct napi_struct *napi)
|
||||
list_add_rcu(&napi->dev_list, higher); /* adds after higher */
|
||||
}
|
||||
|
||||
/* Double check that napi_get_frags() allocates skbs with
|
||||
* skb->head being backed by slab, not a page fragment.
|
||||
* This is to make sure bug fixed in 3226b158e67c
|
||||
* ("net: avoid 32 x truesize under-estimation for tiny skbs")
|
||||
* does not accidentally come back.
|
||||
*/
|
||||
static void napi_get_frags_check(struct napi_struct *napi)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
local_bh_disable();
|
||||
skb = napi_get_frags(napi);
|
||||
WARN_ON_ONCE(skb && skb->head_frag);
|
||||
napi_free_frags(napi);
|
||||
local_bh_enable();
|
||||
}
|
||||
|
||||
void netif_napi_add_weight_locked(struct net_device *dev,
|
||||
struct napi_struct *napi,
|
||||
int (*poll)(struct napi_struct *, int),
|
||||
@@ -11880,11 +11968,9 @@ EXPORT_SYMBOL(unregister_netdevice_many);
|
||||
*/
|
||||
void unregister_netdev(struct net_device *dev)
|
||||
{
|
||||
struct net *net = dev_net(dev);
|
||||
|
||||
rtnl_net_lock(net);
|
||||
rtnl_net_dev_lock(dev);
|
||||
unregister_netdevice(dev);
|
||||
rtnl_net_unlock(net);
|
||||
rtnl_net_dev_unlock(dev);
|
||||
}
|
||||
EXPORT_SYMBOL(unregister_netdev);
|
||||
|
||||
|
||||
@@ -1734,30 +1734,30 @@ static int __init init_net_drop_monitor(void)
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
rc = genl_register_family(&net_drop_monitor_family);
|
||||
if (rc) {
|
||||
pr_err("Could not create drop monitor netlink family\n");
|
||||
return rc;
|
||||
}
|
||||
WARN_ON(net_drop_monitor_family.mcgrp_offset != NET_DM_GRP_ALERT);
|
||||
|
||||
rc = register_netdevice_notifier(&dropmon_net_notifier);
|
||||
if (rc < 0) {
|
||||
pr_crit("Failed to register netdevice notifier\n");
|
||||
goto out_unreg;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
net_dm_cpu_data_init(cpu);
|
||||
net_dm_hw_cpu_data_init(cpu);
|
||||
}
|
||||
|
||||
rc = register_netdevice_notifier(&dropmon_net_notifier);
|
||||
if (rc < 0) {
|
||||
pr_crit("Failed to register netdevice notifier\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = genl_register_family(&net_drop_monitor_family);
|
||||
if (rc) {
|
||||
pr_err("Could not create drop monitor netlink family\n");
|
||||
goto out_unreg;
|
||||
}
|
||||
WARN_ON(net_drop_monitor_family.mcgrp_offset != NET_DM_GRP_ALERT);
|
||||
|
||||
rc = 0;
|
||||
|
||||
goto out;
|
||||
|
||||
out_unreg:
|
||||
genl_unregister_family(&net_drop_monitor_family);
|
||||
WARN_ON(unregister_netdevice_notifier(&dropmon_net_notifier));
|
||||
out:
|
||||
return rc;
|
||||
}
|
||||
@@ -1766,19 +1766,18 @@ static void exit_net_drop_monitor(void)
|
||||
{
|
||||
int cpu;
|
||||
|
||||
BUG_ON(unregister_netdevice_notifier(&dropmon_net_notifier));
|
||||
|
||||
/*
|
||||
* Because of the module_get/put we do in the trace state change path
|
||||
* we are guaranteed not to have any current users when we get here
|
||||
*/
|
||||
BUG_ON(genl_unregister_family(&net_drop_monitor_family));
|
||||
|
||||
BUG_ON(unregister_netdevice_notifier(&dropmon_net_notifier));
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
net_dm_hw_cpu_data_fini(cpu);
|
||||
net_dm_cpu_data_fini(cpu);
|
||||
}
|
||||
|
||||
BUG_ON(genl_unregister_family(&net_drop_monitor_family));
|
||||
}
|
||||
|
||||
module_init(init_net_drop_monitor);
|
||||
|
||||
@@ -853,23 +853,30 @@ __skb_flow_dissect_ports(const struct sk_buff *skb,
|
||||
void *target_container, const void *data,
|
||||
int nhoff, u8 ip_proto, int hlen)
|
||||
{
|
||||
enum flow_dissector_key_id dissector_ports = FLOW_DISSECTOR_KEY_MAX;
|
||||
struct flow_dissector_key_ports *key_ports;
|
||||
struct flow_dissector_key_ports_range *key_ports_range = NULL;
|
||||
struct flow_dissector_key_ports *key_ports = NULL;
|
||||
__be32 ports;
|
||||
|
||||
if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS))
|
||||
dissector_ports = FLOW_DISSECTOR_KEY_PORTS;
|
||||
else if (dissector_uses_key(flow_dissector,
|
||||
FLOW_DISSECTOR_KEY_PORTS_RANGE))
|
||||
dissector_ports = FLOW_DISSECTOR_KEY_PORTS_RANGE;
|
||||
key_ports = skb_flow_dissector_target(flow_dissector,
|
||||
FLOW_DISSECTOR_KEY_PORTS,
|
||||
target_container);
|
||||
|
||||
if (dissector_ports == FLOW_DISSECTOR_KEY_MAX)
|
||||
if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS_RANGE))
|
||||
key_ports_range = skb_flow_dissector_target(flow_dissector,
|
||||
FLOW_DISSECTOR_KEY_PORTS_RANGE,
|
||||
target_container);
|
||||
|
||||
if (!key_ports && !key_ports_range)
|
||||
return;
|
||||
|
||||
key_ports = skb_flow_dissector_target(flow_dissector,
|
||||
dissector_ports,
|
||||
target_container);
|
||||
key_ports->ports = __skb_flow_get_ports(skb, nhoff, ip_proto,
|
||||
data, hlen);
|
||||
ports = __skb_flow_get_ports(skb, nhoff, ip_proto, data, hlen);
|
||||
|
||||
if (key_ports)
|
||||
key_ports->ports = ports;
|
||||
|
||||
if (key_ports_range)
|
||||
key_ports_range->tp.ports = ports;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -924,6 +931,7 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys,
|
||||
struct flow_dissector *flow_dissector,
|
||||
void *target_container)
|
||||
{
|
||||
struct flow_dissector_key_ports_range *key_ports_range = NULL;
|
||||
struct flow_dissector_key_ports *key_ports = NULL;
|
||||
struct flow_dissector_key_control *key_control;
|
||||
struct flow_dissector_key_basic *key_basic;
|
||||
@@ -968,20 +976,21 @@ static void __skb_flow_bpf_to_target(const struct bpf_flow_keys *flow_keys,
|
||||
key_control->addr_type = FLOW_DISSECTOR_KEY_IPV6_ADDRS;
|
||||
}
|
||||
|
||||
if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS))
|
||||
if (dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_PORTS)) {
|
||||
key_ports = skb_flow_dissector_target(flow_dissector,
|
||||
FLOW_DISSECTOR_KEY_PORTS,
|
||||
target_container);
|
||||
else if (dissector_uses_key(flow_dissector,
|
||||
FLOW_DISSECTOR_KEY_PORTS_RANGE))
|
||||
key_ports = skb_flow_dissector_target(flow_dissector,
|
||||
FLOW_DISSECTOR_KEY_PORTS_RANGE,
|
||||
target_container);
|
||||
|
||||
if (key_ports) {
|
||||
key_ports->src = flow_keys->sport;
|
||||
key_ports->dst = flow_keys->dport;
|
||||
}
|
||||
if (dissector_uses_key(flow_dissector,
|
||||
FLOW_DISSECTOR_KEY_PORTS_RANGE)) {
|
||||
key_ports_range = skb_flow_dissector_target(flow_dissector,
|
||||
FLOW_DISSECTOR_KEY_PORTS_RANGE,
|
||||
target_container);
|
||||
key_ports_range->tp.src = flow_keys->sport;
|
||||
key_ports_range->tp.dst = flow_keys->dport;
|
||||
}
|
||||
|
||||
if (dissector_uses_key(flow_dissector,
|
||||
FLOW_DISSECTOR_KEY_FLOW_LABEL)) {
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
|
||||
#define MAX_GRO_SKBS 8
|
||||
|
||||
/* This should be increased if a protocol with a bigger head is added. */
|
||||
#define GRO_MAX_HEAD (MAX_HEADER + 128)
|
||||
|
||||
static DEFINE_SPINLOCK(offload_lock);
|
||||
|
||||
/**
|
||||
|
||||
@@ -464,7 +464,7 @@ static void net_complete_free(void)
|
||||
|
||||
}
|
||||
|
||||
static void net_free(struct net *net)
|
||||
void net_passive_dec(struct net *net)
|
||||
{
|
||||
if (refcount_dec_and_test(&net->passive)) {
|
||||
kfree(rcu_access_pointer(net->gen));
|
||||
@@ -482,7 +482,7 @@ void net_drop_ns(void *p)
|
||||
struct net *net = (struct net *)p;
|
||||
|
||||
if (net)
|
||||
net_free(net);
|
||||
net_passive_dec(net);
|
||||
}
|
||||
|
||||
struct net *copy_net_ns(unsigned long flags,
|
||||
@@ -523,7 +523,7 @@ put_userns:
|
||||
key_remove_domain(net->key_domain);
|
||||
#endif
|
||||
put_user_ns(user_ns);
|
||||
net_free(net);
|
||||
net_passive_dec(net);
|
||||
dec_ucounts:
|
||||
dec_net_namespaces(ucounts);
|
||||
return ERR_PTR(rv);
|
||||
@@ -672,7 +672,7 @@ static void cleanup_net(struct work_struct *work)
|
||||
key_remove_domain(net->key_domain);
|
||||
#endif
|
||||
put_user_ns(net->user_ns);
|
||||
net_free(net);
|
||||
net_passive_dec(net);
|
||||
}
|
||||
cleanup_net_task = NULL;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user