07 Aug, 2011

1 commit

  • Computers have become a lot faster since we compromised on the
    partial MD4 hash which we use currently for performance reasons.

    MD5 is a much safer choice, and is inline with both RFC1948 and
    other ISS generators (OpenBSD, Solaris, etc.)

    Furthermore, only having 24-bits of the sequence number be truly
    unpredictable is a very serious limitation. So the periodic
    regeneration and 8-bit counter have been removed. We compute and
    use a full 32-bit sequence number.

    For ipv6, DCCP was found to use a 32-bit truncated initial sequence
    number (it needs 43-bits) and that is fixed here as well.

    Reported-by: Dan Kaminsky
    Tested-by: Willy Tarreau
    Signed-off-by: David S. Miller

    David S. Miller
     

19 Jan, 2011

1 commit

  • Fix a bunch of
    warning: ‘inline’ is not at beginning of declaration
    messages when building a 'make allyesconfig' kernel with -Wextra.

    These warnings are trivial to kill, yet rather annoying when building with
    -Wextra.
    The more we can cut down on pointless crap like this the better (IMHO).

    A previous patch to do this for a 'allnoconfig' build has already been
    merged. This just takes the cleanup a little further.

    Signed-off-by: Jesper Juhl
    Signed-off-by: Jiri Kosina

    Jesper Juhl
     

09 Dec, 2009

1 commit

  • First patch changes __inet_hash_nolisten() and __inet6_hash()
    to get a timewait parameter to be able to unhash it from ehash
    at same time the new socket is inserted in hash.

    This makes sure timewait socket wont be found by a concurrent
    writer in __inet_check_established()

    Reported-by: kapil dakhane
    Signed-off-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Eric Dumazet
     

04 Dec, 2009

1 commit

  • Its currently possible that several threads issuing a connect() find
    the same timewait socket and try to reuse it, leading to list
    corruptions.

    Condition for bug is that these threads bound their socket on same
    address/port of to-be-find timewait socket, and connected to same
    target. (SO_REUSEADDR needed)

    To fix this problem, we could unhash timewait socket while holding
    ehash lock, to make sure lookups/changes will be serialized. Only
    first thread finds the timewait socket, other ones find the
    established socket and return an EADDRNOTAVAIL error.

    This second version takes into account Evgeniy's review and makes sure
    inet_twsk_put() is called outside of locked sections.

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

    Eric Dumazet
     

19 Oct, 2009

1 commit

  • In order to have better cache layouts of struct sock (separate zones
    for rx/tx paths), we need this preliminary patch.

    Goal is to transfert fields used at lookup time in the first
    read-mostly cache line (inside struct sock_common) and move sk_refcnt
    to a separate cache line (only written by rx path)

    This patch adds inet_ prefix to daddr, rcv_saddr, dport, num, saddr,
    sport and id fields. This allows a future patch to define these
    fields as macros, like sk_refcnt, without name clashes.

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

    Eric Dumazet
     

13 Oct, 2009

1 commit


26 Feb, 2009

1 commit

  • We already have a valid net in that place, but this is not just a
    cleanup - the tw pointer can be NULL there sometimes, thus causing
    an oops in NET_NS=y case.

    The same place in ipv4 code already works correctly using existing
    net, rather than tw's one.

    The bug exists since 2.6.27.

    Signed-off-by: Pavel Emelyanov
    Signed-off-by: David S. Miller

    Pavel Emelyanov
     

24 Nov, 2008

1 commit

  • This is the last step to be able to perform full RCU lookups
    in __inet_lookup() : After established/timewait tables, we
    add RCU lookups to listening hash table.

    The only trick here is that a socket of a given type (TCP ipv4,
    TCP ipv6, ...) can now flight between two different tables
    (established and listening) during a RCU grace period, so we
    must use different 'nulls' end-of-chain values for two tables.

    We define a large value :

    #define LISTENING_NULLS_BASE (1U << 29)

    So that slots in listening table are guaranteed to have different
    end-of-chain values than slots in established table. A reader can
    still detect it finished its lookup in the right chain.

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

    Eric Dumazet
     

21 Nov, 2008

1 commit

  • Now TCP & DCCP use RCU lookups, we can convert ehash rwlocks to spinlocks.

    /proc/net/tcp and other seq_file 'readers' can safely be converted to 'writers'.

    This should speedup writers, since spin_lock()/spin_unlock()
    only use one atomic operation instead of two for write_lock()/write_unlock()

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

    Eric Dumazet
     

20 Nov, 2008

1 commit

  • This patch prepares RCU migration of listening_hash table for
    TCP/DCCP protocols.

    listening_hash table being small (32 slots per protocol), we add
    a spinlock for each slot, instead of a single rwlock for whole table.

    This should reduce hold time of readers, and writers concurrency.

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

    Eric Dumazet
     

17 Nov, 2008

1 commit

  • RCU was added to UDP lookups, using a fast infrastructure :
    - sockets kmem_cache use SLAB_DESTROY_BY_RCU and dont pay the
    price of call_rcu() at freeing time.
    - hlist_nulls permits to use few memory barriers.

    This patch uses same infrastructure for TCP/DCCP established
    and timewait sockets.

    Thanks to SLAB_DESTROY_BY_RCU, no slowdown for applications
    using short lived TCP connections. A followup patch, converting
    rwlocks to spinlocks will even speedup this case.

    __inet_lookup_established() is pretty fast now we dont have to
    dirty a contended cache line (read_lock/read_unlock)

    Only established and timewait hashtable are converted to RCU
    (bind table and listen table are still using traditional locking)

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

    Eric Dumazet
     

26 Jul, 2008

1 commit

  • Removes legacy reinvent-the-wheel type thing. The generic
    machinery integrates much better to automated debugging aids
    such as kerneloops.org (and others), and is unambiguous due to
    better naming. Non-intuively BUG_TRAP() is actually equal to
    WARN_ON() rather than BUG_ON() though some might actually be
    promoted to BUG_ON() but I left that to future.

    I could make at least one BUILD_BUG_ON conversion.

    Signed-off-by: Ilpo Järvinen
    Signed-off-by: David S. Miller

    Ilpo Järvinen
     

17 Jul, 2008

1 commit


17 Jun, 2008

2 commits


01 Apr, 2008

1 commit


26 Mar, 2008

2 commits


23 Mar, 2008

1 commit

  • Inspired by the commit ab1e0a13 ([SOCK] proto: Add hashinfo member to
    struct proto) from Arnaldo, I made similar thing for UDP/-Lite IPv4
    and -v6 protocols.

    The result is not that exciting, but it removes some levels of
    indirection in udpxxx_get_port and saves some space in code and text.

    The first step is to union existing hashinfo and new udp_hash on the
    struct proto and give a name to this union, since future initialization
    of tcpxxx_prot, dccp_vx_protinfo and udpxxx_protinfo will cause gcc
    warning about inability to initialize anonymous member this way.

    Signed-off-by: Pavel Emelyanov
    Signed-off-by: David S. Miller

    Pavel Emelyanov
     

05 Feb, 2008

1 commit


03 Feb, 2008

1 commit

  • This way we can remove TCP and DCCP specific versions of

    sk->sk_prot->get_port: both v4 and v6 use inet_csk_get_port
    sk->sk_prot->hash: inet_hash is directly used, only v6 need
    a specific version to deal with mapped sockets
    sk->sk_prot->unhash: both v4 and v6 use inet_hash directly

    struct inet_connection_sock_af_ops also gets a new member, bind_conflict, so
    that inet_csk_get_port can find the per family routine.

    Now only the lookup routines receive as a parameter a struct inet_hashtable.

    With this we further reuse code, reducing the difference among INET transport
    protocols.

    Eventually work has to be done on UDP and SCTP to make them share this
    infrastructure and get as a bonus inet_diag interfaces so that iproute can be
    used with these protocols.

    net-2.6/net/ipv4/inet_hashtables.c:
    struct proto | +8
    struct inet_connection_sock_af_ops | +8
    2 structs changed
    __inet_hash_nolisten | +18
    __inet_hash | -210
    inet_put_port | +8
    inet_bind_bucket_create | +1
    __inet_hash_connect | -8
    5 functions changed, 27 bytes added, 218 bytes removed, diff: -191

    net-2.6/net/core/sock.c:
    proto_seq_show | +3
    1 function changed, 3 bytes added, diff: +3

    net-2.6/net/ipv4/inet_connection_sock.c:
    inet_csk_get_port | +15
    1 function changed, 15 bytes added, diff: +15

    net-2.6/net/ipv4/tcp.c:
    tcp_set_state | -7
    1 function changed, 7 bytes removed, diff: -7

    net-2.6/net/ipv4/tcp_ipv4.c:
    tcp_v4_get_port | -31
    tcp_v4_hash | -48
    tcp_v4_destroy_sock | -7
    tcp_v4_syn_recv_sock | -2
    tcp_unhash | -179
    5 functions changed, 267 bytes removed, diff: -267

    net-2.6/net/ipv6/inet6_hashtables.c:
    __inet6_hash | +8
    1 function changed, 8 bytes added, diff: +8

    net-2.6/net/ipv4/inet_hashtables.c:
    inet_unhash | +190
    inet_hash | +242
    2 functions changed, 432 bytes added, diff: +432

    vmlinux:
    16 functions changed, 485 bytes added, 492 bytes removed, diff: -7

    /home/acme/git/net-2.6/net/ipv6/tcp_ipv6.c:
    tcp_v6_get_port | -31
    tcp_v6_hash | -7
    tcp_v6_syn_recv_sock | -9
    3 functions changed, 47 bytes removed, diff: -47

    /home/acme/git/net-2.6/net/dccp/proto.c:
    dccp_destroy_sock | -7
    dccp_unhash | -179
    dccp_hash | -49
    dccp_set_state | -7
    dccp_done | +1
    5 functions changed, 1 bytes added, 242 bytes removed, diff: -241

    /home/acme/git/net-2.6/net/dccp/ipv4.c:
    dccp_v4_get_port | -31
    dccp_v4_request_recv_sock | -2
    2 functions changed, 33 bytes removed, diff: -33

    /home/acme/git/net-2.6/net/dccp/ipv6.c:
    dccp_v6_get_port | -31
    dccp_v6_hash | -7
    dccp_v6_request_recv_sock | +5
    3 functions changed, 5 bytes added, 38 bytes removed, diff: -33

    Signed-off-by: Arnaldo Carvalho de Melo
    Signed-off-by: David S. Miller

    Arnaldo Carvalho de Melo
     

01 Feb, 2008

3 commits

  • Add a net argument to inet6_lookup and propagate it further.
    Actually, this is tcp-v6 implementation of what was done for
    tcp-v4 sockets in a previous patch.

    Signed-off-by: Pavel Emelyanov
    Signed-off-by: David S. Miller

    Pavel Emelyanov
     
  • These two functions are the same except for what they call
    to "check_established" and "hash" for a socket.

    This saves half-a-kilo for ipv4 and ipv6.

    add/remove: 1/0 grow/shrink: 1/4 up/down: 582/-1128 (-546)
    function old new delta
    __inet_hash_connect - 577 +577
    arp_ignore 108 113 +5
    static.hint 8 4 -4
    rt_worker_func 376 372 -4
    inet6_hash_connect 584 25 -559
    inet_hash_connect 586 25 -561

    Signed-off-by: Pavel Emelyanov
    Signed-off-by: David S. Miller

    Pavel Emelyanov
     
  • We have INET_MATCH, INET_TW_MATCH and INET6_MATCH to test sockets and
    twbuckets for matching, but ipv6 twbuckets are tested manually.

    Here's the INET6_TW_MATCH to help with it.

    Signed-off-by: Pavel Emelyanov
    Signed-off-by: David S. Miller

    Pavel Emelyanov
     

29 Jan, 2008

1 commit

  • 1) Cleanups (all functions are prefixed by sock_prot_inuse)

    sock_prot_inc_use(prot) -> sock_prot_inuse_add(prot,-1)
    sock_prot_dec_use(prot) -> sock_prot_inuse_add(prot,-1)
    sock_prot_inuse() -> sock_prot_inuse_get()

    New functions :

    sock_prot_inuse_init() and sock_prot_inuse_free() to abstract pcounter use.

    2) if CONFIG_PROC_FS=n, we can zap 'inuse' member from "struct proto",
    since nobody wants to read the inuse value.

    This saves 1372 bytes on i386/SMP and some cpu cycles.

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

    Eric Dumazet
     

21 Jan, 2008

1 commit

  • When looking for a conflicting connection the !sk->sk_bound_dev_if
    check is performed only for live sockets, but not for timewait-ed.

    This is not the case for ipv4, for __inet6_lookup_established in
    both ipv4 and ipv6 and for other places that check for tw-s.

    Was this missed accidentally? If so, then this patch fixes it and
    besides makes use if the dif variable declared in the function.

    Signed-off-by: Pavel Emelyanov
    Signed-off-by: David S. Miller

    Pavel Emelyanov
     

07 Nov, 2007

1 commit

  • As done two years ago on IP route cache table (commit
    22c047ccbc68fa8f3fa57f0e8f906479a062c426) , we can avoid using one
    lock per hash bucket for the huge TCP/DCCP hash tables.

    On a typical x86_64 platform, this saves about 2MB or 4MB of ram, for
    litle performance differences. (we hit a different cache line for the
    rwlock, but then the bucket cache line have a better sharing factor
    among cpus, since we dirty it less often). For netstat or ss commands
    that want a full scan of hash table, we perform fewer memory accesses.

    Using a 'small' table of hashed rwlocks should be more than enough to
    provide correct SMP concurrency between different buckets, without
    using too much memory. Sizing of this table depends on
    num_possible_cpus() and various CONFIG settings.

    This patch provides some locking abstraction that may ease a future
    work using a different model for TCP/DCCP table.

    Signed-off-by: Eric Dumazet
    Acked-by: Arnaldo Carvalho de Melo
    Signed-off-by: David S. Miller

    Eric Dumazet
     

19 Oct, 2007

1 commit

  • There is a justifying patch for Stephen's patches. Stephen's patches
    disallows using a port range of one single port and brakes the meaning
    of the 'remaining' variable, in some places it has different meaning.
    My patch gives back the sense of 'remaining' variable. It should mean
    how many ports are remaining and nothing else. Also my patch allows
    using a single port.

    I sure we must be able to use mentioned port range, this does not
    restricted by documentation and does not brake current behavior.

    usefull links:
    Patches posted by Stephen Hemminger
    http://marc.info/?l=linux-netdev&m=119206106218187&w=2
    http://marc.info/?l=linux-netdev&m=119206109918235&w=2

    Andrew Morton's comment
    http://marc.info/?l=linux-kernel&m=119248225007737&w=2

    1. Allows using a port range of one single port.
    2. Gives back sense of 'remaining' variable.

    Signed-off-by: Anton Arapov
    Acked-by: Stephen Hemminger
    Signed-off-by: David S. Miller

    Anton Arapov
     

11 Oct, 2007

1 commit

  • Expansion of original idea from Denis V. Lunev

    Add robustness and locking to the local_port_range sysctl.
    1. Enforce that low < high when setting.
    2. Use seqlock to ensure atomic update.

    The locking might seem like overkill, but there are
    cases where sysadmin might want to change value in the
    middle of a DoS attack.

    Signed-off-by: Stephen Hemminger
    Signed-off-by: David S. Miller

    Stephen Hemminger
     

13 Feb, 2007

1 commit

  • Tetsuo Handa told me that connect(2) with TCPv6
    socket almost always took a few minutes to return when we did not have any
    ports available in the range of net.ipv4.ip_local_port_range.

    The reason was that we used incorrect seed for calculating index of
    hash when we check established sockets in __inet6_check_established().

    Signed-off-by: YOSHIFUJI Hideaki
    Signed-off-by: David S. Miller

    YOSHIFUJI Hideaki
     

11 Feb, 2007

1 commit


09 Feb, 2007

1 commit

  • ehash table layout is currently this one :

    First half of this table is used by sockets not in TIME_WAIT state
    Second half of it is used by sockets in TIME_WAIT state.

    This is non optimal because of for a given hash or socket, the two chain heads
    are located in separate cache lines.
    Moreover the locks of the second half are never used.

    If instead of this halving, we use two list heads in inet_ehash_bucket instead
    of only one, we probably can avoid one cache miss, and reduce ram usage,
    particularly if sizeof(rwlock_t) is big (various CONFIG_DEBUG_SPINLOCK,
    CONFIG_DEBUG_LOCK_ALLOC settings). So we still halves the table but we keep
    together related chains to speedup lookups and socket state change.

    In this patch I did not try to align struct inet_ehash_bucket, but a future
    patch could try to make this structure have a convenient size (a power of two
    or a multiple of L1_CACHE_SIZE).
    I guess rwlock will just vanish as soon as RCU is plugged into ehash :) , so
    maybe we dont need to scratch our heads to align the bucket...

    Note : In case struct inet_ehash_bucket is not a power of two, we could
    probably change alloc_large_system_hash() (in case it use __get_free_pages())
    to free the unused space. It currently allocates a big zone, but the last
    quarter of it could be freed. Again, this should be a temporary 'problem'.

    Patch tested on ipv4 tcp only, but should be OK for IPV6 and DCCP.

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

    Eric Dumazet
     

03 Dec, 2006

1 commit


29 Sep, 2006

1 commit

  • INET_MATCH() and friends depend on an interesting set of kludges:
    * there's a pair of adjacent fields in struct inet_sock - __be16 dport
    followed by __u16 num. We want to search by pair, so we combine the keys into
    a single 32bit value and compare with 32bit value read from &...->dport.
    * on 64bit targets we combine comparisons with pair of adjacent __be32
    fields in the same way.

    Make sure that we don't mix those values with anything else and that pairs
    we form them from have correct types.

    Signed-off-by: Al Viro
    Signed-off-by: David S. Miller

    Al Viro
     

01 Jul, 2006

1 commit


10 Apr, 2006

1 commit

  • Deinline a few functions which produce 200+ bytes of code.

    Size Uses Wasted Name and definition
    ===== ==== ====== ================================================
    429 3 818 __inet6_lookup include/net/inet6_hashtables.h
    404 2 384 __inet6_lookup_established include/net/inet6_hashtables.h
    206 3 372 __inet6_hash include/net/inet6_hashtables.h

    Signed-off-by: Denis Vlasenko
    Signed-off-by: David S. Miller

    Denis Vlasenko
     

14 Mar, 2006

1 commit

  • When we link a socket into the hash table, we need to make sure that we
    set the num/port fields so that it shows us with a non-zero port value
    in proc/netlink and on the wire. This code and comment is copied over
    from the IPv4 stack as is.

    Signed-off-by: Herbert Xu

    Herbert Xu
     

04 Jan, 2006

1 commit


30 Aug, 2005

1 commit