···352352353353 mdio_driver_unregister(&dsa_loop_drv);354354 for (i = 0; i < NUM_FIXED_PHYS; i++)355355- if (phydevs[i])355355+ if (!IS_ERR(phydevs[i]))356356 fixed_phy_unregister(phydevs[i]);357357}358358module_exit(dsa_loop_exit);
+9-26
include/net/inet_frag.h
···11#ifndef __NET_FRAG_H__22#define __NET_FRAG_H__3344-#include <linux/percpu_counter.h>55-64struct netns_frags {77- /* The percpu_counter "mem" need to be cacheline aligned.88- * mem.count must not share cacheline with other writers99- */1010- struct percpu_counter mem ____cacheline_aligned_in_smp;1111-55+ /* Keep atomic mem on separate cachelines in structs that include it */66+ atomic_t mem ____cacheline_aligned_in_smp;127 /* sysctls */138 int timeout;149 int high_thresh;···103108int inet_frags_init(struct inet_frags *);104109void inet_frags_fini(struct inet_frags *);105110106106-static inline int inet_frags_init_net(struct netns_frags *nf)111111+static inline void inet_frags_init_net(struct netns_frags *nf)107112{108108- return percpu_counter_init(&nf->mem, 0, GFP_KERNEL);113113+ atomic_set(&nf->mem, 0);109114}110110-static inline void inet_frags_uninit_net(struct netns_frags *nf)111111-{112112- percpu_counter_destroy(&nf->mem);113113-}114114-115115void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f);116116117117void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f);···130140131141/* Memory Tracking Functions. */132142133133-/* The default percpu_counter batch size is not big enough to scale to134134- * fragmentation mem acct sizes.135135- * The mem size of a 64K fragment is approx:136136- * (44 fragments * 2944 truesize) + frag_queue struct(200) = 129736 bytes137137- */138138-static unsigned int frag_percpu_counter_batch = 130000;139139-140143static inline int frag_mem_limit(struct netns_frags *nf)141144{142142- return percpu_counter_read(&nf->mem);145145+ return atomic_read(&nf->mem);143146}144147145148static inline void sub_frag_mem_limit(struct netns_frags *nf, int i)146149{147147- percpu_counter_add_batch(&nf->mem, -i, frag_percpu_counter_batch);150150+ atomic_sub(i, &nf->mem);148151}149152150153static inline void add_frag_mem_limit(struct netns_frags *nf, int i)151154{152152- percpu_counter_add_batch(&nf->mem, i, frag_percpu_counter_batch);155155+ atomic_add(i, &nf->mem);153156}154157155155-static inline unsigned int sum_frag_mem_limit(struct netns_frags *nf)158158+static inline int sum_frag_mem_limit(struct netns_frags *nf)156159{157157- return percpu_counter_sum_positive(&nf->mem);160160+ return atomic_read(&nf->mem);158161}159162160163/* RFC 3168 support :
+4-3
include/net/route.h
···189189190190 rcu_read_lock();191191 err = ip_route_input_noref(skb, dst, src, tos, devin);192192- if (!err)192192+ if (!err) {193193 skb_dst_force_safe(skb);194194- if (!skb_dst(skb))195195- err = -EINVAL;194194+ if (!skb_dst(skb))195195+ err = -EINVAL;196196+ }196197 rcu_read_unlock();197198198199 return err;
+3-8
net/ieee802154/6lowpan/reassembly.c
···580580{581581 struct netns_ieee802154_lowpan *ieee802154_lowpan =582582 net_ieee802154_lowpan(net);583583- int res;584583585584 ieee802154_lowpan->frags.high_thresh = IPV6_FRAG_HIGH_THRESH;586585 ieee802154_lowpan->frags.low_thresh = IPV6_FRAG_LOW_THRESH;587586 ieee802154_lowpan->frags.timeout = IPV6_FRAG_TIMEOUT;588587589589- res = inet_frags_init_net(&ieee802154_lowpan->frags);590590- if (res)591591- return res;592592- res = lowpan_frags_ns_sysctl_register(net);593593- if (res)594594- inet_frags_uninit_net(&ieee802154_lowpan->frags);595595- return res;588588+ inet_frags_init_net(&ieee802154_lowpan->frags);589589+590590+ return lowpan_frags_ns_sysctl_register(net);596591}597592598593static void __net_exit lowpan_frags_exit_net(struct net *net)
···844844845845static int __net_init ipv4_frags_init_net(struct net *net)846846{847847- int res;848848-849847 /* Fragment cache limits.850848 *851849 * The fragment memory accounting code, (tries to) account for···869871870872 net->ipv4.frags.max_dist = 64;871873872872- res = inet_frags_init_net(&net->ipv4.frags);873873- if (res)874874- return res;875875- res = ip4_frags_ns_ctl_register(net);876876- if (res)877877- inet_frags_uninit_net(&net->ipv4.frags);878878- return res;874874+ inet_frags_init_net(&net->ipv4.frags);875875+876876+ return ip4_frags_ns_ctl_register(net);879877}880878881879static void __net_exit ipv4_frags_exit_net(struct net *net)
+3-9
net/ipv6/netfilter/nf_conntrack_reasm.c
···622622623623static int nf_ct_net_init(struct net *net)624624{625625- int res;626626-627625 net->nf_frag.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;628626 net->nf_frag.frags.low_thresh = IPV6_FRAG_LOW_THRESH;629627 net->nf_frag.frags.timeout = IPV6_FRAG_TIMEOUT;630630- res = inet_frags_init_net(&net->nf_frag.frags);631631- if (res)632632- return res;633633- res = nf_ct_frag6_sysctl_register(net);634634- if (res)635635- inet_frags_uninit_net(&net->nf_frag.frags);636636- return res;628628+ inet_frags_init_net(&net->nf_frag.frags);629629+630630+ return nf_ct_frag6_sysctl_register(net);637631}638632639633static void nf_ct_net_exit(struct net *net)
+3-9
net/ipv6/reassembly.c
···714714715715static int __net_init ipv6_frags_init_net(struct net *net)716716{717717- int res;718718-719717 net->ipv6.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;720718 net->ipv6.frags.low_thresh = IPV6_FRAG_LOW_THRESH;721719 net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT;722720723723- res = inet_frags_init_net(&net->ipv6.frags);724724- if (res)725725- return res;726726- res = ip6_frags_ns_sysctl_register(net);727727- if (res)728728- inet_frags_uninit_net(&net->ipv6.frags);729729- return res;721721+ inet_frags_init_net(&net->ipv6.frags);722722+723723+ return ip6_frags_ns_sysctl_register(net);730724}731725732726static void __net_exit ipv6_frags_exit_net(struct net *net)
+29-14
net/l2tp/l2tp_core.c
···329329 struct hlist_head *g_head;330330 struct hlist_head *head;331331 struct l2tp_net *pn;332332+ int err;332333333334 head = l2tp_session_id_hash(tunnel, session->session_id);334335335336 write_lock_bh(&tunnel->hlist_lock);337337+ if (!tunnel->acpt_newsess) {338338+ err = -ENODEV;339339+ goto err_tlock;340340+ }341341+336342 hlist_for_each_entry(session_walk, head, hlist)337337- if (session_walk->session_id == session->session_id)338338- goto exist;343343+ if (session_walk->session_id == session->session_id) {344344+ err = -EEXIST;345345+ goto err_tlock;346346+ }339347340348 if (tunnel->version == L2TP_HDR_VER_3) {341349 pn = l2tp_pernet(tunnel->l2tp_net);···351343 session->session_id);352344353345 spin_lock_bh(&pn->l2tp_session_hlist_lock);354354- hlist_for_each_entry(session_walk, g_head, global_hlist)355355- if (session_walk->session_id == session->session_id)356356- goto exist_glob;357346347347+ hlist_for_each_entry(session_walk, g_head, global_hlist)348348+ if (session_walk->session_id == session->session_id) {349349+ err = -EEXIST;350350+ goto err_tlock_pnlock;351351+ }352352+353353+ l2tp_tunnel_inc_refcount(tunnel);354354+ sock_hold(tunnel->sock);358355 hlist_add_head_rcu(&session->global_hlist, g_head);356356+359357 spin_unlock_bh(&pn->l2tp_session_hlist_lock);358358+ } else {359359+ l2tp_tunnel_inc_refcount(tunnel);360360+ sock_hold(tunnel->sock);360361 }361362362363 hlist_add_head(&session->hlist, head);···373356374357 return 0;375358376376-exist_glob:359359+err_tlock_pnlock:377360 spin_unlock_bh(&pn->l2tp_session_hlist_lock);378378-exist:361361+err_tlock:379362 write_unlock_bh(&tunnel->hlist_lock);380363381381- return -EEXIST;364364+ return err;382365}383366384367/* Lookup a tunnel by id···12681251 /* Remove hooks into tunnel socket */12691252 sk->sk_destruct = tunnel->old_sk_destruct;12701253 sk->sk_user_data = NULL;12711271- tunnel->sock = NULL;1272125412731255 /* Remove the tunnel struct from the tunnel list */12741256 pn = l2tp_pernet(tunnel->l2tp_net);···12771261 atomic_dec(&l2tp_tunnel_count);1278126212791263 l2tp_tunnel_closeall(tunnel);12641264+12651265+ tunnel->sock = NULL;12801266 l2tp_tunnel_dec_refcount(tunnel);1281126712821268 /* Call the original destructor */···13031285 tunnel->name);1304128613051287 write_lock_bh(&tunnel->hlist_lock);12881288+ tunnel->acpt_newsess = false;13061289 for (hash = 0; hash < L2TP_HASH_SIZE; hash++) {13071290again:13081291 hlist_for_each_safe(walk, tmp, &tunnel->session_hlist[hash]) {···16001581 tunnel->magic = L2TP_TUNNEL_MAGIC;16011582 sprintf(&tunnel->name[0], "tunl %u", tunnel_id);16021583 rwlock_init(&tunnel->hlist_lock);15841584+ tunnel->acpt_newsess = true;1603158516041586 /* The net we belong to */16051587 tunnel->l2tp_net = net;···1848182818491829 return ERR_PTR(err);18501830 }18511851-18521852- l2tp_tunnel_inc_refcount(tunnel);18531853-18541854- /* Ensure tunnel socket isn't deleted */18551855- sock_hold(tunnel->sock);1856183118571832 /* Ignore management session in session count value */18581833 if (session->session_id != 0)
+7-1
net/l2tp/l2tp_core.h
···162162 int magic; /* Should be L2TP_TUNNEL_MAGIC */163163 struct rcu_head rcu;164164 rwlock_t hlist_lock; /* protect session_hlist */165165+ bool acpt_newsess; /* Indicates whether this166166+ * tunnel accepts new sessions.167167+ * Protected by hlist_lock.168168+ */165169 struct hlist_head session_hlist[L2TP_HASH_SIZE];166170 /* hashed list of sessions,167171 * hashed by id */···201197};202198203199struct l2tp_nl_cmd_ops {204204- int (*session_create)(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg);200200+ int (*session_create)(struct net *net, struct l2tp_tunnel *tunnel,201201+ u32 session_id, u32 peer_session_id,202202+ struct l2tp_session_cfg *cfg);205203 int (*session_delete)(struct l2tp_session *session);206204};207205
···643643 break;644644 }645645646646- ret = -EPROTONOSUPPORT;647647- if (l2tp_nl_cmd_ops[cfg.pw_type]->session_create)648648- ret = (*l2tp_nl_cmd_ops[cfg.pw_type]->session_create)(net, tunnel_id,649649- session_id, peer_session_id, &cfg);646646+ ret = l2tp_nl_cmd_ops[cfg.pw_type]->session_create(net, tunnel,647647+ session_id,648648+ peer_session_id,649649+ &cfg);650650651651 if (ret >= 0) {652652 session = l2tp_session_get(net, tunnel, session_id, false);
+7-12
net/l2tp/l2tp_ppp.c
···788788789789#ifdef CONFIG_L2TP_V3790790791791-/* Called when creating sessions via the netlink interface.792792- */793793-static int pppol2tp_session_create(struct net *net, u32 tunnel_id, u32 session_id, u32 peer_session_id, struct l2tp_session_cfg *cfg)791791+/* Called when creating sessions via the netlink interface. */792792+static int pppol2tp_session_create(struct net *net, struct l2tp_tunnel *tunnel,793793+ u32 session_id, u32 peer_session_id,794794+ struct l2tp_session_cfg *cfg)794795{795796 int error;796796- struct l2tp_tunnel *tunnel;797797 struct l2tp_session *session;798798 struct pppol2tp_session *ps;799799800800- tunnel = l2tp_tunnel_find(net, tunnel_id);801801-802802- /* Error if we can't find the tunnel */803803- error = -ENOENT;804804- if (tunnel == NULL)805805- goto out;806806-807800 /* Error if tunnel socket is not prepped */808808- if (tunnel->sock == NULL)801801+ if (!tunnel->sock) {802802+ error = -ENOENT;809803 goto out;804804+ }810805811806 /* Default MTU values. */812807 if (cfg->mtu == 0)