aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorRichard Alpe <richard.alpe@ericsson.com>2015-05-06 07:58:54 -0400
committerDavid S. Miller <davem@davemloft.net>2015-05-09 16:40:02 -0400
commitc3d6fb85b2ed6a57b57b322a470b3b4eefb34fb7 (patch)
treeff59ce5ff68dea45a2cbc8a78634fbc46296c363 /net/tipc
parentc035e183ebfe6905dd0d31f7fe356cc3cfe00893 (diff)
tipc: fix default link prop regression in nl compat
Default link properties can be set for media or bearer. This functionality was missed when introducing the NL compatibility layer. This patch implements this functionality in the compat netlink layer. It works the same way as it did in the old API. We search for media and bearers matching the "link name". If we find a matching media or bearer the link tolerance, priority or window is used as default for new links on that media or bearer. Fixes: 37e2d4843f9e (tipc: convert legacy nl link prop set to nl compat) Reported-by: Tomi Ollila <tomi.ollila@iki.fi> Signed-off-by: Richard Alpe <richard.alpe@ericsson.com> Reviewed-by: Erik Hugne <erik.hugne@ericsson.com> Reviewed-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/bearer.c2
-rw-r--r--net/tipc/netlink_compat.c135
2 files changed, 114 insertions, 23 deletions
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 70e3dacbf84a..99c0bd43feed 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -812,7 +812,7 @@ int tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)
812 char *name; 812 char *name;
813 struct tipc_bearer *b; 813 struct tipc_bearer *b;
814 struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1]; 814 struct nlattr *attrs[TIPC_NLA_BEARER_MAX + 1];
815 struct net *net = genl_info_net(info); 815 struct net *net = sock_net(skb->sk);
816 816
817 if (!info->attrs[TIPC_NLA_BEARER]) 817 if (!info->attrs[TIPC_NLA_BEARER])
818 return -EINVAL; 818 return -EINVAL;
diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
index ce9121e8e990..809aaf027876 100644
--- a/net/tipc/netlink_compat.c
+++ b/net/tipc/netlink_compat.c
@@ -55,6 +55,7 @@ struct tipc_nl_compat_msg {
55 int rep_type; 55 int rep_type;
56 int rep_size; 56 int rep_size;
57 int req_type; 57 int req_type;
58 struct net *net;
58 struct sk_buff *rep; 59 struct sk_buff *rep;
59 struct tlv_desc *req; 60 struct tlv_desc *req;
60 struct sock *dst_sk; 61 struct sock *dst_sk;
@@ -68,7 +69,8 @@ struct tipc_nl_compat_cmd_dump {
68 69
69struct tipc_nl_compat_cmd_doit { 70struct tipc_nl_compat_cmd_doit {
70 int (*doit)(struct sk_buff *skb, struct genl_info *info); 71 int (*doit)(struct sk_buff *skb, struct genl_info *info);
71 int (*transcode)(struct sk_buff *skb, struct tipc_nl_compat_msg *msg); 72 int (*transcode)(struct tipc_nl_compat_cmd_doit *cmd,
73 struct sk_buff *skb, struct tipc_nl_compat_msg *msg);
72}; 74};
73 75
74static int tipc_skb_tailroom(struct sk_buff *skb) 76static int tipc_skb_tailroom(struct sk_buff *skb)
@@ -281,7 +283,7 @@ static int __tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd,
281 if (!trans_buf) 283 if (!trans_buf)
282 return -ENOMEM; 284 return -ENOMEM;
283 285
284 err = (*cmd->transcode)(trans_buf, msg); 286 err = (*cmd->transcode)(cmd, trans_buf, msg);
285 if (err) 287 if (err)
286 goto trans_out; 288 goto trans_out;
287 289
@@ -353,7 +355,8 @@ static int tipc_nl_compat_bearer_dump(struct tipc_nl_compat_msg *msg,
353 nla_len(bearer[TIPC_NLA_BEARER_NAME])); 355 nla_len(bearer[TIPC_NLA_BEARER_NAME]));
354} 356}
355 357
356static int tipc_nl_compat_bearer_enable(struct sk_buff *skb, 358static int tipc_nl_compat_bearer_enable(struct tipc_nl_compat_cmd_doit *cmd,
359 struct sk_buff *skb,
357 struct tipc_nl_compat_msg *msg) 360 struct tipc_nl_compat_msg *msg)
358{ 361{
359 struct nlattr *prop; 362 struct nlattr *prop;
@@ -385,7 +388,8 @@ static int tipc_nl_compat_bearer_enable(struct sk_buff *skb,
385 return 0; 388 return 0;
386} 389}
387 390
388static int tipc_nl_compat_bearer_disable(struct sk_buff *skb, 391static int tipc_nl_compat_bearer_disable(struct tipc_nl_compat_cmd_doit *cmd,
392 struct sk_buff *skb,
389 struct tipc_nl_compat_msg *msg) 393 struct tipc_nl_compat_msg *msg)
390{ 394{
391 char *name; 395 char *name;
@@ -576,11 +580,81 @@ static int tipc_nl_compat_link_dump(struct tipc_nl_compat_msg *msg,
576 &link_info, sizeof(link_info)); 580 &link_info, sizeof(link_info));
577} 581}
578 582
579static int tipc_nl_compat_link_set(struct sk_buff *skb, 583static int __tipc_add_link_prop(struct sk_buff *skb,
580 struct tipc_nl_compat_msg *msg) 584 struct tipc_nl_compat_msg *msg,
585 struct tipc_link_config *lc)
586{
587 switch (msg->cmd) {
588 case TIPC_CMD_SET_LINK_PRI:
589 return nla_put_u32(skb, TIPC_NLA_PROP_PRIO, ntohl(lc->value));
590 case TIPC_CMD_SET_LINK_TOL:
591 return nla_put_u32(skb, TIPC_NLA_PROP_TOL, ntohl(lc->value));
592 case TIPC_CMD_SET_LINK_WINDOW:
593 return nla_put_u32(skb, TIPC_NLA_PROP_WIN, ntohl(lc->value));
594 }
595
596 return -EINVAL;
597}
598
599static int tipc_nl_compat_media_set(struct sk_buff *skb,
600 struct tipc_nl_compat_msg *msg)
581{ 601{
582 struct nlattr *link;
583 struct nlattr *prop; 602 struct nlattr *prop;
603 struct nlattr *media;
604 struct tipc_link_config *lc;
605
606 lc = (struct tipc_link_config *)TLV_DATA(msg->req);
607
608 media = nla_nest_start(skb, TIPC_NLA_MEDIA);
609 if (!media)
610 return -EMSGSIZE;
611
612 if (nla_put_string(skb, TIPC_NLA_MEDIA_NAME, lc->name))
613 return -EMSGSIZE;
614
615 prop = nla_nest_start(skb, TIPC_NLA_MEDIA_PROP);
616 if (!prop)
617 return -EMSGSIZE;
618
619 __tipc_add_link_prop(skb, msg, lc);
620 nla_nest_end(skb, prop);
621 nla_nest_end(skb, media);
622
623 return 0;
624}
625
626static int tipc_nl_compat_bearer_set(struct sk_buff *skb,
627 struct tipc_nl_compat_msg *msg)
628{
629 struct nlattr *prop;
630 struct nlattr *bearer;
631 struct tipc_link_config *lc;
632
633 lc = (struct tipc_link_config *)TLV_DATA(msg->req);
634
635 bearer = nla_nest_start(skb, TIPC_NLA_BEARER);
636 if (!bearer)
637 return -EMSGSIZE;
638
639 if (nla_put_string(skb, TIPC_NLA_BEARER_NAME, lc->name))
640 return -EMSGSIZE;
641
642 prop = nla_nest_start(skb, TIPC_NLA_BEARER_PROP);
643 if (!prop)
644 return -EMSGSIZE;
645
646 __tipc_add_link_prop(skb, msg, lc);
647 nla_nest_end(skb, prop);
648 nla_nest_end(skb, bearer);
649
650 return 0;
651}
652
653static int __tipc_nl_compat_link_set(struct sk_buff *skb,
654 struct tipc_nl_compat_msg *msg)
655{
656 struct nlattr *prop;
657 struct nlattr *link;
584 struct tipc_link_config *lc; 658 struct tipc_link_config *lc;
585 659
586 lc = (struct tipc_link_config *)TLV_DATA(msg->req); 660 lc = (struct tipc_link_config *)TLV_DATA(msg->req);
@@ -596,24 +670,40 @@ static int tipc_nl_compat_link_set(struct sk_buff *skb,
596 if (!prop) 670 if (!prop)
597 return -EMSGSIZE; 671 return -EMSGSIZE;
598 672
599 if (msg->cmd == TIPC_CMD_SET_LINK_PRI) { 673 __tipc_add_link_prop(skb, msg, lc);
600 if (nla_put_u32(skb, TIPC_NLA_PROP_PRIO, ntohl(lc->value)))
601 return -EMSGSIZE;
602 } else if (msg->cmd == TIPC_CMD_SET_LINK_TOL) {
603 if (nla_put_u32(skb, TIPC_NLA_PROP_TOL, ntohl(lc->value)))
604 return -EMSGSIZE;
605 } else if (msg->cmd == TIPC_CMD_SET_LINK_WINDOW) {
606 if (nla_put_u32(skb, TIPC_NLA_PROP_WIN, ntohl(lc->value)))
607 return -EMSGSIZE;
608 }
609
610 nla_nest_end(skb, prop); 674 nla_nest_end(skb, prop);
611 nla_nest_end(skb, link); 675 nla_nest_end(skb, link);
612 676
613 return 0; 677 return 0;
614} 678}
615 679
616static int tipc_nl_compat_link_reset_stats(struct sk_buff *skb, 680static int tipc_nl_compat_link_set(struct tipc_nl_compat_cmd_doit *cmd,
681 struct sk_buff *skb,
682 struct tipc_nl_compat_msg *msg)
683{
684 struct tipc_link_config *lc;
685 struct tipc_bearer *bearer;
686 struct tipc_media *media;
687
688 lc = (struct tipc_link_config *)TLV_DATA(msg->req);
689
690 media = tipc_media_find(lc->name);
691 if (media) {
692 cmd->doit = &tipc_nl_media_set;
693 return tipc_nl_compat_media_set(skb, msg);
694 }
695
696 bearer = tipc_bearer_find(msg->net, lc->name);
697 if (bearer) {
698 cmd->doit = &tipc_nl_bearer_set;
699 return tipc_nl_compat_bearer_set(skb, msg);
700 }
701
702 return __tipc_nl_compat_link_set(skb, msg);
703}
704
705static int tipc_nl_compat_link_reset_stats(struct tipc_nl_compat_cmd_doit *cmd,
706 struct sk_buff *skb,
617 struct tipc_nl_compat_msg *msg) 707 struct tipc_nl_compat_msg *msg)
618{ 708{
619 char *name; 709 char *name;
@@ -851,7 +941,8 @@ static int tipc_nl_compat_node_dump(struct tipc_nl_compat_msg *msg,
851 sizeof(node_info)); 941 sizeof(node_info));
852} 942}
853 943
854static int tipc_nl_compat_net_set(struct sk_buff *skb, 944static int tipc_nl_compat_net_set(struct tipc_nl_compat_cmd_doit *cmd,
945 struct sk_buff *skb,
855 struct tipc_nl_compat_msg *msg) 946 struct tipc_nl_compat_msg *msg)
856{ 947{
857 u32 val; 948 u32 val;
@@ -1007,7 +1098,6 @@ static int tipc_nl_compat_recv(struct sk_buff *skb, struct genl_info *info)
1007 struct nlmsghdr *req_nlh; 1098 struct nlmsghdr *req_nlh;
1008 struct nlmsghdr *rep_nlh; 1099 struct nlmsghdr *rep_nlh;
1009 struct tipc_genlmsghdr *req_userhdr = info->userhdr; 1100 struct tipc_genlmsghdr *req_userhdr = info->userhdr;
1010 struct net *net = genl_info_net(info);
1011 1101
1012 memset(&msg, 0, sizeof(msg)); 1102 memset(&msg, 0, sizeof(msg));
1013 1103
@@ -1015,6 +1105,7 @@ static int tipc_nl_compat_recv(struct sk_buff *skb, struct genl_info *info)
1015 msg.req = nlmsg_data(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN; 1105 msg.req = nlmsg_data(req_nlh) + GENL_HDRLEN + TIPC_GENL_HDRLEN;
1016 msg.cmd = req_userhdr->cmd; 1106 msg.cmd = req_userhdr->cmd;
1017 msg.dst_sk = info->dst_sk; 1107 msg.dst_sk = info->dst_sk;
1108 msg.net = genl_info_net(info);
1018 1109
1019 if ((msg.cmd & 0xC000) && (!netlink_net_capable(skb, CAP_NET_ADMIN))) { 1110 if ((msg.cmd & 0xC000) && (!netlink_net_capable(skb, CAP_NET_ADMIN))) {
1020 msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_NET_ADMIN); 1111 msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_NET_ADMIN);
@@ -1043,7 +1134,7 @@ send:
1043 rep_nlh = nlmsg_hdr(msg.rep); 1134 rep_nlh = nlmsg_hdr(msg.rep);
1044 memcpy(rep_nlh, info->nlhdr, len); 1135 memcpy(rep_nlh, info->nlhdr, len);
1045 rep_nlh->nlmsg_len = msg.rep->len; 1136 rep_nlh->nlmsg_len = msg.rep->len;
1046 genlmsg_unicast(net, msg.rep, NETLINK_CB(skb).portid); 1137 genlmsg_unicast(msg.net, msg.rep, NETLINK_CB(skb).portid);
1047 1138
1048 return err; 1139 return err;
1049} 1140}