tipc: make legacy address flag readable over netlink
authorJohn Rutherford <john.rutherford@dektech.com.au>
Thu, 19 Dec 2019 05:03:57 +0000 (16:03 +1100)
committerDavid S. Miller <davem@davemloft.net>
Sat, 21 Dec 2019 05:18:42 +0000 (21:18 -0800)
To enable iproute2/tipc to generate backwards compatible
printouts and validate command parameters for nodes using a
<z.c.n> node address, it needs to be able to read the legacy
address flag from the kernel.  The legacy address flag records
the way in which the node identity was originally specified.

The legacy address flag is requested by the netlink message
TIPC_NL_ADDR_LEGACY_GET.  If the flag is set the attribute
TIPC_NLA_NET_ADDR_LEGACY is set in the return message.

Signed-off-by: John Rutherford <john.rutherford@dektech.com.au>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/uapi/linux/tipc_netlink.h
net/tipc/net.c
net/tipc/net.h
net/tipc/netlink.c

index 6c2194ab745bd57875530cd36f338fe85ad8318e..dc0d23a50e69e8cfb58ab652fe52aa1372be89e7 100644 (file)
@@ -65,6 +65,7 @@ enum {
        TIPC_NL_UDP_GET_REMOTEIP,
        TIPC_NL_KEY_SET,
        TIPC_NL_KEY_FLUSH,
+       TIPC_NL_ADDR_LEGACY_GET,
 
        __TIPC_NL_CMD_MAX,
        TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1
@@ -176,6 +177,7 @@ enum {
        TIPC_NLA_NET_ADDR,              /* u32 */
        TIPC_NLA_NET_NODEID,            /* u64 */
        TIPC_NLA_NET_NODEID_W1,         /* u64 */
+       TIPC_NLA_NET_ADDR_LEGACY,       /* flag */
 
        __TIPC_NLA_NET_MAX,
        TIPC_NLA_NET_MAX = __TIPC_NLA_NET_MAX - 1
index 2de3cec9929d89213164eba1713177d787c032db..85400e4242de20d8683b9987c442c5ba9b944d22 100644 (file)
@@ -302,3 +302,59 @@ int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info)
 
        return err;
 }
+
+static int __tipc_nl_addr_legacy_get(struct net *net, struct tipc_nl_msg *msg)
+{
+       struct tipc_net *tn = tipc_net(net);
+       struct nlattr *attrs;
+       void *hdr;
+
+       hdr = genlmsg_put(msg->skb, msg->portid, msg->seq, &tipc_genl_family,
+                         0, TIPC_NL_ADDR_LEGACY_GET);
+       if (!hdr)
+               return -EMSGSIZE;
+
+       attrs = nla_nest_start(msg->skb, TIPC_NLA_NET);
+       if (!attrs)
+               goto msg_full;
+
+       if (tn->legacy_addr_format)
+               if (nla_put_flag(msg->skb, TIPC_NLA_NET_ADDR_LEGACY))
+                       goto attr_msg_full;
+
+       nla_nest_end(msg->skb, attrs);
+       genlmsg_end(msg->skb, hdr);
+
+       return 0;
+
+attr_msg_full:
+       nla_nest_cancel(msg->skb, attrs);
+msg_full:
+       genlmsg_cancel(msg->skb, hdr);
+
+       return -EMSGSIZE;
+}
+
+int tipc_nl_net_addr_legacy_get(struct sk_buff *skb, struct genl_info *info)
+{
+       struct net *net = sock_net(skb->sk);
+       struct tipc_nl_msg msg;
+       struct sk_buff *rep;
+       int err;
+
+       rep = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+       if (!rep)
+               return -ENOMEM;
+
+       msg.skb = rep;
+       msg.portid = info->snd_portid;
+       msg.seq = info->snd_seq;
+
+       err = __tipc_nl_addr_legacy_get(net, &msg);
+       if (err) {
+               nlmsg_free(msg.skb);
+               return err;
+       }
+
+       return genlmsg_reply(msg.skb, info);
+}
index b7f2e364eb99e774854ea22837107991619ef00a..6740d97c706e5d1314d66472f0a4d992db0b8929 100644 (file)
@@ -47,5 +47,6 @@ void tipc_net_stop(struct net *net);
 int tipc_nl_net_dump(struct sk_buff *skb, struct netlink_callback *cb);
 int tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info);
 int __tipc_nl_net_set(struct sk_buff *skb, struct genl_info *info);
+int tipc_nl_net_addr_legacy_get(struct sk_buff *skb, struct genl_info *info);
 
 #endif
index e53231bd23b42151d0100b11f2f71bf7b668298e..7c35094c20b8b7af139a05220745af9d0fe61e04 100644 (file)
@@ -83,6 +83,7 @@ const struct nla_policy tipc_nl_net_policy[TIPC_NLA_NET_MAX + 1] = {
        [TIPC_NLA_NET_ADDR]             = { .type = NLA_U32 },
        [TIPC_NLA_NET_NODEID]           = { .type = NLA_U64 },
        [TIPC_NLA_NET_NODEID_W1]        = { .type = NLA_U64 },
+       [TIPC_NLA_NET_ADDR_LEGACY]      = { .type = NLA_FLAG }
 };
 
 const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = {
@@ -273,6 +274,11 @@ static const struct genl_ops tipc_genl_v2_ops[] = {
                .doit   = tipc_nl_node_flush_key,
        },
 #endif
+       {
+               .cmd    = TIPC_NL_ADDR_LEGACY_GET,
+               .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
+               .doit   = tipc_nl_net_addr_legacy_get,
+       },
 };
 
 struct genl_family tipc_genl_family __ro_after_init = {