route.c (c0981b863a31a1891aa2719957983f4297770f87) | route.c (73f156a6e8c1074ac6327e0abd1169e95eb66463) |
---|---|
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 * Authors: Ross Biro --- 75 unchanged lines hidden (view full) --- 84#include <linux/igmp.h> 85#include <linux/pkt_sched.h> 86#include <linux/mroute.h> 87#include <linux/netfilter_ipv4.h> 88#include <linux/random.h> 89#include <linux/rcupdate.h> 90#include <linux/times.h> 91#include <linux/slab.h> | 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 * Authors: Ross Biro --- 75 unchanged lines hidden (view full) --- 84#include <linux/igmp.h> 85#include <linux/pkt_sched.h> 86#include <linux/mroute.h> 87#include <linux/netfilter_ipv4.h> 88#include <linux/random.h> 89#include <linux/rcupdate.h> 90#include <linux/times.h> 91#include <linux/slab.h> |
92#include <linux/jhash.h> |
|
92#include <net/dst.h> 93#include <net/net_namespace.h> 94#include <net/protocol.h> 95#include <net/ip.h> 96#include <net/route.h> 97#include <net/inetpeer.h> 98#include <net/sock.h> 99#include <net/ip_fib.h> --- 351 unchanged lines hidden (view full) --- 451 pkey = &ip_hdr(skb)->daddr; 452 453 n = __ipv4_neigh_lookup(dev, *(__force u32 *)pkey); 454 if (n) 455 return n; 456 return neigh_create(&arp_tbl, pkey, dev); 457} 458 | 93#include <net/dst.h> 94#include <net/net_namespace.h> 95#include <net/protocol.h> 96#include <net/ip.h> 97#include <net/route.h> 98#include <net/inetpeer.h> 99#include <net/sock.h> 100#include <net/ip_fib.h> --- 351 unchanged lines hidden (view full) --- 452 pkey = &ip_hdr(skb)->daddr; 453 454 n = __ipv4_neigh_lookup(dev, *(__force u32 *)pkey); 455 if (n) 456 return n; 457 return neigh_create(&arp_tbl, pkey, dev); 458} 459 |
459/* 460 * Peer allocation may fail only in serious out-of-memory conditions. However 461 * we still can generate some output. 462 * Random ID selection looks a bit dangerous because we have no chances to 463 * select ID being unique in a reasonable period of time. 464 * But broken packet identifier may be better than no packet at all. 465 */ 466static void ip_select_fb_ident(struct iphdr *iph) 467{ 468 static DEFINE_SPINLOCK(ip_fb_id_lock); 469 static u32 ip_fallback_id; 470 u32 salt; | 460atomic_t *ip_idents __read_mostly; 461EXPORT_SYMBOL(ip_idents); |
471 | 462 |
472 spin_lock_bh(&ip_fb_id_lock); 473 salt = secure_ip_id((__force __be32)ip_fallback_id ^ iph->daddr); 474 iph->id = htons(salt & 0xFFFF); 475 ip_fallback_id = salt; 476 spin_unlock_bh(&ip_fb_id_lock); 477} 478 479void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more) | 463void __ip_select_ident(struct iphdr *iph, int segs) |
480{ | 464{ |
481 struct net *net = dev_net(dst->dev); 482 struct inet_peer *peer; | 465 static u32 ip_idents_hashrnd __read_mostly; 466 u32 hash, id; |
483 | 467 |
484 peer = inet_getpeer_v4(net->ipv4.peers, iph->daddr, 1); 485 if (peer) { 486 iph->id = htons(inet_getid(peer, more)); 487 inet_putpeer(peer); 488 return; 489 } | 468 net_get_random_once(&ip_idents_hashrnd, sizeof(ip_idents_hashrnd)); |
490 | 469 |
491 ip_select_fb_ident(iph); | 470 hash = jhash_1word((__force u32)iph->daddr, ip_idents_hashrnd); 471 id = ip_idents_reserve(hash, segs); 472 iph->id = htons(id); |
492} 493EXPORT_SYMBOL(__ip_select_ident); 494 495static void __build_flow_key(struct flowi4 *fl4, const struct sock *sk, 496 const struct iphdr *iph, 497 int oif, u8 tos, 498 u8 prot, u32 mark, int flow_flags) 499{ --- 488 unchanged lines hidden (view full) --- 988 989void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, 990 int oif, u32 mark, u8 protocol, int flow_flags) 991{ 992 const struct iphdr *iph = (const struct iphdr *) skb->data; 993 struct flowi4 fl4; 994 struct rtable *rt; 995 | 473} 474EXPORT_SYMBOL(__ip_select_ident); 475 476static void __build_flow_key(struct flowi4 *fl4, const struct sock *sk, 477 const struct iphdr *iph, 478 int oif, u8 tos, 479 u8 prot, u32 mark, int flow_flags) 480{ --- 488 unchanged lines hidden (view full) --- 969 970void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, 971 int oif, u32 mark, u8 protocol, int flow_flags) 972{ 973 const struct iphdr *iph = (const struct iphdr *) skb->data; 974 struct flowi4 fl4; 975 struct rtable *rt; 976 |
977 if (!mark) 978 mark = IP4_REPLY_MARK(net, skb->mark); 979 |
|
996 __build_flow_key(&fl4, NULL, iph, oif, 997 RT_TOS(iph->tos), protocol, mark, flow_flags); 998 rt = __ip_route_output_key(net, &fl4); 999 if (!IS_ERR(rt)) { 1000 __ip_rt_update_pmtu(rt, &fl4, mtu); 1001 ip_rt_put(rt); 1002 } 1003} 1004EXPORT_SYMBOL_GPL(ipv4_update_pmtu); 1005 1006static void __ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) 1007{ 1008 const struct iphdr *iph = (const struct iphdr *) skb->data; 1009 struct flowi4 fl4; 1010 struct rtable *rt; 1011 1012 __build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0); | 980 __build_flow_key(&fl4, NULL, iph, oif, 981 RT_TOS(iph->tos), protocol, mark, flow_flags); 982 rt = __ip_route_output_key(net, &fl4); 983 if (!IS_ERR(rt)) { 984 __ip_rt_update_pmtu(rt, &fl4, mtu); 985 ip_rt_put(rt); 986 } 987} 988EXPORT_SYMBOL_GPL(ipv4_update_pmtu); 989 990static void __ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) 991{ 992 const struct iphdr *iph = (const struct iphdr *) skb->data; 993 struct flowi4 fl4; 994 struct rtable *rt; 995 996 __build_flow_key(&fl4, sk, iph, 0, 0, 0, 0, 0); |
997 998 if (!fl4.flowi4_mark) 999 fl4.flowi4_mark = IP4_REPLY_MARK(sock_net(sk), skb->mark); 1000 |
|
1013 rt = __ip_route_output_key(sock_net(sk), &fl4); 1014 if (!IS_ERR(rt)) { 1015 __ip_rt_update_pmtu(rt, &fl4, mtu); 1016 ip_rt_put(rt); 1017 } 1018} 1019 1020void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) --- 1678 unchanged lines hidden (view full) --- 2699#ifdef CONFIG_IP_ROUTE_CLASSID 2700struct ip_rt_acct __percpu *ip_rt_acct __read_mostly; 2701#endif /* CONFIG_IP_ROUTE_CLASSID */ 2702 2703int __init ip_rt_init(void) 2704{ 2705 int rc = 0; 2706 | 1001 rt = __ip_route_output_key(sock_net(sk), &fl4); 1002 if (!IS_ERR(rt)) { 1003 __ip_rt_update_pmtu(rt, &fl4, mtu); 1004 ip_rt_put(rt); 1005 } 1006} 1007 1008void ipv4_sk_update_pmtu(struct sk_buff *skb, struct sock *sk, u32 mtu) --- 1678 unchanged lines hidden (view full) --- 2687#ifdef CONFIG_IP_ROUTE_CLASSID 2688struct ip_rt_acct __percpu *ip_rt_acct __read_mostly; 2689#endif /* CONFIG_IP_ROUTE_CLASSID */ 2690 2691int __init ip_rt_init(void) 2692{ 2693 int rc = 0; 2694 |
2695 ip_idents = kmalloc(IP_IDENTS_SZ * sizeof(*ip_idents), GFP_KERNEL); 2696 if (!ip_idents) 2697 panic("IP: failed to allocate ip_idents\n"); 2698 2699 prandom_bytes(ip_idents, IP_IDENTS_SZ * sizeof(*ip_idents)); 2700 |
|
2707#ifdef CONFIG_IP_ROUTE_CLASSID 2708 ip_rt_acct = __alloc_percpu(256 * sizeof(struct ip_rt_acct), __alignof__(struct ip_rt_acct)); 2709 if (!ip_rt_acct) 2710 panic("IP: failed to allocate ip_rt_acct\n"); 2711#endif 2712 2713 ipv4_dst_ops.kmem_cachep = 2714 kmem_cache_create("ip_dst_cache", sizeof(struct rtable), 0, --- 42 unchanged lines hidden --- | 2701#ifdef CONFIG_IP_ROUTE_CLASSID 2702 ip_rt_acct = __alloc_percpu(256 * sizeof(struct ip_rt_acct), __alignof__(struct ip_rt_acct)); 2703 if (!ip_rt_acct) 2704 panic("IP: failed to allocate ip_rt_acct\n"); 2705#endif 2706 2707 ipv4_dst_ops.kmem_cachep = 2708 kmem_cache_create("ip_dst_cache", sizeof(struct rtable), 0, --- 42 unchanged lines hidden --- |