aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/icmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/icmp.c')
-rw-r--r--net/ipv4/icmp.c59
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;