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/] [decnet/] [dn_rules.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
 
2
/*
3
 * DECnet       An implementation of the DECnet protocol suite for the LINUX
4
 *              operating system.  DECnet is implemented using the  BSD Socket
5
 *              interface as the means of communication with the user level.
6
 *
7
 *              DECnet Routing Forwarding Information Base (Rules)
8
 *
9
 * Author:      Steve Whitehouse <SteveW@ACM.org>
10
 *              Mostly copied from Alexey Kuznetsov's ipv4/fib_rules.c
11
 *
12
 *
13
 * Changes:
14
 *              Steve Whitehouse <steve@chygwyn.com>
15
 *              Updated for Thomas Graf's generic rules
16
 *
17
 */
18
#include <linux/net.h>
19
#include <linux/init.h>
20
#include <linux/netlink.h>
21
#include <linux/rtnetlink.h>
22
#include <linux/netdevice.h>
23
#include <linux/spinlock.h>
24
#include <linux/list.h>
25
#include <linux/rcupdate.h>
26
#include <net/neighbour.h>
27
#include <net/dst.h>
28
#include <net/flow.h>
29
#include <net/fib_rules.h>
30
#include <net/dn.h>
31
#include <net/dn_fib.h>
32
#include <net/dn_neigh.h>
33
#include <net/dn_dev.h>
34
#include <net/dn_route.h>
35
 
36
static struct fib_rules_ops dn_fib_rules_ops;
37
 
38
struct dn_fib_rule
39
{
40
        struct fib_rule         common;
41
        unsigned char           dst_len;
42
        unsigned char           src_len;
43
        __le16                  src;
44
        __le16                  srcmask;
45
        __le16                  dst;
46
        __le16                  dstmask;
47
        __le16                  srcmap;
48
        u8                      flags;
49
};
50
 
51
 
52
int dn_fib_lookup(struct flowi *flp, struct dn_fib_res *res)
53
{
54
        struct fib_lookup_arg arg = {
55
                .result = res,
56
        };
57
        int err;
58
 
59
        err = fib_rules_lookup(&dn_fib_rules_ops, flp, 0, &arg);
60
        res->r = arg.rule;
61
 
62
        return err;
63
}
64
 
65
static int dn_fib_rule_action(struct fib_rule *rule, struct flowi *flp,
66
                              int flags, struct fib_lookup_arg *arg)
67
{
68
        int err = -EAGAIN;
69
        struct dn_fib_table *tbl;
70
 
71
        switch(rule->action) {
72
        case FR_ACT_TO_TBL:
73
                break;
74
 
75
        case FR_ACT_UNREACHABLE:
76
                err = -ENETUNREACH;
77
                goto errout;
78
 
79
        case FR_ACT_PROHIBIT:
80
                err = -EACCES;
81
                goto errout;
82
 
83
        case FR_ACT_BLACKHOLE:
84
        default:
85
                err = -EINVAL;
86
                goto errout;
87
        }
88
 
89
        tbl = dn_fib_get_table(rule->table, 0);
90
        if (tbl == NULL)
91
                goto errout;
92
 
93
        err = tbl->lookup(tbl, flp, (struct dn_fib_res *)arg->result);
94
        if (err > 0)
95
                err = -EAGAIN;
96
errout:
97
        return err;
98
}
99
 
100
static const struct nla_policy dn_fib_rule_policy[FRA_MAX+1] = {
101
        FRA_GENERIC_POLICY,
102
};
103
 
104
static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
105
{
106
        struct dn_fib_rule *r = (struct dn_fib_rule *)rule;
107
        __le16 daddr = fl->fld_dst;
108
        __le16 saddr = fl->fld_src;
109
 
110
        if (((saddr ^ r->src) & r->srcmask) ||
111
            ((daddr ^ r->dst) & r->dstmask))
112
                return 0;
113
 
114
        return 1;
115
}
116
 
117
static int dn_fib_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
118
                                 struct nlmsghdr *nlh, struct fib_rule_hdr *frh,
119
                                 struct nlattr **tb)
120
{
121
        int err = -EINVAL;
122
        struct dn_fib_rule *r = (struct dn_fib_rule *)rule;
123
 
124
        if (frh->tos)
125
                goto  errout;
126
 
127
        if (rule->table == RT_TABLE_UNSPEC) {
128
                if (rule->action == FR_ACT_TO_TBL) {
129
                        struct dn_fib_table *table;
130
 
131
                        table = dn_fib_empty_table();
132
                        if (table == NULL) {
133
                                err = -ENOBUFS;
134
                                goto errout;
135
                        }
136
 
137
                        rule->table = table->n;
138
                }
139
        }
140
 
141
        if (frh->src_len)
142
                r->src = nla_get_le16(tb[FRA_SRC]);
143
 
144
        if (frh->dst_len)
145
                r->dst = nla_get_le16(tb[FRA_DST]);
146
 
147
        r->src_len = frh->src_len;
148
        r->srcmask = dnet_make_mask(r->src_len);
149
        r->dst_len = frh->dst_len;
150
        r->dstmask = dnet_make_mask(r->dst_len);
151
        err = 0;
152
errout:
153
        return err;
154
}
155
 
156
static int dn_fib_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
157
                               struct nlattr **tb)
158
{
159
        struct dn_fib_rule *r = (struct dn_fib_rule *)rule;
160
 
161
        if (frh->src_len && (r->src_len != frh->src_len))
162
                return 0;
163
 
164
        if (frh->dst_len && (r->dst_len != frh->dst_len))
165
                return 0;
166
 
167
        if (frh->src_len && (r->src != nla_get_le16(tb[FRA_SRC])))
168
                return 0;
169
 
170
        if (frh->dst_len && (r->dst != nla_get_le16(tb[FRA_DST])))
171
                return 0;
172
 
173
        return 1;
174
}
175
 
176
unsigned dnet_addr_type(__le16 addr)
177
{
178
        struct flowi fl = { .nl_u = { .dn_u = { .daddr = addr } } };
179
        struct dn_fib_res res;
180
        unsigned ret = RTN_UNICAST;
181
        struct dn_fib_table *tb = dn_fib_get_table(RT_TABLE_LOCAL, 0);
182
 
183
        res.r = NULL;
184
 
185
        if (tb) {
186
                if (!tb->lookup(tb, &fl, &res)) {
187
                        ret = res.type;
188
                        dn_fib_res_put(&res);
189
                }
190
        }
191
        return ret;
192
}
193
 
194
static int dn_fib_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
195
                            struct nlmsghdr *nlh, struct fib_rule_hdr *frh)
196
{
197
        struct dn_fib_rule *r = (struct dn_fib_rule *)rule;
198
 
199
        frh->family = AF_DECnet;
200
        frh->dst_len = r->dst_len;
201
        frh->src_len = r->src_len;
202
        frh->tos = 0;
203
 
204
        if (r->dst_len)
205
                NLA_PUT_LE16(skb, FRA_DST, r->dst);
206
        if (r->src_len)
207
                NLA_PUT_LE16(skb, FRA_SRC, r->src);
208
 
209
        return 0;
210
 
211
nla_put_failure:
212
        return -ENOBUFS;
213
}
214
 
215
static u32 dn_fib_rule_default_pref(void)
216
{
217
        struct list_head *pos;
218
        struct fib_rule *rule;
219
 
220
        if (!list_empty(&dn_fib_rules_ops.rules_list)) {
221
                pos = dn_fib_rules_ops.rules_list.next;
222
                if (pos->next != &dn_fib_rules_ops.rules_list) {
223
                        rule = list_entry(pos->next, struct fib_rule, list);
224
                        if (rule->pref)
225
                                return rule->pref - 1;
226
                }
227
        }
228
 
229
        return 0;
230
}
231
 
232
static void dn_fib_rule_flush_cache(void)
233
{
234
        dn_rt_cache_flush(-1);
235
}
236
 
237
static struct fib_rules_ops dn_fib_rules_ops = {
238
        .family         = AF_DECnet,
239
        .rule_size      = sizeof(struct dn_fib_rule),
240
        .addr_size      = sizeof(u16),
241
        .action         = dn_fib_rule_action,
242
        .match          = dn_fib_rule_match,
243
        .configure      = dn_fib_rule_configure,
244
        .compare        = dn_fib_rule_compare,
245
        .fill           = dn_fib_rule_fill,
246
        .default_pref   = dn_fib_rule_default_pref,
247
        .flush_cache    = dn_fib_rule_flush_cache,
248
        .nlgroup        = RTNLGRP_DECnet_RULE,
249
        .policy         = dn_fib_rule_policy,
250
        .rules_list     = LIST_HEAD_INIT(dn_fib_rules_ops.rules_list),
251
        .owner          = THIS_MODULE,
252
};
253
 
254
void __init dn_fib_rules_init(void)
255
{
256
        BUG_ON(fib_default_rule_add(&dn_fib_rules_ops, 0x7fff,
257
                                    RT_TABLE_MAIN, 0));
258
        fib_rules_register(&dn_fib_rules_ops);
259
}
260
 
261
void __exit dn_fib_rules_cleanup(void)
262
{
263
        fib_rules_unregister(&dn_fib_rules_ops);
264
}
265
 
266
 

powered by: WebSVN 2.1.0

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