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