net: Move fib_convert_metrics to metrics file
authorDavid Ahern <dsahern@gmail.com>
Wed, 18 Apr 2018 00:33:07 +0000 (17:33 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 18 Apr 2018 03:41:15 +0000 (23:41 -0400)
Move logic of fib_convert_metrics into ip_metrics_convert. This allows
the code that converts netlink attributes into metrics struct to be
re-used in a later patch by IPv6.

This is mostly a code move with the following changes to variable names:
  - fi->fib_net becomes net
  - fc_mx and fc_mx_len are passed as inputs pulled from fib_config
  - metrics array is passed as an input from fi->fib_metrics->metrics

Signed-off-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/ip.h
net/ipv4/Makefile
net/ipv4/fib_semantics.c
net/ipv4/metrics.c [new file with mode: 0644]

index ecffd843e7b896a83416847fdaa452be6223f3dc..dc4a2d6e58a516a5ba8fe38ea3fe07522653da93 100644 (file)
@@ -396,6 +396,9 @@ static inline unsigned int ip_skb_dst_mtu(struct sock *sk,
        return min(READ_ONCE(skb_dst(skb)->dev->mtu), IP_MAX_MTU);
 }
 
+int ip_metrics_convert(struct net *net, struct nlattr *fc_mx, int fc_mx_len,
+                      u32 *metrics);
+
 u32 ip_idents_reserve(u32 hash, int segs);
 void __ip_select_ident(struct net *net, struct iphdr *iph, int segs);
 
index a07b7dd06defbd2faf846b89ac65eb57d4e9acb0..b379520f91334b6ba4c9e8a1410acd8142fc742b 100644 (file)
@@ -13,7 +13,8 @@ obj-y     := route.o inetpeer.o protocol.o \
             tcp_offload.o datagram.o raw.o udp.o udplite.o \
             udp_offload.o arp.o icmp.o devinet.o af_inet.o igmp.o \
             fib_frontend.o fib_semantics.o fib_trie.o fib_notifier.o \
-            inet_fragment.o ping.o ip_tunnel_core.o gre_offload.o
+            inet_fragment.o ping.o ip_tunnel_core.o gre_offload.o \
+            metrics.o
 
 obj-$(CONFIG_NET_IP_TUNNEL) += ip_tunnel.o
 obj-$(CONFIG_SYSCTL) += sysctl_net_ipv4.o
index c27122f01b874d6a2c1ca89c1c3a0482a91106cc..6608db23f54b6afdac0455650b47d64b1b22b255 100644 (file)
@@ -1019,47 +1019,8 @@ static bool fib_valid_prefsrc(struct fib_config *cfg, __be32 fib_prefsrc)
 static int
 fib_convert_metrics(struct fib_info *fi, const struct fib_config *cfg)
 {
-       bool ecn_ca = false;
-       struct nlattr *nla;
-       int remaining;
-
-       if (!cfg->fc_mx)
-               return 0;
-
-       nla_for_each_attr(nla, cfg->fc_mx, cfg->fc_mx_len, remaining) {
-               int type = nla_type(nla);
-               u32 val;
-
-               if (!type)
-                       continue;
-               if (type > RTAX_MAX)
-                       return -EINVAL;
-
-               if (type == RTAX_CC_ALGO) {
-                       char tmp[TCP_CA_NAME_MAX];
-
-                       nla_strlcpy(tmp, nla, sizeof(tmp));
-                       val = tcp_ca_get_key_by_name(fi->fib_net, tmp, &ecn_ca);
-                       if (val == TCP_CA_UNSPEC)
-                               return -EINVAL;
-               } else {
-                       val = nla_get_u32(nla);
-               }
-               if (type == RTAX_ADVMSS && val > 65535 - 40)
-                       val = 65535 - 40;
-               if (type == RTAX_MTU && val > 65535 - 15)
-                       val = 65535 - 15;
-               if (type == RTAX_HOPLIMIT && val > 255)
-                       val = 255;
-               if (type == RTAX_FEATURES && (val & ~RTAX_FEATURE_MASK))
-                       return -EINVAL;
-               fi->fib_metrics->metrics[type - 1] = val;
-       }
-
-       if (ecn_ca)
-               fi->fib_metrics->metrics[RTAX_FEATURES - 1] |= DST_FEATURE_ECN_CA;
-
-       return 0;
+       return ip_metrics_convert(fi->fib_net, cfg->fc_mx, cfg->fc_mx_len,
+                                 fi->fib_metrics->metrics);
 }
 
 struct fib_info *fib_create_info(struct fib_config *cfg,
diff --git a/net/ipv4/metrics.c b/net/ipv4/metrics.c
new file mode 100644 (file)
index 0000000..5121c64
--- /dev/null
@@ -0,0 +1,53 @@
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/types.h>
+#include <net/ip.h>
+#include <net/net_namespace.h>
+#include <net/tcp.h>
+
+int ip_metrics_convert(struct net *net, struct nlattr *fc_mx, int fc_mx_len,
+                      u32 *metrics)
+{
+       bool ecn_ca = false;
+       struct nlattr *nla;
+       int remaining;
+
+       if (!fc_mx)
+               return 0;
+
+       nla_for_each_attr(nla, fc_mx, fc_mx_len, remaining) {
+               int type = nla_type(nla);
+               u32 val;
+
+               if (!type)
+                       continue;
+               if (type > RTAX_MAX)
+                       return -EINVAL;
+
+               if (type == RTAX_CC_ALGO) {
+                       char tmp[TCP_CA_NAME_MAX];
+
+                       nla_strlcpy(tmp, nla, sizeof(tmp));
+                       val = tcp_ca_get_key_by_name(net, tmp, &ecn_ca);
+                       if (val == TCP_CA_UNSPEC)
+                               return -EINVAL;
+               } else {
+                       val = nla_get_u32(nla);
+               }
+               if (type == RTAX_ADVMSS && val > 65535 - 40)
+                       val = 65535 - 40;
+               if (type == RTAX_MTU && val > 65535 - 15)
+                       val = 65535 - 15;
+               if (type == RTAX_HOPLIMIT && val > 255)
+                       val = 255;
+               if (type == RTAX_FEATURES && (val & ~RTAX_FEATURE_MASK))
+                       return -EINVAL;
+               metrics[type - 1] = val;
+       }
+
+       if (ecn_ca)
+               metrics[RTAX_FEATURES - 1] |= DST_FEATURE_ECN_CA;
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(ip_metrics_convert);