route.c (96916090f488986a4ebb8e9ffa6a3b50881d5ccd) | route.c (0bbeafd0118fc3ae54990064760c889d41dc21d6) |
---|---|
1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * ROUTE - implementation of the IP router. 7 * 8 * Version: $Id: route.c,v 1.103 2002/01/12 07:44:09 davem Exp $ --- 1416 unchanged lines hidden (view full) --- 1425 1426 for (i = 0; i < ARRAY_SIZE(mtu_plateau); i++) 1427 if (old_mtu > mtu_plateau[i]) 1428 return mtu_plateau[i]; 1429 return 68; 1430} 1431 1432unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, | 1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * ROUTE - implementation of the IP router. 7 * 8 * Version: $Id: route.c,v 1.103 2002/01/12 07:44:09 davem Exp $ --- 1416 unchanged lines hidden (view full) --- 1425 1426 for (i = 0; i < ARRAY_SIZE(mtu_plateau); i++) 1427 if (old_mtu > mtu_plateau[i]) 1428 return mtu_plateau[i]; 1429 return 68; 1430} 1431 1432unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, |
1433 unsigned short new_mtu) | 1433 unsigned short new_mtu, 1434 struct net_device *dev) |
1434{ | 1435{ |
1435 int i; | 1436 int i, k; |
1436 unsigned short old_mtu = ntohs(iph->tot_len); 1437 struct rtable *rth; | 1437 unsigned short old_mtu = ntohs(iph->tot_len); 1438 struct rtable *rth; |
1439 int ikeys[2] = { dev->ifindex, 0 }; |
|
1438 __be32 skeys[2] = { iph->saddr, 0, }; 1439 __be32 daddr = iph->daddr; 1440 unsigned short est_mtu = 0; 1441 1442 if (ipv4_config.no_pmtu_disc) 1443 return 0; 1444 | 1440 __be32 skeys[2] = { iph->saddr, 0, }; 1441 __be32 daddr = iph->daddr; 1442 unsigned short est_mtu = 0; 1443 1444 if (ipv4_config.no_pmtu_disc) 1445 return 0; 1446 |
1445 for (i = 0; i < 2; i++) { 1446 unsigned hash = rt_hash(daddr, skeys[i], 0); | 1447 for (k = 0; k < 2; k++) { 1448 for (i = 0; i < 2; i++) { 1449 unsigned hash = rt_hash(daddr, skeys[i], ikeys[k]); |
1447 | 1450 |
1448 rcu_read_lock(); 1449 for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; 1450 rth = rcu_dereference(rth->u.dst.rt_next)) { 1451 if (rth->fl.fl4_dst == daddr && 1452 rth->fl.fl4_src == skeys[i] && 1453 rth->rt_dst == daddr && 1454 rth->rt_src == iph->saddr && 1455 rth->fl.iif == 0 && 1456 !(dst_metric_locked(&rth->u.dst, RTAX_MTU)) && 1457 net_eq(dev_net(rth->u.dst.dev), net) && 1458 rth->rt_genid == atomic_read(&rt_genid)) { | 1451 rcu_read_lock(); 1452 for (rth = rcu_dereference(rt_hash_table[hash].chain); rth; 1453 rth = rcu_dereference(rth->u.dst.rt_next)) { |
1459 unsigned short mtu = new_mtu; 1460 | 1454 unsigned short mtu = new_mtu; 1455 |
1456 if (rth->fl.fl4_dst != daddr || 1457 rth->fl.fl4_src != skeys[i] || 1458 rth->rt_dst != daddr || 1459 rth->rt_src != iph->saddr || 1460 rth->fl.oif != ikeys[k] || 1461 rth->fl.iif != 0 || 1462 dst_metric_locked(&rth->u.dst, RTAX_MTU) || 1463 !net_eq(dev_net(rth->u.dst.dev), net) || 1464 rth->rt_genid != atomic_read(&rt_genid)) 1465 continue; 1466 |
|
1461 if (new_mtu < 68 || new_mtu >= old_mtu) { 1462 1463 /* BSD 4.2 compatibility hack :-( */ 1464 if (mtu == 0 && 1465 old_mtu >= rth->u.dst.metrics[RTAX_MTU-1] && 1466 old_mtu >= 68 + (iph->ihl << 2)) 1467 old_mtu -= iph->ihl << 2; 1468 --- 9 unchanged lines hidden (view full) --- 1478 } 1479 rth->u.dst.metrics[RTAX_MTU-1] = mtu; 1480 dst_set_expires(&rth->u.dst, 1481 ip_rt_mtu_expires); 1482 } 1483 est_mtu = mtu; 1484 } 1485 } | 1467 if (new_mtu < 68 || new_mtu >= old_mtu) { 1468 1469 /* BSD 4.2 compatibility hack :-( */ 1470 if (mtu == 0 && 1471 old_mtu >= rth->u.dst.metrics[RTAX_MTU-1] && 1472 old_mtu >= 68 + (iph->ihl << 2)) 1473 old_mtu -= iph->ihl << 2; 1474 --- 9 unchanged lines hidden (view full) --- 1484 } 1485 rth->u.dst.metrics[RTAX_MTU-1] = mtu; 1486 dst_set_expires(&rth->u.dst, 1487 ip_rt_mtu_expires); 1488 } 1489 est_mtu = mtu; 1490 } 1491 } |
1492 rcu_read_unlock(); |
|
1486 } | 1493 } |
1487 rcu_read_unlock(); | |
1488 } 1489 return est_mtu ? : new_mtu; 1490} 1491 1492static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) 1493{ 1494 if (dst->metrics[RTAX_MTU-1] > mtu && mtu >= 68 && 1495 !(dst_metric_locked(dst, RTAX_MTU))) { --- 106 unchanged lines hidden (view full) --- 1602 if (fi) { 1603 if (FIB_RES_GW(*res) && 1604 FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) 1605 rt->rt_gateway = FIB_RES_GW(*res); 1606 memcpy(rt->u.dst.metrics, fi->fib_metrics, 1607 sizeof(rt->u.dst.metrics)); 1608 if (fi->fib_mtu == 0) { 1609 rt->u.dst.metrics[RTAX_MTU-1] = rt->u.dst.dev->mtu; | 1494 } 1495 return est_mtu ? : new_mtu; 1496} 1497 1498static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) 1499{ 1500 if (dst->metrics[RTAX_MTU-1] > mtu && mtu >= 68 && 1501 !(dst_metric_locked(dst, RTAX_MTU))) { --- 106 unchanged lines hidden (view full) --- 1608 if (fi) { 1609 if (FIB_RES_GW(*res) && 1610 FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) 1611 rt->rt_gateway = FIB_RES_GW(*res); 1612 memcpy(rt->u.dst.metrics, fi->fib_metrics, 1613 sizeof(rt->u.dst.metrics)); 1614 if (fi->fib_mtu == 0) { 1615 rt->u.dst.metrics[RTAX_MTU-1] = rt->u.dst.dev->mtu; |
1610 if (rt->u.dst.metrics[RTAX_LOCK-1] & (1 << RTAX_MTU) && | 1616 if (dst_metric_locked(&rt->u.dst, RTAX_MTU) && |
1611 rt->rt_gateway != rt->rt_dst && 1612 rt->u.dst.dev->mtu > 576) 1613 rt->u.dst.metrics[RTAX_MTU-1] = 576; 1614 } 1615#ifdef CONFIG_NET_CLS_ROUTE 1616 rt->u.dst.tclassid = FIB_RES_NH(*res).nh_tclassid; 1617#endif 1618 } else --- 1471 unchanged lines hidden --- | 1617 rt->rt_gateway != rt->rt_dst && 1618 rt->u.dst.dev->mtu > 576) 1619 rt->u.dst.metrics[RTAX_MTU-1] = 576; 1620 } 1621#ifdef CONFIG_NET_CLS_ROUTE 1622 rt->u.dst.tclassid = FIB_RES_NH(*res).nh_tclassid; 1623#endif 1624 } else --- 1471 unchanged lines hidden --- |