hc
2024-02-20 e636c8d336489bf3eed5878299e6cc045bbad077
kernel/include/net/ipv6_frag.h
....@@ -67,6 +67,9 @@
6767 struct sk_buff *head;
6868
6969 rcu_read_lock();
70
+ /* Paired with the WRITE_ONCE() in fqdir_pre_exit(). */
71
+ if (READ_ONCE(fq->q.fqdir->dead))
72
+ goto out_rcu_unlock;
7073 spin_lock(&fq->q.lock);
7174
7275 if (fq->q.flags & INET_FRAG_COMPLETE)
....@@ -106,5 +109,35 @@
106109 rcu_read_unlock();
107110 inet_frag_put(&fq->q);
108111 }
112
+
113
+/* Check if the upper layer header is truncated in the first fragment. */
114
+static inline bool
115
+ipv6frag_thdr_truncated(struct sk_buff *skb, int start, u8 *nexthdrp)
116
+{
117
+ u8 nexthdr = *nexthdrp;
118
+ __be16 frag_off;
119
+ int offset;
120
+
121
+ offset = ipv6_skip_exthdr(skb, start, &nexthdr, &frag_off);
122
+ if (offset < 0 || (frag_off & htons(IP6_OFFSET)))
123
+ return false;
124
+ switch (nexthdr) {
125
+ case NEXTHDR_TCP:
126
+ offset += sizeof(struct tcphdr);
127
+ break;
128
+ case NEXTHDR_UDP:
129
+ offset += sizeof(struct udphdr);
130
+ break;
131
+ case NEXTHDR_ICMP:
132
+ offset += sizeof(struct icmp6hdr);
133
+ break;
134
+ default:
135
+ offset += 1;
136
+ }
137
+ if (offset > skb->len)
138
+ return true;
139
+ return false;
140
+}
141
+
109142 #endif
110143 #endif