28 Jan, 2017

1 commit


27 Jan, 2017

1 commit

  • Unlike ipv4, this control socket is shared by all cpus so we cannot use
    it as scratchpad area to annotate the mark that we pass to ip6_xmit().

    Add a new parameter to ip6_xmit() to indicate the mark. The SCTP socket
    family caches the flowi6 structure in the sctp_transport structure, so
    we cannot use to carry the mark unless we later on reset it back, which
    I discarded since it looks ugly to me.

    Fixes: bf99b4ded5f8 ("tcp: fix mark propagation with fwmark_reflect enabled")
    Suggested-by: Eric Dumazet
    Signed-off-by: Pablo Neira Ayuso
    Signed-off-by: David S. Miller

    Pablo Neira
     

19 Jan, 2017

2 commits

  • The only difference between inet6_csk_bind_conflict and inet_csk_bind_conflict
    is how they check the rcv_saddr, so delete this call back and simply
    change inet_csk_bind_conflict to call inet_rcv_saddr_equal.

    Signed-off-by: Josef Bacik
    Signed-off-by: David S. Miller

    Josef Bacik
     
  • We pass these per-protocol equal functions around in various places, but
    we can just have one function that checks the sk->sk_family and then do
    the right comparison function. I've also changed the ipv4 version to
    not cast to inet_sock since it is unneeded.

    Signed-off-by: Josef Bacik
    Signed-off-by: David S. Miller

    Josef Bacik
     

18 Dec, 2016

1 commit

  • A user may call listen with binding an explicit port with the intent
    that the kernel will assign an available port to the socket. In this
    case inet_csk_get_port does a port scan. For such sockets, the user may
    also set soreuseport with the intent a creating more sockets for the
    port that is selected. The problem is that the initial socket being
    opened could inadvertently choose an existing and unreleated port
    number that was already created with soreuseport.

    This patch adds a boolean parameter to inet_bind_conflict that indicates
    rather soreuseport is allowed for the check (in addition to
    sk->sk_reuseport). In calls to inet_bind_conflict from inet_csk_get_port
    the argument is set to true if an explicit port is being looked up (snum
    argument is nonzero), and is false if port scan is done.

    Signed-off-by: Tom Herbert
    Signed-off-by: David S. Miller

    Tom Herbert
     

05 Nov, 2016

1 commit

  • - Use the UID in routing lookups made by protocol connect() and
    sendmsg() functions.
    - Make sure that routing lookups triggered by incoming packets
    (e.g., Path MTU discovery) take the UID of the socket into
    account.
    - For packets not associated with a userspace socket, (e.g., ping
    replies) use UID 0 inside the user namespace corresponding to
    the network namespace the socket belongs to. This allows
    all namespaces to apply routing and iptables rules to
    kernel-originated traffic in that namespaces by matching UID 0.
    This is better than using the UID of the kernel socket that is
    sending the traffic, because the UID of kernel sockets created
    at namespace creation time (e.g., the per-processor ICMP and
    TCP sockets) is the UID of the user that created the socket,
    which might not be mapped in the namespace.

    Tested: compiles allnoconfig, allyesconfig, allmodconfig
    Tested: https://android-review.googlesource.com/253302
    Signed-off-by: Lorenzo Colitti
    Signed-off-by: David S. Miller

    Lorenzo Colitti
     

11 Feb, 2016

1 commit

  • This change extends the fast SO_REUSEPORT socket lookup implemented
    for UDP to TCP. Listener sockets with SO_REUSEPORT and the same
    receive address are additionally added to an array for faster
    random access. This means that only a single socket from the group
    must be found in the listener list before any socket in the group can
    be used to receive a packet. Previously, every socket in the group
    needed to be considered before handing off the incoming packet.

    This feature also exposes the ability to use a BPF program when
    selecting a socket from a reuseport group.

    Signed-off-by: Craig Gallek
    Signed-off-by: David S. Miller

    Craig Gallek
     

05 Jan, 2016

1 commit

  • Include a struct sock_reuseport instance when a UDP socket binds to
    a specific address for the first time with the reuseport flag set.
    When selecting a socket for an incoming UDP packet, use the information
    available in sock_reuseport if present.

    This required adding an additional field to the UDP source address
    equality function to differentiate between exact and wildcard matches.
    The original use case allowed wildcard matches when checking for
    existing port uses during bind. The new use case of adding a socket
    to a reuseport group requires exact address matching.

    Performance test (using a machine with 2 CPU sockets and a total of
    48 cores): Create reuseport groups of varying size. Use one socket
    from this group per user thread (pinning each thread to a different
    core) calling recvmmsg in a tight loop. Record number of messages
    received per second while saturating a 10G link.
    10 sockets: 18% increase (~2.8M -> 3.3M pkts/s)
    20 sockets: 14% increase (~2.9M -> 3.3M pkts/s)
    40 sockets: 13% increase (~3.0M -> 3.4M pkts/s)

    This work is based off a similar implementation written by
    Ying Cai for implementing policy-based reuseport
    selection.

    Signed-off-by: Craig Gallek
    Signed-off-by: David S. Miller

    Craig Gallek
     

04 Dec, 2015

1 commit

  • While testing the np->opt RCU conversion, I found that UDP/IPv6 was
    using a mixture of xchg() and sk_dst_lock to protect concurrent changes
    to sk->sk_dst_cache, leading to possible corruptions and crashes.

    ip6_sk_dst_lookup_flow() uses sk_dst_check() anyway, so the simplest
    way to fix the mess is to remove sk_dst_lock completely, as we did for
    IPv4.

    __ip6_dst_store() and ip6_dst_store() share same implementation.

    sk_setup_caps() being called with socket lock being held or not,
    we have to use sk_dst_set() instead of __sk_dst_set()

    Note that I had to move the "np->dst_cookie = rt6_get_cookie(rt);"
    in ip6_dst_store() before the sk_setup_caps(sk, dst) call.

    This is because ip6_dst_store() can be called from process context,
    without any lock held.

    As soon as the dst is installed in sk->sk_dst_cache, dst can be freed
    from another cpu doing a concurrent ip6_dst_store()

    Doing the dst dereference before doing the install is needed to make
    sure no use after free would trigger.

    Signed-off-by: Eric Dumazet
    Reported-by: Dmitry Vyukov
    Signed-off-by: David S. Miller

    Eric Dumazet
     

03 Dec, 2015

1 commit

  • This patch addresses multiple problems :

    UDP/RAW sendmsg() need to get a stable struct ipv6_txoptions
    while socket is not locked : Other threads can change np->opt
    concurrently. Dmitry posted a syzkaller
    (http://github.com/google/syzkaller) program desmonstrating
    use-after-free.

    Starting with TCP/DCCP lockless listeners, tcp_v6_syn_recv_sock()
    and dccp_v6_request_recv_sock() also need to use RCU protection
    to dereference np->opt once (before calling ipv6_dup_options())

    This patch adds full RCU protection to np->opt

    Reported-by: Dmitry Vyukov
    Signed-off-by: Eric Dumazet
    Acked-by: Hannes Frederic Sowa
    Signed-off-by: David S. Miller

    Eric Dumazet
     

03 Oct, 2015

2 commits

  • In this patch, we insert request sockets into TCP/DCCP
    regular ehash table (where ESTABLISHED and TIMEWAIT sockets
    are) instead of using the per listener hash table.

    ACK packets find SYN_RECV pseudo sockets without having
    to find and lock the listener.

    In nominal conditions, this halves pressure on listener lock.

    Note that this will allow for SO_REUSEPORT refinements,
    so that we can select a listener using cpu/numa affinities instead
    of the prior 'consistent hash', since only SYN packets will
    apply this selection logic.

    We will shrink listen_sock in the following patch to ease
    code review.

    Signed-off-by: Eric Dumazet
    Cc: Ying Cai
    Cc: Willem de Bruijn
    Signed-off-by: David S. Miller

    Eric Dumazet
     
  • This is no longer used.

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

30 Sep, 2015

1 commit

  • Before changing dccp_v6_request_recv_sock() sock argument
    to const, we need to get rid of security_sk_classify_flow(),
    and it seems doable by reusing inet6_csk_route_req() helper.

    We need to add a proto parameter to inet6_csk_route_req(),
    not assume it is TCP.

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

26 Sep, 2015

1 commit


24 Mar, 2015

1 commit

  • This is a low hanging fruit, as we'll get rid of syn_wait_lock eventually.

    We hold syn_wait_lock for such small sections, that it makes no sense to use
    a read/write lock. A spin lock is simply faster.

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

21 Mar, 2015

2 commits

  • One of the major issue for TCP is the SYNACK rtx handling,
    done by inet_csk_reqsk_queue_prune(), fired by the keepalive
    timer of a TCP_LISTEN socket.

    This function runs for awful long times, with socket lock held,
    meaning that other cpus needing this lock have to spin for hundred of ms.

    SYNACK are sent in huge bursts, likely to cause severe drops anyway.

    This model was OK 15 years ago when memory was very tight.

    We now can afford to have a timer per request sock.

    Timer invocations no longer need to lock the listener,
    and can be run from all cpus in parallel.

    With following patch increasing somaxconn width to 32 bits,
    I tested a listener with more than 4 million active request sockets,
    and a steady SYNFLOOD of ~200,000 SYN per second.
    Host was sending ~830,000 SYNACK per second.

    This is ~100 times more what we could achieve before this patch.

    Later, we will get rid of the listener hash and use ehash instead.

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     
  • When request sock are put in ehash table, the whole notion
    of having a previous request to update dl_next is pointless.

    Also, following patch will get rid of big purge timer,
    so we want to delete a request sock without holding listener lock.

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

25 Aug, 2014

2 commits

  • This patch makes no changes to the logic of the code but simply addresses
    coding style issues as detected by checkpatch.

    Both objdump and diff -w show no differences.

    This patch removes some blank lines between the end of a function
    definition and the EXPORT_SYMBOL_GPL macro in order to prevent
    checkpatch warning that EXPORT_SYMBOL must immediately follow
    a function.

    Signed-off-by: Ian Morris
    Signed-off-by: David S. Miller

    Ian Morris
     
  • This patch makes no changes to the logic of the code but simply addresses
    coding style issues as detected by checkpatch.

    Both objdump and diff -w show no differences.

    A number of items are addressed in this patch:
    * Multiple spaces converted to tabs
    * Spaces before tabs removed.
    * Spaces in pointer typing cleansed (char *)foo etc.
    * Remove space after sizeof
    * Ensure spacing around comparators such as if statements.

    Signed-off-by: Ian Morris
    Signed-off-by: David S. Miller

    Ian Morris
     

14 May, 2014

1 commit

  • When using mark-based routing, sockets returned from accept()
    may need to be marked differently depending on the incoming
    connection request.

    This is the case, for example, if different socket marks identify
    different networks: a listening socket may want to accept
    connections from all networks, but each connection should be
    marked with the network that the request came in on, so that
    subsequent packets are sent on the correct network.

    This patch adds a sysctl to mark TCP sockets based on the fwmark
    of the incoming SYN packet. If enabled, and an unmarked socket
    receives a SYN, then the SYN packet's fwmark is written to the
    connection's inet_request_sock, and later written back to the
    accepted socket when the connection is established. If the
    socket already has a nonzero mark, then the behaviour is the same
    as it is today, i.e., the listening socket's fwmark is used.

    Black-box tested using user-mode linux:

    - IPv4/IPv6 SYN+ACK, FIN, etc. packets are routed based on the
    mark of the incoming SYN packet.
    - The socket returned by accept() is marked with the mark of the
    incoming SYN packet.
    - Tested with syncookies=1 and syncookies=2.

    Signed-off-by: Lorenzo Colitti
    Signed-off-by: David S. Miller

    Lorenzo Colitti
     

16 Apr, 2014

1 commit

  • ip_queue_xmit() assumes the skb it has to transmit is attached to an
    inet socket. Commit 31c70d5956fc ("l2tp: keep original skb ownership")
    changed l2tp to not change skb ownership and thus broke this assumption.

    One fix is to add a new 'struct sock *sk' parameter to ip_queue_xmit(),
    so that we do not assume skb->sk points to the socket used by l2tp
    tunnel.

    Fixes: 31c70d5956fc ("l2tp: keep original skb ownership")
    Reported-by: Zhan Jianyu
    Tested-by: Zhan Jianyu
    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

06 Dec, 2013

1 commit


11 Oct, 2013

1 commit

  • In commit 634fb979e8f ("inet: includes a sock_common in request_sock")
    I forgot that the two ports in sock_common do not have same byte order :

    skc_dport is __be16 (network order), but skc_num is __u16 (host order)

    So sparse complains because ir_loc_port (mapped into skc_num) is
    considered as __u16 while it should be __be16

    Let rename ir_loc_port to ireq->ir_num (analogy with inet->inet_num),
    and perform appropriate htons/ntohs conversions.

    Signed-off-by: Eric Dumazet
    Reported-by: Wu Fengguang
    Signed-off-by: David S. Miller

    Eric Dumazet
     

10 Oct, 2013

1 commit

  • TCP listener refactoring, part 5 :

    We want to be able to insert request sockets (SYN_RECV) into main
    ehash table instead of the per listener hash table to allow RCU
    lookups and remove listener lock contention.

    This patch includes the needed struct sock_common in front
    of struct request_sock

    This means there is no more inet6_request_sock IPv6 specific
    structure.

    Following inet_request_sock fields were renamed as they became
    macros to reference fields from struct sock_common.
    Prefix ir_ was chosen to avoid name collisions.

    loc_port -> ir_loc_port
    loc_addr -> ir_loc_addr
    rmt_addr -> ir_rmt_addr
    rmt_port -> ir_rmt_port
    iif -> ir_iif

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

09 Oct, 2013

1 commit

  • TCP listener refactoring, part 4 :

    To speed up inet lookups, we moved IPv4 addresses from inet to struct
    sock_common

    Now is time to do the same for IPv6, because it permits us to have fast
    lookups for all kind of sockets, including upcoming SYN_RECV.

    Getting IPv6 addresses in TCP lookups currently requires two extra cache
    lines, plus a dereference (and memory stall).

    inet6_sk(sk) does the dereference of inet_sk(__sk)->pinet6

    This patch is way bigger than its IPv4 counter part, because for IPv4,
    we could add aliases (inet_daddr, inet_rcv_saddr), while on IPv6,
    it's not doable easily.

    inet6_sk(sk)->daddr becomes sk->sk_v6_daddr
    inet6_sk(sk)->rcv_saddr becomes sk->sk_v6_rcv_saddr

    And timewait socket also have tw->tw_v6_daddr & tw->tw_v6_rcv_saddr
    at the same offset.

    We get rid of INET6_TW_MATCH() as INET6_MATCH() is now the generic
    macro.

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

09 Mar, 2013

1 commit

  • This patch requires multicast interface-scoped addresses to supply a
    sin6_scope_id. Because the sin6_scope_id is now also correctly used
    in case of interface-scoped multicast traffic this enables one to use
    interface scoped addresses over interfaces which are not targeted by the
    default multicast route (the route has to be put there manually, though).

    getsockname() and getpeername() now return the correct sin6_scope_id in
    case of interface-local mc addresses.

    v2:
    a) rebased ontop of patch 1/4 (now uses ipv6_addr_props)

    v3:
    a) reverted changes for ipv6_addr_props

    v4:
    a) unchanged

    Cc: YOSHIFUJI Hideaki
    Acked-by: YOSHIFUJI Hideaki
    Signed-off-by: Hannes Frederic Sowa
    Acked-by: YOSHIFUJI Hideaki dave
    Signed-off-by: David S. Miller

    Hannes Frederic Sowa
     

06 Mar, 2013

1 commit


28 Feb, 2013

1 commit

  • I'm not sure why, but the hlist for each entry iterators were conceived

    list_for_each_entry(pos, head, member)

    The hlist ones were greedy and wanted an extra parameter:

    hlist_for_each_entry(tpos, pos, head, member)

    Why did they need an extra pos parameter? I'm not quite sure. Not only
    they don't really need it, it also prevents the iterator from looking
    exactly like the list iterator, which is unfortunate.

    Besides the semantic patch, there was some manual work required:

    - Fix up the actual hlist iterators in linux/list.h
    - Fix up the declaration of other iterators based on the hlist ones.
    - A very small amount of places were using the 'node' parameter, this
    was modified to use 'obj->member' instead.
    - Coccinelle didn't handle the hlist_for_each_entry_safe iterator
    properly, so those had to be fixed up manually.

    The semantic patch which is mostly the work of Peter Senna Tschudin is here:

    @@
    iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;

    type T;
    expression a,c,d,e;
    identifier b;
    statement S;
    @@

    -T b;

    [akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
    [akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
    [akpm@linux-foundation.org: checkpatch fixes]
    [akpm@linux-foundation.org: fix warnings]
    [akpm@linux-foudnation.org: redo intrusive kvm changes]
    Tested-by: Peter Senna Tschudin
    Acked-by: Paul E. McKenney
    Signed-off-by: Sasha Levin
    Cc: Wu Fengguang
    Cc: Marcelo Tosatti
    Cc: Gleb Natapov
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Sasha Levin
     

30 Jan, 2013

1 commit

  • When attempting to build linux-next with user namespaces enabled I ran
    into this fun build error.

    CC net/ipv6/inet6_connection_sock.o
    .../net/ipv6/inet6_connection_sock.c: In function ‘inet6_csk_bind_conflict’:
    .../net/ipv6/inet6_connection_sock.c:37:12: error: incompatible types when initializing type ‘int’ using
    type ‘kuid_t’
    .../net/ipv6/inet6_connection_sock.c:54:30: error: incompatible type for argument 1 of ‘uid_eq’
    .../include/linux/uidgid.h:48:20: note: expected ‘kuid_t’ but argument is of type ‘int’
    make[3]: *** [net/ipv6/inet6_connection_sock.o] Error 1
    make[2]: *** [net/ipv6] Error 2
    make[2]: *** Waiting for unfinished jobs....

    Using kuid_t instead of int to hold the uid fixes this.

    Cc: Tom Herbert
    Signed-off-by: "Eric W. Biederman"
    Signed-off-by: David S. Miller

    Eric W. Biederman
     

24 Jan, 2013

1 commit

  • Motivation for soreuseport would be something like a web server
    binding to port 80 running with multiple threads, where each thread
    might have it's own listener socket. This could be done as an
    alternative to other models: 1) have one listener thread which
    dispatches completed connections to workers. 2) accept on a single
    listener socket from multiple threads. In case #1 the listener thread
    can easily become the bottleneck with high connection turn-over rate.
    In case #2, the proportion of connections accepted per thread tends
    to be uneven under high connection load (assuming simple event loop:
    while (1) { accept(); process() }, wakeup does not promote fairness
    among the sockets. We have seen the disproportion to be as high
    as 3:1 ratio between thread accepting most connections and the one
    accepting the fewest. With so_reusport the distribution is
    uniform.

    Signed-off-by: Tom Herbert
    Signed-off-by: David S. Miller

    Tom Herbert
     

21 Nov, 2012

1 commit


19 Sep, 2012

1 commit

  • IPv6 dst should take care of rt_genid too. When a xfrm policy is inserted or
    deleted, all dst should be invalidated.
    To force the validation, dst entries should be created with ->obsolete set to
    DST_OBSOLETE_FORCE_CHK. This was already the case for all functions calling
    ip6_dst_alloc(), except for ip6_rt_copy().

    As a consequence, we can remove the specific code in inet6_connection_sock.

    Signed-off-by: Nicolas Dichtel
    Signed-off-by: David S. Miller

    Nicolas Dichtel
     

18 Jul, 2012

1 commit

  • We should provide to inet6_csk_route_socket a struct flowi6 pointer,
    so that net6_csk_xmit() works correctly instead of sending garbage.

    Also add some consts

    Signed-off-by: Eric Dumazet
    Reported-by: Yuchung Cheng
    Cc: Neal Cardwell
    Signed-off-by: David S. Miller

    Eric Dumazet
     

17 Jul, 2012

1 commit

  • This will be used so that we can compose a full flow key.

    Even though we have a route in this context, we need more. In the
    future the routes will be without destination address, source address,
    etc. keying. One ipv4 route will cover entire subnets, etc.

    In this environment we have to have a way to possess persistent storage
    for redirects and PMTU information. This persistent storage will exist
    in the FIB tables, and that's why we'll need to be able to rebuild a
    full lookup flow key here. Using that flow key will do a fib_lookup()
    and create/update the persistent entry.

    Signed-off-by: David S. Miller

    David S. Miller
     

16 Jul, 2012

1 commit


29 Jun, 2012

2 commits

  • This commit changes inet_csk_route_req() so that it uses a pointer to
    a struct flowi6, rather than allocating its own on the stack. This
    brings its behavior in line with its IPv4 cousin,
    inet_csk_route_req(), and allows a follow-on patch to fix a dst leak.

    Signed-off-by: Neal Cardwell
    Signed-off-by: David S. Miller

    Neal Cardwell
     
  • Fix inet6_csk_route_req() to use as the flowi6_oif the treq->iif,
    which is correctly fixed up in tcp_v6_conn_request() to handle the
    case of link-local addresses. This brings it in line with the
    tcp_v6_send_synack() code, which is already correctly using the
    treq->iif in this way.

    Signed-off-by: Neal Cardwell
    Signed-off-by: David S. Miller

    Neal Cardwell
     

15 Apr, 2012

1 commit

  • We must try harder to get unique (addr, port) pairs when
    doing port autoselection for sockets with SO_REUSEADDR
    option set.

    We achieve this by adding a relaxation parameter to
    inet_csk_bind_conflict. When 'relax' parameter is off
    we return a conflict whenever the current searched
    pair (addr, port) is not unique.

    This tries to address the problems reported in patch:
    8d238b25b1ec22a73b1c2206f111df2faaff8285
    Revert "tcp: bind() fix when many ports are bound"

    Tests where ran for creating and binding(0) many sockets
    on 100 IPs. The results are, on average:

    * 60000 sockets, 600 ports / IP:
    * 0.210 s, 620 (IP, port) duplicates without patch
    * 0.219 s, no duplicates with patch
    * 100000 sockets, 1000 ports / IP:
    * 0.371 s, 1720 duplicates without patch
    * 0.373 s, no duplicates with patch
    * 200000 sockets, 2000 ports / IP:
    * 0.766 s, 6900 duplicates without patch
    * 0.768 s, no duplicates with patch
    * 500000 sockets, 5000 ports / IP:
    * 2.227 s, 41500 duplicates without patch
    * 2.284 s, no duplicates with patch

    Signed-off-by: Alex Copot
    Signed-off-by: Daniel Baluta
    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Alex Copot
     

27 Nov, 2011

1 commit


24 Nov, 2011

1 commit

  • commit 72a3effaf633bc ([NET]: Size listen hash tables using backlog
    hint) added a bug allowing inet6_synq_hash() to return an out of bound
    array index, because of u16 overflow.

    Bug can happen if system admins set net.core.somaxconn &
    net.ipv4.tcp_max_syn_backlog sysctls to values greater than 65536

    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet