From: David Ahern <dsah...@gmail.com>

nhc_flags holds the RTNH_F flags for a given nexthop (fib{6}_nh).
All of the RTNH_F_ flags fit in an unsigned char, and since the API to
userspace (rtnh_flags and lower byte of rtm_flags) is 1 byte it can not
grow. Make nhc_flags in fib_nh_common an unsigned char and shrink the
size of the struct by 8, from 56 to 48 bytes.

Update the flags arguments for up netdevice events and fib_nexthop_info
which determines the RTNH_F flags to return on a dump/event. The RTNH_F
flags are passed in the lower byte of rtm_flags which is an unsigned int
so use a temp variable for the flags to fib_nexthop_info and combine
with rtm_flags in the caller.

Signed-off-by: David Ahern <dsah...@gmail.com>
---
 include/net/ip6_route.h  |  2 +-
 include/net/ip_fib.h     |  8 ++++----
 net/ipv4/fib_semantics.c |  8 ++++----
 net/ipv6/route.c         | 12 ++++++++----
 4 files changed, 17 insertions(+), 13 deletions(-)

diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index df9cebc2b20c..4790beaa86e0 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -182,7 +182,7 @@ int rt6_dump_route(struct fib6_info *f6i, void *p_arg);
 void rt6_mtu_change(struct net_device *dev, unsigned int mtu);
 void rt6_remove_prefsrc(struct inet6_ifaddr *ifp);
 void rt6_clean_tohost(struct net *net, struct in6_addr *gateway);
-void rt6_sync_up(struct net_device *dev, unsigned int nh_flags);
+void rt6_sync_up(struct net_device *dev, unsigned char nh_flags);
 void rt6_disable_ip(struct net_device *dev, unsigned long event);
 void rt6_sync_down_dev(struct net_device *dev, unsigned long event);
 void rt6_multipath_rebalance(struct fib6_info *f6i);
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index d8195c77e247..772a9e61bd84 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -83,11 +83,11 @@ struct fnhe_hash_bucket {
 struct fib_nh_common {
        struct net_device       *nhc_dev;
        int                     nhc_oif;
-       unsigned int            nhc_flags;
-       struct lwtunnel_state   *nhc_lwtstate;
        unsigned char           nhc_scope;
        u8                      nhc_family;
        u8                      nhc_gw_family;
+       unsigned char           nhc_flags;
+       struct lwtunnel_state   *nhc_lwtstate;
 
        union {
                __be32          ipv4;
@@ -425,7 +425,7 @@ int fib_unmerge(struct net *net);
 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);
 int fib_sync_down_addr(struct net_device *dev, __be32 local);
-int fib_sync_up(struct net_device *dev, unsigned int nh_flags);
+int fib_sync_up(struct net_device *dev, unsigned char nh_flags);
 void fib_sync_mtu(struct net_device *dev, u32 orig_mtu);
 
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
@@ -500,7 +500,7 @@ int ip_valid_fib_dump_req(struct net *net, const struct 
nlmsghdr *nlh,
                          struct netlink_callback *cb);
 
 int fib_nexthop_info(struct sk_buff *skb, const struct fib_nh_common *nh,
-                    unsigned int *flags, bool skip_oif);
+                    unsigned char *flags, bool skip_oif);
 int fib_add_nexthop(struct sk_buff *skb, const struct fib_nh_common *nh,
                    int nh_weight);
 #endif  /* _NET_FIB_H */
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index c695e629fac2..4336f1ec8ab0 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -1444,7 +1444,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg,
 }
 
 int fib_nexthop_info(struct sk_buff *skb, const struct fib_nh_common *nhc,
-                    unsigned int *flags, bool skip_oif)
+                    unsigned char *flags, bool skip_oif)
 {
        if (nhc->nhc_flags & RTNH_F_DEAD)
                *flags |= RTNH_F_DEAD;
@@ -1520,7 +1520,7 @@ int fib_add_nexthop(struct sk_buff *skb, const struct 
fib_nh_common *nhc,
 {
        const struct net_device *dev = nhc->nhc_dev;
        struct rtnexthop *rtnh;
-       unsigned int flags = 0;
+       unsigned char flags = 0;
 
        rtnh = nla_reserve_nohdr(skb, sizeof(*rtnh));
        if (!rtnh)
@@ -1619,7 +1619,7 @@ int fib_dump_info(struct sk_buff *skb, u32 portid, u32 
seq, int event,
                goto nla_put_failure;
        if (fi->fib_nhs == 1) {
                struct fib_nh *nh = &fi->fib_nh[0];
-               unsigned int flags = 0;
+               unsigned char flags = 0;
 
                if (fib_nexthop_info(skb, &nh->nh_common, &flags, false) < 0)
                        goto nla_put_failure;
@@ -1902,7 +1902,7 @@ static void fib_select_default(const struct flowi4 *flp, 
struct fib_result *res)
  * Dead device goes up. We wake up dead nexthops.
  * It takes sense only on multipath routes.
  */
-int fib_sync_up(struct net_device *dev, unsigned int nh_flags)
+int fib_sync_up(struct net_device *dev, unsigned char nh_flags)
 {
        struct fib_info *prev_fi;
        unsigned int hash;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 844b16d8d6e8..5de0d65b88d7 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -3912,7 +3912,7 @@ void rt6_clean_tohost(struct net *net, struct in6_addr 
*gateway)
 struct arg_netdev_event {
        const struct net_device *dev;
        union {
-               unsigned int nh_flags;
+               unsigned char nh_flags;
                unsigned long event;
        };
 };
@@ -4025,7 +4025,7 @@ static int fib6_ifup(struct fib6_info *rt, void *p_arg)
        return 0;
 }
 
-void rt6_sync_up(struct net_device *dev, unsigned int nh_flags)
+void rt6_sync_up(struct net_device *dev, unsigned char nh_flags)
 {
        struct arg_netdev_event arg = {
                .dev = dev,
@@ -4082,7 +4082,7 @@ static unsigned int rt6_multipath_dead_count(const struct 
fib6_info *rt,
 
 static void rt6_multipath_nh_flags_set(struct fib6_info *rt,
                                       const struct net_device *dev,
-                                      unsigned int nh_flags)
+                                      unsigned char nh_flags)
 {
        struct fib6_info *iter;
 
@@ -4794,9 +4794,13 @@ static int rt6_fill_node(struct net *net, struct sk_buff 
*skb,
 
                nla_nest_end(skb, mp);
        } else {
+               unsigned char nh_flags = 0;
+
                if (fib_nexthop_info(skb, &rt->fib6_nh.nh_common,
-                                    &rtm->rtm_flags, false) < 0)
+                                    &nh_flags, false) < 0)
                        goto nla_put_failure;
+
+               rtm->rtm_flags |= nh_flags;
        }
 
        if (rt6_flags & RTF_EXPIRES) {
-- 
2.11.0

Reply via email to