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 --- |