tcp v4 connect 三次路由查找 route
https://www.cnblogs.com/codestack/p/12629487.html
tcp_v4_connect调用栈如下
rt = ip_route_connect(fl4, nexthop, inet->inet_saddr,
RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,
IPPROTO_TCP,
orig_sport, orig_dport, sk);
rt = ip_route_newports(fl4, rt, orig_sport, orig_dport,
inet->inet_sport, inet->inet_dport, sk);
static inline struct rtable *ip_route_connect(struct flowi4 *fl4,
__be32 dst, __be32 src, u32 tos,
int oif, u8 protocol,
__be16 sport, __be16 dport,
struct sock *sk)
{
struct net *net = sock_net(sk);
struct rtable *rt;
ip_route_connect_init(fl4, dst, src, tos, oif, protocol,
sport, dport, sk);
if (!dst || !src) {
rt = __ip_route_output_key(net, fl4);
if (IS_ERR(rt))
return rt;
ip_rt_put(rt);
flowi4_update_output(fl4, oif, tos, fl4->daddr, fl4->saddr);
}
security_sk_classify_flow(sk, flowi4_to_flowi(fl4));
return ip_route_output_flow(net, fl4, sk);
}
可知:如果源srcip为0
则会调用三次路由查找
1、第一次saddr 0---- >ip_route_connect---->__ip_route_output_key(net, fl4);
2、第二次saddr 和 daddr 都知道 ---->ip_route_connect--->ip_route_output_flow(net, fl4, sk);
3、由于src port不知道再次查找路由 ---->ip_route_newports
但是里有个很坑的逻辑:在fib_select_path 选择下一条的时候,可能会出现第一次路由选择A,第二次路由选择B
void fib_select_path(struct net *net, struct fib_result *res,
struct flowi4 *fl4, const struct sk_buff *skb)
{
if (fl4->flowi4_oif)
goto check_saddr;
#ifdef CONFIG_IP_ROUTE_MULTIPATH
if (fib_info_num_path(res->fi) > 1) {
int h = fib_multipath_hash(net, fl4, skb, NULL);
fib_select_multipath(res, h);
}
else
#endif
if (!res->prefixlen &&
res->table->tb_num_default > 1 &&
res->type == RTN_UNICAST)
fib_select_default(fl4, res);
check_saddr:
if (!fl4->saddr)
fl4->saddr = fib_result_prefsrc(net, res);
}
也就是hash的时候int h = fib_multipath_hash(net, fl4, skb, NULL);可能选择不同的nexthop
http代理服务器(3-4-7层代理)-网络事件库公共组件、内核kernel驱动 摄像头驱动 tcpip网络协议栈、netfilter、bridge 好像看过!!!!
但行好事 莫问前程
--身高体重180的胖子

浙公网安备 33010602011771号