]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/netfilter/nf_flow_table_ip.c
Merge tag 'acpi-5.6-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[linux.git] / net / netfilter / nf_flow_table_ip.c
index 7ea2ddc2aa930ced6efda1d02b2a1c5dc092966e..9e563fd3da0f88168f287fb171dbe3f52f54d41d 100644 (file)
@@ -144,11 +144,11 @@ static int nf_flow_nat_ip(const struct flow_offload *flow, struct sk_buff *skb,
 {
        struct iphdr *iph = ip_hdr(skb);
 
-       if (flow->flags & FLOW_OFFLOAD_SNAT &&
+       if (test_bit(NF_FLOW_SNAT, &flow->flags) &&
            (nf_flow_snat_port(flow, skb, thoff, iph->protocol, dir) < 0 ||
             nf_flow_snat_ip(flow, skb, iph, thoff, dir) < 0))
                return -1;
-       if (flow->flags & FLOW_OFFLOAD_DNAT &&
+       if (test_bit(NF_FLOW_DNAT, &flow->flags) &&
            (nf_flow_dnat_port(flow, skb, thoff, iph->protocol, dir) < 0 ||
             nf_flow_dnat_ip(flow, skb, iph, thoff, dir) < 0))
                return -1;
@@ -232,6 +232,13 @@ static unsigned int nf_flow_xmit_xfrm(struct sk_buff *skb,
        return NF_STOLEN;
 }
 
+static bool nf_flow_offload_refresh(struct nf_flowtable *flow_table,
+                                   struct flow_offload *flow)
+{
+       return nf_flowtable_hw_offload(flow_table) &&
+              test_and_clear_bit(NF_FLOW_HW_REFRESH, &flow->flags);
+}
+
 unsigned int
 nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
                        const struct nf_hook_state *state)
@@ -272,6 +279,9 @@ nf_flow_offload_ip_hook(void *priv, struct sk_buff *skb,
        if (nf_flow_state_check(flow, ip_hdr(skb)->protocol, skb, thoff))
                return NF_ACCEPT;
 
+       if (unlikely(nf_flow_offload_refresh(flow_table, flow)))
+               nf_flow_offload_add(flow_table, flow);
+
        if (nf_flow_offload_dst_check(&rt->dst)) {
                flow_offload_teardown(flow);
                return NF_ACCEPT;
@@ -414,11 +424,11 @@ static int nf_flow_nat_ipv6(const struct flow_offload *flow,
        struct ipv6hdr *ip6h = ipv6_hdr(skb);
        unsigned int thoff = sizeof(*ip6h);
 
-       if (flow->flags & FLOW_OFFLOAD_SNAT &&
+       if (test_bit(NF_FLOW_SNAT, &flow->flags) &&
            (nf_flow_snat_port(flow, skb, thoff, ip6h->nexthdr, dir) < 0 ||
             nf_flow_snat_ipv6(flow, skb, ip6h, thoff, dir) < 0))
                return -1;
-       if (flow->flags & FLOW_OFFLOAD_DNAT &&
+       if (test_bit(NF_FLOW_DNAT, &flow->flags) &&
            (nf_flow_dnat_port(flow, skb, thoff, ip6h->nexthdr, dir) < 0 ||
             nf_flow_dnat_ipv6(flow, skb, ip6h, thoff, dir) < 0))
                return -1;
@@ -498,6 +508,9 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
                                sizeof(*ip6h)))
                return NF_ACCEPT;
 
+       if (unlikely(nf_flow_offload_refresh(flow_table, flow)))
+               nf_flow_offload_add(flow_table, flow);
+
        if (nf_flow_offload_dst_check(&rt->dst)) {
                flow_offload_teardown(flow);
                return NF_ACCEPT;