diff options
Diffstat (limited to 'net/ipv4/icmp.c')
-rw-r--r-- | net/ipv4/icmp.c | 59 |
1 files changed, 31 insertions, 28 deletions
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 8d091954625b..8eca3c28cbc3 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -353,14 +353,14 @@ static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) | |||
353 | daddr = icmp_param->replyopts.faddr; | 353 | daddr = icmp_param->replyopts.faddr; |
354 | } | 354 | } |
355 | { | 355 | { |
356 | struct flowi fl = { | 356 | struct flowi4 fl4 = { |
357 | .fl4_dst = daddr, | 357 | .daddr = daddr, |
358 | .fl4_src = rt->rt_spec_dst, | 358 | .saddr = rt->rt_spec_dst, |
359 | .fl4_tos = RT_TOS(ip_hdr(skb)->tos), | 359 | .flowi4_tos = RT_TOS(ip_hdr(skb)->tos), |
360 | .flowi_proto = IPPROTO_ICMP, | 360 | .flowi4_proto = IPPROTO_ICMP, |
361 | }; | 361 | }; |
362 | security_skb_classify_flow(skb, &fl); | 362 | security_skb_classify_flow(skb, flowi4_to_flowi(&fl4)); |
363 | rt = ip_route_output_key(net, &fl); | 363 | rt = ip_route_output_key(net, &fl4); |
364 | if (IS_ERR(rt)) | 364 | if (IS_ERR(rt)) |
365 | goto out_unlock; | 365 | goto out_unlock; |
366 | } | 366 | } |
@@ -378,30 +378,31 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in, | |||
378 | int type, int code, | 378 | int type, int code, |
379 | struct icmp_bxm *param) | 379 | struct icmp_bxm *param) |
380 | { | 380 | { |
381 | struct flowi fl = { | 381 | struct flowi4 fl4 = { |
382 | .fl4_dst = (param->replyopts.srr ? | 382 | .daddr = (param->replyopts.srr ? |
383 | param->replyopts.faddr : iph->saddr), | 383 | param->replyopts.faddr : iph->saddr), |
384 | .fl4_src = saddr, | 384 | .saddr = saddr, |
385 | .fl4_tos = RT_TOS(tos), | 385 | .flowi4_tos = RT_TOS(tos), |
386 | .flowi_proto = IPPROTO_ICMP, | 386 | .flowi4_proto = IPPROTO_ICMP, |
387 | .fl4_icmp_type = type, | 387 | .uli.icmpt.type = type, |
388 | .fl4_icmp_code = code, | 388 | .uli.icmpt.code = code, |
389 | }; | 389 | }; |
390 | struct rtable *rt, *rt2; | 390 | struct rtable *rt, *rt2; |
391 | int err; | 391 | int err; |
392 | 392 | ||
393 | security_skb_classify_flow(skb_in, &fl); | 393 | security_skb_classify_flow(skb_in, flowi4_to_flowi(&fl4)); |
394 | rt = __ip_route_output_key(net, &fl); | 394 | rt = __ip_route_output_key(net, &fl4); |
395 | if (IS_ERR(rt)) | 395 | if (IS_ERR(rt)) |
396 | return rt; | 396 | return rt; |
397 | 397 | ||
398 | /* No need to clone since we're just using its address. */ | 398 | /* No need to clone since we're just using its address. */ |
399 | rt2 = rt; | 399 | rt2 = rt; |
400 | 400 | ||
401 | if (!fl.fl4_src) | 401 | if (!fl4.saddr) |
402 | fl.fl4_src = rt->rt_src; | 402 | fl4.saddr = rt->rt_src; |
403 | 403 | ||
404 | rt = (struct rtable *) xfrm_lookup(net, &rt->dst, &fl, NULL, 0); | 404 | rt = (struct rtable *) xfrm_lookup(net, &rt->dst, |
405 | flowi4_to_flowi(&fl4), NULL, 0); | ||
405 | if (!IS_ERR(rt)) { | 406 | if (!IS_ERR(rt)) { |
406 | if (rt != rt2) | 407 | if (rt != rt2) |
407 | return rt; | 408 | return rt; |
@@ -410,27 +411,27 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in, | |||
410 | } else | 411 | } else |
411 | return rt; | 412 | return rt; |
412 | 413 | ||
413 | err = xfrm_decode_session_reverse(skb_in, &fl, AF_INET); | 414 | err = xfrm_decode_session_reverse(skb_in, flowi4_to_flowi(&fl4), AF_INET); |
414 | if (err) | 415 | if (err) |
415 | goto relookup_failed; | 416 | goto relookup_failed; |
416 | 417 | ||
417 | if (inet_addr_type(net, fl.fl4_src) == RTN_LOCAL) { | 418 | if (inet_addr_type(net, fl4.saddr) == RTN_LOCAL) { |
418 | rt2 = __ip_route_output_key(net, &fl); | 419 | rt2 = __ip_route_output_key(net, &fl4); |
419 | if (IS_ERR(rt2)) | 420 | if (IS_ERR(rt2)) |
420 | err = PTR_ERR(rt2); | 421 | err = PTR_ERR(rt2); |
421 | } else { | 422 | } else { |
422 | struct flowi fl2 = {}; | 423 | struct flowi4 fl4_2 = {}; |
423 | unsigned long orefdst; | 424 | unsigned long orefdst; |
424 | 425 | ||
425 | fl2.fl4_dst = fl.fl4_src; | 426 | fl4_2.daddr = fl4.saddr; |
426 | rt2 = ip_route_output_key(net, &fl2); | 427 | rt2 = ip_route_output_key(net, &fl4_2); |
427 | if (IS_ERR(rt2)) { | 428 | if (IS_ERR(rt2)) { |
428 | err = PTR_ERR(rt2); | 429 | err = PTR_ERR(rt2); |
429 | goto relookup_failed; | 430 | goto relookup_failed; |
430 | } | 431 | } |
431 | /* Ugh! */ | 432 | /* Ugh! */ |
432 | orefdst = skb_in->_skb_refdst; /* save old refdst */ | 433 | orefdst = skb_in->_skb_refdst; /* save old refdst */ |
433 | err = ip_route_input(skb_in, fl.fl4_dst, fl.fl4_src, | 434 | err = ip_route_input(skb_in, fl4.daddr, fl4.saddr, |
434 | RT_TOS(tos), rt2->dst.dev); | 435 | RT_TOS(tos), rt2->dst.dev); |
435 | 436 | ||
436 | dst_release(&rt2->dst); | 437 | dst_release(&rt2->dst); |
@@ -441,7 +442,9 @@ static struct rtable *icmp_route_lookup(struct net *net, struct sk_buff *skb_in, | |||
441 | if (err) | 442 | if (err) |
442 | goto relookup_failed; | 443 | goto relookup_failed; |
443 | 444 | ||
444 | rt2 = (struct rtable *) xfrm_lookup(net, &rt2->dst, &fl, NULL, XFRM_LOOKUP_ICMP); | 445 | rt2 = (struct rtable *) xfrm_lookup(net, &rt2->dst, |
446 | flowi4_to_flowi(&fl4), NULL, | ||
447 | XFRM_LOOKUP_ICMP); | ||
445 | if (!IS_ERR(rt2)) { | 448 | if (!IS_ERR(rt2)) { |
446 | dst_release(&rt->dst); | 449 | dst_release(&rt->dst); |
447 | rt = rt2; | 450 | rt = rt2; |