• Pavel Emelyanov's avatar
    sk-filter: Add ability to get socket filter program (v2) · a8fc9277
    Pavel Emelyanov authored
    The SO_ATTACH_FILTER option is set only. I propose to add the get
    ability by using SO_ATTACH_FILTER in getsockopt. To be less
    irritating to eyes the SO_GET_FILTER alias to it is declared. This
    ability is required by checkpoint-restore project to be able to
    save full state of a socket.
    There are two issues with getting filter back.
    First, kernel modifies the sock_filter->code on filter load, thus in
    order to return the filter element back to user we have to decode it
    into user-visible constants. Fortunately the modification in question
    is interconvertible.
    Second, the BPF_S_ALU_DIV_K code modifies the command argument k to
    speed up the run-time division by doing kernel_k = reciprocal(user_k).
    Bad news is that different user_k may result in same kernel_k, so we
    can't get the original user_k back. Good news is that we don't have
    to do it. What we need to is calculate a user2_k so, that
      reciprocal(user2_k) == reciprocal(user_k) == kernel_k
    i.e. if it's re-loaded back the compiled again value will be exactly
    the same as it was. That said, the user2_k can be calculated like this
      user2_k = reciprocal(kernel_k)
    with an exception, that if kernel_k == 0, then user2_k == 1.
    The optlen argument is treated like this -- when zero, kernel returns
    the amount of sock_fprog elements in filter, otherwise it should be
    large enough for the sock_fprog array.
    changes since v1:
    * Declared SO_GET_FILTER in all arch headers
    * Added decode of vlan-tag codes
    Signed-off-by: default avatarPavel Emelyanov <xemul@parallels.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>