hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/net/netfilter/utils.c
....@@ -17,16 +17,17 @@
1717 case CHECKSUM_COMPLETE:
1818 if (hook != NF_INET_PRE_ROUTING && hook != NF_INET_LOCAL_IN)
1919 break;
20
- if ((protocol == 0 && !csum_fold(skb->csum)) ||
20
+ if ((protocol != IPPROTO_TCP && protocol != IPPROTO_UDP &&
21
+ !csum_fold(skb->csum)) ||
2122 !csum_tcpudp_magic(iph->saddr, iph->daddr,
2223 skb->len - dataoff, protocol,
2324 skb->csum)) {
2425 skb->ip_summed = CHECKSUM_UNNECESSARY;
2526 break;
2627 }
27
- /* fall through */
28
+ fallthrough;
2829 case CHECKSUM_NONE:
29
- if (protocol == 0)
30
+ if (protocol != IPPROTO_TCP && protocol != IPPROTO_UDP)
3031 skb->csum = 0;
3132 else
3233 skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
....@@ -50,7 +51,7 @@
5051 case CHECKSUM_COMPLETE:
5152 if (len == skb->len - dataoff)
5253 return nf_ip_checksum(skb, hook, dataoff, protocol);
53
- /* fall through */
54
+ fallthrough;
5455 case CHECKSUM_NONE:
5556 skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr, protocol,
5657 skb->len - dataoff, 0);
....@@ -78,7 +79,7 @@
7879 skb->ip_summed = CHECKSUM_UNNECESSARY;
7980 break;
8081 }
81
- /* fall through */
82
+ fallthrough;
8283 case CHECKSUM_NONE:
8384 skb->csum = ~csum_unfold(
8485 csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
....@@ -105,7 +106,7 @@
105106 case CHECKSUM_COMPLETE:
106107 if (len == skb->len - dataoff)
107108 return nf_ip6_checksum(skb, hook, dataoff, protocol);
108
- /* fall through */
109
+ fallthrough;
109110 case CHECKSUM_NONE:
110111 hsum = skb_checksum(skb, 0, dataoff, 0);
111112 skb->csum = ~csum_unfold(csum_ipv6_magic(&ip6h->saddr,
....@@ -162,7 +163,7 @@
162163 int nf_route(struct net *net, struct dst_entry **dst, struct flowi *fl,
163164 bool strict, unsigned short family)
164165 {
165
- const struct nf_ipv6_ops *v6ops;
166
+ const struct nf_ipv6_ops *v6ops __maybe_unused;
166167 int ret = 0;
167168
168169 switch (family) {
....@@ -170,9 +171,7 @@
170171 ret = nf_ip_route(net, dst, fl, strict);
171172 break;
172173 case AF_INET6:
173
- v6ops = rcu_dereference(nf_ipv6_ops);
174
- if (v6ops)
175
- ret = v6ops->route(net, dst, fl, strict);
174
+ ret = nf_ip6_route(net, dst, fl, strict);
176175 break;
177176 }
178177
....@@ -180,6 +179,25 @@
180179 }
181180 EXPORT_SYMBOL_GPL(nf_route);
182181
182
+static int nf_ip_reroute(struct sk_buff *skb, const struct nf_queue_entry *entry)
183
+{
184
+#ifdef CONFIG_INET
185
+ const struct ip_rt_info *rt_info = nf_queue_entry_reroute(entry);
186
+
187
+ if (entry->state.hook == NF_INET_LOCAL_OUT) {
188
+ const struct iphdr *iph = ip_hdr(skb);
189
+
190
+ if (!(iph->tos == rt_info->tos &&
191
+ skb->mark == rt_info->mark &&
192
+ iph->daddr == rt_info->daddr &&
193
+ iph->saddr == rt_info->saddr))
194
+ return ip_route_me_harder(entry->state.net, entry->state.sk,
195
+ skb, RTN_UNSPEC);
196
+ }
197
+#endif
198
+ return 0;
199
+}
200
+
183201 int nf_reroute(struct sk_buff *skb, struct nf_queue_entry *entry)
184202 {
185203 const struct nf_ipv6_ops *v6ops;