diff options
author | Simon Horman <horms@verge.net.au> | 2010-08-22 08:37:51 -0400 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2010-10-04 09:45:23 -0400 |
commit | 5b57a98c1f0d78a4c238d83c4ac70de3bd237b2f (patch) | |
tree | 13c4076a4fa804a97e67fe51b084635fbfaa8638 /net | |
parent | 001985b2c0cfad48e1dec8e30f4d432eac240dd2 (diff) |
IPVS: compact ip_vs_sched_persist()
Compact ip_vs_sched_persist() by setting up parameters
and calling functions once.
Signed-off-by: Simon Horman <horms@verge.net.au>
Acked-by: Julian Anastasov <ja@ssi.bg>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/ipvs/ip_vs_core.c | 156 |
1 files changed, 51 insertions, 105 deletions
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 06c388bf4e3..70a5cacf86d 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
@@ -193,10 +193,14 @@ ip_vs_sched_persist(struct ip_vs_service *svc, | |||
193 | struct ip_vs_iphdr iph; | 193 | struct ip_vs_iphdr iph; |
194 | struct ip_vs_dest *dest; | 194 | struct ip_vs_dest *dest; |
195 | struct ip_vs_conn *ct; | 195 | struct ip_vs_conn *ct; |
196 | __be16 dport; /* destination port to forward */ | 196 | int protocol = iph.protocol; |
197 | __be16 dport = 0; /* destination port to forward */ | ||
198 | __be16 vport = 0; /* virtual service port */ | ||
197 | unsigned int flags; | 199 | unsigned int flags; |
198 | union nf_inet_addr snet; /* source network of the client, | 200 | union nf_inet_addr snet; /* source network of the client, |
199 | after masking */ | 201 | after masking */ |
202 | const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) }; | ||
203 | const union nf_inet_addr *vaddr = &iph.daddr; | ||
200 | 204 | ||
201 | ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph); | 205 | ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph); |
202 | 206 | ||
@@ -227,119 +231,61 @@ ip_vs_sched_persist(struct ip_vs_service *svc, | |||
227 | * service, and a template like <caddr, 0, vaddr, vport, daddr, dport> | 231 | * service, and a template like <caddr, 0, vaddr, vport, daddr, dport> |
228 | * is created for other persistent services. | 232 | * is created for other persistent services. |
229 | */ | 233 | */ |
230 | if (ports[1] == svc->port) { | 234 | { |
231 | /* Check if a template already exists */ | 235 | if (ports[1] == svc->port) { |
232 | if (svc->port != FTPPORT) | 236 | /* non-FTP template: |
233 | ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0, | 237 | * <protocol, caddr, 0, vaddr, vport, daddr, dport> |
234 | &iph.daddr, ports[1]); | 238 | * FTP template: |
235 | else | 239 | * <protocol, caddr, 0, vaddr, 0, daddr, 0> |
236 | ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0, | ||
237 | &iph.daddr, 0); | ||
238 | |||
239 | if (!ct || !ip_vs_check_template(ct)) { | ||
240 | /* | ||
241 | * No template found or the dest of the connection | ||
242 | * template is not available. | ||
243 | */ | ||
244 | dest = svc->scheduler->schedule(svc, skb); | ||
245 | if (dest == NULL) { | ||
246 | IP_VS_DBG(1, "p-schedule: no dest found.\n"); | ||
247 | return NULL; | ||
248 | } | ||
249 | |||
250 | /* | ||
251 | * Create a template like <protocol,caddr,0, | ||
252 | * vaddr,vport,daddr,dport> for non-ftp service, | ||
253 | * and <protocol,caddr,0,vaddr,0,daddr,0> | ||
254 | * for ftp service. | ||
255 | */ | 240 | */ |
256 | if (svc->port != FTPPORT) | 241 | if (svc->port != FTPPORT) |
257 | ct = ip_vs_conn_new(svc->af, iph.protocol, | 242 | vport = ports[1]; |
258 | &snet, 0, | ||
259 | &iph.daddr, | ||
260 | ports[1], | ||
261 | &dest->addr, dest->port, | ||
262 | IP_VS_CONN_F_TEMPLATE, | ||
263 | dest); | ||
264 | else | ||
265 | ct = ip_vs_conn_new(svc->af, iph.protocol, | ||
266 | &snet, 0, | ||
267 | &iph.daddr, 0, | ||
268 | &dest->addr, 0, | ||
269 | IP_VS_CONN_F_TEMPLATE, | ||
270 | dest); | ||
271 | if (ct == NULL) | ||
272 | return NULL; | ||
273 | |||
274 | ct->timeout = svc->timeout; | ||
275 | } else { | 243 | } else { |
276 | /* set destination with the found template */ | 244 | /* Note: persistent fwmark-based services and |
277 | dest = ct->dest; | 245 | * persistent port zero service are handled here. |
246 | * fwmark template: | ||
247 | * <IPPROTO_IP,caddr,0,fwmark,0,daddr,0> | ||
248 | * port zero template: | ||
249 | * <protocol,caddr,0,vaddr,0,daddr,0> | ||
250 | */ | ||
251 | if (svc->fwmark) { | ||
252 | protocol = IPPROTO_IP; | ||
253 | vaddr = &fwmark; | ||
254 | } | ||
278 | } | 255 | } |
279 | dport = dest->port; | 256 | } |
280 | } else { | 257 | |
281 | /* | 258 | /* Check if a template already exists */ |
282 | * Note: persistent fwmark-based services and persistent | 259 | ct = ip_vs_ct_in_get(svc->af, protocol, &snet, 0, vaddr, vport); |
283 | * port zero service are handled here. | 260 | |
284 | * fwmark template: <IPPROTO_IP,caddr,0,fwmark,0,daddr,0> | 261 | if (!ct || !ip_vs_check_template(ct)) { |
285 | * port zero template: <protocol,caddr,0,vaddr,0,daddr,0> | 262 | /* No template found or the dest of the connection |
263 | * template is not available. | ||
286 | */ | 264 | */ |
287 | if (svc->fwmark) { | 265 | dest = svc->scheduler->schedule(svc, skb); |
288 | union nf_inet_addr fwmark = { | 266 | if (!dest) { |
289 | .ip = htonl(svc->fwmark) | 267 | IP_VS_DBG(1, "p-schedule: no dest found.\n"); |
290 | }; | 268 | return NULL; |
269 | } | ||
291 | 270 | ||
292 | ct = ip_vs_ct_in_get(svc->af, IPPROTO_IP, &snet, 0, | 271 | if (ports[1] == svc->port && svc->port != FTPPORT) |
293 | &fwmark, 0); | 272 | dport = dest->port; |
294 | } else | ||
295 | ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0, | ||
296 | &iph.daddr, 0); | ||
297 | 273 | ||
298 | if (!ct || !ip_vs_check_template(ct)) { | 274 | /* Create a template */ |
299 | /* | 275 | ct = ip_vs_conn_new(svc->af, protocol, &snet, 0,vaddr, vport, |
300 | * If it is not persistent port zero, return NULL, | 276 | &dest->addr, dport, |
301 | * otherwise create a connection template. | 277 | IP_VS_CONN_F_TEMPLATE, dest); |
302 | */ | 278 | if (ct == NULL) |
303 | if (svc->port) | 279 | return NULL; |
304 | return NULL; | ||
305 | 280 | ||
306 | dest = svc->scheduler->schedule(svc, skb); | 281 | ct->timeout = svc->timeout; |
307 | if (dest == NULL) { | 282 | } else |
308 | IP_VS_DBG(1, "p-schedule: no dest found.\n"); | 283 | /* set destination with the found template */ |
309 | return NULL; | 284 | dest = ct->dest; |
310 | } | ||
311 | 285 | ||
312 | /* | 286 | dport = ports[1]; |
313 | * Create a template according to the service | 287 | if (dport == svc->port && dest->port) |
314 | */ | 288 | dport = dest->port; |
315 | if (svc->fwmark) { | ||
316 | union nf_inet_addr fwmark = { | ||
317 | .ip = htonl(svc->fwmark) | ||
318 | }; | ||
319 | |||
320 | ct = ip_vs_conn_new(svc->af, IPPROTO_IP, | ||
321 | &snet, 0, | ||
322 | &fwmark, 0, | ||
323 | &dest->addr, 0, | ||
324 | IP_VS_CONN_F_TEMPLATE, | ||
325 | dest); | ||
326 | } else | ||
327 | ct = ip_vs_conn_new(svc->af, iph.protocol, | ||
328 | &snet, 0, | ||
329 | &iph.daddr, 0, | ||
330 | &dest->addr, 0, | ||
331 | IP_VS_CONN_F_TEMPLATE, | ||
332 | dest); | ||
333 | if (ct == NULL) | ||
334 | return NULL; | ||
335 | |||
336 | ct->timeout = svc->timeout; | ||
337 | } else { | ||
338 | /* set destination with the found template */ | ||
339 | dest = ct->dest; | ||
340 | } | ||
341 | dport = ports[1]; | ||
342 | } | ||
343 | 289 | ||
344 | flags = (svc->flags & IP_VS_SVC_F_ONEPACKET | 290 | flags = (svc->flags & IP_VS_SVC_F_ONEPACKET |
345 | && iph.protocol == IPPROTO_UDP)? | 291 | && iph.protocol == IPPROTO_UDP)? |