History

net/sched: Retire ipt action

The tc ipt action was intended to run all netfilter/iptables target. Unfortunately it has not benefitted over the years from proper updates when netfilter changes, and for that reason it has remained rudimentary. Pinging a bunch of people that i was aware were using this indicates that removing it wont affect them. Retire it to reduce maintenance efforts. Buh-bye.

Jamal Hadi Salim committed 2 years ago

Commit ba24ea11 parent 993498e8 files · +2 −510Browse files

Unified · Split

8 files
  1. include/net/tc_act/tc_ipt.h +0 −17
  2. include/net/tc_wrapper.h +0 −4
  3. include/uapi/linux/pkt_cls.h +2 −2
  4. include/uapi/linux/tc_act/tc_ipt.h +0 −20
  5. net/sched/Makefile +0 −1
  6. net/sched/act_ipt.c +0 −464
  7. tools/testing/selftests/tc-testing/config +0 −1
  8. tools/testing/selftests/tc-testing/tdc.sh +0 −1
include/net/tc_act/tc_ipt.h+0−17
@@ -1,17 +0,0 @@
1−/* SPDX-License-Identifier: GPL-2.0 */
2−#ifndef __NET_TC_IPT_H
3−#define __NET_TC_IPT_H
4−
5−#include <net/act_api.h>
6−
7−struct xt_entry_target;
8−
9−struct tcf_ipt {
10− struct tc_action common;
11− u32 tcfi_hook;
12− char *tcfi_tname;
13− struct xt_entry_target *tcfi_t;
14−};
15−#define to_ipt(a) ((struct tcf_ipt *)a)
16−
17−#endif /* __NET_TC_IPT_H */
include/net/tc_wrapper.h+0−4
@@ -117,10 +117,6 @@ static inline int tc_act(struct sk_buff *skb, const struct tc_action *a, · 116 unmodified lines
117117 if (a->ops->act == tcf_ife_act)
118118 return tcf_ife_act(skb, a, res);
119119 #endif
120−#if IS_BUILTIN(CONFIG_NET_ACT_IPT)
121− if (a->ops->act == tcf_ipt_act)
122− return tcf_ipt_act(skb, a, res);
123−#endif
124120 #if IS_BUILTIN(CONFIG_NET_ACT_SIMP)
125121 if (a->ops->act == tcf_simp_act)
126122 return tcf_simp_act(skb, a, res);
include/uapi/linux/pkt_cls.h+2−2
@@ -99,7 +99,7 @@ enum { · 98 unmodified lines
9999 * versions.
100100 */
101101 #define TCA_ACT_GACT 5
102−#define TCA_ACT_IPT 6
102+#define TCA_ACT_IPT 6 /* obsoleted, can be reused */
103103 #define TCA_ACT_PEDIT 7
104104 #define TCA_ACT_MIRRED 8
105105 #define TCA_ACT_NAT 9
@@ -120,7 +120,7 @@ enum tca_id { · 14 unmodified lines
120120 TCA_ID_UNSPEC = 0,
121121 TCA_ID_POLICE = 1,
122122 TCA_ID_GACT = TCA_ACT_GACT,
123− TCA_ID_IPT = TCA_ACT_IPT,
123+ TCA_ID_IPT = TCA_ACT_IPT, /* Obsoleted, can be reused */
124124 TCA_ID_PEDIT = TCA_ACT_PEDIT,
125125 TCA_ID_MIRRED = TCA_ACT_MIRRED,
126126 TCA_ID_NAT = TCA_ACT_NAT,
include/uapi/linux/tc_act/tc_ipt.h+0−20
@@ -1,20 +0,0 @@
1−/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
2−#ifndef __LINUX_TC_IPT_H
3−#define __LINUX_TC_IPT_H
4−
5−#include <linux/pkt_cls.h>
6−
7−enum {
8− TCA_IPT_UNSPEC,
9− TCA_IPT_TABLE,
10− TCA_IPT_HOOK,
11− TCA_IPT_INDEX,
12− TCA_IPT_CNT,
13− TCA_IPT_TM,
14− TCA_IPT_TARG,
15− TCA_IPT_PAD,
16− __TCA_IPT_MAX
17−};
18−#define TCA_IPT_MAX (__TCA_IPT_MAX - 1)
19−
20−#endif
net/sched/Makefile+0−1
@@ -13,7 +13,6 @@ obj-$(CONFIG_NET_ACT_POLICE) += act_police.o · 12 unmodified lines
1313 obj-$(CONFIG_NET_ACT_GACT) += act_gact.o
1414 obj-$(CONFIG_NET_ACT_MIRRED) += act_mirred.o
1515 obj-$(CONFIG_NET_ACT_SAMPLE) += act_sample.o
16−obj-$(CONFIG_NET_ACT_IPT) += act_ipt.o
1716 obj-$(CONFIG_NET_ACT_NAT) += act_nat.o
1817 obj-$(CONFIG_NET_ACT_PEDIT) += act_pedit.o
1918 obj-$(CONFIG_NET_ACT_SIMP) += act_simple.o
net/sched/act_ipt.c+0−464
@@ -1,464 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0-or-later
2−/*
3− * net/sched/act_ipt.c iptables target interface
4− *
5− *TODO: Add other tables. For now we only support the ipv4 table targets
6− *
7− * Copyright: Jamal Hadi Salim (2002-13)
8− */
9−
10−#include <linux/types.h>
11−#include <linux/kernel.h>
12−#include <linux/string.h>
13−#include <linux/errno.h>
14−#include <linux/skbuff.h>
15−#include <linux/rtnetlink.h>
16−#include <linux/module.h>
17−#include <linux/init.h>
18−#include <linux/slab.h>
19−#include <net/netlink.h>
20−#include <net/pkt_sched.h>
21−#include <linux/tc_act/tc_ipt.h>
22−#include <net/tc_act/tc_ipt.h>
23−#include <net/tc_wrapper.h>
24−#include <net/ip.h>
25−
26−#include <linux/netfilter_ipv4/ip_tables.h>
27−
28−
29−static struct tc_action_ops act_ipt_ops;
30−static struct tc_action_ops act_xt_ops;
31−
32−static int ipt_init_target(struct net *net, struct xt_entry_target *t,
33− char *table, unsigned int hook)
34−{
35− struct xt_tgchk_param par;
36− struct xt_target *target;
37− struct ipt_entry e = {};
38− int ret = 0;
39−
40− target = xt_request_find_target(AF_INET, t->u.user.name,
41− t->u.user.revision);
42− if (IS_ERR(target))
43− return PTR_ERR(target);
44−
45− t->u.kernel.target = target;
46− memset(&par, 0, sizeof(par));
47− par.net = net;
48− par.table = table;
49− par.entryinfo = &e;
50− par.target = target;
51− par.targinfo = t->data;
52− par.hook_mask = 1 << hook;
53− par.family = NFPROTO_IPV4;
54−
55− ret = xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false);
56− if (ret < 0) {
57− module_put(t->u.kernel.target->me);
58− return ret;
59− }
60− return 0;
61−}
62−
63−static void ipt_destroy_target(struct xt_entry_target *t, struct net *net)
64−{
65− struct xt_tgdtor_param par = {
66− .target = t->u.kernel.target,
67− .targinfo = t->data,
68− .family = NFPROTO_IPV4,
69− .net = net,
70− };
71− if (par.target->destroy != NULL)
72− par.target->destroy(&par);
73− module_put(par.target->me);
74−}
75−
76−static void tcf_ipt_release(struct tc_action *a)
77−{
78− struct tcf_ipt *ipt = to_ipt(a);
79−
80− if (ipt->tcfi_t) {
81− ipt_destroy_target(ipt->tcfi_t, a->idrinfo->net);
82− kfree(ipt->tcfi_t);
83− }
84− kfree(ipt->tcfi_tname);
85−}
86−
87−static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] = {
88− [TCA_IPT_TABLE] = { .type = NLA_STRING, .len = IFNAMSIZ },
89− [TCA_IPT_HOOK] = NLA_POLICY_RANGE(NLA_U32, NF_INET_PRE_ROUTING,
90− NF_INET_NUMHOOKS),
91− [TCA_IPT_INDEX] = { .type = NLA_U32 },
92− [TCA_IPT_TARG] = { .len = sizeof(struct xt_entry_target) },
93−};
94−
95−static int __tcf_ipt_init(struct net *net, unsigned int id, struct nlattr *nla,
96− struct nlattr *est, struct tc_action **a,
97− const struct tc_action_ops *ops,
98− struct tcf_proto *tp, u32 flags)
99−{
100− struct tc_action_net *tn = net_generic(net, id);
101− bool bind = flags & TCA_ACT_FLAGS_BIND;
102− struct nlattr *tb[TCA_IPT_MAX + 1];
103− struct tcf_ipt *ipt;
104− struct xt_entry_target *td, *t;
105− char *tname;
106− bool exists = false;
107− int ret = 0, err;
108− u32 hook = 0;
109− u32 index = 0;
110−
111− if (nla == NULL)
112− return -EINVAL;
113−
114− err = nla_parse_nested_deprecated(tb, TCA_IPT_MAX, nla, ipt_policy,
115− NULL);
116− if (err < 0)
117− return err;
118−
119− if (tb[TCA_IPT_INDEX] != NULL)
120− index = nla_get_u32(tb[TCA_IPT_INDEX]);
121−
122− err = tcf_idr_check_alloc(tn, &index, a, bind);
123− if (err < 0)
124− return err;
125− exists = err;
126− if (exists && bind)
127− return 0;
128−
129− if (tb[TCA_IPT_HOOK] == NULL || tb[TCA_IPT_TARG] == NULL) {
130− if (exists)
131− tcf_idr_release(*a, bind);
132− else
133− tcf_idr_cleanup(tn, index);
134− return -EINVAL;
135− }
136−
137− td = (struct xt_entry_target *)nla_data(tb[TCA_IPT_TARG]);
138− if (nla_len(tb[TCA_IPT_TARG]) != td->u.target_size) {
139− if (exists)
140− tcf_idr_release(*a, bind);
141− else
142− tcf_idr_cleanup(tn, index);
143− return -EINVAL;
144− }
145−
146− if (!exists) {
147− ret = tcf_idr_create(tn, index, est, a, ops, bind,
148− false, flags);
149− if (ret) {
150− tcf_idr_cleanup(tn, index);
151− return ret;
152− }
153− ret = ACT_P_CREATED;
154− } else {
155− if (bind)/* dont override defaults */
156− return 0;
157−
158− if (!(flags & TCA_ACT_FLAGS_REPLACE)) {
159− tcf_idr_release(*a, bind);
160− return -EEXIST;
161− }
162− }
163−
164− err = -EINVAL;
165− hook = nla_get_u32(tb[TCA_IPT_HOOK]);
166− switch (hook) {
167− case NF_INET_PRE_ROUTING:
168− break;
169− case NF_INET_POST_ROUTING:
170− break;
171− default:
172− goto err1;
173− }
174−
175− if (tb[TCA_IPT_TABLE]) {
176− /* mangle only for now */
177− if (nla_strcmp(tb[TCA_IPT_TABLE], "mangle"))
178− goto err1;
179− }
180−
181− tname = kstrdup("mangle", GFP_KERNEL);
182− if (unlikely(!tname))
183− goto err1;
184−
185− t = kmemdup(td, td->u.target_size, GFP_KERNEL);
186− if (unlikely(!t))
187− goto err2;
188−
189− err = ipt_init_target(net, t, tname, hook);
190− if (err < 0)
191− goto err3;
192−
193− ipt = to_ipt(*a);
194−
195− spin_lock_bh(&ipt->tcf_lock);
196− if (ret != ACT_P_CREATED) {
197− ipt_destroy_target(ipt->tcfi_t, net);
198− kfree(ipt->tcfi_tname);
199− kfree(ipt->tcfi_t);
200− }
201− ipt->tcfi_tname = tname;
202− ipt->tcfi_t = t;
203− ipt->tcfi_hook = hook;
204− spin_unlock_bh(&ipt->tcf_lock);
205− return ret;
206−
207−err3:
208− kfree(t);
209−err2:
210− kfree(tname);
211−err1:
212− tcf_idr_release(*a, bind);
213− return err;
214−}
215−
216−static int tcf_ipt_init(struct net *net, struct nlattr *nla,
217− struct nlattr *est, struct tc_action **a,
218− struct tcf_proto *tp,
219− u32 flags, struct netlink_ext_ack *extack)
220−{
221− return __tcf_ipt_init(net, act_ipt_ops.net_id, nla, est,
222− a, &act_ipt_ops, tp, flags);
223−}
224−
225−static int tcf_xt_init(struct net *net, struct nlattr *nla,
226− struct nlattr *est, struct tc_action **a,
227− struct tcf_proto *tp,
228− u32 flags, struct netlink_ext_ack *extack)
229−{
230− return __tcf_ipt_init(net, act_xt_ops.net_id, nla, est,
231− a, &act_xt_ops, tp, flags);
232−}
233−
234−static bool tcf_ipt_act_check(struct sk_buff *skb)
235−{
236− const struct iphdr *iph;
237− unsigned int nhoff, len;
238−
239− if (!pskb_may_pull(skb, sizeof(struct iphdr)))
240− return false;
241−
242− nhoff = skb_network_offset(skb);
243− iph = ip_hdr(skb);
244− if (iph->ihl < 5 || iph->version != 4)
245− return false;
246−
247− len = skb_ip_totlen(skb);
248− if (skb->len < nhoff + len || len < (iph->ihl * 4u))
249− return false;
250−
251− return pskb_may_pull(skb, iph->ihl * 4u);
252−}
253−
254−TC_INDIRECT_SCOPE int tcf_ipt_act(struct sk_buff *skb,
255− const struct tc_action *a,
256− struct tcf_result *res)
257−{
258− char saved_cb[sizeof_field(struct sk_buff, cb)];
259− int ret = 0, result = 0;
260− struct tcf_ipt *ipt = to_ipt(a);
261− struct xt_action_param par;
262− struct nf_hook_state state = {
263− .net = dev_net(skb->dev),
264− .in = skb->dev,
265− .hook = ipt->tcfi_hook,
266− .pf = NFPROTO_IPV4,
267− };
268−
269− if (skb_protocol(skb, false) != htons(ETH_P_IP))
270− return TC_ACT_UNSPEC;
271−
272− if (skb_unclone(skb, GFP_ATOMIC))
273− return TC_ACT_UNSPEC;
274−
275− if (!tcf_ipt_act_check(skb))
276− return TC_ACT_UNSPEC;
277−
278− if (state.hook == NF_INET_POST_ROUTING) {
279− if (!skb_dst(skb))
280− return TC_ACT_UNSPEC;
281−
282− state.out = skb->dev;
283− }
284−
285− memcpy(saved_cb, skb->cb, sizeof(saved_cb));
286−
287− spin_lock(&ipt->tcf_lock);
288−
289− tcf_lastuse_update(&ipt->tcf_tm);
290− bstats_update(&ipt->tcf_bstats, skb);
291−
292− /* yes, we have to worry about both in and out dev
293− * worry later - danger - this API seems to have changed
294− * from earlier kernels
295− */
296− par.state = &state;
297− par.target = ipt->tcfi_t->u.kernel.target;
298− par.targinfo = ipt->tcfi_t->data;
299−
300− memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
301−
302− ret = par.target->target(skb, &par);
303−
304− switch (ret) {
305− case NF_ACCEPT:
306− result = TC_ACT_OK;
307− break;
308− case NF_DROP:
309− result = TC_ACT_SHOT;
310− ipt->tcf_qstats.drops++;
311− break;
312− case XT_CONTINUE:
313− result = TC_ACT_PIPE;
314− break;
315− default:
316− net_notice_ratelimited("tc filter: Bogus netfilter code %d assume ACCEPT\n",
317− ret);
318− result = TC_ACT_OK;
319− break;
320− }
321− spin_unlock(&ipt->tcf_lock);
322−
323− memcpy(skb->cb, saved_cb, sizeof(skb->cb));
324−
325− return result;
326−
327−}
328−
329−static int tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind,
330− int ref)
331−{
332− unsigned char *b = skb_tail_pointer(skb);
333− struct tcf_ipt *ipt = to_ipt(a);
334− struct xt_entry_target *t;
335− struct tcf_t tm;
336− struct tc_cnt c;
337−
338− /* for simple targets kernel size == user size
339− * user name = target name
340− * for foolproof you need to not assume this
341− */
342−
343− spin_lock_bh(&ipt->tcf_lock);
344− t = kmemdup(ipt->tcfi_t, ipt->tcfi_t->u.user.target_size, GFP_ATOMIC);
345− if (unlikely(!t))
346− goto nla_put_failure;
347−
348− c.bindcnt = atomic_read(&ipt->tcf_bindcnt) - bind;
349− c.refcnt = refcount_read(&ipt->tcf_refcnt) - ref;
350− strcpy(t->u.user.name, ipt->tcfi_t->u.kernel.target->name);
351−
352− if (nla_put(skb, TCA_IPT_TARG, ipt->tcfi_t->u.user.target_size, t) ||
353− nla_put_u32(skb, TCA_IPT_INDEX, ipt->tcf_index) ||
354− nla_put_u32(skb, TCA_IPT_HOOK, ipt->tcfi_hook) ||
355− nla_put(skb, TCA_IPT_CNT, sizeof(struct tc_cnt), &c) ||
356− nla_put_string(skb, TCA_IPT_TABLE, ipt->tcfi_tname))
357− goto nla_put_failure;
358−
359− tcf_tm_dump(&tm, &ipt->tcf_tm);
360− if (nla_put_64bit(skb, TCA_IPT_TM, sizeof(tm), &tm, TCA_IPT_PAD))
361− goto nla_put_failure;
362−
363− spin_unlock_bh(&ipt->tcf_lock);
364− kfree(t);
365− return skb->len;
366−
367−nla_put_failure:
368− spin_unlock_bh(&ipt->tcf_lock);
369− nlmsg_trim(skb, b);
370− kfree(t);
371− return -1;
372−}
373−
374−static struct tc_action_ops act_ipt_ops = {
375− .kind = "ipt",
376− .id = TCA_ID_IPT,
377− .owner = THIS_MODULE,
378− .act = tcf_ipt_act,
379− .dump = tcf_ipt_dump,
380− .cleanup = tcf_ipt_release,
381− .init = tcf_ipt_init,
382− .size = sizeof(struct tcf_ipt),
383−};
384−
385−static __net_init int ipt_init_net(struct net *net)
386−{
387− struct tc_action_net *tn = net_generic(net, act_ipt_ops.net_id);
388−
389− return tc_action_net_init(net, tn, &act_ipt_ops);
390−}
391−
392−static void __net_exit ipt_exit_net(struct list_head *net_list)
393−{
394− tc_action_net_exit(net_list, act_ipt_ops.net_id);
395−}
396−
397−static struct pernet_operations ipt_net_ops = {
398− .init = ipt_init_net,
399− .exit_batch = ipt_exit_net,
400− .id = &act_ipt_ops.net_id,
401− .size = sizeof(struct tc_action_net),
402−};
403−
404−static struct tc_action_ops act_xt_ops = {
405− .kind = "xt",
406− .id = TCA_ID_XT,
407− .owner = THIS_MODULE,
408− .act = tcf_ipt_act,
409− .dump = tcf_ipt_dump,
410− .cleanup = tcf_ipt_release,
411− .init = tcf_xt_init,
412− .size = sizeof(struct tcf_ipt),
413−};
414−
415−static __net_init int xt_init_net(struct net *net)
416−{
417− struct tc_action_net *tn = net_generic(net, act_xt_ops.net_id);
418−
419− return tc_action_net_init(net, tn, &act_xt_ops);
420−}
421−
422−static void __net_exit xt_exit_net(struct list_head *net_list)
423−{
424− tc_action_net_exit(net_list, act_xt_ops.net_id);
425−}
426−
427−static struct pernet_operations xt_net_ops = {
428− .init = xt_init_net,
429− .exit_batch = xt_exit_net,
430− .id = &act_xt_ops.net_id,
431− .size = sizeof(struct tc_action_net),
432−};
433−
434−MODULE_AUTHOR("Jamal Hadi Salim(2002-13)");
435−MODULE_DESCRIPTION("Iptables target actions");
436−MODULE_LICENSE("GPL");
437−MODULE_ALIAS("act_xt");
438−
439−static int __init ipt_init_module(void)
440−{
441− int ret1, ret2;
442−
443− ret1 = tcf_register_action(&act_xt_ops, &xt_net_ops);
444− if (ret1 < 0)
445− pr_err("Failed to load xt action\n");
446−
447− ret2 = tcf_register_action(&act_ipt_ops, &ipt_net_ops);
448− if (ret2 < 0)
449− pr_err("Failed to load ipt action\n");
450−
451− if (ret1 < 0 && ret2 < 0) {
452− return ret1;
453− } else
454− return 0;
455−}
456−
457−static void __exit ipt_cleanup_module(void)
458−{
459− tcf_unregister_action(&act_ipt_ops, &ipt_net_ops);
460− tcf_unregister_action(&act_xt_ops, &xt_net_ops);
461−}
462−
463−module_init(ipt_init_module);
464−module_exit(ipt_cleanup_module);
tools/testing/selftests/tc-testing/config+0−1
@@ -82,7 +82,6 @@ CONFIG_NET_ACT_GACT=m · 81 unmodified lines
8282 CONFIG_GACT_PROB=y
8383 CONFIG_NET_ACT_MIRRED=m
8484 CONFIG_NET_ACT_SAMPLE=m
85−CONFIG_NET_ACT_IPT=m
8685 CONFIG_NET_ACT_NAT=m
8786 CONFIG_NET_ACT_PEDIT=m
8887 CONFIG_NET_ACT_SIMP=m
tools/testing/selftests/tc-testing/tdc.sh+0−1
@@ -20,7 +20,6 @@ try_modprobe act_ct · 19 unmodified lines
2020 try_modprobe act_ctinfo
2121 try_modprobe act_gact
2222 try_modprobe act_gate
23−try_modprobe act_ipt
2423 try_modprobe act_mirred
2524 try_modprobe act_mpls
2625 try_modprobe act_nat

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t