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/] [tags/] [linux-2.6/] [linux-2.6.24_or32_unified_v2.3/] [net/] [ipv4/] [tunnel4.c] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/* tunnel4.c: Generic IP tunnel transformer.
2
 *
3
 * Copyright (C) 2003 David S. Miller (davem@redhat.com)
4
 */
5
 
6
#include <linux/init.h>
7
#include <linux/module.h>
8
#include <linux/mutex.h>
9
#include <linux/netdevice.h>
10
#include <linux/skbuff.h>
11
#include <net/icmp.h>
12
#include <net/ip.h>
13
#include <net/protocol.h>
14
#include <net/xfrm.h>
15
 
16
static struct xfrm_tunnel *tunnel4_handlers;
17
static struct xfrm_tunnel *tunnel64_handlers;
18
static DEFINE_MUTEX(tunnel4_mutex);
19
 
20
static inline struct xfrm_tunnel **fam_handlers(unsigned short family)
21
{
22
        return (family == AF_INET) ? &tunnel4_handlers : &tunnel64_handlers;
23
}
24
 
25
int xfrm4_tunnel_register(struct xfrm_tunnel *handler, unsigned short family)
26
{
27
        struct xfrm_tunnel **pprev;
28
        int ret = -EEXIST;
29
        int priority = handler->priority;
30
 
31
        mutex_lock(&tunnel4_mutex);
32
 
33
        for (pprev = fam_handlers(family); *pprev; pprev = &(*pprev)->next) {
34
                if ((*pprev)->priority > priority)
35
                        break;
36
                if ((*pprev)->priority == priority)
37
                        goto err;
38
        }
39
 
40
        handler->next = *pprev;
41
        *pprev = handler;
42
 
43
        ret = 0;
44
 
45
err:
46
        mutex_unlock(&tunnel4_mutex);
47
 
48
        return ret;
49
}
50
 
51
EXPORT_SYMBOL(xfrm4_tunnel_register);
52
 
53
int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler, unsigned short family)
54
{
55
        struct xfrm_tunnel **pprev;
56
        int ret = -ENOENT;
57
 
58
        mutex_lock(&tunnel4_mutex);
59
 
60
        for (pprev = fam_handlers(family); *pprev; pprev = &(*pprev)->next) {
61
                if (*pprev == handler) {
62
                        *pprev = handler->next;
63
                        ret = 0;
64
                        break;
65
                }
66
        }
67
 
68
        mutex_unlock(&tunnel4_mutex);
69
 
70
        synchronize_net();
71
 
72
        return ret;
73
}
74
 
75
EXPORT_SYMBOL(xfrm4_tunnel_deregister);
76
 
77
static int tunnel4_rcv(struct sk_buff *skb)
78
{
79
        struct xfrm_tunnel *handler;
80
 
81
        if (!pskb_may_pull(skb, sizeof(struct iphdr)))
82
                goto drop;
83
 
84
        for (handler = tunnel4_handlers; handler; handler = handler->next)
85
                if (!handler->handler(skb))
86
                        return 0;
87
 
88
        icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
89
 
90
drop:
91
        kfree_skb(skb);
92
        return 0;
93
}
94
 
95
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
96
static int tunnel64_rcv(struct sk_buff *skb)
97
{
98
        struct xfrm_tunnel *handler;
99
 
100
        if (!pskb_may_pull(skb, sizeof(struct iphdr)))
101
                goto drop;
102
 
103
        for (handler = tunnel64_handlers; handler; handler = handler->next)
104
                if (!handler->handler(skb))
105
                        return 0;
106
 
107
        icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
108
 
109
drop:
110
        kfree_skb(skb);
111
        return 0;
112
}
113
#endif
114
 
115
static void tunnel4_err(struct sk_buff *skb, u32 info)
116
{
117
        struct xfrm_tunnel *handler;
118
 
119
        for (handler = tunnel4_handlers; handler; handler = handler->next)
120
                if (!handler->err_handler(skb, info))
121
                        break;
122
}
123
 
124
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
125
static void tunnel64_err(struct sk_buff *skb, u32 info)
126
{
127
        struct xfrm_tunnel *handler;
128
 
129
        for (handler = tunnel64_handlers; handler; handler = handler->next)
130
                if (!handler->err_handler(skb, info))
131
                        break;
132
}
133
#endif
134
 
135
static struct net_protocol tunnel4_protocol = {
136
        .handler        =       tunnel4_rcv,
137
        .err_handler    =       tunnel4_err,
138
        .no_policy      =       1,
139
};
140
 
141
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
142
static struct net_protocol tunnel64_protocol = {
143
        .handler        =       tunnel64_rcv,
144
        .err_handler    =       tunnel64_err,
145
        .no_policy      =       1,
146
};
147
#endif
148
 
149
static int __init tunnel4_init(void)
150
{
151
        if (inet_add_protocol(&tunnel4_protocol, IPPROTO_IPIP)) {
152
                printk(KERN_ERR "tunnel4 init: can't add protocol\n");
153
                return -EAGAIN;
154
        }
155
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
156
        if (inet_add_protocol(&tunnel64_protocol, IPPROTO_IPV6)) {
157
                printk(KERN_ERR "tunnel64 init: can't add protocol\n");
158
                inet_del_protocol(&tunnel4_protocol, IPPROTO_IPIP);
159
                return -EAGAIN;
160
        }
161
#endif
162
        return 0;
163
}
164
 
165
static void __exit tunnel4_fini(void)
166
{
167
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
168
        if (inet_del_protocol(&tunnel64_protocol, IPPROTO_IPV6))
169
                printk(KERN_ERR "tunnel64 close: can't remove protocol\n");
170
#endif
171
        if (inet_del_protocol(&tunnel4_protocol, IPPROTO_IPIP))
172
                printk(KERN_ERR "tunnel4 close: can't remove protocol\n");
173
}
174
 
175
module_init(tunnel4_init);
176
module_exit(tunnel4_fini);
177
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

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