|
@@ -1,9 +1,64 @@
|
|
|
+// SPDX-License-Identifier: GPL-2.0
|
|
|
#include <linux/kernel.h>
|
|
|
#include <linux/netfilter.h>
|
|
|
#include <linux/netfilter_ipv4.h>
|
|
|
#include <linux/netfilter_ipv6.h>
|
|
|
#include <net/netfilter/nf_queue.h>
|
|
|
|
|
|
+#ifdef CONFIG_INET
|
|
|
+__sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
|
|
|
+ unsigned int dataoff, u8 protocol)
|
|
|
+{
|
|
|
+ const struct iphdr *iph = ip_hdr(skb);
|
|
|
+ __sum16 csum = 0;
|
|
|
+
|
|
|
+ switch (skb->ip_summed) {
|
|
|
+ case CHECKSUM_COMPLETE:
|
|
|
+ if (hook != NF_INET_PRE_ROUTING && hook != NF_INET_LOCAL_IN)
|
|
|
+ break;
|
|
|
+ if ((protocol == 0 && !csum_fold(skb->csum)) ||
|
|
|
+ !csum_tcpudp_magic(iph->saddr, iph->daddr,
|
|
|
+ skb->len - dataoff, protocol,
|
|
|
+ skb->csum)) {
|
|
|
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ /* fall through */
|
|
|
+ case CHECKSUM_NONE:
|
|
|
+ if (protocol == 0)
|
|
|
+ skb->csum = 0;
|
|
|
+ else
|
|
|
+ skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr,
|
|
|
+ skb->len - dataoff,
|
|
|
+ protocol, 0);
|
|
|
+ csum = __skb_checksum_complete(skb);
|
|
|
+ }
|
|
|
+ return csum;
|
|
|
+}
|
|
|
+EXPORT_SYMBOL(nf_ip_checksum);
|
|
|
+#endif
|
|
|
+
|
|
|
+static __sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook,
|
|
|
+ unsigned int dataoff, unsigned int len,
|
|
|
+ u8 protocol)
|
|
|
+{
|
|
|
+ const struct iphdr *iph = ip_hdr(skb);
|
|
|
+ __sum16 csum = 0;
|
|
|
+
|
|
|
+ switch (skb->ip_summed) {
|
|
|
+ case CHECKSUM_COMPLETE:
|
|
|
+ if (len == skb->len - dataoff)
|
|
|
+ return nf_ip_checksum(skb, hook, dataoff, protocol);
|
|
|
+ /* fall through */
|
|
|
+ case CHECKSUM_NONE:
|
|
|
+ skb->csum = csum_tcpudp_nofold(iph->saddr, iph->daddr, protocol,
|
|
|
+ skb->len - dataoff, 0);
|
|
|
+ skb->ip_summed = CHECKSUM_NONE;
|
|
|
+ return __skb_checksum_complete_head(skb, dataoff + len);
|
|
|
+ }
|
|
|
+ return csum;
|
|
|
+}
|
|
|
+
|
|
|
__sum16 nf_checksum(struct sk_buff *skb, unsigned int hook,
|
|
|
unsigned int dataoff, u_int8_t protocol,
|
|
|
unsigned short family)
|