05 Jun, 2020

1 commit

  • The seg6_validate_srh() is used to validate SRH for three cases:

    case1: SRH of data-plane SRv6 packets to be processed by the Linux kernel.
    Case2: SRH of the netlink message received from user-space (iproute2)
    Case3: SRH injected into packets through setsockopt

    In case1, the SRH can be encoded in the Reduced way (i.e., first SID is
    carried in DA only and not represented as SID in the SRH) and the
    seg6_validate_srh() now handles this case correctly.

    In case2 and case3, the SRH shouldn’t be encoded in the Reduced way
    otherwise we lose the first segment (i.e., the first hop).

    The current implementation of the seg6_validate_srh() allow SRH of case2
    and case3 to be encoded in the Reduced way. This leads a slab-out-of-bounds
    problem.

    This patch verifies SRH of case1, case2 and case3. Allowing case1 to be
    reduced while preventing SRH of case2 and case3 from being reduced .

    Reported-by: syzbot+e8c028b62439eac42073@syzkaller.appspotmail.com
    Reported-by: YueHaibing
    Fixes: 0cb7498f234e ("seg6: fix SRH processing to comply with RFC8754")
    Signed-off-by: Ahmed Abdelsalam
    Signed-off-by: David S. Miller

    Ahmed Abdelsalam
     

30 Mar, 2020

1 commit

  • The build_state callback of lwtunnel doesn't contain the net namespace
    structure yet. This patch will add it so we can check on specific
    address configuration at creation time of rpl source routes.

    Signed-off-by: Alexander Aring
    Signed-off-by: David S. Miller

    Alexander Aring
     

12 Mar, 2020

1 commit

  • The Internet Assigned Numbers Authority (IANA) has recently assigned
    a protocol number value of 143 for Ethernet [1].

    Before this assignment, encapsulation mechanisms such as Segment Routing
    used the IPv6-NoNxt protocol number (59) to indicate that the encapsulated
    payload is an Ethernet frame.

    In this patch, we add the definition of the Ethernet protocol number to the
    kernel headers and update the SRv6 L2 tunnels to use it.

    [1] https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml

    Signed-off-by: Paolo Lungaroni
    Reviewed-by: Andrea Mayer
    Acked-by: Ahmed Abdelsalam
    Signed-off-by: David S. Miller

    Paolo Lungaroni
     

21 Jan, 2020

1 commit

  • After LRO/GRO is applied, SRv6 encapsulated packets have
    SKB_GSO_IPXIP6 feature flag, and this flag must be removed right after
    decapulation procedure.

    Currently, SKB_GSO_IPXIP6 flag is not removed on End.D* actions, which
    creates inconsistent packet state, that is, a normal TCP/IP packets
    have the SKB_GSO_IPXIP6 flag. This behavior can cause unexpected
    fallback to GSO on routing to netdevices that do not support
    SKB_GSO_IPXIP6. For example, on inter-VRF forwarding, decapsulated
    packets separated into small packets by GSO because VRF devices do not
    support TSO for packets with SKB_GSO_IPXIP6 flag, and this degrades
    forwarding performance.

    This patch removes encapsulation related GSO flags from the skb right
    after the End.D* action is applied.

    Fixes: d7a669dd2f8b ("ipv6: sr: add helper functions for seg6local")
    Signed-off-by: Yuki Taguchi
    Signed-off-by: David S. Miller

    Yuki Taguchi
     

23 Nov, 2019

1 commit

  • End.DT6 behavior makes use of seg6_lookup_nexthop() function which drops
    all packets that are destined to be locally processed. However, DT* should
    be able to deliver decapsulated packets that are destined to local
    addresses. Function seg6_lookup_nexthop() is also used by DX6, so in order
    to maintain compatibility I created another routing helper function which
    is called seg6_lookup_any_nexthop(). This function is able to take into
    account both packets that have to be processed locally and the ones that
    are destined to be forwarded directly to another machine. Hence,
    seg6_lookup_any_nexthop() is used in DT6 rather than seg6_lookup_nexthop()
    to allow local delivery.

    Signed-off-by: Andrea Mayer
    Signed-off-by: David S. Miller

    Andrea Mayer
     

17 Nov, 2019

2 commits

  • in the receive path (more precisely in ip6_rcv_core()) the
    skb->transport_header is set to skb->network_header + sizeof(*hdr). As a
    consequence, after routing operations, destination input expects to find
    skb->transport_header correctly set to the next protocol (or extension
    header) that follows the network protocol. However, decap behaviors (DX*,
    DT*) remove the outer IPv6 and SRH extension and do not set again the
    skb->transport_header pointer correctly. For this reason, the patch sets
    the skb->transport_header to the skb->network_header + sizeof(hdr) in each
    DX* and DT* behavior.

    Signed-off-by: Andrea Mayer
    Signed-off-by: David S. Miller

    Andrea Mayer
     
  • pskb_may_pull may change pointers in header. For this reason, it is
    mandatory to reload any pointer that points into skb header.

    Signed-off-by: Andrea Mayer
    Signed-off-by: David S. Miller

    Andrea Mayer
     

31 May, 2019

1 commit

  • Based on 1 normalized pattern(s):

    this program is free software you can redistribute it and or modify
    it under the terms of the gnu general public license as published by
    the free software foundation either version 2 of the license or at
    your option any later version

    extracted by the scancode license scanner the SPDX license identifier

    GPL-2.0-or-later

    has been chosen to replace the boilerplate/reference in 3029 file(s).

    Signed-off-by: Thomas Gleixner
    Reviewed-by: Allison Randal
    Cc: linux-spdx@vger.kernel.org
    Link: https://lkml.kernel.org/r/20190527070032.746973796@linutronix.de
    Signed-off-by: Greg Kroah-Hartman

    Thomas Gleixner
     

28 Apr, 2019

2 commits

  • We currently have two levels of strict validation:

    1) liberal (default)
    - undefined (type >= max) & NLA_UNSPEC attributes accepted
    - attribute length >= expected accepted
    - garbage at end of message accepted
    2) strict (opt-in)
    - NLA_UNSPEC attributes accepted
    - attribute length >= expected accepted

    Split out parsing strictness into four different options:
    * TRAILING - check that there's no trailing data after parsing
    attributes (in message or nested)
    * MAXTYPE - reject attrs > max known type
    * UNSPEC - reject attributes with NLA_UNSPEC policy entries
    * STRICT_ATTRS - strictly validate attribute size

    The default for future things should be *everything*.
    The current *_strict() is a combination of TRAILING and MAXTYPE,
    and is renamed to _deprecated_strict().
    The current regular parsing has none of this, and is renamed to
    *_parse_deprecated().

    Additionally it allows us to selectively set one of the new flags
    even on old policies. Notably, the UNSPEC flag could be useful in
    this case, since it can be arranged (by filling in the policy) to
    not be an incompatible userspace ABI change, but would then going
    forward prevent forgetting attribute entries. Similar can apply
    to the POLICY flag.

    We end up with the following renames:
    * nla_parse -> nla_parse_deprecated
    * nla_parse_strict -> nla_parse_deprecated_strict
    * nlmsg_parse -> nlmsg_parse_deprecated
    * nlmsg_parse_strict -> nlmsg_parse_deprecated_strict
    * nla_parse_nested -> nla_parse_nested_deprecated
    * nla_validate_nested -> nla_validate_nested_deprecated

    Using spatch, of course:
    @@
    expression TB, MAX, HEAD, LEN, POL, EXT;
    @@
    -nla_parse(TB, MAX, HEAD, LEN, POL, EXT)
    +nla_parse_deprecated(TB, MAX, HEAD, LEN, POL, EXT)

    @@
    expression NLH, HDRLEN, TB, MAX, POL, EXT;
    @@
    -nlmsg_parse(NLH, HDRLEN, TB, MAX, POL, EXT)
    +nlmsg_parse_deprecated(NLH, HDRLEN, TB, MAX, POL, EXT)

    @@
    expression NLH, HDRLEN, TB, MAX, POL, EXT;
    @@
    -nlmsg_parse_strict(NLH, HDRLEN, TB, MAX, POL, EXT)
    +nlmsg_parse_deprecated_strict(NLH, HDRLEN, TB, MAX, POL, EXT)

    @@
    expression TB, MAX, NLA, POL, EXT;
    @@
    -nla_parse_nested(TB, MAX, NLA, POL, EXT)
    +nla_parse_nested_deprecated(TB, MAX, NLA, POL, EXT)

    @@
    expression START, MAX, POL, EXT;
    @@
    -nla_validate_nested(START, MAX, POL, EXT)
    +nla_validate_nested_deprecated(START, MAX, POL, EXT)

    @@
    expression NLH, HDRLEN, MAX, POL, EXT;
    @@
    -nlmsg_validate(NLH, HDRLEN, MAX, POL, EXT)
    +nlmsg_validate_deprecated(NLH, HDRLEN, MAX, POL, EXT)

    For this patch, don't actually add the strict, non-renamed versions
    yet so that it breaks compile if I get it wrong.

    Also, while at it, make nla_validate and nla_parse go down to a
    common __nla_validate_parse() function to avoid code duplication.

    Ultimately, this allows us to have very strict validation for every
    new caller of nla_parse()/nlmsg_parse() etc as re-introduced in the
    next patch, while existing things will continue to work as is.

    In effect then, this adds fully strict validation for any new command.

    Signed-off-by: Johannes Berg
    Signed-off-by: David S. Miller

    Johannes Berg
     
  • Even if the NLA_F_NESTED flag was introduced more than 11 years ago, most
    netlink based interfaces (including recently added ones) are still not
    setting it in kernel generated messages. Without the flag, message parsers
    not aware of attribute semantics (e.g. wireshark dissector or libmnl's
    mnl_nlmsg_fprintf()) cannot recognize nested attributes and won't display
    the structure of their contents.

    Unfortunately we cannot just add the flag everywhere as there may be
    userspace applications which check nlattr::nla_type directly rather than
    through a helper masking out the flags. Therefore the patch renames
    nla_nest_start() to nla_nest_start_noflag() and introduces nla_nest_start()
    as a wrapper adding NLA_F_NESTED. The calls which add NLA_F_NESTED manually
    are rewritten to use nla_nest_start().

    Except for changes in include/net/netlink.h, the patch was generated using
    this semantic patch:

    @@ expression E1, E2; @@
    -nla_nest_start(E1, E2)
    +nla_nest_start_noflag(E1, E2)

    @@ expression E1, E2; @@
    -nla_nest_start_noflag(E1, E2 | NLA_F_NESTED)
    +nla_nest_start(E1, E2)

    Signed-off-by: Michal Kubecek
    Acked-by: Jiri Pirko
    Acked-by: David Ahern
    Signed-off-by: David S. Miller

    Michal Kubecek
     

31 Jul, 2018

1 commit

  • The seg6local LWT provides the End.DT6 action, which allows to
    decapsulate an outer IPv6 header containing a Segment Routing Header
    (SRH), full specification is available here:

    https://tools.ietf.org/html/draft-filsfils-spring-srv6-network-programming-05

    This patch adds this action now to the seg6local BPF
    interface. Since it is not mandatory that the inner IPv6 header also
    contains a SRH, seg6_bpf_srh_state has been extended with a pointer to
    a possible SRH of the outermost IPv6 header. This helps assessing if the
    validation must be triggered or not, and avoids some calls to
    ipv6_find_hdr.

    v3: s/1/true, s/0/false for boolean values
    v2: - changed true/false -> 1/0
    - preempt_enable no longer called in first conditional block

    Signed-off-by: Mathieu Xhonneux
    Signed-off-by: Daniel Borkmann

    Mathieu Xhonneux
     

24 Jul, 2018

1 commit


24 May, 2018

3 commits

  • This patch adds the End.BPF action to the LWT seg6local infrastructure.
    This action works like any other seg6local End action, meaning that an IPv6
    header with SRH is needed, whose DA has to be equal to the SID of the
    action. It will also advance the SRH to the next segment, the BPF program
    does not have to take care of this.

    Since the BPF program may not be a source of instability in the kernel, it
    is important to ensure that the integrity of the packet is maintained
    before yielding it back to the IPv6 layer. The hook hence keeps track if
    the SRH has been altered through the helpers, and re-validates its
    content if needed with seg6_validate_srh. The state kept for validation is
    stored in a per-CPU buffer. The BPF program is not allowed to directly
    write into the packet, and only some fields of the SRH can be altered
    through the helper bpf_lwt_seg6_store_bytes.

    Performances profiling has shown that the SRH re-validation does not induce
    a significant overhead. If the altered SRH is deemed as invalid, the packet
    is dropped.

    This validation is also done before executing any action through
    bpf_lwt_seg6_action, and will not be performed again if the SRH is not
    modified after calling the action.

    The BPF program may return 3 types of return codes:
    - BPF_OK: the End.BPF action will look up the next destination through
    seg6_lookup_nexthop.
    - BPF_REDIRECT: if an action has been executed through the
    bpf_lwt_seg6_action helper, the BPF program should return this
    value, as the skb's destination is already set and the default
    lookup should not be performed.
    - BPF_DROP : the packet will be dropped.

    Signed-off-by: Mathieu Xhonneux
    Acked-by: David Lebrun
    Signed-off-by: Daniel Borkmann

    Mathieu Xhonneux
     
  • The BPF seg6local hook should be powerful enough to enable users to
    implement most of the use-cases one could think of. After some thinking,
    we figured out that the following actions should be possible on a SRv6
    packet, requiring 3 specific helpers :
    - bpf_lwt_seg6_store_bytes: Modify non-sensitive fields of the SRH
    - bpf_lwt_seg6_adjust_srh: Allow to grow or shrink a SRH
    (to add/delete TLVs)
    - bpf_lwt_seg6_action: Apply some SRv6 network programming actions
    (specifically End.X, End.T, End.B6 and
    End.B6.Encap)

    The specifications of these helpers are provided in the patch (see
    include/uapi/linux/bpf.h).

    The non-sensitive fields of the SRH are the following : flags, tag and
    TLVs. The other fields can not be modified, to maintain the SRH
    integrity. Flags, tag and TLVs can easily be modified as their validity
    can be checked afterwards via seg6_validate_srh. It is not allowed to
    modify the segments directly. If one wants to add segments on the path,
    he should stack a new SRH using the End.B6 action via
    bpf_lwt_seg6_action.

    Growing, shrinking or editing TLVs via the helpers will flag the SRH as
    invalid, and it will have to be re-validated before re-entering the IPv6
    layer. This flag is stored in a per-CPU buffer, along with the current
    header length in bytes.

    Storing the SRH len in bytes in the control block is mandatory when using
    bpf_lwt_seg6_adjust_srh. The Header Ext. Length field contains the SRH
    len rounded to 8 bytes (a padding TLV can be inserted to ensure the 8-bytes
    boundary). When adding/deleting TLVs within the BPF program, the SRH may
    temporary be in an invalid state where its length cannot be rounded to 8
    bytes without remainder, hence the need to store the length in bytes
    separately. The caller of the BPF program can then ensure that the SRH's
    final length is valid using this value. Again, a final SRH modified by a
    BPF program which doesn’t respect the 8-bytes boundary will be discarded
    as it will be considered as invalid.

    Finally, a fourth helper is provided, bpf_lwt_push_encap, which is
    available from the LWT BPF IN hook, but not from the seg6local BPF one.
    This helper allows to encapsulate a Segment Routing Header (either with
    a new outer IPv6 header, or by inlining it directly in the existing IPv6
    header) into a non-SRv6 packet. This helper is required if we want to
    offer the possibility to dynamically encapsulate a SRH for non-SRv6 packet,
    as the BPF seg6local hook only works on traffic already containing a SRH.
    This is the BPF equivalent of the seg6 LWT infrastructure, which achieves
    the same purpose but with a static SRH per route.

    These helpers require CONFIG_IPV6=y (and not =m).

    Signed-off-by: Mathieu Xhonneux
    Acked-by: David Lebrun
    Signed-off-by: Daniel Borkmann

    Mathieu Xhonneux
     
  • The function lookup_nexthop is essential to implement most of the seg6local
    actions. As we want to provide a BPF helper allowing to apply some of these
    actions on the packet being processed, the helper should be able to call
    this function, hence the need to make it public.

    Moreover, if one argument is incorrect or if the next hop can not be found,
    an error should be returned by the BPF helper so the BPF program can adapt
    its processing of the packet (return an error, properly force the drop,
    ...). This patch hence makes this function return dst->error to indicate a
    possible error.

    Signed-off-by: Mathieu Xhonneux
    Acked-by: David Lebrun
    Signed-off-by: Daniel Borkmann

    Mathieu Xhonneux
     

05 Mar, 2018

1 commit

  • IPv6 does path selection for multipath routes deep in the lookup
    functions. The next patch adds L4 hash option and needs the skb
    for the forward path. To get the skb to the relevant FIB lookup
    functions it needs to go through the fib rules layer, so add a
    lookup_data argument to the fib_lookup_arg struct.

    Signed-off-by: David Ahern
    Reviewed-by: Ido Schimmel
    Reviewed-by: Nikolay Aleksandrov
    Signed-off-by: David S. Miller

    David Ahern
     

10 Jan, 2018

1 commit


12 Sep, 2017

1 commit


31 Aug, 2017

1 commit

  • IPv6 packet may carry more than one extension header, and IPv6 nodes must
    accept and attempt to process extension headers in any order and occurring
    any number of times in the same packet. Hence, there should be no
    assumption that Segment Routing extension header is to appear immediately
    after the IPv6 header.

    Moreover, section 4.1 of RFC 8200 gives a recommendation on the order of
    appearance of those extension headers within an IPv6 packet. According to
    this recommendation, Segment Routing extension header should appear after
    Hop-by-Hop and Destination Options headers (if they present).

    This patch fixes the get_srh(), so it gets the segment routing header
    regardless of its position in the chain of the extension headers in IPv6
    packet, and makes sure that the IPv6 routing extension header is of Type 4.

    Signed-off-by: Ahmed Abdelsalam
    Acked-by: David Lebrun
    Signed-off-by: David S. Miller

    Ahmed Abdelsalam
     

26 Aug, 2017

4 commits

  • This patch implements the following seg6local actions.

    - SEG6_LOCAL_ACTION_END_T: regular SRH processing and forward to the
    next-hop looked up in the specified routing table.

    - SEG6_LOCAL_ACTION_END_DX2: decapsulate an L2 frame and forward it to
    the specified network interface.

    - SEG6_LOCAL_ACTION_END_DX4: decapsulate an IPv4 packet and forward it,
    possibly to the specified next-hop.

    - SEG6_LOCAL_ACTION_END_DT6: decapsulate an IPv6 packet and forward it
    to the next-hop looked up in the specified routing table.

    Signed-off-by: David Lebrun
    Signed-off-by: David S. Miller

    David Lebrun
     
  • This patch adds three helper functions to be used with the seg6local packet
    processing actions.

    The decap_and_validate() function will be used by the End.D* actions, that
    decapsulate an SR-enabled packet.

    The advance_nextseg() function applies the fundamental operations to update
    an SRH for the next segment.

    The lookup_nexthop() function helps select the next-hop for the processed
    SR packets. It supports an optional next-hop address to route the packet
    specifically through it, and an optional routing table to use.

    Signed-off-by: David Lebrun
    Signed-off-by: David S. Miller

    David Lebrun
     
  • This patch ensures that the seg6local lightweight tunnel is used solely
    with IPv6 routes and processes only IPv6 packets.

    Signed-off-by: David Lebrun
    Signed-off-by: David S. Miller

    David Lebrun
     
  • This patch enables the SRv6 encapsulation mode to carry an IPv4 payload.
    All the infrastructure was already present, I just had to add a parameter
    to seg6_do_srh_encap() to specify the inner packet protocol, and perform
    some additional checks.

    Usage example:
    ip route add 1.2.3.4 encap seg6 mode encap segs fc00::1,fc00::2 dev eth0

    Signed-off-by: David Lebrun
    Signed-off-by: David S. Miller

    David Lebrun
     

08 Aug, 2017

3 commits

  • This patch implements the following seg6local actions.

    - SEG6_LOCAL_ACTION_END: regular SRH processing. The DA of the packet
    is updated to the next segment and forwarded accordingly.

    - SEG6_LOCAL_ACTION_END_X: same as above, except that the packet is
    forwarded to the specified IPv6 next-hop.

    - SEG6_LOCAL_ACTION_END_DX6: decapsulate the packet and forward to
    inner IPv6 packet to the specified IPv6 next-hop.

    - SEG6_LOCAL_ACTION_END_B6: insert the specified SRH directly after
    the IPv6 header of the packet.

    - SEG6_LOCAL_ACTION_END_B6_ENCAP: encapsulate the packet within
    an outer IPv6 header, containing the specified SRH.

    Signed-off-by: David Lebrun
    Signed-off-by: David S. Miller

    David Lebrun
     
  • This patch adds the necessary functions to parse, fill, and compare
    seg6local rtnetlink attributes, for all defined action parameters.

    - The SRH parameter defines an SRH to be inserted or encapsulated.
    - The TABLE parameter defines the table to use for the route lookup of
    the next segment or the inner decapsulated packet.
    - The NH4 parameter defines the IPv4 next-hop for an inner decapsulated
    IPv4 packet.
    - The NH6 parameter defines the IPv6 next-hop for the next segment or
    for an inner decapsulated IPv6 packet
    - The IIF parameter defines an ingress interface index.
    - The OIF parameter defines an egress interface index.

    Signed-off-by: David Lebrun
    Signed-off-by: David S. Miller

    David Lebrun
     
  • This patch implements a new type of lightweight tunnel named seg6local.
    A seg6local lwt is defined by a type of action and a set of parameters.
    The action represents the operation to perform on the packets matching the
    lwt's route, and is not necessarily an encapsulation. The set of parameters
    are arguments for the processing function.

    Each action is defined in a struct seg6_action_desc within
    seg6_action_table[]. This structure contains the action, mandatory
    attributes, the processing function, and a static headroom size required by
    the action. The mandatory attributes are encoded as a bitmask field. The
    static headroom is set to a non-zero value when the processing function
    always add a constant number of bytes to the skb (e.g. the header size for
    encapsulations).

    To facilitate rtnetlink-related operations such as parsing, fill_encap,
    and cmp_encap, each type of action parameter is associated to three
    function pointers, in seg6_action_params[].

    All actions defined in seg6_local.h are detailed in [1].

    [1] https://tools.ietf.org/html/draft-filsfils-spring-srv6-network-programming-01

    Signed-off-by: David Lebrun
    Signed-off-by: David S. Miller

    David Lebrun