aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2011-01-19 22:00:42 -0500
committerDavid S. Miller <davem@davemloft.net>2011-01-21 02:28:54 -0500
commitffa934f192c8381061242eb170419266ef229902 (patch)
treefb09699460d85166bfa64c524eb6eda01b899c4a /net
parentd52344a7ae8a3fb660636f7de4f1c542b0036cbb (diff)
rtnetlink: fix link attribute validation with IFLA_GROUP
rtnl_group_changelink() is invoked by rtnl_newlink() before the link attributes have been validated. Additionally the group changes are performed even if NLM_F_CREATE is specified and a new link is created, while more reasonable semantics would be to set the group value on the newly created link. Fix both problems by moving the rtnl_group_changelink() invocation down to the handling of non-existant links without NLM_F_CREATE() and add a dev_set_group() call to rtnl_create_link(). Signed-off-by: Patrick McHardy <kaber@trash.net> Acked-by: Vlad Dogaru <ddvlad@rosedu.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/core/rtnetlink.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index a0b2eeb3b610..310eb804e092 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1548,6 +1548,8 @@ struct net_device *rtnl_create_link(struct net *src_net, struct net *net,
1548 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); 1548 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
1549 if (tb[IFLA_LINKMODE]) 1549 if (tb[IFLA_LINKMODE])
1550 dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); 1550 dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
1551 if (tb[IFLA_GROUP])
1552 dev_set_group(dev, nla_get_u32(tb[IFLA_GROUP]));
1551 1553
1552 return dev; 1554 return dev;
1553 1555
@@ -1606,10 +1608,6 @@ replay:
1606 else { 1608 else {
1607 if (ifname[0]) 1609 if (ifname[0])
1608 dev = __dev_get_by_name(net, ifname); 1610 dev = __dev_get_by_name(net, ifname);
1609 else if (tb[IFLA_GROUP])
1610 return rtnl_group_changelink(net,
1611 nla_get_u32(tb[IFLA_GROUP]),
1612 ifm, tb);
1613 else 1611 else
1614 dev = NULL; 1612 dev = NULL;
1615 } 1613 }
@@ -1676,8 +1674,13 @@ replay:
1676 return do_setlink(dev, ifm, tb, ifname, modified); 1674 return do_setlink(dev, ifm, tb, ifname, modified);
1677 } 1675 }
1678 1676
1679 if (!(nlh->nlmsg_flags & NLM_F_CREATE)) 1677 if (!(nlh->nlmsg_flags & NLM_F_CREATE)) {
1678 if (ifm->ifi_index == 0 && tb[IFLA_GROUP])
1679 return rtnl_group_changelink(net,
1680 nla_get_u32(tb[IFLA_GROUP]),
1681 ifm, tb);
1680 return -ENODEV; 1682 return -ENODEV;
1683 }
1681 1684
1682 if (ifm->ifi_index) 1685 if (ifm->ifi_index)
1683 return -EOPNOTSUPP; 1686 return -EOPNOTSUPP;