.. | .. |
---|
100 | 100 | return 1; |
---|
101 | 101 | } |
---|
102 | 102 | |
---|
| 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 | + |
---|
103 | 117 | static inline void IP_ECN_clear(struct iphdr *iph) |
---|
104 | 118 | { |
---|
105 | 119 | iph->tos &= ~INET_ECN_MASK; |
---|
.. | .. |
---|
135 | 149 | return 1; |
---|
136 | 150 | } |
---|
137 | 151 | |
---|
| 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 | + |
---|
138 | 168 | static inline void ipv6_copy_dscp(unsigned int dscp, struct ipv6hdr *inner) |
---|
139 | 169 | { |
---|
140 | 170 | dscp &= ~INET_ECN_MASK; |
---|
.. | .. |
---|
154 | 184 | if (skb_network_header(skb) + sizeof(struct ipv6hdr) <= |
---|
155 | 185 | skb_tail_pointer(skb)) |
---|
156 | 186 | 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)); |
---|
157 | 206 | break; |
---|
158 | 207 | } |
---|
159 | 208 | |
---|
.. | .. |
---|
184 | 233 | * 1 if something is broken and should be logged (!!! above) |
---|
185 | 234 | * 2 if packet should be dropped |
---|
186 | 235 | */ |
---|
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) |
---|
189 | 237 | { |
---|
190 | 238 | if (INET_ECN_is_not_ect(inner)) { |
---|
191 | 239 | switch (outer & INET_ECN_MASK) { |
---|
.. | .. |
---|
199 | 247 | } |
---|
200 | 248 | } |
---|
201 | 249 | |
---|
202 | | - if (INET_ECN_is_ce(outer)) |
---|
203 | | - INET_ECN_set_ce(skb); |
---|
204 | | - |
---|
| 250 | + *set_ce = INET_ECN_is_ce(outer); |
---|
205 | 251 | return 0; |
---|
206 | 252 | } |
---|
207 | 253 | |
---|
| 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 | + |
---|
208 | 271 | static inline int IP_ECN_decapsulate(const struct iphdr *oiph, |
---|
209 | 272 | struct sk_buff *skb) |
---|
210 | 273 | { |
---|