act_mirred.c (a3b072cd180c12e8fe0ece9487b9065808327640) act_mirred.c (86062033feb8a1692f7a3d570c652f1b4a4b4b52)
1/*
2 * net/sched/mirred.c packet mirroring and redirect actions
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *

--- 19 unchanged lines hidden (view full) ---

28#include <net/tc_act/tc_mirred.h>
29
30#include <linux/if_arp.h>
31
32#define MIRRED_TAB_MASK 7
33static LIST_HEAD(mirred_list);
34static struct tcf_hashinfo mirred_hash_info;
35
1/*
2 * net/sched/mirred.c packet mirroring and redirect actions
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *

--- 19 unchanged lines hidden (view full) ---

28#include <net/tc_act/tc_mirred.h>
29
30#include <linux/if_arp.h>
31
32#define MIRRED_TAB_MASK 7
33static LIST_HEAD(mirred_list);
34static struct tcf_hashinfo mirred_hash_info;
35
36static int tcf_mirred_release(struct tcf_mirred *m, int bind)
36static int tcf_mirred_release(struct tc_action *a, int bind)
37{
37{
38 struct tcf_mirred *m = to_mirred(a);
38 if (m) {
39 if (bind)
40 m->tcf_bindcnt--;
41 m->tcf_refcnt--;
42 if (!m->tcf_bindcnt && m->tcf_refcnt <= 0) {
43 list_del(&m->tcfm_list);
44 if (m->tcfm_dev)
45 dev_put(m->tcfm_dev);
39 if (m) {
40 if (bind)
41 m->tcf_bindcnt--;
42 m->tcf_refcnt--;
43 if (!m->tcf_bindcnt && m->tcf_refcnt <= 0) {
44 list_del(&m->tcfm_list);
45 if (m->tcfm_dev)
46 dev_put(m->tcfm_dev);
46 tcf_hash_destroy(&m->common, &mirred_hash_info);
47 tcf_hash_destroy(a);
47 return 1;
48 }
49 }
50 return 0;
51}
52
53static const struct nla_policy mirred_policy[TCA_MIRRED_MAX + 1] = {
54 [TCA_MIRRED_PARMS] = { .len = sizeof(struct tc_mirred) },
55};
56
57static int tcf_mirred_init(struct net *net, struct nlattr *nla,
58 struct nlattr *est, struct tc_action *a, int ovr,
59 int bind)
60{
61 struct nlattr *tb[TCA_MIRRED_MAX + 1];
62 struct tc_mirred *parm;
63 struct tcf_mirred *m;
48 return 1;
49 }
50 }
51 return 0;
52}
53
54static const struct nla_policy mirred_policy[TCA_MIRRED_MAX + 1] = {
55 [TCA_MIRRED_PARMS] = { .len = sizeof(struct tc_mirred) },
56};
57
58static int tcf_mirred_init(struct net *net, struct nlattr *nla,
59 struct nlattr *est, struct tc_action *a, int ovr,
60 int bind)
61{
62 struct nlattr *tb[TCA_MIRRED_MAX + 1];
63 struct tc_mirred *parm;
64 struct tcf_mirred *m;
64 struct tcf_common *pc;
65 struct net_device *dev;
66 int ret, ok_push = 0;
67
68 if (nla == NULL)
69 return -EINVAL;
70 ret = nla_parse_nested(tb, TCA_MIRRED_MAX, nla, mirred_policy);
71 if (ret < 0)
72 return ret;

--- 23 unchanged lines hidden (view full) ---

96 default:
97 ok_push = 1;
98 break;
99 }
100 } else {
101 dev = NULL;
102 }
103
65 struct net_device *dev;
66 int ret, ok_push = 0;
67
68 if (nla == NULL)
69 return -EINVAL;
70 ret = nla_parse_nested(tb, TCA_MIRRED_MAX, nla, mirred_policy);
71 if (ret < 0)
72 return ret;

--- 23 unchanged lines hidden (view full) ---

96 default:
97 ok_push = 1;
98 break;
99 }
100 } else {
101 dev = NULL;
102 }
103
104 pc = tcf_hash_check(parm->index, a, bind);
105 if (!pc) {
104 if (!tcf_hash_check(parm->index, a, bind)) {
106 if (dev == NULL)
107 return -EINVAL;
105 if (dev == NULL)
106 return -EINVAL;
108 pc = tcf_hash_create(parm->index, est, a, sizeof(*m), bind);
109 if (IS_ERR(pc))
110 return PTR_ERR(pc);
107 ret = tcf_hash_create(parm->index, est, a, sizeof(*m), bind);
108 if (ret)
109 return ret;
111 ret = ACT_P_CREATED;
112 } else {
113 if (!ovr) {
110 ret = ACT_P_CREATED;
111 } else {
112 if (!ovr) {
114 tcf_mirred_release(to_mirred(pc), bind);
113 tcf_mirred_release(a, bind);
115 return -EEXIST;
116 }
117 }
114 return -EEXIST;
115 }
116 }
118 m = to_mirred(pc);
117 m = to_mirred(a);
119
120 spin_lock_bh(&m->tcf_lock);
121 m->tcf_action = parm->action;
122 m->tcfm_eaction = parm->eaction;
123 if (dev != NULL) {
124 m->tcfm_ifindex = parm->ifindex;
125 if (ret != ACT_P_CREATED)
126 dev_put(m->tcfm_dev);
127 dev_hold(dev);
128 m->tcfm_dev = dev;
129 m->tcfm_ok_push = ok_push;
130 }
131 spin_unlock_bh(&m->tcf_lock);
132 if (ret == ACT_P_CREATED) {
133 list_add(&m->tcfm_list, &mirred_list);
118
119 spin_lock_bh(&m->tcf_lock);
120 m->tcf_action = parm->action;
121 m->tcfm_eaction = parm->eaction;
122 if (dev != NULL) {
123 m->tcfm_ifindex = parm->ifindex;
124 if (ret != ACT_P_CREATED)
125 dev_put(m->tcfm_dev);
126 dev_hold(dev);
127 m->tcfm_dev = dev;
128 m->tcfm_ok_push = ok_push;
129 }
130 spin_unlock_bh(&m->tcf_lock);
131 if (ret == ACT_P_CREATED) {
132 list_add(&m->tcfm_list, &mirred_list);
134 tcf_hash_insert(pc, a->ops->hinfo);
133 tcf_hash_insert(a);
135 }
136
137 return ret;
138}
139
134 }
135
136 return ret;
137}
138
140static int tcf_mirred_cleanup(struct tc_action *a, int bind)
141{
142 struct tcf_mirred *m = a->priv;
143
144 if (m)
145 return tcf_mirred_release(m, bind);
146 return 0;
147}
148
149static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a,
150 struct tcf_result *res)
151{
152 struct tcf_mirred *m = a->priv;
153 struct net_device *dev;
154 struct sk_buff *skb2;
155 u32 at;
156 int retval, err = 1;

--- 97 unchanged lines hidden (view full) ---

254
255static struct tc_action_ops act_mirred_ops = {
256 .kind = "mirred",
257 .hinfo = &mirred_hash_info,
258 .type = TCA_ACT_MIRRED,
259 .owner = THIS_MODULE,
260 .act = tcf_mirred,
261 .dump = tcf_mirred_dump,
139static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a,
140 struct tcf_result *res)
141{
142 struct tcf_mirred *m = a->priv;
143 struct net_device *dev;
144 struct sk_buff *skb2;
145 u32 at;
146 int retval, err = 1;

--- 97 unchanged lines hidden (view full) ---

244
245static struct tc_action_ops act_mirred_ops = {
246 .kind = "mirred",
247 .hinfo = &mirred_hash_info,
248 .type = TCA_ACT_MIRRED,
249 .owner = THIS_MODULE,
250 .act = tcf_mirred,
251 .dump = tcf_mirred_dump,
262 .cleanup = tcf_mirred_cleanup,
252 .cleanup = tcf_mirred_release,
263 .init = tcf_mirred_init,
264};
265
266MODULE_AUTHOR("Jamal Hadi Salim(2002)");
267MODULE_DESCRIPTION("Device Mirror/redirect actions");
268MODULE_LICENSE("GPL");
269
270static int __init mirred_init_module(void)

--- 23 unchanged lines hidden ---
253 .init = tcf_mirred_init,
254};
255
256MODULE_AUTHOR("Jamal Hadi Salim(2002)");
257MODULE_DESCRIPTION("Device Mirror/redirect actions");
258MODULE_LICENSE("GPL");
259
260static int __init mirred_init_module(void)

--- 23 unchanged lines hidden ---