mirror of
https://github.com/tbsdtv/linux_media.git
synced 2025-07-23 12:43:29 +02:00
net: create nf_conntrack_ovs for ovs and tc use
Similar to nf_nat_ovs created by Commit ebddb14049
("net: move the
nat function to nf_nat_ovs for ovs and tc"), this patch is to create
nf_conntrack_ovs to get these functions shared by OVS and TC only.
There are nf_ct_helper() and nf_ct_add_helper() from nf_conntrak_helper
in this patch, and will be more in the following patches.
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:
@@ -189,6 +189,9 @@ config NF_CONNTRACK_LABELS
|
|||||||
to connection tracking entries. It can be used with xtables connlabel
|
to connection tracking entries. It can be used with xtables connlabel
|
||||||
match and the nftables ct expression.
|
match and the nftables ct expression.
|
||||||
|
|
||||||
|
config NF_CONNTRACK_OVS
|
||||||
|
bool
|
||||||
|
|
||||||
config NF_CT_PROTO_DCCP
|
config NF_CT_PROTO_DCCP
|
||||||
bool 'DCCP protocol connection tracking support'
|
bool 'DCCP protocol connection tracking support'
|
||||||
depends on NETFILTER_ADVANCED
|
depends on NETFILTER_ADVANCED
|
||||||
|
@@ -11,6 +11,7 @@ nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMEOUT) += nf_conntrack_timeout.o
|
|||||||
nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMESTAMP) += nf_conntrack_timestamp.o
|
nf_conntrack-$(CONFIG_NF_CONNTRACK_TIMESTAMP) += nf_conntrack_timestamp.o
|
||||||
nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o
|
nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o
|
||||||
nf_conntrack-$(CONFIG_NF_CONNTRACK_LABELS) += nf_conntrack_labels.o
|
nf_conntrack-$(CONFIG_NF_CONNTRACK_LABELS) += nf_conntrack_labels.o
|
||||||
|
nf_conntrack-$(CONFIG_NF_CONNTRACK_OVS) += nf_conntrack_ovs.o
|
||||||
nf_conntrack-$(CONFIG_NF_CT_PROTO_DCCP) += nf_conntrack_proto_dccp.o
|
nf_conntrack-$(CONFIG_NF_CT_PROTO_DCCP) += nf_conntrack_proto_dccp.o
|
||||||
nf_conntrack-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o
|
nf_conntrack-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o
|
||||||
nf_conntrack-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o
|
nf_conntrack-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o
|
||||||
|
@@ -242,104 +242,6 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(__nf_ct_try_assign_helper);
|
EXPORT_SYMBOL_GPL(__nf_ct_try_assign_helper);
|
||||||
|
|
||||||
/* 'skb' should already be pulled to nh_ofs. */
|
|
||||||
int nf_ct_helper(struct sk_buff *skb, struct nf_conn *ct,
|
|
||||||
enum ip_conntrack_info ctinfo, u16 proto)
|
|
||||||
{
|
|
||||||
const struct nf_conntrack_helper *helper;
|
|
||||||
const struct nf_conn_help *help;
|
|
||||||
unsigned int protoff;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if (ctinfo == IP_CT_RELATED_REPLY)
|
|
||||||
return NF_ACCEPT;
|
|
||||||
|
|
||||||
help = nfct_help(ct);
|
|
||||||
if (!help)
|
|
||||||
return NF_ACCEPT;
|
|
||||||
|
|
||||||
helper = rcu_dereference(help->helper);
|
|
||||||
if (!helper)
|
|
||||||
return NF_ACCEPT;
|
|
||||||
|
|
||||||
if (helper->tuple.src.l3num != NFPROTO_UNSPEC &&
|
|
||||||
helper->tuple.src.l3num != proto)
|
|
||||||
return NF_ACCEPT;
|
|
||||||
|
|
||||||
switch (proto) {
|
|
||||||
case NFPROTO_IPV4:
|
|
||||||
protoff = ip_hdrlen(skb);
|
|
||||||
proto = ip_hdr(skb)->protocol;
|
|
||||||
break;
|
|
||||||
case NFPROTO_IPV6: {
|
|
||||||
u8 nexthdr = ipv6_hdr(skb)->nexthdr;
|
|
||||||
__be16 frag_off;
|
|
||||||
int ofs;
|
|
||||||
|
|
||||||
ofs = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr,
|
|
||||||
&frag_off);
|
|
||||||
if (ofs < 0 || (frag_off & htons(~0x7)) != 0) {
|
|
||||||
pr_debug("proto header not found\n");
|
|
||||||
return NF_ACCEPT;
|
|
||||||
}
|
|
||||||
protoff = ofs;
|
|
||||||
proto = nexthdr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
WARN_ONCE(1, "helper invoked on non-IP family!");
|
|
||||||
return NF_DROP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (helper->tuple.dst.protonum != proto)
|
|
||||||
return NF_ACCEPT;
|
|
||||||
|
|
||||||
err = helper->help(skb, protoff, ct, ctinfo);
|
|
||||||
if (err != NF_ACCEPT)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
/* Adjust seqs after helper. This is needed due to some helpers (e.g.,
|
|
||||||
* FTP with NAT) adusting the TCP payload size when mangling IP
|
|
||||||
* addresses and/or port numbers in the text-based control connection.
|
|
||||||
*/
|
|
||||||
if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) &&
|
|
||||||
!nf_ct_seq_adjust(skb, ct, ctinfo, protoff))
|
|
||||||
return NF_DROP;
|
|
||||||
return NF_ACCEPT;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(nf_ct_helper);
|
|
||||||
|
|
||||||
int nf_ct_add_helper(struct nf_conn *ct, const char *name, u8 family,
|
|
||||||
u8 proto, bool nat, struct nf_conntrack_helper **hp)
|
|
||||||
{
|
|
||||||
struct nf_conntrack_helper *helper;
|
|
||||||
struct nf_conn_help *help;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
helper = nf_conntrack_helper_try_module_get(name, family, proto);
|
|
||||||
if (!helper)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
help = nf_ct_helper_ext_add(ct, GFP_KERNEL);
|
|
||||||
if (!help) {
|
|
||||||
nf_conntrack_helper_put(helper);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
#if IS_ENABLED(CONFIG_NF_NAT)
|
|
||||||
if (nat) {
|
|
||||||
ret = nf_nat_helper_try_module_get(name, family, proto);
|
|
||||||
if (ret) {
|
|
||||||
nf_conntrack_helper_put(helper);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
rcu_assign_pointer(help->helper, helper);
|
|
||||||
*hp = helper;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(nf_ct_add_helper);
|
|
||||||
|
|
||||||
/* appropriate ct lock protecting must be taken by caller */
|
/* appropriate ct lock protecting must be taken by caller */
|
||||||
static int unhelp(struct nf_conn *ct, void *me)
|
static int unhelp(struct nf_conn *ct, void *me)
|
||||||
{
|
{
|
||||||
|
104
net/netfilter/nf_conntrack_ovs.c
Normal file
104
net/netfilter/nf_conntrack_ovs.c
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/* Support ct functions for openvswitch and used by OVS and TC conntrack. */
|
||||||
|
|
||||||
|
#include <net/netfilter/nf_conntrack_helper.h>
|
||||||
|
#include <net/netfilter/nf_conntrack_seqadj.h>
|
||||||
|
#include <net/ip.h>
|
||||||
|
|
||||||
|
/* 'skb' should already be pulled to nh_ofs. */
|
||||||
|
int nf_ct_helper(struct sk_buff *skb, struct nf_conn *ct,
|
||||||
|
enum ip_conntrack_info ctinfo, u16 proto)
|
||||||
|
{
|
||||||
|
const struct nf_conntrack_helper *helper;
|
||||||
|
const struct nf_conn_help *help;
|
||||||
|
unsigned int protoff;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (ctinfo == IP_CT_RELATED_REPLY)
|
||||||
|
return NF_ACCEPT;
|
||||||
|
|
||||||
|
help = nfct_help(ct);
|
||||||
|
if (!help)
|
||||||
|
return NF_ACCEPT;
|
||||||
|
|
||||||
|
helper = rcu_dereference(help->helper);
|
||||||
|
if (!helper)
|
||||||
|
return NF_ACCEPT;
|
||||||
|
|
||||||
|
if (helper->tuple.src.l3num != NFPROTO_UNSPEC &&
|
||||||
|
helper->tuple.src.l3num != proto)
|
||||||
|
return NF_ACCEPT;
|
||||||
|
|
||||||
|
switch (proto) {
|
||||||
|
case NFPROTO_IPV4:
|
||||||
|
protoff = ip_hdrlen(skb);
|
||||||
|
proto = ip_hdr(skb)->protocol;
|
||||||
|
break;
|
||||||
|
case NFPROTO_IPV6: {
|
||||||
|
u8 nexthdr = ipv6_hdr(skb)->nexthdr;
|
||||||
|
__be16 frag_off;
|
||||||
|
int ofs;
|
||||||
|
|
||||||
|
ofs = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr,
|
||||||
|
&frag_off);
|
||||||
|
if (ofs < 0 || (frag_off & htons(~0x7)) != 0) {
|
||||||
|
pr_debug("proto header not found\n");
|
||||||
|
return NF_ACCEPT;
|
||||||
|
}
|
||||||
|
protoff = ofs;
|
||||||
|
proto = nexthdr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
WARN_ONCE(1, "helper invoked on non-IP family!");
|
||||||
|
return NF_DROP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (helper->tuple.dst.protonum != proto)
|
||||||
|
return NF_ACCEPT;
|
||||||
|
|
||||||
|
err = helper->help(skb, protoff, ct, ctinfo);
|
||||||
|
if (err != NF_ACCEPT)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
/* Adjust seqs after helper. This is needed due to some helpers (e.g.,
|
||||||
|
* FTP with NAT) adusting the TCP payload size when mangling IP
|
||||||
|
* addresses and/or port numbers in the text-based control connection.
|
||||||
|
*/
|
||||||
|
if (test_bit(IPS_SEQ_ADJUST_BIT, &ct->status) &&
|
||||||
|
!nf_ct_seq_adjust(skb, ct, ctinfo, protoff))
|
||||||
|
return NF_DROP;
|
||||||
|
return NF_ACCEPT;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(nf_ct_helper);
|
||||||
|
|
||||||
|
int nf_ct_add_helper(struct nf_conn *ct, const char *name, u8 family,
|
||||||
|
u8 proto, bool nat, struct nf_conntrack_helper **hp)
|
||||||
|
{
|
||||||
|
struct nf_conntrack_helper *helper;
|
||||||
|
struct nf_conn_help *help;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
helper = nf_conntrack_helper_try_module_get(name, family, proto);
|
||||||
|
if (!helper)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
help = nf_ct_helper_ext_add(ct, GFP_KERNEL);
|
||||||
|
if (!help) {
|
||||||
|
nf_conntrack_helper_put(helper);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
#if IS_ENABLED(CONFIG_NF_NAT)
|
||||||
|
if (nat) {
|
||||||
|
ret = nf_nat_helper_try_module_get(name, family, proto);
|
||||||
|
if (ret) {
|
||||||
|
nf_conntrack_helper_put(helper);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
rcu_assign_pointer(help->helper, helper);
|
||||||
|
*hp = helper;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(nf_ct_add_helper);
|
@@ -15,6 +15,7 @@ config OPENVSWITCH
|
|||||||
select NET_MPLS_GSO
|
select NET_MPLS_GSO
|
||||||
select DST_CACHE
|
select DST_CACHE
|
||||||
select NET_NSH
|
select NET_NSH
|
||||||
|
select NF_CONNTRACK_OVS if NF_CONNTRACK
|
||||||
select NF_NAT_OVS if NF_NAT
|
select NF_NAT_OVS if NF_NAT
|
||||||
help
|
help
|
||||||
Open vSwitch is a multilayer Ethernet switch targeted at virtualized
|
Open vSwitch is a multilayer Ethernet switch targeted at virtualized
|
||||||
|
@@ -984,6 +984,7 @@ config NET_ACT_TUNNEL_KEY
|
|||||||
config NET_ACT_CT
|
config NET_ACT_CT
|
||||||
tristate "connection tracking tc action"
|
tristate "connection tracking tc action"
|
||||||
depends on NET_CLS_ACT && NF_CONNTRACK && (!NF_NAT || NF_NAT) && NF_FLOW_TABLE
|
depends on NET_CLS_ACT && NF_CONNTRACK && (!NF_NAT || NF_NAT) && NF_FLOW_TABLE
|
||||||
|
select NF_CONNTRACK_OVS
|
||||||
select NF_NAT_OVS if NF_NAT
|
select NF_NAT_OVS if NF_NAT
|
||||||
help
|
help
|
||||||
Say Y here to allow sending the packets to conntrack module.
|
Say Y here to allow sending the packets to conntrack module.
|
||||||
|
Reference in New Issue
Block a user