• Florian Westphal's avatar
    mptcp: add MPTCP_TCPINFO getsockopt support · 06f15cee
    Florian Westphal authored
    Allow users to retrieve TCP_INFO data of all subflows.
    
    Users need to pre-initialize a meta header that has to be
    prepended to the data buffer that will be filled with the tcp info data.
    
    The meta header looks like this:
    
    struct mptcp_subflow_data {
     __u32 size_subflow_data;/* size of this structure in userspace */
     __u32 num_subflows;	/* must be 0, set by kernel */
     __u32 size_kernel;	/* must be 0, set by kernel */
     __u32 size_user;	/* size of one element in data[] */
    } __attribute__((aligned(8)));
    
    size_subflow_data has to be set to 'sizeof(struct mptcp_subflow_data)'.
    This allows to extend mptcp_subflow_data structure later on without
    breaking backwards compatibility.
    
    If the structure is extended later on, kernel knows where the
    userspace-provided meta header ends, even if userspace uses an older
    (smaller) version of the structure.
    
    num_subflows must be set to 0. If the getsockopt request succeeds (return
    value is 0), it will be updated to contain the number of active subflows
    for the given logical connection.
    
    size_kernel must be set to 0. If the getsockopt request is successful,
    it will contain the size of the 'struct tcp_info' as known by the kernel.
    This is informational only.
    
    size_user must be set to 'sizeof(struct tcp_info)'.
    
    This allows the kernel to only fill in the space reserved/expected by
    userspace.
    
    Example:
    
    struct my_tcp_info {
      struct mptcp_subflow_data d;
      struct tcp_info ti[2];
    };
    struct my_tcp_info ti;
    socklen_t olen;
    
    memset(&ti, 0, sizeof(ti));
    
    ti.d.size_subflow_data = sizeof(struct mptcp_subflow_data);
    ti.d.size_user = sizeof(struct tcp_info);
    olen = sizeof(ti);
    
    ret = getsockopt(fd, SOL_MPTCP, MPTCP_TCPINFO, &ti, &olen);
    if (ret < 0)
    	die_perror("getsockopt MPTCP_TCPINFO");
    
    mptcp_subflow_data.num_subflows is populated with the number of
    subflows that exist on the kernel side for the logical mptcp connection.
    
    This allows userspace to re-try with a larger tcp_info array if the number
    of subflows was larger than the available space in the ti[] array.
    
    olen has to be set to the number of bytes that userspace has allocated to
    receive the kernel data.  It will be updated to contain the real number
    bytes that have been copied to by the kernel.
    
    In the above example, if the number if subflows was 1, olen is equal to
    'sizeof(struct mptcp_subflow_data) + sizeof(struct tcp_info).
    For 2 or more subflows olen is equal to 'sizeof(struct my_tcp_info)'.
    
    If there was more data that could not be copied due to lack of space
    in the option buffer, userspace can detect this by checking
    mptcp_subflow_data->num_subflows.
    Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
    Signed-off-by: default avatarMat Martineau <mathew.j.martineau@linux.intel.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    06f15cee
sockopt.c 24.3 KB