Commit 67fc5d7f authored by Xin Long's avatar Xin Long Committed by Jakub Kicinski

net: extract nf_ct_skb_network_trim function to nf_conntrack_ovs

There are almost the same code in ovs_skb_network_trim() and
tcf_ct_skb_network_trim(), this patch extracts them into a function
nf_ct_skb_network_trim() and moves the function to nf_conntrack_ovs.
Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
Reviewed-by: default avatarSimon Horman <simon.horman@corigine.com>
Reviewed-by: default avatarAaron Conole <aconole@redhat.com>
Acked-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent c0c3ab63
...@@ -362,6 +362,8 @@ static inline struct nf_conntrack_net *nf_ct_pernet(const struct net *net) ...@@ -362,6 +362,8 @@ static inline struct nf_conntrack_net *nf_ct_pernet(const struct net *net)
return net_generic(net, nf_conntrack_net_id); return net_generic(net, nf_conntrack_net_id);
} }
int nf_ct_skb_network_trim(struct sk_buff *skb, int family);
#define NF_CT_STAT_INC(net, count) __this_cpu_inc((net)->ct.stat->count) #define NF_CT_STAT_INC(net, count) __this_cpu_inc((net)->ct.stat->count)
#define NF_CT_STAT_INC_ATOMIC(net, count) this_cpu_inc((net)->ct.stat->count) #define NF_CT_STAT_INC_ATOMIC(net, count) this_cpu_inc((net)->ct.stat->count)
#define NF_CT_STAT_ADD_ATOMIC(net, count, v) this_cpu_add((net)->ct.stat->count, (v)) #define NF_CT_STAT_ADD_ATOMIC(net, count, v) this_cpu_add((net)->ct.stat->count, (v))
......
...@@ -102,3 +102,29 @@ int nf_ct_add_helper(struct nf_conn *ct, const char *name, u8 family, ...@@ -102,3 +102,29 @@ int nf_ct_add_helper(struct nf_conn *ct, const char *name, u8 family,
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(nf_ct_add_helper); EXPORT_SYMBOL_GPL(nf_ct_add_helper);
/* Trim the skb to the length specified by the IP/IPv6 header,
* removing any trailing lower-layer padding. This prepares the skb
* for higher-layer processing that assumes skb->len excludes padding
* (such as nf_ip_checksum). The caller needs to pull the skb to the
* network header, and ensure ip_hdr/ipv6_hdr points to valid data.
*/
int nf_ct_skb_network_trim(struct sk_buff *skb, int family)
{
unsigned int len;
switch (family) {
case NFPROTO_IPV4:
len = skb_ip_totlen(skb);
break;
case NFPROTO_IPV6:
len = sizeof(struct ipv6hdr)
+ ntohs(ipv6_hdr(skb)->payload_len);
break;
default:
len = skb->len;
}
return pskb_trim_rcsum(skb, len);
}
EXPORT_SYMBOL_GPL(nf_ct_skb_network_trim);
...@@ -1091,36 +1091,6 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key, ...@@ -1091,36 +1091,6 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key,
return 0; return 0;
} }
/* Trim the skb to the length specified by the IP/IPv6 header,
* removing any trailing lower-layer padding. This prepares the skb
* for higher-layer processing that assumes skb->len excludes padding
* (such as nf_ip_checksum). The caller needs to pull the skb to the
* network header, and ensure ip_hdr/ipv6_hdr points to valid data.
*/
static int ovs_skb_network_trim(struct sk_buff *skb)
{
unsigned int len;
int err;
switch (skb->protocol) {
case htons(ETH_P_IP):
len = skb_ip_totlen(skb);
break;
case htons(ETH_P_IPV6):
len = sizeof(struct ipv6hdr)
+ ntohs(ipv6_hdr(skb)->payload_len);
break;
default:
len = skb->len;
}
err = pskb_trim_rcsum(skb, len);
if (err)
kfree_skb(skb);
return err;
}
/* Returns 0 on success, -EINPROGRESS if 'skb' is stolen, or other nonzero /* Returns 0 on success, -EINPROGRESS if 'skb' is stolen, or other nonzero
* value if 'skb' is freed. * value if 'skb' is freed.
*/ */
...@@ -1135,9 +1105,11 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb, ...@@ -1135,9 +1105,11 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb,
nh_ofs = skb_network_offset(skb); nh_ofs = skb_network_offset(skb);
skb_pull_rcsum(skb, nh_ofs); skb_pull_rcsum(skb, nh_ofs);
err = ovs_skb_network_trim(skb); err = nf_ct_skb_network_trim(skb, info->family);
if (err) if (err) {
kfree_skb(skb);
return err; return err;
}
if (key->ip.frag != OVS_FRAG_TYPE_NONE) { if (key->ip.frag != OVS_FRAG_TYPE_NONE) {
err = handle_fragments(net, key, info->zone.id, skb); err = handle_fragments(net, key, info->zone.id, skb);
......
...@@ -726,31 +726,6 @@ static bool tcf_ct_skb_nfct_cached(struct net *net, struct sk_buff *skb, ...@@ -726,31 +726,6 @@ static bool tcf_ct_skb_nfct_cached(struct net *net, struct sk_buff *skb,
return false; return false;
} }
/* Trim the skb to the length specified by the IP/IPv6 header,
* removing any trailing lower-layer padding. This prepares the skb
* for higher-layer processing that assumes skb->len excludes padding
* (such as nf_ip_checksum). The caller needs to pull the skb to the
* network header, and ensure ip_hdr/ipv6_hdr points to valid data.
*/
static int tcf_ct_skb_network_trim(struct sk_buff *skb, int family)
{
unsigned int len;
switch (family) {
case NFPROTO_IPV4:
len = skb_ip_totlen(skb);
break;
case NFPROTO_IPV6:
len = sizeof(struct ipv6hdr)
+ ntohs(ipv6_hdr(skb)->payload_len);
break;
default:
len = skb->len;
}
return pskb_trim_rcsum(skb, len);
}
static u8 tcf_ct_skb_nf_family(struct sk_buff *skb) static u8 tcf_ct_skb_nf_family(struct sk_buff *skb)
{ {
u8 family = NFPROTO_UNSPEC; u8 family = NFPROTO_UNSPEC;
...@@ -1011,7 +986,7 @@ TC_INDIRECT_SCOPE int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a, ...@@ -1011,7 +986,7 @@ TC_INDIRECT_SCOPE int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
if (err) if (err)
goto drop; goto drop;
err = tcf_ct_skb_network_trim(skb, family); err = nf_ct_skb_network_trim(skb, family);
if (err) if (err)
goto drop; goto drop;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment