compat: backport net_ns_type_operations
[~emulex/for-vlad/old/compat.git] / compat / compat-2.6.32.c
1 /*
2  * Copyright 2007       Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * Compatibility file for Linux wireless for kernels 2.6.32.
9  */
10
11 #include <linux/compat.h>
12
13 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32))
14
15 #include <linux/netdevice.h>
16
17 int __dev_addr_add(struct dev_addr_list **list, int *count,
18                    void *addr, int alen, int glbl)
19 {
20         struct dev_addr_list *da;
21
22         for (da = *list; da != NULL; da = da->next) {
23                 if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
24                     da->da_addrlen == alen) {
25                         if (glbl) {
26                                 int old_glbl = da->da_gusers;
27                                 da->da_gusers = 1;
28                                 if (old_glbl)
29                                         return 0;
30                         }
31                         da->da_users++;
32                         return 0;
33                 }
34         }
35
36         da = kzalloc(sizeof(*da), GFP_ATOMIC);
37         if (da == NULL)
38                 return -ENOMEM;
39         memcpy(da->da_addr, addr, alen);
40         da->da_addrlen = alen;
41         da->da_users = 1;
42         da->da_gusers = glbl ? 1 : 0;
43         da->next = *list;
44         *list = da;
45         (*count)++;
46         return 0;
47 }
48
49 int __dev_addr_delete(struct dev_addr_list **list, int *count,
50                       void *addr, int alen, int glbl)
51 {
52         struct dev_addr_list *da;
53
54         for (; (da = *list) != NULL; list = &da->next) {
55                 if (memcmp(da->da_addr, addr, da->da_addrlen) == 0 &&
56                     alen == da->da_addrlen) {
57                         if (glbl) {
58                                 int old_glbl = da->da_gusers;
59                                 da->da_gusers = 0;
60                                 if (old_glbl == 0)
61                                         break;
62                         }
63                         if (--da->da_users)
64                                 return 0;
65
66                         *list = da->next;
67                         kfree(da);
68                         (*count)--;
69                         return 0;
70                 }
71         }
72         return -ENOENT;
73 }
74
75 int __dev_addr_sync(struct dev_addr_list **to, int *to_count,
76                     struct dev_addr_list **from, int *from_count)
77 {
78         struct dev_addr_list *da, *next;
79         int err = 0;
80
81         da = *from;
82         while (da != NULL) {
83                 next = da->next;
84                 if (!da->da_synced) {
85                         err = __dev_addr_add(to, to_count,
86                                              da->da_addr, da->da_addrlen, 0);
87                         if (err < 0)
88                                 break;
89                         da->da_synced = 1;
90                         da->da_users++;
91                 } else if (da->da_users == 1) {
92                         __dev_addr_delete(to, to_count,
93                                           da->da_addr, da->da_addrlen, 0);
94                         __dev_addr_delete(from, from_count,
95                                           da->da_addr, da->da_addrlen, 0);
96                 }
97                 da = next;
98         }
99         return err;
100 }
101 EXPORT_SYMBOL_GPL(__dev_addr_sync);
102
103 void __dev_addr_unsync(struct dev_addr_list **to, int *to_count,
104                        struct dev_addr_list **from, int *from_count)
105 {
106         struct dev_addr_list *da, *next;
107
108         da = *from;
109         while (da != NULL) {
110                 next = da->next;
111                 if (da->da_synced) {
112                         __dev_addr_delete(to, to_count,
113                                           da->da_addr, da->da_addrlen, 0);
114                         da->da_synced = 0;
115                         __dev_addr_delete(from, from_count,
116                                           da->da_addr, da->da_addrlen, 0);
117                 }
118                 da = next;
119         }
120 }
121 EXPORT_SYMBOL_GPL(__dev_addr_unsync);
122
123 #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)) */
124