|
@@ -264,9 +264,11 @@ int ip_dont_fragment(struct sock *sk, struct dst_entry *dst)
|
|
|
|
|
|
extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more);
|
|
|
|
|
|
-static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, struct sock *sk)
|
|
|
+static inline void ip_select_ident(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk)
|
|
|
{
|
|
|
- if (iph->frag_off & htons(IP_DF)) {
|
|
|
+ struct iphdr *iph = ip_hdr(skb);
|
|
|
+
|
|
|
+ if ((iph->frag_off & htons(IP_DF)) && !skb->local_df) {
|
|
|
/* This is only to work around buggy Windows95/2000
|
|
|
* VJ compression implementations. If the ID field
|
|
|
* does not change, they drop every other packet in
|
|
@@ -278,9 +280,11 @@ static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, str
|
|
|
__ip_select_ident(iph, dst, 0);
|
|
|
}
|
|
|
|
|
|
-static inline void ip_select_ident_more(struct iphdr *iph, struct dst_entry *dst, struct sock *sk, int more)
|
|
|
+static inline void ip_select_ident_more(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk, int more)
|
|
|
{
|
|
|
- if (iph->frag_off & htons(IP_DF)) {
|
|
|
+ struct iphdr *iph = ip_hdr(skb);
|
|
|
+
|
|
|
+ if ((iph->frag_off & htons(IP_DF)) && !skb->local_df) {
|
|
|
if (sk && inet_sk(sk)->inet_daddr) {
|
|
|
iph->id = htons(inet_sk(sk)->inet_id);
|
|
|
inet_sk(sk)->inet_id += 1 + more;
|