Thanks, I'll take a look.
On Mon, Apr 1, 2019 at 11:23 AM Gregory Rose <[email protected]> wrote: > > > > On 3/29/2019 4:01 PM, Yifeng Sun wrote: > > Hi Greg, > > > > I tried 4.20.17 on 16.04 and it is still working. > > Do you mind sharing your .config file? Maybe there is some config > > differences between our test machines? > > Hmm... well, I poked around a bit but I'm still getting the issue with > no obvious solution. I've attached my > config file. > > Thanks, > > - Greg > > > Thanks, > > Yifeng > > > > On Fri, Mar 29, 2019 at 3:28 PM Gregory Rose <[email protected]> wrote: > >> > >> > >> On 3/29/2019 3:16 PM, Yifeng Sun wrote: > >>> Hi Greg, I tried new kernel 4.20.17 on ubuntu 8.10 but everything works > >>> fine. > >>> Do you mind telling me what Linux were you using? > >>> > >>> Thanks, > >>> Yifeng > >> It was a Ubuntu Xenial 16.04 with the custom built 4.20.17 kernel from > >> kernel.org. I'm not sure what difference > >> that should make though. > >> > >> - Greg > >> > >>> On Fri, Mar 29, 2019 at 9:21 AM Yifeng Sun <[email protected]> wrote: > >>>> Hi Greg, thanks for the review. I will check on it. > >>>> Yifeng > >>>> > >>>> On Fri, Mar 29, 2019 at 8:19 AM Gregory Rose <[email protected]> > >>>> wrote: > >>>>> On 3/15/2019 7:20 PM, Yifeng Sun wrote: > >>>>>> This patch introduces changes needed by OVS to support latest > >>>>>> Linux kernels (4.19.x and 4.20.x). Recent kernels changed many > >>>>>> APIs used by OVS. One major change is that struct nf_conntrack_l3proto > >>>>>> became unvisible outside of kernel, so the needed get_l4proto > >>>>>> function is added in file compact/nf_conntrack_core.c to > >>>>>> accommodate this issue. > >>>>>> > >>>>>> This patch doesn't introduce new failed tests when running > >>>>>> 'make check-kmod' for kernels listed below: > >>>>>> 3.10.0-957.5.1.el7.x86_64 > >>>>>> 4.4.0-142-generic > >>>>>> 4.17.14 > >>>>>> 4.18.0-16-generic > >>>>>> 4.19.26 > >>>>>> 4.20.13 > >>>>>> > >>>>>> Travis passed at > >>>>>> https://travis-ci.org/yifsun/ovs-travis/builds/507034016 > >>>>> Hi Yifeng, > >>>>> > >>>>> thanks for doing this work! However, I am seeing an issue when > >>>>> compiling on 4.20.17 and then installing > >>>>> the kernel modules: > >>>>> > >>>>> make -C /lib/modules/4.20.17/build > >>>>> M=/home/gvrose/prj/ovs-experimental/_build/datapath/linux > >>>>> modules_install > >>>>> make[2]: Entering directory '/home/gvrose/prj/linux-4.20.17' > >>>>> INSTALL > >>>>> /home/gvrose/prj/ovs-experimental/_build/datapath/linux/openvswitch.ko > >>>>> INSTALL > >>>>> /home/gvrose/prj/ovs-experimental/_build/datapath/linux/vport-geneve.ko > >>>>> INSTALL > >>>>> /home/gvrose/prj/ovs-experimental/_build/datapath/linux/vport-gre.ko > >>>>> INSTALL > >>>>> /home/gvrose/prj/ovs-experimental/_build/datapath/linux/vport-lisp.ko > >>>>> INSTALL > >>>>> /home/gvrose/prj/ovs-experimental/_build/datapath/linux/vport-stt.ko > >>>>> INSTALL > >>>>> /home/gvrose/prj/ovs-experimental/_build/datapath/linux/vport-vxlan.ko > >>>>> DEPMOD 4.20.17 > >>>>> depmod: WARNING: /lib/modules/4.20.17/extra/vport-lisp.ko needs unknown > >>>>> symbol rpl_rtnl_delete_link > >>>>> depmod: WARNING: /lib/modules/4.20.17/extra/vport-lisp.ko needs unknown > >>>>> symbol rpl_lisp_xmit > >>>>> depmod: WARNING: /lib/modules/4.20.17/extra/vport-lisp.ko needs unknown > >>>>> symbol rpl_lisp_dev_create_fb > >>>>> depmod: WARNING: /lib/modules/4.20.17/extra/vport-stt.ko needs unknown > >>>>> symbol rpl_rtnl_delete_link > >>>>> depmod: WARNING: /lib/modules/4.20.17/extra/vport-stt.ko needs unknown > >>>>> symbol ovs_stt_dev_create_fb > >>>>> depmod: WARNING: /lib/modules/4.20.17/extra/vport-stt.ko needs unknown > >>>>> symbol ovs_stt_xmit > >>>>> make[2]: Leaving directory '/home/gvrose/prj/linux-4.20.17' > >>>>> > >>>>> Could you check that? Maybe there were changes from 4.20.13 to 4.20.17? > >>>>> > >>>>> Thanks, > >>>>> > >>>>> - Greg > >>>>> > >>>>>> Signed-off-by: Yifeng Sun <[email protected]> > >>>>>> --- > >>>>>> .travis.yml | 2 + > >>>>>> NEWS | 2 + > >>>>>> acinclude.m4 | 20 ++++- > >>>>>> datapath/conntrack.c | 72 > >>>>>> ++++++++++++++++- > >>>>>> .../include/net/netfilter/nf_conntrack_core.h | 6 ++ > >>>>>> .../net/netfilter/nf_conntrack_count.h | 2 + > >>>>>> datapath/linux/compat/nf_conncount.c | 6 +- > >>>>>> datapath/linux/compat/nf_conntrack_core.c | 80 > >>>>>> +++++++++++++++++++ > >>>>>> datapath/linux/compat/nf_conntrack_proto.c | 3 + > >>>>>> 9 files changed, 186 insertions(+), 7 deletions(-) > >>>>>> > >>>>>> diff --git a/.travis.yml b/.travis.yml > >>>>>> index 32d5f1918..dc7a20b6e 100644 > >>>>>> --- a/.travis.yml > >>>>>> +++ b/.travis.yml > >>>>>> @@ -35,6 +35,8 @@ env: > >>>>>> - KERNEL=3.16.54 TESTSUITE=1 DPDK=1 > >>>>>> - KERNEL=3.16.54 DPDK_SHARED=1 > >>>>>> - KERNEL=3.16.54 DPDK_SHARED=1 OPTS="--enable-shared" > >>>>>> + - KERNEL=4.20.16 > >>>>>> + - KERNEL=4.19.29 > >>>>>> - KERNEL=4.18.20 > >>>>>> - KERNEL=4.17.19 > >>>>>> - KERNEL=4.16.18 > >>>>>> diff --git a/NEWS b/NEWS > >>>>>> index 1e4744dbd..af5b5222f 100644 > >>>>>> --- a/NEWS > >>>>>> +++ b/NEWS > >>>>>> @@ -25,6 +25,8 @@ Post-v2.11.0 > >>>>>> - OVN: > >>>>>> * Select IPAM mac_prefix in a random manner if not provided > >>>>>> by the user > >>>>>> - New QoS type "linux-netem" on Linux. > >>>>>> + - Linux datapath: > >>>>>> + * Support for the kernel versions 4.19.x, 4.20.x. > >>>>>> > >>>>>> v2.11.0 - 19 Feb 2019 > >>>>>> --------------------- > >>>>>> diff --git a/acinclude.m4 b/acinclude.m4 > >>>>>> index 3cd6ea730..7b11b7740 100644 > >>>>>> --- a/acinclude.m4 > >>>>>> +++ b/acinclude.m4 > >>>>>> @@ -151,10 +151,10 @@ AC_DEFUN([OVS_CHECK_LINUX], [ > >>>>>> AC_MSG_RESULT([$kversion]) > >>>>>> > >>>>>> if test "$version" -ge 4; then > >>>>>> - if test "$version" = 4 && test "$patchlevel" -le 18; then > >>>>>> + if test "$version" = 4 && test "$patchlevel" -le 20; then > >>>>>> : # Linux 4.x > >>>>>> else > >>>>>> - AC_ERROR([Linux kernel in $KBUILD is version $kversion, but > >>>>>> version newer than 4.18.x is not supported (please refer to the FAQ > >>>>>> for advice)]) > >>>>>> + AC_ERROR([Linux kernel in $KBUILD is version $kversion, but > >>>>>> version newer than 4.20.x is not supported (please refer to the FAQ > >>>>>> for advice)]) > >>>>>> fi > >>>>>> elif test "$version" = 3 && test "$patchlevel" -ge 10; then > >>>>>> : # Linux 3.x > >>>>>> @@ -583,6 +583,22 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ > >>>>>> [OVS_DEFINE([HAVE_VOID_INET_FRAGS_INIT])]) > >>>>>> OVS_GREP_IFELSE([$KSRC/include/net/inetpeer.h], [vif], > >>>>>> [OVS_DEFINE([HAVE_INETPEER_VIF_SUPPORT])]) > >>>>>> + > >>>>>> OVS_FIND_PARAM_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_helper.h], > >>>>>> + [nf_ct_helper_ext_add], [nf_conntrack_helper], > >>>>>> + > >>>>>> [OVS_DEFINE([HAVE_NF_CT_HELPER_EXT_ADD_TAKES_HELPER])]) > >>>>>> + > >>>>>> OVS_FIND_PARAM_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_core.h], > >>>>>> + [nf_ct_invert_tuple], [l3proto], > >>>>>> + > >>>>>> [OVS_DEFINE([HAVE_NF_CT_INVERT_TUPLE_TAKES_L3PROTO])]) > >>>>>> + OVS_GREP_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_core.h], > >>>>>> [nf_ct_get_tuple], > >>>>>> + [OVS_DEFINE([HAVE_NF_CT_GET_TUPLE])]) > >>>>>> + > >>>>>> OVS_FIND_PARAM_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_core.h], > >>>>>> + [nf_conntrack_in], [net], > >>>>>> + > >>>>>> [OVS_DEFINE([HAVE_NF_CONNTRACK_IN_TAKES_NET])]) > >>>>>> + OVS_GREP_IFELSE([$KSRC/include/net/ipv6_frag.h], > >>>>>> [IP6_DEFRAG_CONNTRACK_IN], > >>>>>> + [OVS_DEFINE([HAVE_IPV6_FRAG_H])]) > >>>>>> + > >>>>>> OVS_FIND_PARAM_IFELSE([$KSRC/include/net/netfilter/nf_conntrack_l4proto.h], > >>>>>> + [__nf_ct_l4proto_find], [l3proto], > >>>>>> + > >>>>>> [OVS_DEFINE([HAVE_NF_CT_L4PROTO_FIND_TAKES_L3PROTO])]) > >>>>>> > >>>>>> dnl Check for dst_cache and ipv6 lable to use backported tunnel > >>>>>> infrastructure. > >>>>>> dnl OVS does not really need ipv6 label field, but its presence > >>>>>> signifies that > >>>>>> diff --git a/datapath/conntrack.c b/datapath/conntrack.c > >>>>>> index a7dc9e0c3..b9b79e2cc 100644 > >>>>>> --- a/datapath/conntrack.c > >>>>>> +++ b/datapath/conntrack.c > >>>>>> @@ -38,6 +38,10 @@ > >>>>>> #include <net/netfilter/nf_nat_l3proto.h> > >>>>>> #endif > >>>>>> > >>>>>> +#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) && defined(HAVE_IPV6_FRAG_H) > >>>>>> +#include <net/ipv6_frag.h> > >>>>>> +#endif > >>>>>> + > >>>>>> #include "datapath.h" > >>>>>> #include "conntrack.h" > >>>>>> #include "flow.h" > >>>>>> @@ -645,32 +649,62 @@ static struct nf_conn * > >>>>>> ovs_ct_find_existing(struct net *net, const struct > >>>>>> nf_conntrack_zone *zone, > >>>>>> u8 l3num, struct sk_buff *skb, bool natted) > >>>>>> { > >>>>>> - const struct nf_conntrack_l3proto *l3proto; > >>>>>> const struct nf_conntrack_l4proto *l4proto; > >>>>>> struct nf_conntrack_tuple tuple; > >>>>>> struct nf_conntrack_tuple_hash *h; > >>>>>> struct nf_conn *ct; > >>>>>> - unsigned int dataoff; > >>>>>> u8 protonum; > >>>>>> > >>>>>> +#ifdef HAVE_NF_CT_INVERT_TUPLE_TAKES_L3PROTO > >>>>>> + const struct nf_conntrack_l3proto *l3proto; > >>>>>> + unsigned int dataoff; > >>>>>> + > >>>>>> l3proto = __nf_ct_l3proto_find(l3num); > >>>>>> if (l3proto->get_l4proto(skb, skb_network_offset(skb), > >>>>>> &dataoff, > >>>>>> &protonum) <= 0) { > >>>>>> pr_debug("ovs_ct_find_existing: Can't get protonum\n"); > >>>>>> return NULL; > >>>>>> } > >>>>>> +#else > >>>>>> + int protooff; > >>>>>> + > >>>>>> + protooff = get_l4proto(skb, skb_network_offset(skb), > >>>>>> + l3num, &protonum); > >>>>>> + if (protooff <= 0) { > >>>>>> + pr_warn("ovs_ct_find_existing: Can't get protonum\n"); > >>>>>> + return NULL; > >>>>>> + } > >>>>>> +#endif > >>>>>> + > >>>>>> +#ifdef HAVE_NF_CT_L4PROTO_FIND_TAKES_L3PROTO > >>>>>> l4proto = __nf_ct_l4proto_find(l3num, protonum); > >>>>>> - if (!nf_ct_get_tuple(skb, skb_network_offset(skb), dataoff, > >>>>>> l3num, > >>>>>> - protonum, net, &tuple, l3proto, l4proto)) { > >>>>>> +#else > >>>>>> + l4proto = __nf_ct_l4proto_find(protonum); > >>>>>> +#endif > >>>>>> + > >>>>>> +#ifdef HAVE_NF_CT_GET_TUPLE > >>>>>> + if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), > >>>>>> + l3num, net, &tuple)) { > >>>>>> + pr_debug("ovs_ct_find_existing: Can't get tuple\n"); > >>>>>> + return NULL; > >>>>>> + } > >>>>>> +#else > >>>>>> + if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), > >>>>>> + l3num, net, &tuple)) { > >>>>>> pr_debug("ovs_ct_find_existing: Can't get tuple\n"); > >>>>>> return NULL; > >>>>>> } > >>>>>> +#endif > >>>>>> > >>>>>> /* Must invert the tuple if skb has been transformed by NAT. */ > >>>>>> if (natted) { > >>>>>> struct nf_conntrack_tuple inverse; > >>>>>> > >>>>>> +#ifdef HAVE_NF_CT_INVERT_TUPLE_TAKES_L3PROTO > >>>>>> if (!nf_ct_invert_tuple(&inverse, &tuple, l3proto, > >>>>>> l4proto)) { > >>>>>> +#else > >>>>>> + if (!nf_ct_invert_tuple(&inverse, &tuple, l4proto)) { > >>>>>> +#endif > >>>>>> pr_debug("ovs_ct_find_existing: Inversion > >>>>>> failed!\n"); > >>>>>> return NULL; > >>>>>> } > >>>>>> @@ -989,6 +1023,9 @@ static int __ovs_ct_lookup(struct net *net, > >>>>>> struct sw_flow_key *key, > >>>>>> if (!cached) { > >>>>>> struct nf_conn *tmpl = info->ct; > >>>>>> int err; > >>>>>> +#ifndef HAVE_NF_CONNTRACK_IN_TAKES_NET > >>>>>> + struct nf_hook_state state = {}; > >>>>>> +#endif > >>>>>> > >>>>>> /* Associate skb with specified zone. */ > >>>>>> if (tmpl) { > >>>>>> @@ -998,8 +1035,15 @@ static int __ovs_ct_lookup(struct net *net, > >>>>>> struct sw_flow_key *key, > >>>>>> nf_ct_set(skb, tmpl, IP_CT_NEW); > >>>>>> } > >>>>>> > >>>>>> +#ifdef HAVE_NF_CONNTRACK_IN_TAKES_NET > >>>>>> err = nf_conntrack_in(net, info->family, > >>>>>> NF_INET_PRE_ROUTING, skb); > >>>>>> +#else > >>>>>> + state.hook = NF_INET_PRE_ROUTING, > >>>>>> + state.pf = info->family, > >>>>>> + state.net = net, > >>>>>> + err = nf_conntrack_in(skb, &state); > >>>>>> +#endif > >>>>>> if (err != NF_ACCEPT) > >>>>>> return -ENOENT; > >>>>>> > >>>>>> @@ -1307,9 +1351,17 @@ int ovs_ct_execute(struct net *net, struct > >>>>>> sk_buff *skb, > >>>>>> { > >>>>>> int nh_ofs; > >>>>>> int err; > >>>>>> + /* From kernel 4.19.0+, Function handle_fragments may shrink > >>>>>> skb's > >>>>>> + * headroom, which will result in loss of ethernet header data. > >>>>>> + * This buf is used to backup the header data before calling > >>>>>> + * handle_fragments. */ > >>>>>> + char buf[32]; > >>>>>> > >>>>>> /* The conntrack module expects to be working at L3. */ > >>>>>> nh_ofs = skb_network_offset(skb); > >>>>>> + if (nh_ofs > sizeof(buf)) > >>>>>> + return -EINVAL; > >>>>>> + memcpy(buf, skb->data, nh_ofs); > >>>>>> skb_pull_rcsum(skb, nh_ofs); > >>>>>> > >>>>>> err = ovs_skb_network_trim(skb); > >>>>>> @@ -1326,8 +1378,16 @@ int ovs_ct_execute(struct net *net, struct > >>>>>> sk_buff *skb, > >>>>>> err = ovs_ct_commit(net, key, info, skb); > >>>>>> else > >>>>>> err = ovs_ct_lookup(net, key, info, skb); > >>>>>> + if (err) > >>>>>> + return err; > >>>>>> > >>>>>> + if (skb_headroom(skb) < nh_ofs) { > >>>>>> + err = pskb_expand_head(skb, nh_ofs, 0, GFP_ATOMIC); > >>>>>> + if (err) > >>>>>> + return err; > >>>>>> + } > >>>>>> skb_push(skb, nh_ofs); > >>>>>> + memcpy(skb->data, buf, nh_ofs); > >>>>>> skb_postpush_rcsum(skb, skb->data, nh_ofs); > >>>>>> if (err) > >>>>>> kfree_skb(skb); > >>>>>> @@ -1362,7 +1422,11 @@ static int ovs_ct_add_helper(struct > >>>>>> ovs_conntrack_info *info, const char *name, > >>>>>> return -EINVAL; > >>>>>> } > >>>>>> > >>>>>> +#ifdef HAVE_NF_CT_HELPER_EXT_ADD_TAKES_HELPER > >>>>>> help = nf_ct_helper_ext_add(info->ct, helper, GFP_KERNEL); > >>>>>> +#else > >>>>>> + help = nf_ct_helper_ext_add(info->ct, GFP_KERNEL); > >>>>>> +#endif > >>>>>> if (!help) { > >>>>>> nf_conntrack_helper_put(helper); > >>>>>> return -ENOMEM; > >>>>>> diff --git > >>>>>> a/datapath/linux/compat/include/net/netfilter/nf_conntrack_core.h > >>>>>> b/datapath/linux/compat/include/net/netfilter/nf_conntrack_core.h > >>>>>> index 7834c8c25..7fca7dc55 100644 > >>>>>> --- a/datapath/linux/compat/include/net/netfilter/nf_conntrack_core.h > >>>>>> +++ b/datapath/linux/compat/include/net/netfilter/nf_conntrack_core.h > >>>>>> @@ -104,4 +104,10 @@ static inline bool rpl_nf_ct_delete(struct > >>>>>> nf_conn *ct, u32 portid, int report) > >>>>>> #define nf_ct_delete rpl_nf_ct_delete > >>>>>> #endif /* HAVE_NF_CONN_TIMER */ > >>>>>> > >>>>>> +#ifndef HAVE_NF_CT_INVERT_TUPLE_TAKES_L3PROTO > >>>>>> +int rpl_get_l4proto(const struct sk_buff *skb, > >>>>>> + unsigned int nhoff, u8 pf, u8 *l4num); > >>>>>> +#define get_l4proto rpl_get_l4proto > >>>>>> +#endif > >>>>>> + > >>>>>> #endif /* _NF_CONNTRACK_CORE_WRAPPER_H */ > >>>>>> diff --git > >>>>>> a/datapath/linux/compat/include/net/netfilter/nf_conntrack_count.h > >>>>>> b/datapath/linux/compat/include/net/netfilter/nf_conntrack_count.h > >>>>>> index fd536f3e1..a26eb9f87 100644 > >>>>>> --- a/datapath/linux/compat/include/net/netfilter/nf_conntrack_count.h > >>>>>> +++ b/datapath/linux/compat/include/net/netfilter/nf_conntrack_count.h > >>>>>> @@ -4,6 +4,8 @@ > >>>>>> #include <linux/list.h> > >>>>>> > >>>>>> #ifdef HAVE_UPSTREAM_NF_CONNCOUNT > >>>>>> +#include <net/netfilter/nf_conntrack_tuple.h> > >>>>>> +#include <net/netfilter/nf_conntrack_zones.h> > >>>>>> #include_next <net/netfilter/nf_conntrack_count.h> > >>>>>> > >>>>>> static inline int rpl_nf_conncount_modinit(void) > >>>>>> diff --git a/datapath/linux/compat/nf_conncount.c > >>>>>> b/datapath/linux/compat/nf_conncount.c > >>>>>> index 0bee96274..eeae440f8 100644 > >>>>>> --- a/datapath/linux/compat/nf_conncount.c > >>>>>> +++ b/datapath/linux/compat/nf_conncount.c > >>>>>> @@ -13,6 +13,8 @@ > >>>>>> * only ignore TIME_WAIT or gone connections > >>>>>> * (C) CC Computer Consultants GmbH, 2007 > >>>>>> */ > >>>>>> +#ifndef HAVE_UPSTREAM_NF_CONNCOUNT > >>>>>> + > >>>>>> #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt > >>>>>> #include <linux/in.h> > >>>>>> #include <linux/in6.h> > >>>>>> @@ -138,7 +140,7 @@ static bool conn_free(struct nf_conncount_list > >>>>>> *list, > >>>>>> > >>>>>> if (list->count == 0) { > >>>>>> spin_unlock(&list->list_lock); > >>>>>> - return free_entry; > >>>>>> + return free_entry; > >>>>>> } > >>>>>> > >>>>>> list->count--; > >>>>>> @@ -635,3 +637,5 @@ void rpl_nf_conncount_modexit(void) > >>>>>> kmem_cache_destroy(conncount_conn_cachep); > >>>>>> kmem_cache_destroy(conncount_rb_cachep); > >>>>>> } > >>>>>> + > >>>>>> +#endif /* HAVE_UPSTREAM_NF_CONNCOUNT */ > >>>>>> diff --git a/datapath/linux/compat/nf_conntrack_core.c > >>>>>> b/datapath/linux/compat/nf_conntrack_core.c > >>>>>> index a7d3d4331..ecfeae1a0 100644 > >>>>>> --- a/datapath/linux/compat/nf_conntrack_core.c > >>>>>> +++ b/datapath/linux/compat/nf_conntrack_core.c > >>>>>> @@ -1,4 +1,7 @@ > >>>>>> +#include <linux/types.h> > >>>>>> #include <linux/version.h> > >>>>>> +#include <net/ip.h> > >>>>>> +#include <net/ipv6.h> > >>>>>> > >>>>>> #ifndef HAVE_NF_CT_ZONE_INIT > >>>>>> > >>>>>> @@ -11,3 +14,80 @@ const struct nf_conntrack_zone nf_ct_zone_dflt = { > >>>>>> }; > >>>>>> > >>>>>> #endif /* HAVE_NF_CT_ZONE_INIT */ > >>>>>> + > >>>>>> +#ifndef HAVE_NF_CT_INVERT_TUPLE_TAKES_L3PROTO > >>>>>> +static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int > >>>>>> nhoff, > >>>>>> + u_int8_t *protonum) > >>>>>> +{ > >>>>>> + int dataoff = -1; > >>>>>> + const struct iphdr *iph; > >>>>>> + struct iphdr _iph; > >>>>>> + > >>>>>> + iph = skb_header_pointer(skb, nhoff, sizeof(_iph), &_iph); > >>>>>> + if (!iph) > >>>>>> + return -1; > >>>>>> + > >>>>>> + /* Conntrack defragments packets, we might still see fragments > >>>>>> + * inside ICMP packets though. > >>>>>> + */ > >>>>>> + if (iph->frag_off & htons(IP_OFFSET)) > >>>>>> + return -1; > >>>>>> + > >>>>>> + dataoff = nhoff + (iph->ihl << 2); > >>>>>> + *protonum = iph->protocol; > >>>>>> + > >>>>>> + /* Check bogus IP headers */ > >>>>>> + if (dataoff > skb->len) { > >>>>>> + pr_debug("bogus IPv4 packet: nhoff %u, ihl %u, skblen > >>>>>> %u\n", > >>>>>> + nhoff, iph->ihl << 2, skb->len); > >>>>>> + return -1; > >>>>>> + } > >>>>>> + return dataoff; > >>>>>> +} > >>>>>> + > >>>>>> +#if IS_ENABLED(CONFIG_IPV6) > >>>>>> +static int ipv6_get_l4proto(const struct sk_buff *skb, unsigned int > >>>>>> nhoff, > >>>>>> + u8 *protonum) > >>>>>> +{ > >>>>>> + int protoff = -1; > >>>>>> + unsigned int extoff = nhoff + sizeof(struct ipv6hdr); > >>>>>> + __be16 frag_off; > >>>>>> + u8 nexthdr; > >>>>>> + > >>>>>> + if (skb_copy_bits(skb, nhoff + offsetof(struct ipv6hdr, nexthdr), > >>>>>> + &nexthdr, sizeof(nexthdr)) != 0) { > >>>>>> + pr_debug("can't get nexthdr\n"); > >>>>>> + return -1; > >>>>>> + } > >>>>>> + protoff = ipv6_skip_exthdr(skb, extoff, &nexthdr, &frag_off); > >>>>>> + /* > >>>>>> + * (protoff == skb->len) means the packet has not data, just > >>>>>> + * IPv6 and possibly extensions headers, but it is tracked anyway > >>>>>> + */ > >>>>>> + if (protoff < 0 || (frag_off & htons(~0x7)) != 0) { > >>>>>> + pr_debug("can't find proto in pkt\n"); > >>>>>> + return -1; > >>>>>> + } > >>>>>> + > >>>>>> + *protonum = nexthdr; > >>>>>> + return protoff; > >>>>>> +} > >>>>>> +#endif > >>>>>> + > >>>>>> +int rpl_get_l4proto(const struct sk_buff *skb, > >>>>>> + unsigned int nhoff, u8 pf, u8 *l4num) > >>>>>> +{ > >>>>>> + switch (pf) { > >>>>>> + case NFPROTO_IPV4: > >>>>>> + return ipv4_get_l4proto(skb, nhoff, l4num); > >>>>>> +#if IS_ENABLED(CONFIG_IPV6) > >>>>>> + case NFPROTO_IPV6: > >>>>>> + return ipv6_get_l4proto(skb, nhoff, l4num); > >>>>>> +#endif > >>>>>> + default: > >>>>>> + *l4num = 0; > >>>>>> + break; > >>>>>> + } > >>>>>> + return -1; > >>>>>> +} > >>>>>> +#endif /* HAVE_NF_CT_INVERT_TUPLE_TAKES_L3PROTO */ > >>>>>> diff --git a/datapath/linux/compat/nf_conntrack_proto.c > >>>>>> b/datapath/linux/compat/nf_conntrack_proto.c > >>>>>> index 4ac66f61c..89c2f5422 100644 > >>>>>> --- a/datapath/linux/compat/nf_conntrack_proto.c > >>>>>> +++ b/datapath/linux/compat/nf_conntrack_proto.c > >>>>>> @@ -1,7 +1,10 @@ > >>>>>> #include <linux/types.h> > >>>>>> > >>>>>> #include <net/netfilter/nf_conntrack.h> > >>>>>> + > >>>>>> +#ifdef HAVE_NF_CT_INVERT_TUPLE_TAKES_L3PROTO > >>>>>> #include <net/netfilter/nf_conntrack_l3proto.h> > >>>>>> +#endif > >>>>>> > >>>>>> /* > >>>>>> * Upstream net-next commmit 7e35ec0e8044 > _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
