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: Xin Long <lucien.xin@gmail.com>
Reviewed-by: Simon Horman <simon.horman@corigine.com>
Reviewed-by: Aaron Conole <aconole@redhat.com>
Acked-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Xin Long 2023-02-07 17:52:07 -05:00 committed by Jakub Kicinski
parent c0c3ab63de
commit 67fc5d7ffb
4 changed files with 33 additions and 58 deletions

View File

@ -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);
}
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_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))

View File

@ -102,3 +102,29 @@ int nf_ct_add_helper(struct nf_conn *ct, const char *name, u8 family,
return ret;
}
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);

View File

@ -1091,36 +1091,6 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key,
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
* value if 'skb' is freed.
*/
@ -1135,9 +1105,11 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb,
nh_ofs = skb_network_offset(skb);
skb_pull_rcsum(skb, nh_ofs);
err = ovs_skb_network_trim(skb);
if (err)
err = nf_ct_skb_network_trim(skb, info->family);
if (err) {
kfree_skb(skb);
return err;
}
if (key->ip.frag != OVS_FRAG_TYPE_NONE) {
err = handle_fragments(net, key, info->zone.id, skb);

View File

@ -726,31 +726,6 @@ drop_ct:
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)
{
u8 family = NFPROTO_UNSPEC;
@ -1011,7 +986,7 @@ TC_INDIRECT_SCOPE int tcf_ct_act(struct sk_buff *skb, const struct tc_action *a,
if (err)
goto drop;
err = tcf_ct_skb_network_trim(skb, family);
err = nf_ct_skb_network_trim(skb, family);
if (err)
goto drop;