1) In the Linux kernel, the route of the IP package is called "destination entry" (DST_ENTRY), the destination entry reflects a "image" of the adjacent external host inside the host, the IP package first injected into the destination entry After a series of IP packet filters, finally injected into a frame head buffer inlet or neighbor entry to the destination entrance, and sends it to the device driver after creating a hardware frame header through the ARP buffer. 2) Routing buffer table is IP routing entry table, it It is an instantiation of the routing rule. When querying IP routing, the system is queried in the routing buffer table. When the route entry already exists, the output package is directly bound to the route entry, and if the matching entry is not found, then By transferring the query routing rules, after the match is successful, create a corresponding destination in the routing table. 3) The routing buffer table is the routing structure (RTABLE) with a hash index, the start of the routing structure is the purpose of the entry structure. They form a joint .ip_route_output (& RT, DADDR, SADDR, OIF) query output device is OIF, destination address is Daddr, the source address is the route entry of Saddr. IP_ROUTE_INPUT (SKB, DADDR, SADDR, TOS, DEV) The receiving package SKB is bound to the input device for the DEV, the destination address is DADDR, the source address is the destination entry for the Saddr, the service type is TOS. Struct DST_ENTRY {strunt DST_ENTRY * Next; atomic_t __refcnt; / * Client References * / int __Use; Struct net_device * dev; int obsolete; int flags; #define DST_HOST 1 unsigned long lastuse; unsigned long expires; unsigned mxlock; unsigned pmtu; unsigned window; unsigned rtt; unsigned rttvar; unsigned ssthresh; unsigned cwnd; unsigned advmss; unsigned reordering; unsigned Long Rate_Last; / * Rate Limiting for ICMP * / Unsigned Long Rate_ToKens; Int Error; Struct neighbour * neighbour struct hh_cache * hh; int (* input) (struct sk_buff *); int (* output) (struct sk_buff *); # ifdef CONFIG_NET_CLS_ROUTE __u32 tclassid; #endif struct dst_ops * ops; char info [0];}; struct rtable {union {struct dst_entry dst; struct rtable * rt_next;} u; unsigned rt_flags; unsigned rt_type; __u32 rt_dst; / * Path destination * / __u32 rt_src; / * Path source * / int rt_iif; / * Info on neighbour * / __u32 rt_gateway; / * Cache lookup keys * / struct rt_key key; / * Miscellaneous cached information * / __u32 rt_spec_dst; / * RFC1122 specific destination * / struct inet_peer * peer; / * long-living peer info * / # ifdef CONFIG_IP_ROUTE_NAT __u32 rt_src_map; __U32 RT_DST_MAP; #ENDIF}; struct dst_ops {UNSIGNED SHORT FAMILY
unsigned short protocol; unsigned gc_thresh; int (* gc) (void); struct dst_entry * (* check) (struct dst_entry *, __u32 cookie); struct dst_entry * (* reroute) (struct dst_entry *, struct sk_buff *); void (* destroy) (struct dst_entry *); struct dst_entry * (* negative_advice) (struct dst_entry *); void (* link_failure) (struct sk_buff *); int entry_size; atomic_t entries; kmem_cache_t * kmem_cachep;}; struct rt_key {__u32 dst; __u32 src; int iif; int oif; #ifdef CONFIG_IP_ROUTE_FWMARK __u32 fwmark; #endif __u8 tos; __u8 scope;}; struct rt_hash_bucket {struct rtable * chain; rwlock_t lock;} __attribute __ ((__ aligned __ (8))) ;; net / ipv4 / route.cstatic struct rt_hash_bucket * rt_hash_table; static unsigned rt_hash_mask; static int rt_hash_log; static __inline__ unsigned rt_hash_code (u32 daddr, u32 saddr, u8 tos) {unsigned hash = ((daddr & 0xF0F0F0F0) >> 4) | ((daddr & 0x0F0F0F0F << 4); HASH ^ = Saddr ^ TOS; HASH ^ = (Hash >> 16); return (haveh ^ (HASH >> 8)) &} static inline int ip_route_output (struct RTable ** RP, u32 daddr, u32 saddr, u32 tos, int oif) {struct rt_key key = {dst: daddr, src: saddr, oif: oif, tos: tos}; return ip_route_output_key (rp, & key);} int ip_route_output_key (struct rtable * * RP, Const struct RT_key * key) {unsigned hash; struct RTable * Rth; hash = rt_hash_code (key-> DST, key-> src ^ (key-> oif << 5), key-> TOS); read_lock_bh ( & rt_hash_table [hash] .lock; for (rth = RT_HASH_TABLE [HASH] .Chain; Rth; Rth = Rth-> u.rt_next) {if (rth-> key.dst == Key-> DST && rth-> key-> .SRC == Key-> SRC && rth-> key.iif == 0 && rth-> key.Oif == key-> OIF &&
#ifdef config_ip_route_fwmark == key-> fwmark && # Endif! ((Rth-> Key.tos ^ Key-> TOS) & (iptos_rt_mask | r_ONLINK) && ((Key-> TOS & RTO_TPROY) || ! (RTH-> RT_FLAGS & RTCF_TPROXY)))) {RTH-> u.dst.lastuse = Jiffies; DST_HOLD (& RTH-> U.DST); RTH-> u.dst .__ use ; read_unlock_bh (& RT_HASH_TABLE [Hash] .lock) ;lock; * rp = rth; return 0;}} read_unlock_bh (& rt_hash_table [hash] .lock); return ip_route_output_slow (rp, key);} int ip_route_input (struct sk_buff * skb, u32 daddr, u32 saddr, u8 tos, struct net_device * dev ) The input IP package from the device DEV is set to the destination {struct RTable * Rth; unsigned hash; int Iif = dev-> ifindex; TOS & = iptos_rt_mask; hash = rt_hash_code (Daddr, Saddr ^ (IIF << 5 ), TOS); read_lock (& RT_HASH_TABLE [HASH] .lock); for (RTH = RT_HASH_TABLE [Hash] .Chain; Rth; Rth = Rth-> u.rt_next) {if (rth-> key.dst == Daddr && Rth-> key.src == saddr && rth-> key.iif == iif && rth-> key.Oif == 0 && # ifdef config_ip_route_fwmark == SKB-> NFMARK && # Endif Rth- > key.tos == TOS) {rth-> u.dst.lastu SE = Jiffies; DST_HOLD (& RTH-> u.dst); Rth-> u.dst .__ use ; read_unlock (& rt_hash_table [hash] .lock); SKB-> DST = (STRUCT DST_ENTRY *) Rth; return 0;}} Read_unlock (& RT_HASH_TABLE [Hash] .lock);