26 #include <linux/module.h>
27 #include <linux/kernel.h>
29 #include <linux/netdevice.h>
32 #include <linux/atalk.h>
33 #include <linux/if_arp.h>
34 #include <linux/slab.h>
36 #include <asm/uaccess.h>
42 static struct ipddp_route *ipddp_route_list;
45 #ifdef CONFIG_IPDDP_ENCAP
46 static int ipddp_mode = IPDDP_ENCAP;
48 static int ipddp_mode = IPDDP_DECAP;
54 static int ipddp_create(
struct ipddp_route *new_rt);
55 static int ipddp_delete(
struct ipddp_route *rt);
56 static struct ipddp_route* __ipddp_find_route(
struct ipddp_route *rt);
60 .ndo_start_xmit = ipddp_xmit,
61 .ndo_do_ioctl = ipddp_ioctl,
69 static unsigned version_printed;
73 dev = alloc_etherdev(0);
80 if (version_printed++ == 0)
104 if(ipddp_mode == IPDDP_ENCAP)
107 if(ipddp_mode == IPDDP_DECAP)
122 struct ipddp_route *rt;
125 spin_lock(&ipddp_route_lock);
130 for(rt = ipddp_route_list; rt !=
NULL; rt = rt->next)
136 spin_unlock(&ipddp_route_lock);
142 if(ipddp_mode == IPDDP_DECAP)
174 *((
__u8 *)(ddp+1)) = 22;
178 dev->
stats.tx_packets++;
183 spin_unlock(&ipddp_route_lock);
192 static int ipddp_create(
struct ipddp_route *new_rt)
207 spin_lock_bh(&ipddp_route_lock);
208 if (__ipddp_find_route(rt)) {
209 spin_unlock_bh(&ipddp_route_lock);
214 rt->next = ipddp_route_list;
215 ipddp_route_list = rt;
217 spin_unlock_bh(&ipddp_route_lock);
226 static int ipddp_delete(
struct ipddp_route *rt)
228 struct ipddp_route **
r = &ipddp_route_list;
229 struct ipddp_route *
tmp;
231 spin_lock_bh(&ipddp_route_lock);
232 while((tmp = *r) !=
NULL)
234 if(tmp->ip == rt->ip &&
235 tmp->at.s_net == rt->at.s_net &&
236 tmp->at.s_node == rt->at.s_node)
239 spin_unlock_bh(&ipddp_route_lock);
246 spin_unlock_bh(&ipddp_route_lock);
253 static struct ipddp_route* __ipddp_find_route(
struct ipddp_route *rt)
255 struct ipddp_route *
f;
257 for(f = ipddp_route_list; f !=
NULL; f = f->next)
259 if(f->ip == rt->ip &&
260 f->at.s_net == rt->at.s_net &&
261 f->at.s_node == rt->at.s_node)
270 struct ipddp_route
__user *rt = ifr->ifr_data;
271 struct ipddp_route rcp, rcp2, *
rp;
282 return ipddp_create(&rcp);
284 case SIOCFINDIPDDPRT:
285 spin_lock_bh(&ipddp_route_lock);
286 rp = __ipddp_find_route(&rcp);
288 memcpy(&rcp2, rp,
sizeof(rcp2));
289 spin_unlock_bh(&ipddp_route_lock);
293 sizeof(
struct ipddp_route)))
300 return ipddp_delete(&rcp);
312 static int __init ipddp_init_module(
void)
314 dev_ipddp = ipddp_init();
315 if (IS_ERR(dev_ipddp))
316 return PTR_ERR(dev_ipddp);
320 static void __exit ipddp_cleanup_module(
void)
322 struct ipddp_route *
p;
327 while (ipddp_route_list) {
328 p = ipddp_route_list->next;
329 kfree(ipddp_route_list);
330 ipddp_route_list =
p;