OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [net/] [sched/] [act_gact.c] - Blame information for rev 17

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
2
 * net/sched/gact.c     Generic 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
 *
9
 * copyright    Jamal Hadi Salim (2002-4)
10
 *
11
 */
12
 
13
#include <linux/types.h>
14
#include <linux/kernel.h>
15
#include <linux/string.h>
16
#include <linux/errno.h>
17
#include <linux/skbuff.h>
18
#include <linux/rtnetlink.h>
19
#include <linux/module.h>
20
#include <linux/init.h>
21
#include <net/netlink.h>
22
#include <net/pkt_sched.h>
23
#include <linux/tc_act/tc_gact.h>
24
#include <net/tc_act/tc_gact.h>
25
 
26
#define GACT_TAB_MASK   15
27
static struct tcf_common *tcf_gact_ht[GACT_TAB_MASK + 1];
28
static u32 gact_idx_gen;
29
static DEFINE_RWLOCK(gact_lock);
30
 
31
static struct tcf_hashinfo gact_hash_info = {
32
        .htab   =       tcf_gact_ht,
33
        .hmask  =       GACT_TAB_MASK,
34
        .lock   =       &gact_lock,
35
};
36
 
37
#ifdef CONFIG_GACT_PROB
38
static int gact_net_rand(struct tcf_gact *gact)
39
{
40
        if (!gact->tcfg_pval || net_random() % gact->tcfg_pval)
41
                return gact->tcf_action;
42
        return gact->tcfg_paction;
43
}
44
 
45
static int gact_determ(struct tcf_gact *gact)
46
{
47
        if (!gact->tcfg_pval || gact->tcf_bstats.packets % gact->tcfg_pval)
48
                return gact->tcf_action;
49
        return gact->tcfg_paction;
50
}
51
 
52
typedef int (*g_rand)(struct tcf_gact *gact);
53
static g_rand gact_rand[MAX_RAND]= { NULL, gact_net_rand, gact_determ };
54
#endif /* CONFIG_GACT_PROB */
55
 
56
static int tcf_gact_init(struct rtattr *rta, struct rtattr *est,
57
                         struct tc_action *a, int ovr, int bind)
58
{
59
        struct rtattr *tb[TCA_GACT_MAX];
60
        struct tc_gact *parm;
61
        struct tcf_gact *gact;
62
        struct tcf_common *pc;
63
        int ret = 0;
64
 
65
        if (rta == NULL || rtattr_parse_nested(tb, TCA_GACT_MAX, rta) < 0)
66
                return -EINVAL;
67
 
68
        if (tb[TCA_GACT_PARMS - 1] == NULL ||
69
            RTA_PAYLOAD(tb[TCA_GACT_PARMS - 1]) < sizeof(*parm))
70
                return -EINVAL;
71
        parm = RTA_DATA(tb[TCA_GACT_PARMS - 1]);
72
 
73
        if (tb[TCA_GACT_PROB-1] != NULL)
74
#ifdef CONFIG_GACT_PROB
75
                if (RTA_PAYLOAD(tb[TCA_GACT_PROB-1]) < sizeof(struct tc_gact_p))
76
                        return -EINVAL;
77
#else
78
                return -EOPNOTSUPP;
79
#endif
80
 
81
        pc = tcf_hash_check(parm->index, a, bind, &gact_hash_info);
82
        if (!pc) {
83
                pc = tcf_hash_create(parm->index, est, a, sizeof(*gact),
84
                                     bind, &gact_idx_gen, &gact_hash_info);
85
                if (unlikely(!pc))
86
                        return -ENOMEM;
87
                ret = ACT_P_CREATED;
88
        } else {
89
                if (!ovr) {
90
                        tcf_hash_release(pc, bind, &gact_hash_info);
91
                        return -EEXIST;
92
                }
93
        }
94
 
95
        gact = to_gact(pc);
96
 
97
        spin_lock_bh(&gact->tcf_lock);
98
        gact->tcf_action = parm->action;
99
#ifdef CONFIG_GACT_PROB
100
        if (tb[TCA_GACT_PROB-1] != NULL) {
101
                struct tc_gact_p *p_parm = RTA_DATA(tb[TCA_GACT_PROB-1]);
102
                gact->tcfg_paction = p_parm->paction;
103
                gact->tcfg_pval    = p_parm->pval;
104
                gact->tcfg_ptype   = p_parm->ptype;
105
        }
106
#endif
107
        spin_unlock_bh(&gact->tcf_lock);
108
        if (ret == ACT_P_CREATED)
109
                tcf_hash_insert(pc, &gact_hash_info);
110
        return ret;
111
}
112
 
113
static int tcf_gact_cleanup(struct tc_action *a, int bind)
114
{
115
        struct tcf_gact *gact = a->priv;
116
 
117
        if (gact)
118
                return tcf_hash_release(&gact->common, bind, &gact_hash_info);
119
        return 0;
120
}
121
 
122
static int tcf_gact(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
123
{
124
        struct tcf_gact *gact = a->priv;
125
        int action = TC_ACT_SHOT;
126
 
127
        spin_lock(&gact->tcf_lock);
128
#ifdef CONFIG_GACT_PROB
129
        if (gact->tcfg_ptype && gact_rand[gact->tcfg_ptype] != NULL)
130
                action = gact_rand[gact->tcfg_ptype](gact);
131
        else
132
                action = gact->tcf_action;
133
#else
134
        action = gact->tcf_action;
135
#endif
136
        gact->tcf_bstats.bytes += skb->len;
137
        gact->tcf_bstats.packets++;
138
        if (action == TC_ACT_SHOT)
139
                gact->tcf_qstats.drops++;
140
        gact->tcf_tm.lastuse = jiffies;
141
        spin_unlock(&gact->tcf_lock);
142
 
143
        return action;
144
}
145
 
146
static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
147
{
148
        unsigned char *b = skb_tail_pointer(skb);
149
        struct tc_gact opt;
150
        struct tcf_gact *gact = a->priv;
151
        struct tcf_t t;
152
 
153
        opt.index = gact->tcf_index;
154
        opt.refcnt = gact->tcf_refcnt - ref;
155
        opt.bindcnt = gact->tcf_bindcnt - bind;
156
        opt.action = gact->tcf_action;
157
        RTA_PUT(skb, TCA_GACT_PARMS, sizeof(opt), &opt);
158
#ifdef CONFIG_GACT_PROB
159
        if (gact->tcfg_ptype) {
160
                struct tc_gact_p p_opt;
161
                p_opt.paction = gact->tcfg_paction;
162
                p_opt.pval = gact->tcfg_pval;
163
                p_opt.ptype = gact->tcfg_ptype;
164
                RTA_PUT(skb, TCA_GACT_PROB, sizeof(p_opt), &p_opt);
165
        }
166
#endif
167
        t.install = jiffies_to_clock_t(jiffies - gact->tcf_tm.install);
168
        t.lastuse = jiffies_to_clock_t(jiffies - gact->tcf_tm.lastuse);
169
        t.expires = jiffies_to_clock_t(gact->tcf_tm.expires);
170
        RTA_PUT(skb, TCA_GACT_TM, sizeof(t), &t);
171
        return skb->len;
172
 
173
rtattr_failure:
174
        nlmsg_trim(skb, b);
175
        return -1;
176
}
177
 
178
static struct tc_action_ops act_gact_ops = {
179
        .kind           =       "gact",
180
        .hinfo          =       &gact_hash_info,
181
        .type           =       TCA_ACT_GACT,
182
        .capab          =       TCA_CAP_NONE,
183
        .owner          =       THIS_MODULE,
184
        .act            =       tcf_gact,
185
        .dump           =       tcf_gact_dump,
186
        .cleanup        =       tcf_gact_cleanup,
187
        .lookup         =       tcf_hash_search,
188
        .init           =       tcf_gact_init,
189
        .walk           =       tcf_generic_walker
190
};
191
 
192
MODULE_AUTHOR("Jamal Hadi Salim(2002-4)");
193
MODULE_DESCRIPTION("Generic Classifier actions");
194
MODULE_LICENSE("GPL");
195
 
196
static int __init gact_init_module(void)
197
{
198
#ifdef CONFIG_GACT_PROB
199
        printk("GACT probability on\n");
200
#else
201
        printk("GACT probability NOT on\n");
202
#endif
203
        return tcf_register_action(&act_gact_ops);
204
}
205
 
206
static void __exit gact_cleanup_module(void)
207
{
208
        tcf_unregister_action(&act_gact_ops);
209
}
210
 
211
module_init(gact_init_module);
212
module_exit(gact_cleanup_module);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.