diff mbox series

[net,5/5] ipv4: nexthop version of fib_info_nh_uses_dev

Message ID 20200526150114.41687-6-dsahern@kernel.org
State Accepted
Delegated to: David Miller
Headers show
Series nexthops: Fix 2 fundamental flaws with nexthop groups | expand

Commit Message

David Ahern May 26, 2020, 3:01 p.m. UTC
From: David Ahern <dsahern@gmail.com>

Similar to the last path, need to fix fib_info_nh_uses_dev for
external nexthops to avoid referencing multiple nh_grp structs.
Move the device check in fib_info_nh_uses_dev to a helper and
create a nexthop version that is called if the fib_info uses an
external nexthop.

Fixes: 430a049190de ("nexthop: Add support for nexthop groups")
Signed-off-by: David Ahern <dsahern@gmail.com>
---
 include/net/ip_fib.h    | 10 ++++++++++
 include/net/nexthop.h   | 25 +++++++++++++++++++++++++
 net/ipv4/fib_frontend.c | 19 ++++++++++---------
 3 files changed, 45 insertions(+), 9 deletions(-)

Comments

Nikolay Aleksandrov May 26, 2020, 3:10 p.m. UTC | #1
On 26/05/2020 18:01, David Ahern wrote:
> From: David Ahern <dsahern@gmail.com>
> 
> Similar to the last path, need to fix fib_info_nh_uses_dev for
> external nexthops to avoid referencing multiple nh_grp structs.
> Move the device check in fib_info_nh_uses_dev to a helper and
> create a nexthop version that is called if the fib_info uses an
> external nexthop.
> 
> Fixes: 430a049190de ("nexthop: Add support for nexthop groups")
> Signed-off-by: David Ahern <dsahern@gmail.com>
> ---
>  include/net/ip_fib.h    | 10 ++++++++++
>  include/net/nexthop.h   | 25 +++++++++++++++++++++++++
>  net/ipv4/fib_frontend.c | 19 ++++++++++---------
>  3 files changed, 45 insertions(+), 9 deletions(-)
> 

Acked-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>

> diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
> index 1f1dd22980e4..6683558db7c9 100644
> --- a/include/net/ip_fib.h
> +++ b/include/net/ip_fib.h
> @@ -448,6 +448,16 @@ static inline int fib_num_tclassid_users(struct net *net)
>  #endif
>  int fib_unmerge(struct net *net);
>  
> +static inline bool nhc_l3mdev_matches_dev(const struct fib_nh_common *nhc,
> +const struct net_device *dev)
> +{
> +	if (nhc->nhc_dev == dev ||
> +	    l3mdev_master_ifindex_rcu(nhc->nhc_dev) == dev->ifindex)
> +			return true;
> +
> +	return false;
> +}
> +
>  /* Exported by fib_semantics.c */
>  int ip_fib_check_default(__be32 gw, struct net_device *dev);
>  int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force);
> diff --git a/include/net/nexthop.h b/include/net/nexthop.h
> index 9414ae46fc1c..35680a8c2a1c 100644
> --- a/include/net/nexthop.h
> +++ b/include/net/nexthop.h
> @@ -266,6 +266,31 @@ struct fib_nh_common *nexthop_get_nhc_lookup(const struct nexthop *nh,
>  	return NULL;
>  }
>  
> +static inline bool nexthop_uses_dev(const struct nexthop *nh,
> +				    const struct net_device *dev)
> +{
> +	struct nh_info *nhi;
> +
> +	if (nh->is_group) {
> +		struct nh_group *nhg = rcu_dereference(nh->nh_grp);
> +		int i;
> +
> +		for (i = 0; i < nhg->num_nh; i++) {
> +			struct nexthop *nhe = nhg->nh_entries[i].nh;
> +
> +			nhi = rcu_dereference(nhe->nh_info);
> +			if (nhc_l3mdev_matches_dev(&nhi->fib_nhc, dev))
> +				return true;
> +                }
> +        } else {
> +		nhi = rcu_dereference(nh->nh_info);
> +		if (nhc_l3mdev_matches_dev(&nhi->fib_nhc, dev))
> +			return true;
> +        }
> +
> +	return false;
> +}
> +
>  static inline unsigned int fib_info_num_path(const struct fib_info *fi)
>  {
>  	if (unlikely(fi->nh))
> diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
> index 213be9c050ad..aebb50735c68 100644
> --- a/net/ipv4/fib_frontend.c
> +++ b/net/ipv4/fib_frontend.c
> @@ -309,17 +309,18 @@ bool fib_info_nh_uses_dev(struct fib_info *fi, const struct net_device *dev)
>  {
>  	bool dev_match = false;
>  #ifdef CONFIG_IP_ROUTE_MULTIPATH
> -	int ret;
> +	if (unlikely(fi->nh)) {
> +		dev_match = nexthop_uses_dev(fi->nh, dev);
> +	} else {
> +		int ret;
>  
> -	for (ret = 0; ret < fib_info_num_path(fi); ret++) {
> -		const struct fib_nh_common *nhc = fib_info_nhc(fi, ret);
> +		for (ret = 0; ret < fib_info_num_path(fi); ret++) {
> +			const struct fib_nh_common *nhc = fib_info_nhc(fi, ret);
>  
> -		if (nhc->nhc_dev == dev) {
> -			dev_match = true;
> -			break;
> -		} else if (l3mdev_master_ifindex_rcu(nhc->nhc_dev) == dev->ifindex) {
> -			dev_match = true;
> -			break;
> +			if (nhc_l3mdev_matches_dev(nhc, dev)) {
> +				dev_match = true;
> +				break;
> +			}
>  		}
>  	}
>  #else
>
Jakub Kicinski May 26, 2020, 6:37 p.m. UTC | #2
On Tue, 26 May 2020 09:01:14 -0600 David Ahern wrote:
> From: David Ahern <dsahern@gmail.com>
> 
> Similar to the last path, need to fix fib_info_nh_uses_dev for
> external nexthops to avoid referencing multiple nh_grp structs.
> Move the device check in fib_info_nh_uses_dev to a helper and
> create a nexthop version that is called if the fib_info uses an
> external nexthop.
> 
> Fixes: 430a049190de ("nexthop: Add support for nexthop groups")
> Signed-off-by: David Ahern <dsahern@gmail.com>

Dave, bunch of white space problems here according to checkpatch:

CHECK: Alignment should match open parenthesis
#31: FILE: include/net/ip_fib.h:451:
+static inline bool nhc_l3mdev_matches_dev(const struct fib_nh_common *nhc,
+const struct net_device *dev)

WARNING: suspect code indent for conditional statements (8, 24)
#33: FILE: include/net/ip_fib.h:453:
+	if (nhc->nhc_dev == dev ||
[...]
+			return true;

ERROR: code indent should use tabs where possible
#66: FILE: include/net/nexthop.h:284:
+                }$

WARNING: please, no spaces at the start of a line
#66: FILE: include/net/nexthop.h:284:
+                }$

ERROR: code indent should use tabs where possible
#67: FILE: include/net/nexthop.h:285:
+        } else {$

WARNING: please, no spaces at the start of a line
#67: FILE: include/net/nexthop.h:285:
+        } else {$

ERROR: code indent should use tabs where possible
#71: FILE: include/net/nexthop.h:289:
+        }$

WARNING: please, no spaces at the start of a line
#71: FILE: include/net/nexthop.h:289:
+        }$

total: 3 errors, 4 warnings, 1 checks, 74 lines checked
David Ahern May 26, 2020, 6:39 p.m. UTC | #3
On 5/26/20 12:37 PM, Jakub Kicinski wrote:
> Dave, bunch of white space problems here according to checkpatch:
> 

ugh, the VM I used for iterations did not have the git hook to run
checkpatch on commit. Will re-spin.
diff mbox series

Patch

diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 1f1dd22980e4..6683558db7c9 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -448,6 +448,16 @@  static inline int fib_num_tclassid_users(struct net *net)
 #endif
 int fib_unmerge(struct net *net);
 
+static inline bool nhc_l3mdev_matches_dev(const struct fib_nh_common *nhc,
+const struct net_device *dev)
+{
+	if (nhc->nhc_dev == dev ||
+	    l3mdev_master_ifindex_rcu(nhc->nhc_dev) == dev->ifindex)
+			return true;
+
+	return false;
+}
+
 /* Exported by fib_semantics.c */
 int ip_fib_check_default(__be32 gw, struct net_device *dev);
 int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force);
diff --git a/include/net/nexthop.h b/include/net/nexthop.h
index 9414ae46fc1c..35680a8c2a1c 100644
--- a/include/net/nexthop.h
+++ b/include/net/nexthop.h
@@ -266,6 +266,31 @@  struct fib_nh_common *nexthop_get_nhc_lookup(const struct nexthop *nh,
 	return NULL;
 }
 
+static inline bool nexthop_uses_dev(const struct nexthop *nh,
+				    const struct net_device *dev)
+{
+	struct nh_info *nhi;
+
+	if (nh->is_group) {
+		struct nh_group *nhg = rcu_dereference(nh->nh_grp);
+		int i;
+
+		for (i = 0; i < nhg->num_nh; i++) {
+			struct nexthop *nhe = nhg->nh_entries[i].nh;
+
+			nhi = rcu_dereference(nhe->nh_info);
+			if (nhc_l3mdev_matches_dev(&nhi->fib_nhc, dev))
+				return true;
+                }
+        } else {
+		nhi = rcu_dereference(nh->nh_info);
+		if (nhc_l3mdev_matches_dev(&nhi->fib_nhc, dev))
+			return true;
+        }
+
+	return false;
+}
+
 static inline unsigned int fib_info_num_path(const struct fib_info *fi)
 {
 	if (unlikely(fi->nh))
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 213be9c050ad..aebb50735c68 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -309,17 +309,18 @@  bool fib_info_nh_uses_dev(struct fib_info *fi, const struct net_device *dev)
 {
 	bool dev_match = false;
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
-	int ret;
+	if (unlikely(fi->nh)) {
+		dev_match = nexthop_uses_dev(fi->nh, dev);
+	} else {
+		int ret;
 
-	for (ret = 0; ret < fib_info_num_path(fi); ret++) {
-		const struct fib_nh_common *nhc = fib_info_nhc(fi, ret);
+		for (ret = 0; ret < fib_info_num_path(fi); ret++) {
+			const struct fib_nh_common *nhc = fib_info_nhc(fi, ret);
 
-		if (nhc->nhc_dev == dev) {
-			dev_match = true;
-			break;
-		} else if (l3mdev_master_ifindex_rcu(nhc->nhc_dev) == dev->ifindex) {
-			dev_match = true;
-			break;
+			if (nhc_l3mdev_matches_dev(nhc, dev)) {
+				dev_match = true;
+				break;
+			}
 		}
 	}
 #else