欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

route

程序员文章站 2022-06-02 18:35:26
...
// sk->sk_dst_cache存储路由信息 -- 抵达目的地的路径
static inline void
__sk_dst_set(struct sock *sk, struct dst_entry *dst)
{
	struct dst_entry *old_dst;

	old_dst = sk->sk_dst_cache;
	sk->sk_dst_cache = dst;
	dst_release(old_dst);
}

static inline void
sk_dst_set(struct sock *sk, struct dst_entry *dst)
{
	write_lock(&sk->sk_dst_lock);
	__sk_dst_set(sk, dst);
	write_unlock(&sk->sk_dst_lock);
}

// return sock->sk_dst_cache, 有效则返回,无效则返回null
static inline struct dst_entry *
__sk_dst_check(struct sock *sk, u32 cookie)
{
	struct dst_entry *dst = sk->sk_dst_cache;

	if (dst && dst->obsolete && dst->ops->check(dst, cookie) == NULL) {
		sk->sk_dst_cache = NULL;
		dst_release(dst);
		return NULL;
	}

	return dst;
}

转发包,没有socket字段相关联

socket的选项信息,存放在inet_sock->opt字段中,因为选项通常是相同的,所以无需在skbuff中,特意创建字段
替每个封包重建选项信息,太浪费性能了

在sock和skb_buff中,都有路由信息 即sock->sk_dst_cache 和 skb->dst

ip_queue_xmit中路由相关的处理逻辑:
如果skb中已经包含路由信息,直接跳出;
如果skb中没有路由信息,而sock中的路由信息是有效的,则将sock中的信息,复制到skb中;

即:

rt = sk_dst_check(sk, 0);
skb->dst = dst_clone(&rt->u.dst);  

如果sock中的路径也是无效的,则使用路由子系统,查找新的路径,给skb使用,调用的函数为 ip_route_output_flow.
最简单的情况下,直接将inet->daddr设置为DIP即可,在有source route选项是,会有特殊处理,代码没有细看