hc
2024-01-31 f9004dbfff8a3fbbd7e2a88c8a4327c7f2f8e5b2
kernel/include/net/inet_ecn.h
....@@ -100,6 +100,20 @@
100100 return 1;
101101 }
102102
103
+static inline int IP_ECN_set_ect1(struct iphdr *iph)
104
+{
105
+ u32 check = (__force u32)iph->check;
106
+
107
+ if ((iph->tos & INET_ECN_MASK) != INET_ECN_ECT_0)
108
+ return 0;
109
+
110
+ check += (__force u16)htons(0x1);
111
+
112
+ iph->check = (__force __sum16)(check + (check>=0xFFFF));
113
+ iph->tos ^= INET_ECN_MASK;
114
+ return 1;
115
+}
116
+
103117 static inline void IP_ECN_clear(struct iphdr *iph)
104118 {
105119 iph->tos &= ~INET_ECN_MASK;
....@@ -135,6 +149,22 @@
135149 return 1;
136150 }
137151
152
+static inline int IP6_ECN_set_ect1(struct sk_buff *skb, struct ipv6hdr *iph)
153
+{
154
+ __be32 from, to;
155
+
156
+ if ((ipv6_get_dsfield(iph) & INET_ECN_MASK) != INET_ECN_ECT_0)
157
+ return 0;
158
+
159
+ from = *(__be32 *)iph;
160
+ to = from ^ htonl(INET_ECN_MASK << 20);
161
+ *(__be32 *)iph = to;
162
+ if (skb->ip_summed == CHECKSUM_COMPLETE)
163
+ skb->csum = csum_add(csum_sub(skb->csum, (__force __wsum)from),
164
+ (__force __wsum)to);
165
+ return 1;
166
+}
167
+
138168 static inline void ipv6_copy_dscp(unsigned int dscp, struct ipv6hdr *inner)
139169 {
140170 dscp &= ~INET_ECN_MASK;
....@@ -154,6 +184,25 @@
154184 if (skb_network_header(skb) + sizeof(struct ipv6hdr) <=
155185 skb_tail_pointer(skb))
156186 return IP6_ECN_set_ce(skb, ipv6_hdr(skb));
187
+ break;
188
+ }
189
+
190
+ return 0;
191
+}
192
+
193
+static inline int INET_ECN_set_ect1(struct sk_buff *skb)
194
+{
195
+ switch (skb_protocol(skb, true)) {
196
+ case cpu_to_be16(ETH_P_IP):
197
+ if (skb_network_header(skb) + sizeof(struct iphdr) <=
198
+ skb_tail_pointer(skb))
199
+ return IP_ECN_set_ect1(ip_hdr(skb));
200
+ break;
201
+
202
+ case cpu_to_be16(ETH_P_IPV6):
203
+ if (skb_network_header(skb) + sizeof(struct ipv6hdr) <=
204
+ skb_tail_pointer(skb))
205
+ return IP6_ECN_set_ect1(skb, ipv6_hdr(skb));
157206 break;
158207 }
159208
....@@ -184,8 +233,7 @@
184233 * 1 if something is broken and should be logged (!!! above)
185234 * 2 if packet should be dropped
186235 */
187
-static inline int INET_ECN_decapsulate(struct sk_buff *skb,
188
- __u8 outer, __u8 inner)
236
+static inline int __INET_ECN_decapsulate(__u8 outer, __u8 inner, bool *set_ce)
189237 {
190238 if (INET_ECN_is_not_ect(inner)) {
191239 switch (outer & INET_ECN_MASK) {
....@@ -199,12 +247,27 @@
199247 }
200248 }
201249
202
- if (INET_ECN_is_ce(outer))
203
- INET_ECN_set_ce(skb);
204
-
250
+ *set_ce = INET_ECN_is_ce(outer);
205251 return 0;
206252 }
207253
254
+static inline int INET_ECN_decapsulate(struct sk_buff *skb,
255
+ __u8 outer, __u8 inner)
256
+{
257
+ bool set_ce = false;
258
+ int rc;
259
+
260
+ rc = __INET_ECN_decapsulate(outer, inner, &set_ce);
261
+ if (!rc) {
262
+ if (set_ce)
263
+ INET_ECN_set_ce(skb);
264
+ else if ((outer & INET_ECN_MASK) == INET_ECN_ECT_1)
265
+ INET_ECN_set_ect1(skb);
266
+ }
267
+
268
+ return rc;
269
+}
270
+
208271 static inline int IP_ECN_decapsulate(const struct iphdr *oiph,
209272 struct sk_buff *skb)
210273 {