diff --git a/src/linux/include/net/nip_fib.h b/src/linux/include/net/nip_fib.h index 150e1319bf7bd602dad5329f9310799e9a8c4cdf..0d24d932d0717ba44e5cf74a45f46d684889b900 100644 --- a/src/linux/include/net/nip_fib.h +++ b/src/linux/include/net/nip_fib.h @@ -142,7 +142,7 @@ struct nip_fib_node *nip_fib_locate(struct hlist_head *nip_tb_head, void nip_fib_clean_all(struct net *net, int (*func)(struct nip_rt_info *, void *arg), void *arg); -int nip_fib_add(struct hlist_head *nip_tb_head, struct nip_rt_info *rt); +int nip_fib_add(struct nip_fib_table *table, struct nip_rt_info *rt); int nip_fib_del(struct nip_rt_info *rt_info, struct nl_info *info); diff --git a/src/linux/net/newip/nip_fib.c b/src/linux/net/newip/nip_fib.c index e00f5e6edfeedb63bc5d263627984fcf9d7a1543..fbf25d2eddcc2cb2ab7786a00633c8b08220dd04 100644 --- a/src/linux/net/newip/nip_fib.c +++ b/src/linux/net/newip/nip_fib.c @@ -103,7 +103,7 @@ struct nip_fib_node *nip_fib_locate(struct hlist_head *nip_tb_head, } /* nip_tb_lock must be taken to avoid racing */ -int nip_fib_add(struct hlist_head *nip_tb_head, struct nip_rt_info *rt) +int nip_fib_add(struct nip_fib_table *table, struct nip_rt_info *rt) { struct nip_fib_node *fib_node, *new_node; int err = 0; @@ -113,15 +113,23 @@ int nip_fib_add(struct hlist_head *nip_tb_head, struct nip_rt_info *rt) char gateway[NIP_ADDR_BIT_LEN_MAX] = {0}; hash = ninet_route_hash(&rt->rt_dst); - h = &nip_tb_head[hash]; + h = &table->nip_tb_head[hash]; hlist_for_each_entry(fib_node, h, fib_hlist) { - if (nip_addr_and_ifindex_eq - (&fib_node->nip_route_info->rt_dst, &rt->rt_dst, - fib_node->nip_route_info->rt_idev->dev->ifindex, - rt->rt_idev->dev->ifindex)) { - err = -EEXIST; - goto fail; + if (table->nip_tb_id == NIP_RT_TABLE_MAIN) { + if (nip_addr_eq(&fib_node->nip_route_info->rt_dst, + &rt->rt_dst)) { + err = -EEXIST; + goto fail; + } + } else if (table->nip_tb_id == NIP_RT_TABLE_LOCAL) { + if (nip_addr_and_ifindex_eq + (&fib_node->nip_route_info->rt_dst, &rt->rt_dst, + fib_node->nip_route_info->rt_idev->dev->ifindex, + rt->rt_idev->dev->ifindex)) { + err = -EEXIST; + goto fail; + } } } diff --git a/src/linux/net/newip/route.c b/src/linux/net/newip/route.c index 3430e31eeef60c21880cc488e8988c335c1b2f7a..0ede62a441f6fa3e8cb7ccc992386b7fea3ca0fc 100644 --- a/src/linux/net/newip/route.c +++ b/src/linux/net/newip/route.c @@ -496,7 +496,7 @@ static int __nip_ins_rt(struct nip_rt_info *rt) table = rt->rt_table; spin_lock_bh(&table->nip_tb_lock); - err = nip_fib_add(table->nip_tb_head, rt); + err = nip_fib_add(table, rt); spin_unlock_bh(&table->nip_tb_lock); return err; diff --git a/src/linux/net/newip/tcp_nip_input.c b/src/linux/net/newip/tcp_nip_input.c index 289973ef9f7462ef823c16d80e83d49729e6242d..c8ef3a6c056632993bac5fb1e8e0e3e3977ef38f 100644 --- a/src/linux/net/newip/tcp_nip_input.c +++ b/src/linux/net/newip/tcp_nip_input.c @@ -695,8 +695,8 @@ static int tcp_nip_clean_rtx_queue(struct sock *sk, ktime_t *skb_snd_tstamp) tcp_unlink_write_queue(skb, sk); sk_wmem_free_skb(sk, skb); } - - icsk->icsk_rto = (unsigned int)(HZ / get_nip_rto()); /* V4 no modified this line */ + /* V4 no modified this line */ + icsk->icsk_rto = get_nip_rto() == 0 ? TCP_TIMEOUT_INIT : (HZ / get_nip_rto()); if (flag & FLAG_ACKED) tcp_nip_rearm_rto(sk); return 0;