Skip to content
  • Hadar Hen Zion's avatar
    IB/core: Add receive flow steering support · 319a441d
    Hadar Hen Zion authored
    
    
    The RDMA stack allows for applications to create IB_QPT_RAW_PACKET
    QPs, which receive plain Ethernet packets, specifically packets that
    don't carry any QPN to be matched by the receiving side.  Applications
    using these QPs must be provided with a method to program some
    steering rule with the HW so packets arriving at the local port can be
    routed to them.
    
    This patch adds ib_create_flow(), which allow providing a flow
    specification for a QP.  When there's a match between the
    specification and a received packet, the packet is forwarded to that
    QP, in a the same way one uses ib_attach_multicast() for IB UD
    multicast handling.
    
    Flow specifications are provided as instances of struct ib_flow_spec_yyy,
    which describe L2, L3 and L4 headers.  Currently specs for Ethernet, IPv4,
    TCP and UDP are defined.  Flow specs are made of values and masks.
    
    The input to ib_create_flow() is a struct ib_flow_attr, which contains
    a few mandatory control elements and optional flow specs.
    
        struct ib_flow_attr {
                enum ib_flow_attr_type type;
                u16      size;
                u16      priority;
                u32      flags;
                u8       num_of_specs;
                u8       port;
                /* Following are the optional layers according to user request
                 * struct ib_flow_spec_yyy
                 * struct ib_flow_spec_zzz
                 */
        };
    
    As these specs are eventually coming from user space, they are defined and
    used in a way which allows adding new spec types without kernel/user ABI
    change, just with a little API enhancement which defines the newly added spec.
    
    The flow spec structures are defined with TLV (Type-Length-Value)
    entries, which allows calling ib_create_flow() with a list of variable
    length of optional specs.
    
    For the actual processing of ib_flow_attr the driver uses the number
    of specs and the size mandatory fields along with the TLV nature of
    the specs.
    
    Steering rules processing order is according to the domain over which
    the rule is set and the rule priority.  All rules set by user space
    applicatations fall into the IB_FLOW_DOMAIN_USER domain, other domains
    could be used by future IPoIB RFS and Ethetool flow-steering interface
    implementation.  Lower numerical value for the priority field means
    higher priority.
    
    The returned value from ib_create_flow() is a struct ib_flow, which
    contains a database pointer (handle) provided by the HW driver to be
    used when calling ib_destroy_flow().
    
    Applications that offload TCP/IP traffic can also be written over IB
    UD QPs.  The ib_create_flow() / ib_destroy_flow() API is designed to
    support UD QPs too.  A HW driver can set IB_DEVICE_MANAGED_FLOW_STEERING
    to denote support for flow steering.
    
    The ib_flow_attr enum type supports usage of flow steering for promiscuous
    and sniffer purposes:
    
        IB_FLOW_ATTR_NORMAL - "regular" rule, steering according to rule specification
    
        IB_FLOW_ATTR_ALL_DEFAULT - default unicast and multicast rule, receive
            all Ethernet traffic which isn't steered to any QP
    
        IB_FLOW_ATTR_MC_DEFAULT - same as IB_FLOW_ATTR_ALL_DEFAULT but only for multicast
    
        IB_FLOW_ATTR_SNIFFER - sniffer rule, receive all port traffic
    
    ALL_DEFAULT and MC_DEFAULT rules options are valid only for Ethernet link type.
    
    Signed-off-by: default avatarHadar Hen Zion <hadarh@mellanox.com>
    Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
    Signed-off-by: default avatarRoland Dreier <roland@purestorage.com>
    319a441d