~ubuntu-branches/ubuntu/trusty/libnl3/trusty

« back to all changes in this revision

Viewing changes to lib/route/qdisc/red.c

  • Committer: Bazaar Package Importer
  • Author(s): Heiko Stuebner
  • Date: 2011-05-21 19:25:13 UTC
  • Revision ID: james.westby@ubuntu.com-20110521192513-1ieyu9w9kym4bt16
Tags: upstream-3.0
ImportĀ upstreamĀ versionĀ 3.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * lib/route/qdisc/red.c                RED Qdisc
 
3
 *
 
4
 *      This library is free software; you can redistribute it and/or
 
5
 *      modify it under the terms of the GNU Lesser General Public
 
6
 *      License as published by the Free Software Foundation version 2.1
 
7
 *      of the License.
 
8
 *
 
9
 * Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
 
10
 */
 
11
 
 
12
/**
 
13
 * @ingroup qdisc
 
14
 * @defgroup qdisc_red Random Early Detection (RED)
 
15
 * @brief
 
16
 * @{
 
17
 */
 
18
 
 
19
#include <netlink-local.h>
 
20
#include <netlink-tc.h>
 
21
#include <netlink/netlink.h>
 
22
#include <netlink/utils.h>
 
23
#include <netlink/route/tc-api.h>
 
24
#include <netlink/route/qdisc.h>
 
25
#include <netlink/route/qdisc/red.h>
 
26
 
 
27
/** @cond SKIP */
 
28
#define RED_ATTR_LIMIT          0x01
 
29
#define RED_ATTR_QTH_MIN        0x02
 
30
#define RED_ATTR_QTH_MAX        0x04
 
31
#define RED_ATTR_FLAGS          0x08
 
32
#define RED_ATTR_WLOG           0x10
 
33
#define RED_ATTR_PLOG           0x20
 
34
#define RED_ATTR_SCELL_LOG      0x40
 
35
/** @endcond */
 
36
 
 
37
static struct nla_policy red_policy[TCA_RED_MAX+1] = {
 
38
        [TCA_RED_PARMS]         = { .minlen = sizeof(struct tc_red_qopt) },
 
39
};
 
40
 
 
41
static int red_msg_parser(struct rtnl_tc *tc, void *data)
 
42
{
 
43
        struct nlattr *tb[TCA_RED_MAX+1];
 
44
        struct rtnl_red *red = data;
 
45
        struct tc_red_qopt *opts;
 
46
        int err;
 
47
 
 
48
        if (!(tc->ce_mask & TCA_ATTR_OPTS))
 
49
                return 0;
 
50
 
 
51
        err = tca_parse(tb, TCA_RED_MAX, tc, red_policy);
 
52
        if (err < 0)
 
53
                return err;
 
54
 
 
55
        if (!tb[TCA_RED_PARMS])
 
56
                return -NLE_MISSING_ATTR;
 
57
 
 
58
        opts = nla_data(tb[TCA_RED_PARMS]);
 
59
 
 
60
        red->qr_limit = opts->limit;
 
61
        red->qr_qth_min = opts->qth_min;
 
62
        red->qr_qth_max = opts->qth_max;
 
63
        red->qr_flags = opts->flags;
 
64
        red->qr_wlog = opts->Wlog;
 
65
        red->qr_plog = opts->Plog;
 
66
        red->qr_scell_log = opts->Scell_log;
 
67
 
 
68
        red->qr_mask = (RED_ATTR_LIMIT | RED_ATTR_QTH_MIN | RED_ATTR_QTH_MAX |
 
69
                        RED_ATTR_FLAGS | RED_ATTR_WLOG | RED_ATTR_PLOG |
 
70
                        RED_ATTR_SCELL_LOG);
 
71
 
 
72
        return 0;
 
73
}
 
74
 
 
75
static void red_dump_line(struct rtnl_tc *tc, void *data,
 
76
                          struct nl_dump_params *p)
 
77
{
 
78
        struct rtnl_red *red = data;
 
79
 
 
80
        if (red) {
 
81
                /* XXX: limit, min, max, flags */
 
82
        }
 
83
}
 
84
 
 
85
static void red_dump_details(struct rtnl_tc *tc, void *data,
 
86
                             struct nl_dump_params *p)
 
87
{
 
88
        struct rtnl_red *red = data;
 
89
 
 
90
        if (red) {
 
91
                /* XXX: wlog, plog, scell_log */
 
92
        }
 
93
}
 
94
 
 
95
static void red_dump_stats(struct rtnl_tc *tc, void *data,
 
96
                           struct nl_dump_params *p)
 
97
{
 
98
        struct rtnl_red *red = data;
 
99
 
 
100
        if (red) {
 
101
                /* XXX: xstats */
 
102
        }
 
103
}
 
104
 
 
105
static int red_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
 
106
{
 
107
        struct rtnl_red *red = data;
 
108
 
 
109
        if (!red)
 
110
                BUG();
 
111
 
 
112
#if 0
 
113
        memset(&opts, 0, sizeof(opts));
 
114
        opts.quantum = sfq->qs_quantum;
 
115
        opts.perturb_period = sfq->qs_perturb;
 
116
        opts.limit = sfq->qs_limit;
 
117
 
 
118
        if (nlmsg_append(msg, &opts, sizeof(opts), NL_DONTPAD) < 0)
 
119
                goto errout;
 
120
#endif
 
121
 
 
122
        return -NLE_OPNOTSUPP;
 
123
}
 
124
 
 
125
/**
 
126
 * @name Attribute Access
 
127
 * @{
 
128
 */
 
129
 
 
130
/**
 
131
 * Set limit of RED qdisc.
 
132
 * @arg qdisc           RED qdisc to be modified.
 
133
 * @arg limit           New limit in number of packets.
 
134
 * @return 0 on success or a negative error code.
 
135
 */
 
136
void rtnl_red_set_limit(struct rtnl_qdisc *qdisc, int limit)
 
137
{
 
138
        struct rtnl_red *red;
 
139
 
 
140
        if (!(red = rtnl_tc_data(TC_CAST(qdisc))))
 
141
                BUG();
 
142
 
 
143
        red->qr_limit = limit;
 
144
        red->qr_mask |= RED_ATTR_LIMIT;
 
145
}
 
146
 
 
147
/**
 
148
 * Get limit of RED qdisc.
 
149
 * @arg qdisc           RED qdisc.
 
150
 * @return Limit or a negative error code.
 
151
 */
 
152
int rtnl_red_get_limit(struct rtnl_qdisc *qdisc)
 
153
{
 
154
        struct rtnl_red *red;
 
155
 
 
156
        if (!(red = rtnl_tc_data(TC_CAST(qdisc))))
 
157
                BUG();
 
158
 
 
159
        if (red->qr_mask & RED_ATTR_LIMIT)
 
160
                return red->qr_limit;
 
161
        else
 
162
                return -NLE_NOATTR;
 
163
}
 
164
 
 
165
/** @} */
 
166
 
 
167
static struct rtnl_tc_ops red_ops = {
 
168
        .to_kind                = "red",
 
169
        .to_type                = RTNL_TC_TYPE_QDISC,
 
170
        .to_size                = sizeof(struct rtnl_red),
 
171
        .to_msg_parser          = red_msg_parser,
 
172
        .to_dump = {
 
173
            [NL_DUMP_LINE]      = red_dump_line,
 
174
            [NL_DUMP_DETAILS]   = red_dump_details,
 
175
            [NL_DUMP_STATS]     = red_dump_stats,
 
176
        },
 
177
        .to_msg_fill            = red_msg_fill,
 
178
};
 
179
 
 
180
static void __init red_init(void)
 
181
{
 
182
        rtnl_tc_register(&red_ops);
 
183
}
 
184
 
 
185
static void __exit red_exit(void)
 
186
{
 
187
        rtnl_tc_unregister(&red_ops);
 
188
}
 
189
 
 
190
/** @} */