aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_policy.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_policy.c')
-rw-r--r--net/xfrm/xfrm_policy.c179
1 files changed, 4 insertions, 175 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index af27c193697c..b702bd8a3893 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -49,8 +49,6 @@ static DEFINE_SPINLOCK(xfrm_policy_gc_lock);
49 49
50static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family); 50static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family);
51static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo); 51static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo);
52static struct xfrm_policy_afinfo *xfrm_policy_lock_afinfo(unsigned int family);
53static void xfrm_policy_unlock_afinfo(struct xfrm_policy_afinfo *afinfo);
54 52
55static inline int 53static inline int
56__xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl) 54__xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl)
@@ -86,72 +84,6 @@ int xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
86 return 0; 84 return 0;
87} 85}
88 86
89int xfrm_register_type(struct xfrm_type *type, unsigned short family)
90{
91 struct xfrm_policy_afinfo *afinfo = xfrm_policy_lock_afinfo(family);
92 struct xfrm_type **typemap;
93 int err = 0;
94
95 if (unlikely(afinfo == NULL))
96 return -EAFNOSUPPORT;
97 typemap = afinfo->type_map;
98
99 if (likely(typemap[type->proto] == NULL))
100 typemap[type->proto] = type;
101 else
102 err = -EEXIST;
103 xfrm_policy_unlock_afinfo(afinfo);
104 return err;
105}
106EXPORT_SYMBOL(xfrm_register_type);
107
108int xfrm_unregister_type(struct xfrm_type *type, unsigned short family)
109{
110 struct xfrm_policy_afinfo *afinfo = xfrm_policy_lock_afinfo(family);
111 struct xfrm_type **typemap;
112 int err = 0;
113
114 if (unlikely(afinfo == NULL))
115 return -EAFNOSUPPORT;
116 typemap = afinfo->type_map;
117
118 if (unlikely(typemap[type->proto] != type))
119 err = -ENOENT;
120 else
121 typemap[type->proto] = NULL;
122 xfrm_policy_unlock_afinfo(afinfo);
123 return err;
124}
125EXPORT_SYMBOL(xfrm_unregister_type);
126
127struct xfrm_type *xfrm_get_type(u8 proto, unsigned short family)
128{
129 struct xfrm_policy_afinfo *afinfo;
130 struct xfrm_type **typemap;
131 struct xfrm_type *type;
132 int modload_attempted = 0;
133
134retry:
135 afinfo = xfrm_policy_get_afinfo(family);
136 if (unlikely(afinfo == NULL))
137 return NULL;
138 typemap = afinfo->type_map;
139
140 type = typemap[proto];
141 if (unlikely(type && !try_module_get(type->owner)))
142 type = NULL;
143 if (!type && !modload_attempted) {
144 xfrm_policy_put_afinfo(afinfo);
145 request_module("xfrm-type-%d-%d",
146 (int) family, (int) proto);
147 modload_attempted = 1;
148 goto retry;
149 }
150
151 xfrm_policy_put_afinfo(afinfo);
152 return type;
153}
154
155int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, 87int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl,
156 unsigned short family) 88 unsigned short family)
157{ 89{
@@ -170,94 +102,6 @@ int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl,
170} 102}
171EXPORT_SYMBOL(xfrm_dst_lookup); 103EXPORT_SYMBOL(xfrm_dst_lookup);
172 104
173void xfrm_put_type(struct xfrm_type *type)
174{
175 module_put(type->owner);
176}
177
178int xfrm_register_mode(struct xfrm_mode *mode, int family)
179{
180 struct xfrm_policy_afinfo *afinfo;
181 struct xfrm_mode **modemap;
182 int err;
183
184 if (unlikely(mode->encap >= XFRM_MODE_MAX))
185 return -EINVAL;
186
187 afinfo = xfrm_policy_lock_afinfo(family);
188 if (unlikely(afinfo == NULL))
189 return -EAFNOSUPPORT;
190
191 err = -EEXIST;
192 modemap = afinfo->mode_map;
193 if (likely(modemap[mode->encap] == NULL)) {
194 modemap[mode->encap] = mode;
195 err = 0;
196 }
197
198 xfrm_policy_unlock_afinfo(afinfo);
199 return err;
200}
201EXPORT_SYMBOL(xfrm_register_mode);
202
203int xfrm_unregister_mode(struct xfrm_mode *mode, int family)
204{
205 struct xfrm_policy_afinfo *afinfo;
206 struct xfrm_mode **modemap;
207 int err;
208
209 if (unlikely(mode->encap >= XFRM_MODE_MAX))
210 return -EINVAL;
211
212 afinfo = xfrm_policy_lock_afinfo(family);
213 if (unlikely(afinfo == NULL))
214 return -EAFNOSUPPORT;
215
216 err = -ENOENT;
217 modemap = afinfo->mode_map;
218 if (likely(modemap[mode->encap] == mode)) {
219 modemap[mode->encap] = NULL;
220 err = 0;
221 }
222
223 xfrm_policy_unlock_afinfo(afinfo);
224 return err;
225}
226EXPORT_SYMBOL(xfrm_unregister_mode);
227
228struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family)
229{
230 struct xfrm_policy_afinfo *afinfo;
231 struct xfrm_mode *mode;
232 int modload_attempted = 0;
233
234 if (unlikely(encap >= XFRM_MODE_MAX))
235 return NULL;
236
237retry:
238 afinfo = xfrm_policy_get_afinfo(family);
239 if (unlikely(afinfo == NULL))
240 return NULL;
241
242 mode = afinfo->mode_map[encap];
243 if (unlikely(mode && !try_module_get(mode->owner)))
244 mode = NULL;
245 if (!mode && !modload_attempted) {
246 xfrm_policy_put_afinfo(afinfo);
247 request_module("xfrm-mode-%d-%d", family, encap);
248 modload_attempted = 1;
249 goto retry;
250 }
251
252 xfrm_policy_put_afinfo(afinfo);
253 return mode;
254}
255
256void xfrm_put_mode(struct xfrm_mode *mode)
257{
258 module_put(mode->owner);
259}
260
261static inline unsigned long make_jiffies(long secs) 105static inline unsigned long make_jiffies(long secs)
262{ 106{
263 if (secs >= (MAX_SCHEDULE_TIMEOUT-1)/HZ) 107 if (secs >= (MAX_SCHEDULE_TIMEOUT-1)/HZ)
@@ -2096,7 +1940,8 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
2096 if (xdst->genid != dst->xfrm->genid) 1940 if (xdst->genid != dst->xfrm->genid)
2097 return 0; 1941 return 0;
2098 1942
2099 if (strict && fl && dst->xfrm->props.mode != XFRM_MODE_TUNNEL && 1943 if (strict && fl &&
1944 !(dst->xfrm->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL) &&
2100 !xfrm_state_addr_flow_check(dst->xfrm, fl, family)) 1945 !xfrm_state_addr_flow_check(dst->xfrm, fl, family))
2101 return 0; 1946 return 0;
2102 1947
@@ -2213,23 +2058,6 @@ static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo)
2213 read_unlock(&xfrm_policy_afinfo_lock); 2058 read_unlock(&xfrm_policy_afinfo_lock);
2214} 2059}
2215 2060
2216static struct xfrm_policy_afinfo *xfrm_policy_lock_afinfo(unsigned int family)
2217{
2218 struct xfrm_policy_afinfo *afinfo;
2219 if (unlikely(family >= NPROTO))
2220 return NULL;
2221 write_lock_bh(&xfrm_policy_afinfo_lock);
2222 afinfo = xfrm_policy_afinfo[family];
2223 if (unlikely(!afinfo))
2224 write_unlock_bh(&xfrm_policy_afinfo_lock);
2225 return afinfo;
2226}
2227
2228static void xfrm_policy_unlock_afinfo(struct xfrm_policy_afinfo *afinfo)
2229{
2230 write_unlock_bh(&xfrm_policy_afinfo_lock);
2231}
2232
2233static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr) 2061static int xfrm_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
2234{ 2062{
2235 struct net_device *dev = ptr; 2063 struct net_device *dev = ptr;
@@ -2464,7 +2292,8 @@ static int xfrm_policy_migrate(struct xfrm_policy *pol,
2464 if (!migrate_tmpl_match(mp, &pol->xfrm_vec[i])) 2292 if (!migrate_tmpl_match(mp, &pol->xfrm_vec[i]))
2465 continue; 2293 continue;
2466 n++; 2294 n++;
2467 if (pol->xfrm_vec[i].mode != XFRM_MODE_TUNNEL) 2295 if (pol->xfrm_vec[i].mode != XFRM_MODE_TUNNEL &&
2296 pol->xfrm_vec[i].mode != XFRM_MODE_BEET)
2468 continue; 2297 continue;
2469 /* update endpoints */ 2298 /* update endpoints */
2470 memcpy(&pol->xfrm_vec[i].id.daddr, &mp->new_daddr, 2299 memcpy(&pol->xfrm_vec[i].id.daddr, &mp->new_daddr,