diff mbox series

ipv4: only allow increasing fib_info_hash_size

Message ID 20211012110658.10166-1-zhangkaiheb@126.com (mailing list archive)
State Changes Requested
Delegated to: Netdev Maintainers
Headers show
Series ipv4: only allow increasing fib_info_hash_size | expand

Checks

Context Check Description
netdev/cover_letter success Single patches do not need cover letters
netdev/fixes_present success Fixes tag not required for -next series
netdev/patch_count success Link
netdev/tree_selection success Guessed tree name to be net-next
netdev/subject_prefix warning Target tree name not specified in the subject
netdev/cc_maintainers success CCed 5 of 5 maintainers
netdev/source_inline success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/module_param success Was 0 now: 0
netdev/build_32bit success Errors and warnings before: 1 this patch: 1
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/verify_fixes success No Fixes tag
netdev/checkpatch warning CHECK: Unbalanced braces around else statement CHECK: braces {} should be used on all arms of this statement WARNING: line length of 91 exceeds 80 columns
netdev/build_allmodconfig_warn success Errors and warnings before: 1 this patch: 1
netdev/header_inline success No static functions without inline keyword in header files

Commit Message

kai zhang Oct. 12, 2021, 11:06 a.m. UTC
and when failed to allocate memory, check fib_info_hash_size.

Signed-off-by: zhang kai <zhangkaiheb@126.com>
---
 net/ipv4/fib_semantics.c | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

Comments

David Ahern Oct. 12, 2021, 1:55 p.m. UTC | #1
On 10/12/21 5:06 AM, zhang kai wrote:
> and when failed to allocate memory, check fib_info_hash_size.


what problem are you trying to solve?



> 
> Signed-off-by: zhang kai <zhangkaiheb@126.com>
> ---
>  net/ipv4/fib_semantics.c | 25 ++++++++++++++-----------
>  1 file changed, 14 insertions(+), 11 deletions(-)
> 
> diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
> index a632b66bc..7547708a9 100644
> --- a/net/ipv4/fib_semantics.c
> +++ b/net/ipv4/fib_semantics.c
> @@ -1403,17 +1403,20 @@ struct fib_info *fib_create_info(struct fib_config *cfg,
>  
>  		if (!new_size)
>  			new_size = 16;
> -		bytes = new_size * sizeof(struct hlist_head *);
> -		new_info_hash = fib_info_hash_alloc(bytes);
> -		new_laddrhash = fib_info_hash_alloc(bytes);
> -		if (!new_info_hash || !new_laddrhash) {
> -			fib_info_hash_free(new_info_hash, bytes);
> -			fib_info_hash_free(new_laddrhash, bytes);
> -		} else
> -			fib_info_hash_move(new_info_hash, new_laddrhash, new_size);
> -
> -		if (!fib_info_hash_size)
> -			goto failure;
> +
> +		if (new_size > fib_info_hash_size) {
> +			bytes = new_size * sizeof(struct hlist_head *);
> +			new_info_hash = fib_info_hash_alloc(bytes);
> +			new_laddrhash = fib_info_hash_alloc(bytes);
> +			if (!new_info_hash || !new_laddrhash) {
> +				fib_info_hash_free(new_info_hash, bytes);
> +				fib_info_hash_free(new_laddrhash, bytes);
> +
> +				if (!fib_info_hash_size)
> +					goto failure;
> +			} else
> +				fib_info_hash_move(new_info_hash, new_laddrhash, new_size);
> +		}
>  	}
>  
>  	fi = kzalloc(struct_size(fi, fib_nh, nhs), GFP_KERNEL);
>
David Ahern Oct. 13, 2021, 2:33 a.m. UTC | #2
On 10/12/21 7:10 PM, 张凯 wrote:
> 
> 1) Below shift operation will set fib_info_hash_size to zero if there
> are so many routes: 
>   unsigned int new_size = fib_info_hash_size << 1;
> 
>     This will wrap value of fib_info_hash_size, and a lot of fib_info
> will insert to a small hash bucket.
> so this patch disables above wrap.
> 2) Check whether fib_info_hash_size is zero only needed after allocation
> failed:
> if (!new_info_hash || !new_laddrhash) {
> 
> 

why not something simpler like this:

diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 3364cb9c67e0..5c4bd1cebe0a 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -1401,6 +1401,10 @@ struct fib_info *fib_create_info(struct
fib_config *cfg,

                if (!new_size)
                        new_size = 16;
+
+               if (new_size < fib_info_hash_size)
+                       goto failure;
+
                bytes = new_size * sizeof(struct hlist_head *);
                new_info_hash = fib_info_hash_alloc(bytes);
                new_laddrhash = fib_info_hash_alloc(bytes);
David Ahern Oct. 14, 2021, 2:51 a.m. UTC | #3
On 10/13/21 2:05 AM, 张凯 wrote:
> Should we let the function still work when the below check is true, not goto failure?
> 
>        if (new_size < fib_info_hash_size)
>                goto failure;
> 
> 

no, it can not.

if (fib_info_cnt >= fib_info_hash_size) {

means the hash table is full. It is going down this path to expand. If
expansion can not happen then you can not add more entries.

This is all theory hence the request for a simpler change; in reality
there should never be so many unique fib_info entries across namespaces
to hit an overflow.
diff mbox series

Patch

diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index a632b66bc..7547708a9 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -1403,17 +1403,20 @@  struct fib_info *fib_create_info(struct fib_config *cfg,
 
 		if (!new_size)
 			new_size = 16;
-		bytes = new_size * sizeof(struct hlist_head *);
-		new_info_hash = fib_info_hash_alloc(bytes);
-		new_laddrhash = fib_info_hash_alloc(bytes);
-		if (!new_info_hash || !new_laddrhash) {
-			fib_info_hash_free(new_info_hash, bytes);
-			fib_info_hash_free(new_laddrhash, bytes);
-		} else
-			fib_info_hash_move(new_info_hash, new_laddrhash, new_size);
-
-		if (!fib_info_hash_size)
-			goto failure;
+
+		if (new_size > fib_info_hash_size) {
+			bytes = new_size * sizeof(struct hlist_head *);
+			new_info_hash = fib_info_hash_alloc(bytes);
+			new_laddrhash = fib_info_hash_alloc(bytes);
+			if (!new_info_hash || !new_laddrhash) {
+				fib_info_hash_free(new_info_hash, bytes);
+				fib_info_hash_free(new_laddrhash, bytes);
+
+				if (!fib_info_hash_size)
+					goto failure;
+			} else
+				fib_info_hash_move(new_info_hash, new_laddrhash, new_size);
+		}
 	}
 
 	fi = kzalloc(struct_size(fi, fib_nh, nhs), GFP_KERNEL);