14 Mar, 2014

1 commit


01 Nov, 2013

1 commit

  • On some codepaths the skb does not have a dst entry
    when xfrm_decode_session() is called. So check for
    a valid skb_dst() before dereferencing the device
    interface index. We use 0 as the device index if
    there is no valid skb_dst(), or at reverse decoding
    we use skb_iif as device interface index.

    Bug was introduced with git commit bafd4bd4dc
    ("xfrm: Decode sessions with output interface.").

    Reported-by: Meelis Roos
    Tested-by: Meelis Roos
    Signed-off-by: Steffen Klassert

    Steffen Klassert
     

28 Oct, 2013

1 commit

  • With the removal of the routing cache, we lost the
    option to tweak the garbage collector threshold
    along with the maximum routing cache size. So git
    commit 703fb94ec ("xfrm: Fix the gc threshold value
    for ipv4") moved back to a static threshold.

    It turned out that the current threshold before we
    start garbage collecting is much to small for some
    workloads, so increase it from 1024 to 32768. This
    means that we start the garbage collector if we have
    more than 32768 dst entries in the system and refuse
    new allocations if we are above 65536.

    Reported-by: Wolfgang Walter
    Signed-off-by: Steffen Klassert

    Steffen Klassert
     

16 Sep, 2013

1 commit


12 May, 2013

1 commit


06 Feb, 2013

1 commit

  • The xfrm gc threshold can be configured via xfrm{4,6}_gc_thresh
    sysctl but currently only in init_net, other namespaces always
    use the default value. This can substantially limit the number
    of IPsec tunnels that can be effectively used.

    Signed-off-by: Michal Kubecek
    Signed-off-by: Steffen Klassert

    Michal Kubecek
     

18 Jan, 2013

1 commit


16 Nov, 2012

1 commit


15 Nov, 2012

1 commit

  • Unlike ipv4 did, ipv6 does not handle the maximum number of cached
    routes dynamically. So no need to try to handle the IPsec gc threshold
    value dynamically. This patch sets the IPsec gc threshold value back to
    1024 routes, as it is for non-IPsec routes.

    Signed-off-by: Steffen Klassert

    Steffen Klassert
     

02 Nov, 2012

1 commit

  • #if defined(CONFIG_FOO) || defined(CONFIG_FOO_MODULE)

    can be replaced by

    #if IS_ENABLED(CONFIG_FOO)

    Cc: David S. Miller
    Signed-off-by: Cong Wang
    Signed-off-by: David S. Miller

    Amerigo Wang
     

20 Aug, 2012

1 commit

  • Commit 97bab73f (inet: Hide route peer accesses behind helpers.) introduced
    a bug in xfrm6_policy_destroy(). The xfrm_dst's _rt6i_peer member is not
    initialized, causing a false positive result from inetpeer_ptr_is_peer(),
    which in turn causes a NULL pointer dereference in inet_putpeer().

    Pid: 314, comm: kworker/0:1 Not tainted 3.6.0-rc1+ #17 To Be Filled By O.E.M. To Be Filled By O.E.M./P4S800D-X
    EIP: 0060:[] EFLAGS: 00010246 CPU: 0
    EIP is at inet_putpeer+0xe/0x16
    EAX: 00000000 EBX: f3481700 ECX: 00000000 EDX: 000dd641
    ESI: f3481700 EDI: c05e949c EBP: f551def4 ESP: f551def4
    DS: 007b ES: 007b FS: 0000 GS: 00e0 SS: 0068
    CR0: 8005003b CR2: 00000070 CR3: 3243d000 CR4: 00000750
    DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
    DR6: ffff0ff0 DR7: 00000400
    f551df04 c0423de1 00000000 f3481700 f551df18 c038d5f7 f254b9f8 f551df28
    f34f85d8 f551df20 c03ef48d f551df3c c0396870 f30697e8 f24e1738 c05e98f4
    f5509540 c05cd2b4 f551df7c c0142d2b c043feb5 f5509540 00000000 c05cd2e8
    [] xfrm6_dst_destroy+0x42/0xdb
    [] dst_destroy+0x1d/0xa4
    [] xfrm_bundle_flo_delete+0x2b/0x36
    [] flow_cache_gc_task+0x85/0x9f
    [] process_one_work+0x122/0x441
    [] ? apic_timer_interrupt+0x31/0x38
    [] ? flow_cache_new_hashrnd+0x2b/0x2b
    [] worker_thread+0x113/0x3cc

    Fix by adding a init_dst() callback to struct xfrm_policy_afinfo to
    properly initialize the dst's peer pointer.

    Signed-off-by: Patrick McHardy
    Signed-off-by: David S. Miller

    Patrick McHardy
     

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
     

12 Jul, 2012

1 commit


05 Jul, 2012

1 commit


11 Jun, 2012

1 commit

  • We encode the pointer(s) into an unsigned long with one state bit.

    The state bit is used so we can store the inetpeer tree root to use
    when resolving the peer later.

    Later the peer roots will be per-FIB table, and this change works to
    facilitate that.

    Signed-off-by: David S. Miller

    David S. Miller
     

21 Apr, 2012

1 commit


23 Nov, 2011

1 commit


23 Apr, 2011

1 commit


13 Mar, 2011

5 commits


02 Mar, 2011

1 commit


24 Feb, 2011

1 commit


23 Feb, 2011

2 commits


27 Jan, 2011

2 commits

  • Routing metrics are now copy-on-write.

    Initially a route entry points it's metrics at a read-only location.
    If a routing table entry exists, it will point there. Else it will
    point at the all zero metric place-holder called 'dst_default_metrics'.

    The writeability state of the metrics is stored in the low bits of the
    metrics pointer, we have two bits left to spare if we want to store
    more states.

    For the initial implementation, COW is implemented simply via kmalloc.
    However future enhancements will change this to place the writable
    metrics somewhere else, in order to increase sharing. Very likely
    this "somewhere else" will be the inetpeer cache.

    Note also that this means that metrics updates may transiently fail
    if we cannot COW the metrics successfully.

    But even by itself, this patch should decrease memory usage and
    increase cache locality especially for routing workloads. In those
    cases the read-only metric copies stay in place and never get written
    to.

    TCP workloads where metrics get updated, and those rare cases where
    PMTU triggers occur, will take a very slight performance hit. But
    that hit will be alleviated when the long-term writable metrics
    move to a more sharable location.

    Since the metrics storage went from a u32 array of RTAX_MAX entries to
    what is essentially a pointer, some retooling of the dst_entry layout
    was necessary.

    Most importantly, we need to preserve the alignment of the reference
    count so that it doesn't share cache lines with the read-mostly state,
    as per Eric Dumazet's alignment assertion checks.

    The only non-trivial bit here is the move of the 'flags' member into
    the writeable cacheline. This is OK since we are always accessing the
    flags around the same moment when we made a modification to the
    reference count.

    Signed-off-by: David S. Miller

    David S. Miller
     
  • Like ipv4, we have to propagate the ipv6 route peer into
    the ipsec top-level route during instantiation.

    Signed-off-by: David S. Miller

    David S. Miller
     

12 Oct, 2010

1 commit

  • struct dst_ops tracks number of allocated dst in an atomic_t field,
    subject to high cache line contention in stress workload.

    Switch to a percpu_counter, to reduce number of time we need to dirty a
    central location. Place it on a separate cache line to avoid dirtying
    read only fields.

    Stress test :

    (Sending 160.000.000 UDP frames,
    IP route cache disabled, dual E5540 @2.53GHz,
    32bit kernel, FIB_TRIE, SLUB/NUMA)

    Before:

    real 0m51.179s
    user 0m15.329s
    sys 10m15.942s

    After:

    real 0m45.570s
    user 0m15.525s
    sys 9m56.669s

    With a small reordering of struct neighbour fields, subject of a
    following patch, (to separate refcnt from other read mostly fields)

    real 0m41.841s
    user 0m15.261s
    sys 8m45.949s

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

    Eric Dumazet
     

24 Sep, 2010

1 commit


05 Jul, 2010

1 commit

  • While using xfrm by MARK feature in
    2.6.34 - 2.6.35 kernels, the mark
    is always cleared in flowi structure via memset in
    _decode_session4 (net/ipv4/xfrm4_policy.c), so
    the policy lookup fails.
    IPv6 code is affected by this bug too.

    Signed-off-by: Peter Kosyh
    Acked-by: Eric Dumazet
    Signed-off-by: David S. Miller

    Peter Kosyh
     

28 Apr, 2010

1 commit


22 Apr, 2010

1 commit


07 Apr, 2010

1 commit

  • __xfrm_lookup() is called for each packet transmitted out of
    system. The xfrm_find_bundle() does a linear search which can
    kill system performance depending on how many bundles are
    required per policy.

    This modifies __xfrm_lookup() to store bundles directly in
    the flow cache. If we did not get a hit, we just create a new
    bundle instead of doing slow search. This means that we can now
    get multiple xfrm_dst's for same flow (on per-cpu basis).

    Signed-off-by: Timo Teras
    Signed-off-by: David S. Miller

    Timo Teräs
     

03 Mar, 2010

1 commit

  • When I merged the bundle creation code, I introduced a bogus
    flowi value in the bundle. Instead of getting from the caller,
    it was instead set to the flow in the route object, which is
    totally different.

    The end result is that the bundles we created never match, and
    we instead end up with an ever growing bundle list.

    Thanks to Jamal for find this problem.

    Reported-by: Jamal Hadi Salim
    Signed-off-by: Herbert Xu
    Acked-by: Steffen Klassert
    Acked-by: Jamal Hadi Salim
    Signed-off-by: David S. Miller

    Herbert Xu
     

25 Jan, 2010

1 commit

  • GC is non-existent in netns, so after you hit GC threshold, no new
    dst entries will be created until someone triggers cleanup in init_net.

    Make xfrm4_dst_ops and xfrm6_dst_ops per-netns.
    This is not done in a generic way, because it woule waste
    (AF_MAX - 2) * sizeof(struct dst_ops) bytes per-netns.

    Reorder GC threshold initialization so it'd be done before registering
    XFRM policies.

    Signed-off-by: Alexey Dobriyan
    Signed-off-by: David S. Miller

    Alexey Dobriyan
     

12 Nov, 2009

1 commit

  • Now that sys_sysctl is a compatiblity wrapper around /proc/sys
    all sysctl strategy routines, and all ctl_name and strategy
    entries in the sysctl tables are unused, and can be
    revmoed.

    In addition neigh_sysctl_register has been modified to no longer
    take a strategy argument and it's callers have been modified not
    to pass one.

    Cc: "David Miller"
    Cc: Hideaki YOSHIFUJI
    Cc: netdev@vger.kernel.org
    Signed-off-by: Eric W. Biederman

    Eric W. Biederman
     

05 Aug, 2009

1 commit


31 Jul, 2009

1 commit

  • Choose saner defaults for xfrm[4|6] gc_thresh values on init

    Currently, the xfrm[4|6] code has hard-coded initial gc_thresh values
    (set to 1024). Given that the ipv4 and ipv6 routing caches are sized
    dynamically at boot time, the static selections can be non-sensical.
    This patch dynamically selects an appropriate gc threshold based on
    the corresponding main routing table size, using the assumption that
    we should in the worst case be able to handle as many connections as
    the routing table can.

    For ipv4, the maximum route cache size is 16 * the number of hash
    buckets in the route cache. Given that xfrm4 starts garbage
    collection at the gc_thresh and prevents new allocations at 2 *
    gc_thresh, we set gc_thresh to half the maximum route cache size.

    For ipv6, its a bit trickier. there is no maximum route cache size,
    but the ipv6 dst_ops gc_thresh is statically set to 1024. It seems
    sane to select a simmilar gc_thresh for the xfrm6 code that is half
    the number of hash buckets in the v6 route cache times 16 (like the v4
    code does).

    Signed-off-by: Neil Horman
    Signed-off-by: David S. Miller

    Neil Horman