三、路由缓存表
3.1 基本结构
(1)路由缓存存放在全局散列表rt_hash_table中,类型为rt_hash_bucket,该成员变量指向缓存元素。
struct rt_hash_bucket {
struct rtable *chain;
用来储存缓存中的路由表项,可以通过/proc/net/rt_cache查看
(4)dst_entry结构
存储缓存路由项中独立于协议的信息。
3.1 基本结构
(1)路由缓存存放在全局散列表rt_hash_table中,类型为rt_hash_bucket,该成员变量指向缓存元素。
struct rt_hash_bucket {
struct rtable *chain;
};
用来储存缓存中的路由表项,可以通过/proc/net/rt_cache查看
struct rtable
{
union
{
struct dst_entry dst;//独立于协议的信息
} u;
/* Cache lookup keys */
struct flowi fl;//缓存查询键值
struct in_device *idev;//输出网络设备的IP配置
int rt_genid;
unsigned rt_flags;//标识路由表项的特征
__u16 rt_type;//路由的类型,
__be32 rt_dst; /* Path destination */
__be32 rt_src; /* Path source */
int rt_iif; //输入设备的标识
/* Info on neighbour */
__be32 rt_gateway; //目的地址或下一跳网关
/* Miscellaneous cached information */
__be32 rt_spec_dst; /* RFC1122 specific destination */
struct inet_peer *peer; /* long-living peer info */
#if defined(CONFIG_MV_ETH_NFP_FIB_LEARN)
bool nfp;
#endif /* CONFIG_MV_ETH_NFP_FIB_LEARN */
};
(3)flowi结构
根据诸如输入网络设备、输出网络设备、三层和四层协议报头中的参数等字段组合。struct flowi {
int oif;//输出网络设备索引
int iif;//输入网络设备索引
__u32 mark;
union {
struct {
__be32 daddr;
__be32 saddr;
__u8 tos;
__u8 scope;
} ip4_u;
struct {
struct in6_addr daddr;
struct in6_addr saddr;
__be32 flowlabel;
} ip6_u;
struct {
__le16 daddr;
__le16 saddr;
__u8 scope;
} dn_u;
} nl_u;//三层相关成员,地址联合体,针对IPV4/IPV6/DECnet
#define fld_dst nl_u.dn_u.daddr
#define fld_src nl_u.dn_u.saddr
#define fld_scope nl_u.dn_u.scope
#define fl6_dst nl_u.ip6_u.daddr
#define fl6_src nl_u.ip6_u.saddr
#define fl6_flowlabel nl_u.ip6_u.flowlabel
#define fl4_dst nl_u.ip4_u.daddr
#define fl4_src nl_u.ip4_u.saddr
#define fl4_tos nl_u.ip4_u.tos
#define fl4_scope nl_u.ip4_u.scope
__u8 proto;//标识四层协议
__u8 flags;
#define FLOWI_FLAG_ANYSRC 0x01
union {
struct {
__be16 sport;
__be16 dport;
} ports;
struct {
__u8 type;
__u8 code;
} icmpt;
struct {
__le16 sport;
__le16 dport;
} dnports;
__be32 spi;
struct {
__u8 type;
} mht;
} uli_u;//四层协议参数联合体,针对TCP/UDP/ICMP/DECnet/IPsec
#define fl_ip_sport uli_u.ports.sport
#define fl_ip_dport uli_u.ports.dport
#define fl_icmp_type uli_u.icmpt.type
#define fl_icmp_code uli_u.icmpt.code
#define fl_ipsec_spi uli_u.spi
#define fl_mh_type uli_u.mht.type
__u32 secid; /* used by xfrm; see secid.txt */
}
(4)dst_entry结构
存储缓存路由项中独立于协议的信息。
struct dst_entry
{
struct rcu_head rcu_head;
struct dst_entry *child;
struct net_device *dev;//输出网络设备
short error;//fib_lookup查找失败时的错误码
short obsolete;
int flags;
#define DST_HOST 1
#define DST_NOXFRM 2
#define DST_NOPOLICY 4
#define DST_NOHASH 8
unsigned long expires;//过期的时间戳
unsigned short header_len; /* more space at head required */
unsigned short trailer_len; /* space to reserve at tail */
unsigned int rate_tokens; //对ICMP消息限速
unsigned long rate_last; /* rate limiting for ICMP */
struct dst_entry *path;
struct neighbour *neighbour;
struct hh_cache *hh; //指向缓存的二层头部
#ifdef CONFIG_XFRM
struct xfrm_state *xfrm;
#else
void *__pad1;
#endif
//暂时写下,后面再理解
/*输入、输出相关的函数指针,当在函数ip_rcv_finish中,完成路由的查找后,
根据input、output函数,传递数据包。
本地接收的数据包,则其input指向函数ip_local_deliver,只用到input函数
要转发的数据包,其input指向函数ip_forward,其output指向函数ip_output,两个都要用
本地发出的数据包,只用到output */
int (*input)(struct sk_buff*);
int (*output)(struct sk_buff*);
struct dst_ops *ops;//用于处理dst_entry的函数集
u32 metrics[RTAX_MAX]; //保存很多和对端通信时所需的数值,比如initcwnd、max_mtu等
#ifdef CONFIG_NET_CLS_ROUTE
__u32 tclassid;
#else
__u32 __pad2;
#endif
/*
* Align __refcnt to a 64 bytes alignment
* (L1_CACHE_SIZE would be too much)
*/
#ifdef CONFIG_64BIT
long __pad_to_align_refcnt[2];
#else
long __pad_to_align_refcnt[1];
#endif
/*
* __refcnt wants to be on a different cache line from
* input/output/ops or performance tanks badly
*/
atomic_t __refcnt; /* client references *///引用计数
int __use;
unsigned long lastuse;//最近一次使用该路由缓存的时间戳
union {
struct dst_entry *next;
struct rtable *rt_next;
struct rt6_info *rt6_next;
struct dn_route *dn_next;
};
}