diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-11 23:27:06 +0100 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-11 23:27:06 +0100 |
commit | 70e71ca0af244f48a5dcf56dc435243792e3a495 (patch) | |
tree | f7d9c4c4d9a857a00043e9bf6aa2d6f533a34778 /net/sched | |
parent | Merge tag 'sound-3.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/t... (diff) | |
parent | Fix race condition between vxlan_sock_add and vxlan_sock_release (diff) | |
download | linux-70e71ca0af244f48a5dcf56dc435243792e3a495.tar.xz linux-70e71ca0af244f48a5dcf56dc435243792e3a495.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller:
1) New offloading infrastructure and example 'rocker' driver for
offloading of switching and routing to hardware.
This work was done by a large group of dedicated individuals, not
limited to: Scott Feldman, Jiri Pirko, Thomas Graf, John Fastabend,
Jamal Hadi Salim, Andy Gospodarek, Florian Fainelli, Roopa Prabhu
2) Start making the networking operate on IOV iterators instead of
modifying iov objects in-situ during transfers. Thanks to Al Viro
and Herbert Xu.
3) A set of new netlink interfaces for the TIPC stack, from Richard
Alpe.
4) Remove unnecessary looping during ipv6 routing lookups, from Martin
KaFai Lau.
5) Add PAUSE frame generation support to gianfar driver, from Matei
Pavaluca.
6) Allow for larger reordering levels in TCP, which are easily
achievable in the real world right now, from Eric Dumazet.
7) Add a variable of napi_schedule that doesn't need to disable cpu
interrupts, from Eric Dumazet.
8) Use a doubly linked list to optimize neigh_parms_release(), from
Nicolas Dichtel.
9) Various enhancements to the kernel BPF verifier, and allow eBPF
programs to actually be attached to sockets. From Alexei
Starovoitov.
10) Support TSO/LSO in sunvnet driver, from David L Stevens.
11) Allow controlling ECN usage via routing metrics, from Florian
Westphal.
12) Remote checksum offload, from Tom Herbert.
13) Add split-header receive, BQL, and xmit_more support to amd-xgbe
driver, from Thomas Lendacky.
14) Add MPLS support to openvswitch, from Simon Horman.
15) Support wildcard tunnel endpoints in ipv6 tunnels, from Steffen
Klassert.
16) Do gro flushes on a per-device basis using a timer, from Eric
Dumazet. This tries to resolve the conflicting goals between the
desired handling of bulk vs. RPC-like traffic.
17) Allow userspace to ask for the CPU upon what a packet was
received/steered, via SO_INCOMING_CPU. From Eric Dumazet.
18) Limit GSO packets to half the current congestion window, from Eric
Dumazet.
19) Add a generic helper so that all drivers set their RSS keys in a
consistent way, from Eric Dumazet.
20) Add xmit_more support to enic driver, from Govindarajulu
Varadarajan.
21) Add VLAN packet scheduler action, from Jiri Pirko.
22) Support configurable RSS hash functions via ethtool, from Eyal
Perry.
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1820 commits)
Fix race condition between vxlan_sock_add and vxlan_sock_release
net/macb: fix compilation warning for print_hex_dump() called with skb->mac_header
net/mlx4: Add support for A0 steering
net/mlx4: Refactor QUERY_PORT
net/mlx4_core: Add explicit error message when rule doesn't meet configuration
net/mlx4: Add A0 hybrid steering
net/mlx4: Add mlx4_bitmap zone allocator
net/mlx4: Add a check if there are too many reserved QPs
net/mlx4: Change QP allocation scheme
net/mlx4_core: Use tasklet for user-space CQ completion events
net/mlx4_core: Mask out host side virtualization features for guests
net/mlx4_en: Set csum level for encapsulated packets
be2net: Export tunnel offloads only when a VxLAN tunnel is created
gianfar: Fix dma check map error when DMA_API_DEBUG is enabled
cxgb4/csiostor: Don't use MASTER_MUST for fw_hello call
net: fec: only enable mdio interrupt before phy device link up
net: fec: clear all interrupt events to support i.MX6SX
net: fec: reset fep link status in suspend function
net: sock: fix access via invalid file descriptor
net: introduce helper macro for_each_cmsghdr
...
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/Kconfig | 18 | ||||
-rw-r--r-- | net/sched/Makefile | 1 | ||||
-rw-r--r-- | net/sched/act_gact.c | 2 | ||||
-rw-r--r-- | net/sched/act_ipt.c | 2 | ||||
-rw-r--r-- | net/sched/act_mirred.c | 2 | ||||
-rw-r--r-- | net/sched/act_pedit.c | 2 | ||||
-rw-r--r-- | net/sched/act_police.c | 2 | ||||
-rw-r--r-- | net/sched/act_simple.c | 2 | ||||
-rw-r--r-- | net/sched/act_vlan.c | 207 | ||||
-rw-r--r-- | net/sched/cls_basic.c | 26 | ||||
-rw-r--r-- | net/sched/cls_bpf.c | 26 | ||||
-rw-r--r-- | net/sched/cls_cgroup.c | 14 | ||||
-rw-r--r-- | net/sched/cls_flow.c | 14 | ||||
-rw-r--r-- | net/sched/cls_fw.c | 8 | ||||
-rw-r--r-- | net/sched/cls_route.c | 8 | ||||
-rw-r--r-- | net/sched/cls_rsvp.h | 8 | ||||
-rw-r--r-- | net/sched/cls_tcindex.c | 15 | ||||
-rw-r--r-- | net/sched/cls_u32.c | 5 | ||||
-rw-r--r-- | net/sched/sch_fq.c | 9 | ||||
-rw-r--r-- | net/sched/sch_fq_codel.c | 2 | ||||
-rw-r--r-- | net/sched/sch_netem.c | 27 |
21 files changed, 266 insertions, 134 deletions
diff --git a/net/sched/Kconfig b/net/sched/Kconfig index a1a8e29e5fc9..c54c9d9d1ffb 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -22,8 +22,9 @@ menuconfig NET_SCHED This code is considered to be experimental. To administer these schedulers, you'll need the user-level utilities - from the package iproute2+tc at <ftp://ftp.tux.org/pub/net/ip-routing/>. - That package also contains some documentation; for more, check out + from the package iproute2+tc at + <https://www.kernel.org/pub/linux/utils/net/iproute2/>. That package + also contains some documentation; for more, check out <http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2>. This Quality of Service (QoS) support will enable you to use @@ -336,7 +337,7 @@ config NET_SCH_PLUG of virtual machines by allowing the generated network output to be rolled back if needed. - For more information, please refer to http://wiki.xensource.com/xenwiki/Remus + For more information, please refer to <http://wiki.xenproject.org/wiki/Remus> Say Y here if you are using this kernel for Xen dom0 and want to protect Xen guests with Remus. @@ -686,6 +687,17 @@ config NET_ACT_CSUM To compile this code as a module, choose M here: the module will be called act_csum. +config NET_ACT_VLAN + tristate "Vlan manipulation" + depends on NET_CLS_ACT + ---help--- + Say Y here to push or pop vlan headers. + + If unsure, say N. + + To compile this code as a module, choose M here: the + module will be called act_vlan. + config NET_CLS_IND bool "Incoming device classification" depends on NET_CLS_U32 || NET_CLS_FW diff --git a/net/sched/Makefile b/net/sched/Makefile index 0a869a11f3e6..679f24ae7f93 100644 --- a/net/sched/Makefile +++ b/net/sched/Makefile @@ -16,6 +16,7 @@ obj-$(CONFIG_NET_ACT_PEDIT) += act_pedit.o obj-$(CONFIG_NET_ACT_SIMP) += act_simple.o obj-$(CONFIG_NET_ACT_SKBEDIT) += act_skbedit.o obj-$(CONFIG_NET_ACT_CSUM) += act_csum.o +obj-$(CONFIG_NET_ACT_VLAN) += act_vlan.o obj-$(CONFIG_NET_SCH_FIFO) += sch_fifo.o obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index d6bcbd9f7791..7fffc2272701 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c @@ -1,5 +1,5 @@ /* - * net/sched/gact.c Generic actions + * net/sched/act_gact.c Generic actions * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 8a64a0734aee..cbc8dd7dd48a 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c @@ -1,5 +1,5 @@ /* - * net/sched/ipt.c iptables target interface + * net/sched/act_ipt.c iptables target interface * *TODO: Add other tables. For now we only support the ipv4 table targets * diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index eb48306033d9..5953517ec059 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -1,5 +1,5 @@ /* - * net/sched/mirred.c packet mirroring and redirect actions + * net/sched/act_mirred.c packet mirroring and redirect actions * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 5f9bcb2e080b..59649d588d79 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c @@ -1,5 +1,5 @@ /* - * net/sched/pedit.c Generic packet editor + * net/sched/act_pedit.c Generic packet editor * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 69791ca77a05..9a1c42a43f92 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c @@ -1,5 +1,5 @@ /* - * net/sched/police.c Input police filter. + * net/sched/act_police.c Input police filter * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index 992c2317ce88..6a8d9488613a 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c @@ -1,5 +1,5 @@ /* - * net/sched/simp.c Simple example of an action + * net/sched/act_simple.c Simple example of an action * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c new file mode 100644 index 000000000000..d735ecf0b1a7 --- /dev/null +++ b/net/sched/act_vlan.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us> + * + * 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. + */ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/skbuff.h> +#include <linux/rtnetlink.h> +#include <linux/if_vlan.h> +#include <net/netlink.h> +#include <net/pkt_sched.h> + +#include <linux/tc_act/tc_vlan.h> +#include <net/tc_act/tc_vlan.h> + +#define VLAN_TAB_MASK 15 + +static int tcf_vlan(struct sk_buff *skb, const struct tc_action *a, + struct tcf_result *res) +{ + struct tcf_vlan *v = a->priv; + int action; + int err; + + spin_lock(&v->tcf_lock); + v->tcf_tm.lastuse = jiffies; + bstats_update(&v->tcf_bstats, skb); + action = v->tcf_action; + + switch (v->tcfv_action) { + case TCA_VLAN_ACT_POP: + err = skb_vlan_pop(skb); + if (err) + goto drop; + break; + case TCA_VLAN_ACT_PUSH: + err = skb_vlan_push(skb, v->tcfv_push_proto, v->tcfv_push_vid); + if (err) + goto drop; + break; + default: + BUG(); + } + + goto unlock; + +drop: + action = TC_ACT_SHOT; + v->tcf_qstats.drops++; +unlock: + spin_unlock(&v->tcf_lock); + return action; +} + +static const struct nla_policy vlan_policy[TCA_VLAN_MAX + 1] = { + [TCA_VLAN_PARMS] = { .len = sizeof(struct tc_vlan) }, + [TCA_VLAN_PUSH_VLAN_ID] = { .type = NLA_U16 }, + [TCA_VLAN_PUSH_VLAN_PROTOCOL] = { .type = NLA_U16 }, +}; + +static int tcf_vlan_init(struct net *net, struct nlattr *nla, + struct nlattr *est, struct tc_action *a, + int ovr, int bind) +{ + struct nlattr *tb[TCA_VLAN_MAX + 1]; + struct tc_vlan *parm; + struct tcf_vlan *v; + int action; + __be16 push_vid = 0; + __be16 push_proto = 0; + int ret = 0; + int err; + + if (!nla) + return -EINVAL; + + err = nla_parse_nested(tb, TCA_VLAN_MAX, nla, vlan_policy); + if (err < 0) + return err; + + if (!tb[TCA_VLAN_PARMS]) + return -EINVAL; + parm = nla_data(tb[TCA_VLAN_PARMS]); + switch (parm->v_action) { + case TCA_VLAN_ACT_POP: + break; + case TCA_VLAN_ACT_PUSH: + if (!tb[TCA_VLAN_PUSH_VLAN_ID]) + return -EINVAL; + push_vid = nla_get_u16(tb[TCA_VLAN_PUSH_VLAN_ID]); + if (push_vid >= VLAN_VID_MASK) + return -ERANGE; + + if (tb[TCA_VLAN_PUSH_VLAN_PROTOCOL]) { + push_proto = nla_get_be16(tb[TCA_VLAN_PUSH_VLAN_PROTOCOL]); + switch (push_proto) { + case htons(ETH_P_8021Q): + case htons(ETH_P_8021AD): + break; + default: + return -EPROTONOSUPPORT; + } + } else { + push_proto = htons(ETH_P_8021Q); + } + break; + default: + return -EINVAL; + } + action = parm->v_action; + + if (!tcf_hash_check(parm->index, a, bind)) { + ret = tcf_hash_create(parm->index, est, a, sizeof(*v), bind); + if (ret) + return ret; + + ret = ACT_P_CREATED; + } else { + if (bind) + return 0; + tcf_hash_release(a, bind); + if (!ovr) + return -EEXIST; + } + + v = to_vlan(a); + + spin_lock_bh(&v->tcf_lock); + + v->tcfv_action = action; + v->tcfv_push_vid = push_vid; + v->tcfv_push_proto = push_proto; + + v->tcf_action = parm->action; + + spin_unlock_bh(&v->tcf_lock); + + if (ret == ACT_P_CREATED) + tcf_hash_insert(a); + return ret; +} + +static int tcf_vlan_dump(struct sk_buff *skb, struct tc_action *a, + int bind, int ref) +{ + unsigned char *b = skb_tail_pointer(skb); + struct tcf_vlan *v = a->priv; + struct tc_vlan opt = { + .index = v->tcf_index, + .refcnt = v->tcf_refcnt - ref, + .bindcnt = v->tcf_bindcnt - bind, + .action = v->tcf_action, + .v_action = v->tcfv_action, + }; + struct tcf_t t; + + if (nla_put(skb, TCA_VLAN_PARMS, sizeof(opt), &opt)) + goto nla_put_failure; + + if (v->tcfv_action == TCA_VLAN_ACT_PUSH && + (nla_put_u16(skb, TCA_VLAN_PUSH_VLAN_ID, v->tcfv_push_vid) || + nla_put_be16(skb, TCA_VLAN_PUSH_VLAN_PROTOCOL, v->tcfv_push_proto))) + goto nla_put_failure; + + t.install = jiffies_to_clock_t(jiffies - v->tcf_tm.install); + t.lastuse = jiffies_to_clock_t(jiffies - v->tcf_tm.lastuse); + t.expires = jiffies_to_clock_t(v->tcf_tm.expires); + if (nla_put(skb, TCA_VLAN_TM, sizeof(t), &t)) + goto nla_put_failure; + return skb->len; + +nla_put_failure: + nlmsg_trim(skb, b); + return -1; +} + +static struct tc_action_ops act_vlan_ops = { + .kind = "vlan", + .type = TCA_ACT_VLAN, + .owner = THIS_MODULE, + .act = tcf_vlan, + .dump = tcf_vlan_dump, + .init = tcf_vlan_init, +}; + +static int __init vlan_init_module(void) +{ + return tcf_register_action(&act_vlan_ops, VLAN_TAB_MASK); +} + +static void __exit vlan_cleanup_module(void) +{ + tcf_unregister_action(&act_vlan_ops); +} + +module_init(vlan_init_module); +module_exit(vlan_cleanup_module); + +MODULE_AUTHOR("Jiri Pirko <jiri@resnulli.us>"); +MODULE_DESCRIPTION("vlan manipulation actions"); +MODULE_LICENSE("GPL v2"); diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index cd61280941e5..5aed341406c2 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c @@ -72,10 +72,6 @@ static unsigned long basic_get(struct tcf_proto *tp, u32 handle) return l; } -static void basic_put(struct tcf_proto *tp, unsigned long f) -{ -} - static int basic_init(struct tcf_proto *tp) { struct basic_head *head; @@ -113,18 +109,12 @@ static void basic_destroy(struct tcf_proto *tp) static int basic_delete(struct tcf_proto *tp, unsigned long arg) { - struct basic_head *head = rtnl_dereference(tp->root); - struct basic_filter *t, *f = (struct basic_filter *) arg; - - list_for_each_entry(t, &head->flist, link) - if (t == f) { - list_del_rcu(&t->link); - tcf_unbind_filter(tp, &t->res); - call_rcu(&t->rcu, basic_delete_filter); - return 0; - } + struct basic_filter *f = (struct basic_filter *) arg; - return -ENOENT; + list_del_rcu(&f->link); + tcf_unbind_filter(tp, &f->res); + call_rcu(&f->rcu, basic_delete_filter); + return 0; } static const struct nla_policy basic_policy[TCA_BASIC_MAX + 1] = { @@ -188,10 +178,9 @@ static int basic_change(struct net *net, struct sk_buff *in_skb, return -EINVAL; } - err = -ENOBUFS; fnew = kzalloc(sizeof(*fnew), GFP_KERNEL); - if (fnew == NULL) - goto errout; + if (!fnew) + return -ENOBUFS; tcf_exts_init(&fnew->exts, TCA_BASIC_ACT, TCA_BASIC_POLICE); err = -EINVAL; @@ -293,7 +282,6 @@ static struct tcf_proto_ops cls_basic_ops __read_mostly = { .init = basic_init, .destroy = basic_destroy, .get = basic_get, - .put = basic_put, .change = basic_change, .delete = basic_delete, .walk = basic_walk, diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c index eed49d1d0878..84c8219c3e1c 100644 --- a/net/sched/cls_bpf.c +++ b/net/sched/cls_bpf.c @@ -109,19 +109,12 @@ static void __cls_bpf_delete_prog(struct rcu_head *rcu) static int cls_bpf_delete(struct tcf_proto *tp, unsigned long arg) { - struct cls_bpf_head *head = rtnl_dereference(tp->root); - struct cls_bpf_prog *prog, *todel = (struct cls_bpf_prog *) arg; + struct cls_bpf_prog *prog = (struct cls_bpf_prog *) arg; - list_for_each_entry(prog, &head->plist, link) { - if (prog == todel) { - list_del_rcu(&prog->link); - tcf_unbind_filter(tp, &prog->res); - call_rcu(&prog->rcu, __cls_bpf_delete_prog); - return 0; - } - } - - return -ENOENT; + list_del_rcu(&prog->link); + tcf_unbind_filter(tp, &prog->res); + call_rcu(&prog->rcu, __cls_bpf_delete_prog); + return 0; } static void cls_bpf_destroy(struct tcf_proto *tp) @@ -148,7 +141,7 @@ static unsigned long cls_bpf_get(struct tcf_proto *tp, u32 handle) if (head == NULL) return 0UL; - list_for_each_entry_rcu(prog, &head->plist, link) { + list_for_each_entry(prog, &head->plist, link) { if (prog->handle == handle) { ret = (unsigned long) prog; break; @@ -158,10 +151,6 @@ static unsigned long cls_bpf_get(struct tcf_proto *tp, u32 handle) return ret; } -static void cls_bpf_put(struct tcf_proto *tp, unsigned long f) -{ -} - static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp, struct cls_bpf_prog *prog, unsigned long base, struct nlattr **tb, @@ -344,7 +333,7 @@ static void cls_bpf_walk(struct tcf_proto *tp, struct tcf_walker *arg) struct cls_bpf_head *head = rtnl_dereference(tp->root); struct cls_bpf_prog *prog; - list_for_each_entry_rcu(prog, &head->plist, link) { + list_for_each_entry(prog, &head->plist, link) { if (arg->count < arg->skip) goto skip; if (arg->fn(tp, (unsigned long) prog, arg) < 0) { @@ -363,7 +352,6 @@ static struct tcf_proto_ops cls_bpf_ops __read_mostly = { .init = cls_bpf_init, .destroy = cls_bpf_destroy, .get = cls_bpf_get, - .put = cls_bpf_put, .change = cls_bpf_change, .delete = cls_bpf_delete, .walk = cls_bpf_walk, diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index d61a801222c1..221697ab0247 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c @@ -67,10 +67,6 @@ static unsigned long cls_cgroup_get(struct tcf_proto *tp, u32 handle) return 0UL; } -static void cls_cgroup_put(struct tcf_proto *tp, unsigned long f) -{ -} - static int cls_cgroup_init(struct tcf_proto *tp) { return 0; @@ -117,11 +113,7 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb, return -ENOBUFS; tcf_exts_init(&new->exts, TCA_CGROUP_ACT, TCA_CGROUP_POLICE); - if (head) - new->handle = head->handle; - else - new->handle = handle; - + new->handle = handle; new->tp = tp; err = nla_parse_nested(tb, TCA_CGROUP_MAX, tca[TCA_OPTIONS], cgroup_policy); @@ -185,7 +177,6 @@ static int cls_cgroup_dump(struct net *net, struct tcf_proto *tp, unsigned long struct sk_buff *skb, struct tcmsg *t) { struct cls_cgroup_head *head = rtnl_dereference(tp->root); - unsigned char *b = skb_tail_pointer(skb); struct nlattr *nest; t->tcm_handle = head->handle; @@ -206,7 +197,7 @@ static int cls_cgroup_dump(struct net *net, struct tcf_proto *tp, unsigned long return skb->len; nla_put_failure: - nlmsg_trim(skb, b); + nla_nest_cancel(skb, nest); return -1; } @@ -217,7 +208,6 @@ static struct tcf_proto_ops cls_cgroup_ops __read_mostly = { .classify = cls_cgroup_classify, .destroy = cls_cgroup_destroy, .get = cls_cgroup_get, - .put = cls_cgroup_put, .delete = cls_cgroup_delete, .walk = cls_cgroup_walk, .dump = cls_cgroup_dump, diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index 4ac515f2a6ce..15d68f24a521 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c @@ -426,10 +426,7 @@ static int flow_change(struct net *net, struct sk_buff *in_skb, goto err2; /* Copy fold into fnew */ - fnew->handle = fold->handle; - fnew->keymask = fold->keymask; fnew->tp = fold->tp; - fnew->handle = fold->handle; fnew->nkeys = fold->nkeys; fnew->keymask = fold->keymask; @@ -578,16 +575,12 @@ static unsigned long flow_get(struct tcf_proto *tp, u32 handle) struct flow_head *head = rtnl_dereference(tp->root); struct flow_filter *f; - list_for_each_entry_rcu(f, &head->filters, list) + list_for_each_entry(f, &head->filters, list) if (f->handle == handle) return (unsigned long)f; return 0; } -static void flow_put(struct tcf_proto *tp, unsigned long f) -{ -} - static int flow_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, struct sk_buff *skb, struct tcmsg *t) { @@ -645,7 +638,7 @@ static int flow_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, return skb->len; nla_put_failure: - nlmsg_trim(skb, nest); + nla_nest_cancel(skb, nest); return -1; } @@ -654,7 +647,7 @@ static void flow_walk(struct tcf_proto *tp, struct tcf_walker *arg) struct flow_head *head = rtnl_dereference(tp->root); struct flow_filter *f; - list_for_each_entry_rcu(f, &head->filters, list) { + list_for_each_entry(f, &head->filters, list) { if (arg->count < arg->skip) goto skip; if (arg->fn(tp, (unsigned long)f, arg) < 0) { @@ -674,7 +667,6 @@ static struct tcf_proto_ops cls_flow_ops __read_mostly = { .change = flow_change, .delete = flow_delete, .get = flow_get, - .put = flow_put, .dump = flow_dump, .walk = flow_walk, .owner = THIS_MODULE, diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index dbfdfd1f1a9f..a5269f76004c 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c @@ -111,10 +111,6 @@ static unsigned long fw_get(struct tcf_proto *tp, u32 handle) return 0; } -static void fw_put(struct tcf_proto *tp, unsigned long f) -{ -} - static int fw_init(struct tcf_proto *tp) { return 0; @@ -360,7 +356,6 @@ static int fw_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, { struct fw_head *head = rtnl_dereference(tp->root); struct fw_filter *f = (struct fw_filter *)fh; - unsigned char *b = skb_tail_pointer(skb); struct nlattr *nest; if (f == NULL) @@ -401,7 +396,7 @@ static int fw_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, return skb->len; nla_put_failure: - nlmsg_trim(skb, b); + nla_nest_cancel(skb, nest); return -1; } @@ -411,7 +406,6 @@ static struct tcf_proto_ops cls_fw_ops __read_mostly = { .init = fw_init, .destroy = fw_destroy, .get = fw_get, - .put = fw_put, .change = fw_change, .delete = fw_delete, .walk = fw_walk, diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index 109a329b7198..2ecd24688554 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c @@ -256,10 +256,6 @@ static unsigned long route4_get(struct tcf_proto *tp, u32 handle) return 0; } -static void route4_put(struct tcf_proto *tp, unsigned long f) -{ -} - static int route4_init(struct tcf_proto *tp) { return 0; @@ -597,7 +593,6 @@ static int route4_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, struct sk_buff *skb, struct tcmsg *t) { struct route4_filter *f = (struct route4_filter *)fh; - unsigned char *b = skb_tail_pointer(skb); struct nlattr *nest; u32 id; @@ -639,7 +634,7 @@ static int route4_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, return skb->len; nla_put_failure: - nlmsg_trim(skb, b); + nla_nest_cancel(skb, nest); return -1; } @@ -649,7 +644,6 @@ static struct tcf_proto_ops cls_route4_ops __read_mostly = { .init = route4_init, .destroy = route4_destroy, .get = route4_get, - .put = route4_put, .change = route4_change, .delete = route4_delete, .walk = route4_walk, diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 6bb55f277a5a..edd8ade3fbc1 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -271,10 +271,6 @@ static unsigned long rsvp_get(struct tcf_proto *tp, u32 handle) return 0; } -static void rsvp_put(struct tcf_proto *tp, unsigned long f) -{ -} - static int rsvp_init(struct tcf_proto *tp) { struct rsvp_head *data; @@ -657,7 +653,6 @@ static int rsvp_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, { struct rsvp_filter *f = (struct rsvp_filter *)fh; struct rsvp_session *s; - unsigned char *b = skb_tail_pointer(skb); struct nlattr *nest; struct tc_rsvp_pinfo pinfo; @@ -698,7 +693,7 @@ static int rsvp_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, return skb->len; nla_put_failure: - nlmsg_trim(skb, b); + nla_nest_cancel(skb, nest); return -1; } @@ -708,7 +703,6 @@ static struct tcf_proto_ops RSVP_OPS __read_mostly = { .init = rsvp_init, .destroy = rsvp_destroy, .get = rsvp_get, - .put = rsvp_put, .change = rsvp_change, .delete = rsvp_delete, .walk = rsvp_walk, diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index 30f10fb07f4a..bd49bf547a47 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -116,13 +116,6 @@ static unsigned long tcindex_get(struct tcf_proto *tp, u32 handle) return r && tcindex_filter_is_set(r) ? (unsigned long) r : 0UL; } - -static void tcindex_put(struct tcf_proto *tp, unsigned long f) -{ - pr_debug("tcindex_put(tp %p,f 0x%lx)\n", tp, f); -} - - static int tcindex_init(struct tcf_proto *tp) { struct tcindex_data *p; @@ -496,11 +489,10 @@ static int tcindex_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, { struct tcindex_data *p = rtnl_dereference(tp->root); struct tcindex_filter_result *r = (struct tcindex_filter_result *) fh; - unsigned char *b = skb_tail_pointer(skb); struct nlattr *nest; - pr_debug("tcindex_dump(tp %p,fh 0x%lx,skb %p,t %p),p %p,r %p,b %p\n", - tp, fh, skb, t, p, r, b); + pr_debug("tcindex_dump(tp %p,fh 0x%lx,skb %p,t %p),p %p,r %p\n", + tp, fh, skb, t, p, r); pr_debug("p->perfect %p p->h %p\n", p->perfect, p->h); nest = nla_nest_start(skb, TCA_OPTIONS); @@ -550,7 +542,7 @@ static int tcindex_dump(struct net *net, struct tcf_proto *tp, unsigned long fh, return skb->len; nla_put_failure: - nlmsg_trim(skb, b); + nla_nest_cancel(skb, nest); return -1; } @@ -560,7 +552,6 @@ static struct tcf_proto_ops cls_tcindex_ops __read_mostly = { .init = tcindex_init, .destroy = tcindex_destroy, .get = tcindex_get, - .put = tcindex_put, .change = tcindex_change, .delete = tcindex_delete, .walk = tcindex_walk, diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 0472909bb014..09487afbfd51 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -299,10 +299,6 @@ static unsigned long u32_get(struct tcf_proto *tp, u32 handle) return (unsigned long)u32_lookup_key(ht, handle); } -static void u32_put(struct tcf_proto *tp, unsigned long f) -{ -} - static u32 gen_new_htid(struct tc_u_common *tp_c) { int i = 0x800; @@ -1021,7 +1017,6 @@ static struct tcf_proto_ops cls_u32_ops __read_mostly = { .init = u32_init, .destroy = u32_destroy, .get = u32_get, - .put = u32_put, .change = u32_change, .delete = u32_delete, .walk = u32_walk, diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c index cbd7e1fd23b4..9b05924cc386 100644 --- a/net/sched/sch_fq.c +++ b/net/sched/sch_fq.c @@ -481,12 +481,11 @@ begin: if (likely(rate)) do_div(len, rate); /* Since socket rate can change later, - * clamp the delay to 125 ms. - * TODO: maybe segment the too big skb, as in commit - * e43ac79a4bc ("sch_tbf: segment too big GSO packets") + * clamp the delay to 1 second. + * Really, providers of too big packets should be fixed ! */ - if (unlikely(len > 125 * NSEC_PER_MSEC)) { - len = 125 * NSEC_PER_MSEC; + if (unlikely(len > NSEC_PER_SEC)) { + len = NSEC_PER_SEC; q->stat_pkts_too_long++; } diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c index b9ca32ebc1de..1e52decb7b59 100644 --- a/net/sched/sch_fq_codel.c +++ b/net/sched/sch_fq_codel.c @@ -94,7 +94,7 @@ static unsigned int fq_codel_classify(struct sk_buff *skb, struct Qdisc *sch, TC_H_MIN(skb->priority) <= q->flows_cnt) return TC_H_MIN(skb->priority); - filter = rcu_dereference(q->filter_list); + filter = rcu_dereference_bh(q->filter_list); if (!filter) return fq_codel_hash(q, skb) + 1; diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index b34331967e02..179f1c8c0d8b 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -139,33 +139,20 @@ struct netem_sched_data { /* Time stamp put into socket buffer control block * Only valid when skbs are in our internal t(ime)fifo queue. + * + * As skb->rbnode uses same storage than skb->next, skb->prev and skb->tstamp, + * and skb->next & skb->prev are scratch space for a qdisc, + * we save skb->tstamp value in skb->cb[] before destroying it. */ struct netem_skb_cb { psched_time_t time_to_send; ktime_t tstamp_save; }; -/* Because space in skb->cb[] is tight, netem overloads skb->next/prev/tstamp - * to hold a rb_node structure. - * - * If struct sk_buff layout is changed, the following checks will complain. - */ -static struct rb_node *netem_rb_node(struct sk_buff *skb) -{ - BUILD_BUG_ON(offsetof(struct sk_buff, next) != 0); - BUILD_BUG_ON(offsetof(struct sk_buff, prev) != - offsetof(struct sk_buff, next) + sizeof(skb->next)); - BUILD_BUG_ON(offsetof(struct sk_buff, tstamp) != - offsetof(struct sk_buff, prev) + sizeof(skb->prev)); - BUILD_BUG_ON(sizeof(struct rb_node) > sizeof(skb->next) + - sizeof(skb->prev) + - sizeof(skb->tstamp)); - return (struct rb_node *)&skb->next; -} static struct sk_buff *netem_rb_to_skb(struct rb_node *rb) { - return (struct sk_buff *)rb; + return container_of(rb, struct sk_buff, rbnode); } static inline struct netem_skb_cb *netem_skb_cb(struct sk_buff *skb) @@ -403,8 +390,8 @@ static void tfifo_enqueue(struct sk_buff *nskb, struct Qdisc *sch) else p = &parent->rb_left; } - rb_link_node(netem_rb_node(nskb), parent, p); - rb_insert_color(netem_rb_node(nskb), &q->t_root); + rb_link_node(&nskb->rbnode, parent, p); + rb_insert_color(&nskb->rbnode, &q->t_root); sch->q.qlen++; } |