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?

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

Reply via email to