lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CALx6S35z6P6B5edDSro7bkH9-webtv98gxNH__K08asWMeNZbg@mail.gmail.com>
Date:   Fri, 26 Jun 2020 11:35:27 -0700
From:   Tom Herbert <tom@...bertland.com>
To:     Justin Iurman <justin.iurman@...ege.be>
Cc:     Linux Kernel Network Developers <netdev@...r.kernel.org>,
        "David S. Miller" <davem@...emloft.net>
Subject: Re: [PATCH net-next 1/5] ipv6: eh: Introduce removable TLVs

On Fri, Jun 26, 2020 at 10:14 AM Justin Iurman <justin.iurman@...ege.be> wrote:
>
> >> Tom,
> >>
> >> >> Hi Tom,
> >> >>
> >> >> >> Add the possibility to remove one or more consecutive TLVs without
> >> >> >> messing up the alignment of others. For now, only IOAM requires this
> >> >> >> behavior.
> >> >> >>
> >> >> > Hi Justin,
> >> >> >
> >> >> > Can you explain the motivation for this? Per RFC8200, extension
> >> >> > headers in flight are not to be added, removed, or modified outside of
> >> >> > the standard rules for processing modifiable HBH and DO TLVs., that
> >> >> > would include adding and removing TLVs in EH. One obvious problem this
> >> >>
> >> >> As you already know from our last meeting, IOAM may be configured on a node such
> >> >> that a specific IOAM namespace should be removed. Therefore, this patch
> >> >> provides support for the deletion of a TLV (or consecutive TLVs), without
> >> >> removing the entire EH (if it's empty, there will be padding). Note that there
> >> >> is a similar "problem" with the Incremental Trace where you'd need to expand
> >> >> the Hop-by-Hop (not included in this patchset). I agree that RFC 8200 is
> >> >> against modification of in-flight EHs, but there are several reasons that, I
> >> >> believe, mitigates this statement.
> >> >>
> >> >> Let's keep in mind that IOAM purpose is "private" (= IOAM domain), ie not widely
> >> >> deployed on the Internet. We can distinguish two big scenarios: (i) in-transit
> >> >> traffic where it is encapsulated (IPv6-in-IPv6) and (ii) traffic inside the
> >> >> domain, ie from an IOAM node inside the domain to another one (no need for
> >> >> encapsulation). In both cases, we kind of own the traffic: (i) encapsulation,
> >> >> so we modify "our" header and (ii) we already own the traffic.
> >> >>
> >> >> And if someone is still angry about this, well, the good news is that such
> >> >> modification can be avoided most of the time. Indeed, operators are advised to
> >> >> remove an IOAM namespace only on egress nodes. This way, the destination
> >> >> (either the tunnel destination or the real destination, depending on the
> >> >> scenario) will receive EHs and take care of them without the need to remove
> >> >> anything. But, again, operators can do what they want and I'd tend to adhere to
> >> >> David's philosophy [1] and give them the possibility to choose what to do.
> >> >>
> >> >
> >> > Justin,
> >> >
> >> > 6man WG has had a _long_ and sometimes bitter discussion around this
> >> > particularly with regards to insertion of SRH. The current consensus
> >> > of IETF is that it is a violation of RFC8200.  We've heard all the
> >> > arguments that it's only for limited domains and narrow use cases,
> >> > nevertheless there are several problems that the header
> >> > insertion/deletion advocates never answered-- it breaks AH, it breaks
> >> > PMTU discovery, it breaks ICMP. There is also a risk that a
> >> > non-standard modification could cause a packet to be dropped
> >> > downstream from the node that modifies it. There is no attribution on
> >> > who created the problem, and hence this can lead to systematic
> >> > blackholes which are the most miserable sort of problem to debug.
> >>
> >> Yes, I know the whole story and it's been stormy from what I understood.
> >>
> >> > Fundamentally, it is not robust per Postel's law (I actually wrote a
> >> > draft to try to make it robust in draft-herbert-6man-eh-attrib-00 if
> >> > you're interested).
> >>
> >> Interesting, I'll take a look.
> >>
> >> > IMO, we shouldn't be using Linux as a backdoor to implement protocol
> >> > that IETF is saying isn't robust. Can you point out in the IOAM drafts
> >> > where this requirement is specified, then I can take it up in IOAM WG
> >> > or 6man if needed...
> >>
> >> Well, I wouldn't say that IETF is considering IPv6-IOAM as not robust since [1]
> >> (IPv6 encapsulation for IOAM) and [2] (IOAM data fields) are about to be
> >> published.
> >
> > I was specifically referring to the requirements around removing the
> > IOAM TLV from packets in-flight. I don't readily see that in the IOAM
> > drafts.
>patch
> Actually, this is not in the draft. Authors wanted to give operators a little bit of freedom and this one would restrict their choices, even if it's better or even the most logical option we could think about. Maybe we could discuss this on the IPPM mailing list as well on whether we should add it or not? I've two advises for operators, one about the encapsulation and this one about the removal of an IOAM option.
>

Justin,

You're welcome to take it up on the IPPM list, but beware there is
going to be pushback. Make sure you can show a clear justification and
how any potential issues it causes are mitigated. If
draft-herbert-6man-eh-attrib-00 facilitates that we can take a look
implementing it.

Until we have clarity on the protocol requirements and the need for
this, I don't think this patch should be accepted.

Tom
> > Also, be careful about saying that drafts are about to be published by
> > IETF. Until a draft reaches the RFC editor we really can't say that. I
> > don't believe drafts you're referring to have even made it through
> > WGLC.
>
> Indeed, but draft-ietf-ippm-ioam-data is already at its second WGLC, did you miss it on the IPPM mailing list? As for draft-ietf-ippm-ioam-ipv6-options, it is just my prediction but I guess it should come soon as well since IANA early allocation (there were talks about that on the WG).
>
> Justin
>
> > Tom
> >
> >>
> >> Justin
> >>
> >>   [1] https://tools.ietf.org/html/draft-ietf-ippm-ioam-ipv6-options-01
> >>   [2] https://tools.ietf.org/html/draft-ietf-ippm-ioam-data-09
> >>
> >> > Tom
> >> >
> >> >> > creates is that it breaks AH if the TLVs are removed in HBH before AH
> >> >> > is processed (AH is processed after HBH).
> >> >>
> >> >> Correct. But I don't think it should prevent us from having IOAM in the kernel.
> >> >> Again, operators could simply apply IOAM on a subset of the traffic that does
> >> >> not include AHs, for example.
> >> >>
> >> >> Justin
> >> >>
> >> >>   [1] https://www.mail-archive.com/netdev@vger.kernel.org/msg136797.html
> >> >>
> >> >> > Tom
> >> >> >> By default, an 8-octet boundary is automatically assumed. This is the
> >> >> >> price to pay (at most a useless 4-octet padding) to make sure everything
> >> >> >> is still aligned after the removal.
> >> >> >>
> >> >> >> Proof: let's assume for instance the following alignments 2n, 4n and 8n
> >> >> >> respectively for options X, Y and Z, inside a Hop-by-Hop extension
> >> >> >> header.
> >> >> >>
> >> >> >> Example 1:
> >> >> >>
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |  Next header  |  Hdr Ext Len  |       X       |       X       |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |       X       |       X       |    Padding    |    Padding    |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |                                                               |
> >> >> >> ~                Option to be removed (8 octets)                ~
> >> >> >> |                                                               |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |       Y       |       Y       |       Y       |       Y       |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |    Padding    |    Padding    |    Padding    |    Padding    |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |       Z       |       Z       |       Z       |       Z       |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |       Z       |       Z       |       Z       |       Z       |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >>
> >> >> >> Result 1: assuming a 4-octet boundary would work, as well as an 8-octet
> >> >> >> boundary (same result in both cases).
> >> >> >>
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |  Next header  |  Hdr Ext Len  |       X       |       X       |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |       X       |       X       |    Padding    |    Padding    |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |       Y       |       Y       |       Y       |       Y       |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |    Padding    |    Padding    |    Padding    |    Padding    |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |       Z       |       Z       |       Z       |       Z       |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |       Z       |       Z       |       Z       |       Z       |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >>
> >> >> >> Example 2:
> >> >> >>
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |  Next header  |  Hdr Ext Len  |       X       |       X       |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |       X       |       X       |    Padding    |    Padding    |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |                Option to be removed (4 octets)                |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |       Y       |       Y       |       Y       |       Y       |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |       Z       |       Z       |       Z       |       Z       |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |       Z       |       Z       |       Z       |       Z       |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >>
> >> >> >> Result 2: assuming a 4-octet boundary WOULD NOT WORK. Indeed, option Z
> >> >> >> would not be 8n-aligned and the Hop-by-Hop size would not be a multiple
> >> >> >> of 8 anymore.
> >> >> >>
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |  Next header  |  Hdr Ext Len  |       X       |       X       |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |       X       |       X       |    Padding    |    Padding    |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |       Y       |       Y       |       Y       |       Y       |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |       Z       |       Z       |       Z       |       Z       |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >> |       Z       |       Z       |       Z       |       Z       |
> >> >> >> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> >> >> >>
> >> >> >> Therefore, the largest (8-octet) boundary is assumed by default and for
> >> >> >> all, which means that blocks are only moved in multiples of 8. This
> >> >> >> assertion guarantees good alignment.
> >> >> >>
> >> >> >> Signed-off-by: Justin Iurman <justin.iurman@...ege.be>
> >> >> >> ---
> >> >> >>  net/ipv6/exthdrs.c | 134 ++++++++++++++++++++++++++++++++++++---------
> >> >> >>  1 file changed, 108 insertions(+), 26 deletions(-)
> >> >> >>
> >> >> >> diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
> >> >> >> index e9b366994475..f27ab3bf2e0c 100644
> >> >> >> --- a/net/ipv6/exthdrs.c
> >> >> >> +++ b/net/ipv6/exthdrs.c
> >> >> >> @@ -52,17 +52,27 @@
> >> >> >>
> >> >> >>  #include <linux/uaccess.h>
> >> >> >>
> >> >> >> -/*
> >> >> >> - *     Parsing tlv encoded headers.
> >> >> >> +/* States for TLV parsing functions. */
> >> >> >> +
> >> >> >> +enum {
> >> >> >> +       TLV_ACCEPT,
> >> >> >> +       TLV_REJECT,
> >> >> >> +       TLV_REMOVE,
> >> >> >> +       __TLV_MAX
> >> >> >> +};
> >> >> >> +
> >> >> >> +/* Parsing TLV encoded headers.
> >> >> >>   *
> >> >> >> - *     Parsing function "func" returns true, if parsing succeed
> >> >> >> - *     and false, if it failed.
> >> >> >> - *     It MUST NOT touch skb->h.
> >> >> >> + * Parsing function "func" returns either:
> >> >> >> + *  - TLV_ACCEPT if parsing succeeds
> >> >> >> + *  - TLV_REJECT if parsing fails
> >> >> >> + *  - TLV_REMOVE if TLV must be removed
> >> >> >> + * It MUST NOT touch skb->h.
> >> >> >>   */
> >> >> >>
> >> >> >>  struct tlvtype_proc {
> >> >> >>         int     type;
> >> >> >> -       bool    (*func)(struct sk_buff *skb, int offset);
> >> >> >> +       int     (*func)(struct sk_buff *skb, int offset);
> >> >> >>  };
> >> >> >>
> >> >> >>  /*********************
> >> >> >> @@ -109,19 +119,67 @@ static bool ip6_tlvopt_unknown(struct sk_buff *skb, int
> >> >> >> optoff,
> >> >> >>         return false;
> >> >> >>  }
> >> >> >>
> >> >> >> +/* Remove one or several consecutive TLVs and recompute offsets, lengths */
> >> >> >> +
> >> >> >> +static int remove_tlv(int start, int end, struct sk_buff *skb)
> >> >> >> +{
> >> >> >> +       int len = end - start;
> >> >> >> +       int padlen = len % 8;
> >> >> >> +       unsigned char *h;
> >> >> >> +       int rlen, off;
> >> >> >> +       u16 pl_len;
> >> >> >> +
> >> >> >> +       rlen = len - padlen;
> >> >> >> +       if (rlen) {
> >> >> >> +               skb_pull(skb, rlen);
> >> >> >> +               memmove(skb_network_header(skb) + rlen, skb_network_header(skb),
> >> >> >> +                       start);
> >> >> >> +               skb_postpull_rcsum(skb, skb_network_header(skb), rlen);
> >> >> >> +
> >> >> >> +               skb_reset_network_header(skb);
> >> >> >> +               skb_set_transport_header(skb, sizeof(struct ipv6hdr));
> >> >> >> +
> >> >> >> +               pl_len = be16_to_cpu(ipv6_hdr(skb)->payload_len) - rlen;
> >> >> >> +               ipv6_hdr(skb)->payload_len = cpu_to_be16(pl_len);
> >> >> >> +
> >> >> >> +               skb_transport_header(skb)[1] -= rlen >> 3;
> >> >> >> +               end -= rlen;
> >> >> >> +       }
> >> >> >> +
> >> >> >> +       if (padlen) {
> >> >> >> +               off = end - padlen;
> >> >> >> +               h = skb_network_header(skb);
> >> >> >> +
> >> >> >> +               if (padlen == 1) {
> >> >> >> +                       h[off] = IPV6_TLV_PAD1;
> >> >> >> +               } else {
> >> >> >> +                       padlen -= 2;
> >> >> >> +
> >> >> >> +                       h[off] = IPV6_TLV_PADN;
> >> >> >> +                       h[off + 1] = padlen;
> >> >> >> +                       memset(&h[off + 2], 0, padlen);
> >> >> >> +               }
> >> >> >> +       }
> >> >> >> +
> >> >> >> +       return end;
> >> >> >> +}
> >> >> >> +
> >> >> >>  /* Parse tlv encoded option header (hop-by-hop or destination) */
> >> >> >>
> >> >> >>  static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
> >> >> >>                           struct sk_buff *skb,
> >> >> >> -                         int max_count)
> >> >> >> +                         int max_count,
> >> >> >> +                         bool removable)
> >> >> >>  {
> >> >> >>         int len = (skb_transport_header(skb)[1] + 1) << 3;
> >> >> >> -       const unsigned char *nh = skb_network_header(skb);
> >> >> >> +       unsigned char *nh = skb_network_header(skb);
> >> >> >>         int off = skb_network_header_len(skb);
> >> >> >>         const struct tlvtype_proc *curr;
> >> >> >>         bool disallow_unknowns = false;
> >> >> >> +       int off_remove = 0;
> >> >> >>         int tlv_count = 0;
> >> >> >>         int padlen = 0;
> >> >> >> +       int ret;
> >> >> >>
> >> >> >>         if (unlikely(max_count < 0)) {
> >> >> >>                 disallow_unknowns = true;
> >> >> >> @@ -173,12 +231,14 @@ static bool ip6_parse_tlv(const struct tlvtype_proc
> >> >> >> *procs,
> >> >> >>                         if (tlv_count > max_count)
> >> >> >>                                 goto bad;
> >> >> >>
> >> >> >> +                       ret = -1;
> >> >> >>                         for (curr = procs; curr->type >= 0; curr++) {
> >> >> >>                                 if (curr->type == nh[off]) {
> >> >> >>                                         /* type specific length/alignment
> >> >> >>                                            checks will be performed in the
> >> >> >>                                            func(). */
> >> >> >> -                                       if (curr->func(skb, off) == false)
> >> >> >> +                                       ret = curr->func(skb, off);
> >> >> >> +                                       if (ret == TLV_REJECT)
> >> >> >>                                                 return false;
> >> >> >>                                         break;
> >> >> >>                                 }
> >> >> >> @@ -187,6 +247,17 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
> >> >> >>                             !ip6_tlvopt_unknown(skb, off, disallow_unknowns))
> >> >> >>                                 return false;
> >> >> >>
> >> >> >> +                       if (removable) {
> >> >> >> +                               if (ret == TLV_REMOVE) {
> >> >> >> +                                       if (!off_remove)
> >> >> >> +                                               off_remove = off - padlen;
> >> >> >> +                               } else if (off_remove) {
> >> >> >> +                                       off = remove_tlv(off_remove, off, skb);
> >> >> >> +                                       nh = skb_network_header(skb);
> >> >> >> +                                       off_remove = 0;
> >> >> >> +                               }
> >> >> >> +                       }
> >> >> >> +
> >> >> >>                         padlen = 0;
> >> >> >>                         break;
> >> >> >>                 }
> >> >> >> @@ -194,8 +265,13 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
> >> >> >>                 len -= optlen;
> >> >> >>         }
> >> >> >>
> >> >> >> -       if (len == 0)
> >> >> >> +       if (len == 0) {
> >> >> >> +               /* Don't forget last TLV if it must be removed */
> >> >> >> +               if (off_remove)
> >> >> >> +                       remove_tlv(off_remove, off, skb);
> >> >> >> +
> >> >> >>                 return true;
> >> >> >> +       }
> >> >> >>  bad:
> >> >> >>         kfree_skb(skb);
> >> >> >>         return false;
> >> >> >> @@ -206,7 +282,7 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
> >> >> >>   *****************************/
> >> >> >>
> >> >> >>  #if IS_ENABLED(CONFIG_IPV6_MIP6)
> >> >> >> -static bool ipv6_dest_hao(struct sk_buff *skb, int optoff)
> >> >> >> +static int ipv6_dest_hao(struct sk_buff *skb, int optoff)
> >> >> >>  {
> >> >> >>         struct ipv6_destopt_hao *hao;
> >> >> >>         struct inet6_skb_parm *opt = IP6CB(skb);
> >> >> >> @@ -257,11 +333,11 @@ static bool ipv6_dest_hao(struct sk_buff *skb, int optoff)
> >> >> >>         if (skb->tstamp == 0)
> >> >> >>                 __net_timestamp(skb);
> >> >> >>
> >> >> >> -       return true;
> >> >> >> +       return TLV_ACCEPT;
> >> >> >>
> >> >> >>   discard:
> >> >> >>         kfree_skb(skb);
> >> >> >> -       return false;
> >> >> >> +       return TLV_REJECT;
> >> >> >>  }
> >> >> >>  #endif
> >> >> >>
> >> >> >> @@ -306,7 +382,8 @@ static int ipv6_destopt_rcv(struct sk_buff *skb)
> >> >> >>  #endif
> >> >> >>
> >> >> >>         if (ip6_parse_tlv(tlvprocdestopt_lst, skb,
> >> >> >> -                         init_net.ipv6.sysctl.max_dst_opts_cnt)) {
> >> >> >> +                         init_net.ipv6.sysctl.max_dst_opts_cnt,
> >> >> >> +                         false)) {
> >> >> >>                 skb->transport_header += extlen;
> >> >> >>                 opt = IP6CB(skb);
> >> >> >>  #if IS_ENABLED(CONFIG_IPV6_MIP6)
> >> >> >> @@ -918,24 +995,24 @@ static inline struct net *ipv6_skb_net(struct sk_buff
> >> >> >> *skb)
> >> >> >>
> >> >> >>  /* Router Alert as of RFC 2711 */
> >> >> >>
> >> >> >> -static bool ipv6_hop_ra(struct sk_buff *skb, int optoff)
> >> >> >> +static int ipv6_hop_ra(struct sk_buff *skb, int optoff)
> >> >> >>  {
> >> >> >>         const unsigned char *nh = skb_network_header(skb);
> >> >> >>
> >> >> >>         if (nh[optoff + 1] == 2) {
> >> >> >>                 IP6CB(skb)->flags |= IP6SKB_ROUTERALERT;
> >> >> >>                 memcpy(&IP6CB(skb)->ra, nh + optoff + 2, sizeof(IP6CB(skb)->ra));
> >> >> >> -               return true;
> >> >> >> +               return TLV_ACCEPT;
> >> >> >>         }
> >> >> >>         net_dbg_ratelimited("ipv6_hop_ra: wrong RA length %d\n",
> >> >> >>                             nh[optoff + 1]);
> >> >> >>         kfree_skb(skb);
> >> >> >> -       return false;
> >> >> >> +       return TLV_REJECT;
> >> >> >>  }
> >> >> >>
> >> >> >>  /* Jumbo payload */
> >> >> >>
> >> >> >> -static bool ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
> >> >> >> +static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
> >> >> >>  {
> >> >> >>         const unsigned char *nh = skb_network_header(skb);
> >> >> >>         struct inet6_dev *idev = __in6_dev_get_safely(skb->dev);
> >> >> >> @@ -953,12 +1030,12 @@ static bool ipv6_hop_jumbo(struct sk_buff *skb, int
> >> >> >> optoff)
> >> >> >>         if (pkt_len <= IPV6_MAXPLEN) {
> >> >> >>                 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
> >> >> >>                 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
> >> >> >> -               return false;
> >> >> >> +               return TLV_REJECT;
> >> >> >>         }
> >> >> >>         if (ipv6_hdr(skb)->payload_len) {
> >> >> >>                 __IP6_INC_STATS(net, idev, IPSTATS_MIB_INHDRERRORS);
> >> >> >>                 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
> >> >> >> -               return false;
> >> >> >> +               return TLV_REJECT;
> >> >> >>         }
> >> >> >>
> >> >> >>         if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
> >> >> >> @@ -970,16 +1047,16 @@ static bool ipv6_hop_jumbo(struct sk_buff *skb, int
> >> >> >> optoff)
> >> >> >>                 goto drop;
> >> >> >>
> >> >> >>         IP6CB(skb)->flags |= IP6SKB_JUMBOGRAM;
> >> >> >> -       return true;
> >> >> >> +       return TLV_ACCEPT;
> >> >> >>
> >> >> >>  drop:
> >> >> >>         kfree_skb(skb);
> >> >> >> -       return false;
> >> >> >> +       return TLV_REJECT;
> >> >> >>  }
> >> >> >>
> >> >> >>  /* CALIPSO RFC 5570 */
> >> >> >>
> >> >> >> -static bool ipv6_hop_calipso(struct sk_buff *skb, int optoff)
> >> >> >> +static int ipv6_hop_calipso(struct sk_buff *skb, int optoff)
> >> >> >>  {
> >> >> >>         const unsigned char *nh = skb_network_header(skb);
> >> >> >>
> >> >> >> @@ -992,11 +1069,11 @@ static bool ipv6_hop_calipso(struct sk_buff *skb, int
> >> >> >> optoff)
> >> >> >>         if (!calipso_validate(skb, nh + optoff))
> >> >> >>                 goto drop;
> >> >> >>
> >> >> >> -       return true;
> >> >> >> +       return TLV_ACCEPT;
> >> >> >>
> >> >> >>  drop:
> >> >> >>         kfree_skb(skb);
> >> >> >> -       return false;
> >> >> >> +       return TLV_REJECT;
> >> >> >>  }
> >> >> >>
> >> >> >>  static const struct tlvtype_proc tlvprochopopt_lst[] = {
> >> >> >> @@ -1041,7 +1118,12 @@ int ipv6_parse_hopopts(struct sk_buff *skb)
> >> >> >>
> >> >> >>         opt->flags |= IP6SKB_HOPBYHOP;
> >> >> >>         if (ip6_parse_tlv(tlvprochopopt_lst, skb,
> >> >> >> -                         init_net.ipv6.sysctl.max_hbh_opts_cnt)) {
> >> >> >> +                         init_net.ipv6.sysctl.max_hbh_opts_cnt,
> >> >> >> +                         true)) {
> >> >> >> +               /* we need to refresh the length in case
> >> >> >> +                * at least one TLV was removed
> >> >> >> +                */
> >> >> >> +               extlen = (skb_transport_header(skb)[1] + 1) << 3;
> >> >> >>                 skb->transport_header += extlen;
> >> >> >>                 opt = IP6CB(skb);
> >> >> >>                 opt->nhoff = sizeof(struct ipv6hdr);
> >> >> >> --
> > > > > >> 2.17.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ