aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/rtnetlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/rtnetlink.c')
-rw-r--r--net/core/rtnetlink.c198
1 files changed, 103 insertions, 95 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 01ced4a889e0..dc004b1e1f85 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1328,10 +1328,6 @@ static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
1328 [IFLA_INFO_SLAVE_DATA] = { .type = NLA_NESTED }, 1328 [IFLA_INFO_SLAVE_DATA] = { .type = NLA_NESTED },
1329}; 1329};
1330 1330
1331static const struct nla_policy ifla_vfinfo_policy[IFLA_VF_INFO_MAX+1] = {
1332 [IFLA_VF_INFO] = { .type = NLA_NESTED },
1333};
1334
1335static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = { 1331static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
1336 [IFLA_VF_MAC] = { .len = sizeof(struct ifla_vf_mac) }, 1332 [IFLA_VF_MAC] = { .len = sizeof(struct ifla_vf_mac) },
1337 [IFLA_VF_VLAN] = { .len = sizeof(struct ifla_vf_vlan) }, 1333 [IFLA_VF_VLAN] = { .len = sizeof(struct ifla_vf_vlan) },
@@ -1488,96 +1484,98 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
1488 return 0; 1484 return 0;
1489} 1485}
1490 1486
1491static int do_setvfinfo(struct net_device *dev, struct nlattr *attr) 1487static int do_setvfinfo(struct net_device *dev, struct nlattr **tb)
1492{ 1488{
1493 int rem, err = -EINVAL;
1494 struct nlattr *vf;
1495 const struct net_device_ops *ops = dev->netdev_ops; 1489 const struct net_device_ops *ops = dev->netdev_ops;
1490 int err = -EINVAL;
1496 1491
1497 nla_for_each_nested(vf, attr, rem) { 1492 if (tb[IFLA_VF_MAC]) {
1498 switch (nla_type(vf)) { 1493 struct ifla_vf_mac *ivm = nla_data(tb[IFLA_VF_MAC]);
1499 case IFLA_VF_MAC: {
1500 struct ifla_vf_mac *ivm;
1501 ivm = nla_data(vf);
1502 err = -EOPNOTSUPP;
1503 if (ops->ndo_set_vf_mac)
1504 err = ops->ndo_set_vf_mac(dev, ivm->vf,
1505 ivm->mac);
1506 break;
1507 }
1508 case IFLA_VF_VLAN: {
1509 struct ifla_vf_vlan *ivv;
1510 ivv = nla_data(vf);
1511 err = -EOPNOTSUPP;
1512 if (ops->ndo_set_vf_vlan)
1513 err = ops->ndo_set_vf_vlan(dev, ivv->vf,
1514 ivv->vlan,
1515 ivv->qos);
1516 break;
1517 }
1518 case IFLA_VF_TX_RATE: {
1519 struct ifla_vf_tx_rate *ivt;
1520 struct ifla_vf_info ivf;
1521 ivt = nla_data(vf);
1522 err = -EOPNOTSUPP;
1523 if (ops->ndo_get_vf_config)
1524 err = ops->ndo_get_vf_config(dev, ivt->vf,
1525 &ivf);
1526 if (err)
1527 break;
1528 err = -EOPNOTSUPP;
1529 if (ops->ndo_set_vf_rate)
1530 err = ops->ndo_set_vf_rate(dev, ivt->vf,
1531 ivf.min_tx_rate,
1532 ivt->rate);
1533 break;
1534 }
1535 case IFLA_VF_RATE: {
1536 struct ifla_vf_rate *ivt;
1537 ivt = nla_data(vf);
1538 err = -EOPNOTSUPP;
1539 if (ops->ndo_set_vf_rate)
1540 err = ops->ndo_set_vf_rate(dev, ivt->vf,
1541 ivt->min_tx_rate,
1542 ivt->max_tx_rate);
1543 break;
1544 }
1545 case IFLA_VF_SPOOFCHK: {
1546 struct ifla_vf_spoofchk *ivs;
1547 ivs = nla_data(vf);
1548 err = -EOPNOTSUPP;
1549 if (ops->ndo_set_vf_spoofchk)
1550 err = ops->ndo_set_vf_spoofchk(dev, ivs->vf,
1551 ivs->setting);
1552 break;
1553 }
1554 case IFLA_VF_LINK_STATE: {
1555 struct ifla_vf_link_state *ivl;
1556 ivl = nla_data(vf);
1557 err = -EOPNOTSUPP;
1558 if (ops->ndo_set_vf_link_state)
1559 err = ops->ndo_set_vf_link_state(dev, ivl->vf,
1560 ivl->link_state);
1561 break;
1562 }
1563 case IFLA_VF_RSS_QUERY_EN: {
1564 struct ifla_vf_rss_query_en *ivrssq_en;
1565 1494
1566 ivrssq_en = nla_data(vf); 1495 err = -EOPNOTSUPP;
1567 err = -EOPNOTSUPP; 1496 if (ops->ndo_set_vf_mac)
1568 if (ops->ndo_set_vf_rss_query_en) 1497 err = ops->ndo_set_vf_mac(dev, ivm->vf,
1569 err = ops->ndo_set_vf_rss_query_en(dev, 1498 ivm->mac);
1570 ivrssq_en->vf, 1499 if (err < 0)
1571 ivrssq_en->setting); 1500 return err;
1572 break; 1501 }
1573 } 1502
1574 default: 1503 if (tb[IFLA_VF_VLAN]) {
1575 err = -EINVAL; 1504 struct ifla_vf_vlan *ivv = nla_data(tb[IFLA_VF_VLAN]);
1576 break; 1505
1577 } 1506 err = -EOPNOTSUPP;
1578 if (err) 1507 if (ops->ndo_set_vf_vlan)
1579 break; 1508 err = ops->ndo_set_vf_vlan(dev, ivv->vf, ivv->vlan,
1509 ivv->qos);
1510 if (err < 0)
1511 return err;
1512 }
1513
1514 if (tb[IFLA_VF_TX_RATE]) {
1515 struct ifla_vf_tx_rate *ivt = nla_data(tb[IFLA_VF_TX_RATE]);
1516 struct ifla_vf_info ivf;
1517
1518 err = -EOPNOTSUPP;
1519 if (ops->ndo_get_vf_config)
1520 err = ops->ndo_get_vf_config(dev, ivt->vf, &ivf);
1521 if (err < 0)
1522 return err;
1523
1524 err = -EOPNOTSUPP;
1525 if (ops->ndo_set_vf_rate)
1526 err = ops->ndo_set_vf_rate(dev, ivt->vf,
1527 ivf.min_tx_rate,
1528 ivt->rate);
1529 if (err < 0)
1530 return err;
1531 }
1532
1533 if (tb[IFLA_VF_RATE]) {
1534 struct ifla_vf_rate *ivt = nla_data(tb[IFLA_VF_RATE]);
1535
1536 err = -EOPNOTSUPP;
1537 if (ops->ndo_set_vf_rate)
1538 err = ops->ndo_set_vf_rate(dev, ivt->vf,
1539 ivt->min_tx_rate,
1540 ivt->max_tx_rate);
1541 if (err < 0)
1542 return err;
1543 }
1544
1545 if (tb[IFLA_VF_SPOOFCHK]) {
1546 struct ifla_vf_spoofchk *ivs = nla_data(tb[IFLA_VF_SPOOFCHK]);
1547
1548 err = -EOPNOTSUPP;
1549 if (ops->ndo_set_vf_spoofchk)
1550 err = ops->ndo_set_vf_spoofchk(dev, ivs->vf,
1551 ivs->setting);
1552 if (err < 0)
1553 return err;
1580 } 1554 }
1555
1556 if (tb[IFLA_VF_LINK_STATE]) {
1557 struct ifla_vf_link_state *ivl = nla_data(tb[IFLA_VF_LINK_STATE]);
1558
1559 err = -EOPNOTSUPP;
1560 if (ops->ndo_set_vf_link_state)
1561 err = ops->ndo_set_vf_link_state(dev, ivl->vf,
1562 ivl->link_state);
1563 if (err < 0)
1564 return err;
1565 }
1566
1567 if (tb[IFLA_VF_RSS_QUERY_EN]) {
1568 struct ifla_vf_rss_query_en *ivrssq_en;
1569
1570 err = -EOPNOTSUPP;
1571 ivrssq_en = nla_data(tb[IFLA_VF_RSS_QUERY_EN]);
1572 if (ops->ndo_set_vf_rss_query_en)
1573 err = ops->ndo_set_vf_rss_query_en(dev, ivrssq_en->vf,
1574 ivrssq_en->setting);
1575 if (err < 0)
1576 return err;
1577 }
1578
1581 return err; 1579 return err;
1582} 1580}
1583 1581
@@ -1773,14 +1771,21 @@ static int do_setlink(const struct sk_buff *skb,
1773 } 1771 }
1774 1772
1775 if (tb[IFLA_VFINFO_LIST]) { 1773 if (tb[IFLA_VFINFO_LIST]) {
1774 struct nlattr *vfinfo[IFLA_VF_MAX + 1];
1776 struct nlattr *attr; 1775 struct nlattr *attr;
1777 int rem; 1776 int rem;
1777
1778 nla_for_each_nested(attr, tb[IFLA_VFINFO_LIST], rem) { 1778 nla_for_each_nested(attr, tb[IFLA_VFINFO_LIST], rem) {
1779 if (nla_type(attr) != IFLA_VF_INFO) { 1779 if (nla_type(attr) != IFLA_VF_INFO ||
1780 nla_len(attr) < NLA_HDRLEN) {
1780 err = -EINVAL; 1781 err = -EINVAL;
1781 goto errout; 1782 goto errout;
1782 } 1783 }
1783 err = do_setvfinfo(dev, attr); 1784 err = nla_parse_nested(vfinfo, IFLA_VF_MAX, attr,
1785 ifla_vf_policy);
1786 if (err < 0)
1787 goto errout;
1788 err = do_setvfinfo(dev, vfinfo);
1784 if (err < 0) 1789 if (err < 0)
1785 goto errout; 1790 goto errout;
1786 status |= DO_SETLINK_NOTIFY; 1791 status |= DO_SETLINK_NOTIFY;
@@ -1799,10 +1804,13 @@ static int do_setlink(const struct sk_buff *skb,
1799 goto errout; 1804 goto errout;
1800 1805
1801 nla_for_each_nested(attr, tb[IFLA_VF_PORTS], rem) { 1806 nla_for_each_nested(attr, tb[IFLA_VF_PORTS], rem) {
1802 if (nla_type(attr) != IFLA_VF_PORT) 1807 if (nla_type(attr) != IFLA_VF_PORT ||
1803 continue; 1808 nla_len(attr) < NLA_HDRLEN) {
1804 err = nla_parse_nested(port, IFLA_PORT_MAX, 1809 err = -EINVAL;
1805 attr, ifla_port_policy); 1810 goto errout;
1811 }
1812 err = nla_parse_nested(port, IFLA_PORT_MAX, attr,
1813 ifla_port_policy);
1806 if (err < 0) 1814 if (err < 0)
1807 goto errout; 1815 goto errout;
1808 if (!port[IFLA_PORT_VF]) { 1816 if (!port[IFLA_PORT_VF]) {