diff options
Diffstat (limited to 'net/ipv4/route.c')
| -rw-r--r-- | net/ipv4/route.c | 33 | 
1 files changed, 33 insertions, 0 deletions
| diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 6cb7cff22db9..8ea0735a6754 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1647,6 +1647,39 @@ struct rtable *rt_dst_alloc(struct net_device *dev,  }  EXPORT_SYMBOL(rt_dst_alloc); +struct rtable *rt_dst_clone(struct net_device *dev, struct rtable *rt) +{ +	struct rtable *new_rt; + +	new_rt = dst_alloc(&ipv4_dst_ops, dev, 1, DST_OBSOLETE_FORCE_CHK, +			   rt->dst.flags); + +	if (new_rt) { +		new_rt->rt_genid = rt_genid_ipv4(dev_net(dev)); +		new_rt->rt_flags = rt->rt_flags; +		new_rt->rt_type = rt->rt_type; +		new_rt->rt_is_input = rt->rt_is_input; +		new_rt->rt_iif = rt->rt_iif; +		new_rt->rt_pmtu = rt->rt_pmtu; +		new_rt->rt_mtu_locked = rt->rt_mtu_locked; +		new_rt->rt_gw_family = rt->rt_gw_family; +		if (rt->rt_gw_family == AF_INET) +			new_rt->rt_gw4 = rt->rt_gw4; +		else if (rt->rt_gw_family == AF_INET6) +			new_rt->rt_gw6 = rt->rt_gw6; +		INIT_LIST_HEAD(&new_rt->rt_uncached); + +		new_rt->dst.flags |= DST_HOST; +		new_rt->dst.input = rt->dst.input; +		new_rt->dst.output = rt->dst.output; +		new_rt->dst.error = rt->dst.error; +		new_rt->dst.lastuse = jiffies; +		new_rt->dst.lwtstate = lwtstate_get(rt->dst.lwtstate); +	} +	return new_rt; +} +EXPORT_SYMBOL(rt_dst_clone); +  /* called in rcu_read_lock() section */  int ip_mc_validate_source(struct sk_buff *skb, __be32 daddr, __be32 saddr,  			  u8 tos, struct net_device *dev, |