@@ -671,7 +671,10 @@ static inline int ipv6_addr_diff(const struct in6_addr *a1, const struct in6_add
return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
}
-void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt);
+void ipv6_select_ident(struct frag_hdr *fhdr, const struct rt6_info *rt);
+void ipv6_select_ident_by_addr(struct frag_hdr *fhdr,
+ const struct in6_addr *dst,
+ const struct in6_addr *src);
void ipv6_proxy_select_ident(struct sk_buff *skb);
int ip6_dst_hoplimit(struct dst_entry *dst);
@@ -59,17 +59,25 @@ void ipv6_proxy_select_ident(struct sk_buff *skb)
}
EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident);
-void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt)
+void ipv6_select_ident_by_addr(struct frag_hdr *fhdr,
+ const struct in6_addr *dst,
+ const struct in6_addr *src)
{
static u32 ip6_idents_hashrnd __read_mostly;
u32 id;
net_get_random_once(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd));
- id = __ipv6_select_ident(ip6_idents_hashrnd, &rt->rt6i_dst.addr,
- &rt->rt6i_src.addr);
+ id = __ipv6_select_ident(ip6_idents_hashrnd, dst, src);
fhdr->identification = htonl(id);
}
+EXPORT_SYMBOL(ipv6_select_ident_by_addr);
+
+void ipv6_select_ident(struct frag_hdr *fhdr, const struct rt6_info *rt)
+{
+ ipv6_select_ident_by_addr(fhdr, &rt->rt6i_dst.addr,
+ &rt->rt6i_src.addr);
+}
EXPORT_SYMBOL(ipv6_select_ident);
int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
In case the route information is not available but IPv6 identification field needs to be calculated, for example, in ipv6 fragmentation. This new API can used. The current ipv6_select_ident() is kept as is. Its implementation now calls the new API. Signed-off-by: Andy Zhou <azhou@nicira.com> --- include/net/ipv6.h | 5 ++++- net/ipv6/output_core.c | 14 +++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-)