diff options
author | David Ahern <dsahern@gmail.com> | 2017-05-27 18:19:29 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-05-30 11:55:32 -0400 |
commit | a1f10abe12b6d70f8b02dedccb48c9d234a57b67 (patch) | |
tree | be09b101e9c3789ba4d6215f5b06059837f52600 /net/mpls/af_mpls.c | |
parent | 9ae287274817c032a4428fde84d1ab26d6b96761 (diff) |
net: Fill in extack for mpls lwt encap
Fill in extack for errors in build_state for mpls lwt encap including
passing extack to nla_get_labels and adding error messages for failures
in it.
Signed-off-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mpls/af_mpls.c')
-rw-r--r-- | net/mpls/af_mpls.c | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 257ec66009da..f3830951fb1c 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c | |||
@@ -728,8 +728,8 @@ static int mpls_nh_build(struct net *net, struct mpls_route *rt, | |||
728 | goto errout; | 728 | goto errout; |
729 | 729 | ||
730 | if (newdst) { | 730 | if (newdst) { |
731 | err = nla_get_labels(newdst, max_labels, | 731 | err = nla_get_labels(newdst, max_labels, &nh->nh_labels, |
732 | &nh->nh_labels, nh->nh_label); | 732 | nh->nh_label, NULL); |
733 | if (err) | 733 | if (err) |
734 | goto errout; | 734 | goto errout; |
735 | } | 735 | } |
@@ -782,7 +782,8 @@ static u8 mpls_count_nexthops(struct rtnexthop *rtnh, int len, | |||
782 | 782 | ||
783 | nla = nla_find(attrs, attrlen, RTA_NEWDST); | 783 | nla = nla_find(attrs, attrlen, RTA_NEWDST); |
784 | if (nla && | 784 | if (nla && |
785 | nla_get_labels(nla, MAX_NEW_LABELS, &n_labels, NULL) != 0) | 785 | nla_get_labels(nla, MAX_NEW_LABELS, &n_labels, |
786 | NULL, NULL) != 0) | ||
786 | return 0; | 787 | return 0; |
787 | 788 | ||
788 | *max_labels = max_t(u8, *max_labels, n_labels); | 789 | *max_labels = max_t(u8, *max_labels, n_labels); |
@@ -1541,8 +1542,8 @@ int nla_put_labels(struct sk_buff *skb, int attrtype, | |||
1541 | } | 1542 | } |
1542 | EXPORT_SYMBOL_GPL(nla_put_labels); | 1543 | EXPORT_SYMBOL_GPL(nla_put_labels); |
1543 | 1544 | ||
1544 | int nla_get_labels(const struct nlattr *nla, | 1545 | int nla_get_labels(const struct nlattr *nla, u8 max_labels, u8 *labels, |
1545 | u8 max_labels, u8 *labels, u32 label[]) | 1546 | u32 label[], struct netlink_ext_ack *extack) |
1546 | { | 1547 | { |
1547 | unsigned len = nla_len(nla); | 1548 | unsigned len = nla_len(nla); |
1548 | struct mpls_shim_hdr *nla_label; | 1549 | struct mpls_shim_hdr *nla_label; |
@@ -1553,13 +1554,18 @@ int nla_get_labels(const struct nlattr *nla, | |||
1553 | /* len needs to be an even multiple of 4 (the label size). Number | 1554 | /* len needs to be an even multiple of 4 (the label size). Number |
1554 | * of labels is a u8 so check for overflow. | 1555 | * of labels is a u8 so check for overflow. |
1555 | */ | 1556 | */ |
1556 | if (len & 3 || len / 4 > 255) | 1557 | if (len & 3 || len / 4 > 255) { |
1558 | NL_SET_ERR_MSG_ATTR(extack, nla, | ||
1559 | "Invalid length for labels attribute"); | ||
1557 | return -EINVAL; | 1560 | return -EINVAL; |
1561 | } | ||
1558 | 1562 | ||
1559 | /* Limit the number of new labels allowed */ | 1563 | /* Limit the number of new labels allowed */ |
1560 | nla_labels = len/4; | 1564 | nla_labels = len/4; |
1561 | if (nla_labels > max_labels) | 1565 | if (nla_labels > max_labels) { |
1566 | NL_SET_ERR_MSG(extack, "Too many labels"); | ||
1562 | return -EINVAL; | 1567 | return -EINVAL; |
1568 | } | ||
1563 | 1569 | ||
1564 | /* when label == NULL, caller wants number of labels */ | 1570 | /* when label == NULL, caller wants number of labels */ |
1565 | if (!label) | 1571 | if (!label) |
@@ -1574,8 +1580,29 @@ int nla_get_labels(const struct nlattr *nla, | |||
1574 | /* Ensure the bottom of stack flag is properly set | 1580 | /* Ensure the bottom of stack flag is properly set |
1575 | * and ttl and tc are both clear. | 1581 | * and ttl and tc are both clear. |
1576 | */ | 1582 | */ |
1577 | if ((dec.bos != bos) || dec.ttl || dec.tc) | 1583 | if (dec.ttl) { |
1584 | NL_SET_ERR_MSG_ATTR(extack, nla, | ||
1585 | "TTL in label must be 0"); | ||
1586 | return -EINVAL; | ||
1587 | } | ||
1588 | |||
1589 | if (dec.tc) { | ||
1590 | NL_SET_ERR_MSG_ATTR(extack, nla, | ||
1591 | "Traffic class in label must be 0"); | ||
1578 | return -EINVAL; | 1592 | return -EINVAL; |
1593 | } | ||
1594 | |||
1595 | if (dec.bos != bos) { | ||
1596 | NL_SET_BAD_ATTR(extack, nla); | ||
1597 | if (bos) { | ||
1598 | NL_SET_ERR_MSG(extack, | ||
1599 | "BOS bit must be set in first label"); | ||
1600 | } else { | ||
1601 | NL_SET_ERR_MSG(extack, | ||
1602 | "BOS bit can only be set in first label"); | ||
1603 | } | ||
1604 | return -EINVAL; | ||
1605 | } | ||
1579 | 1606 | ||
1580 | switch (dec.label) { | 1607 | switch (dec.label) { |
1581 | case MPLS_LABEL_IMPLNULL: | 1608 | case MPLS_LABEL_IMPLNULL: |
@@ -1583,6 +1610,8 @@ int nla_get_labels(const struct nlattr *nla, | |||
1583 | * assign and distribute, but which never | 1610 | * assign and distribute, but which never |
1584 | * actually appears in the encapsulation. | 1611 | * actually appears in the encapsulation. |
1585 | */ | 1612 | */ |
1613 | NL_SET_ERR_MSG_ATTR(extack, nla, | ||
1614 | "Implicit NULL Label (3) can not be used in encapsulation"); | ||
1586 | return -EINVAL; | 1615 | return -EINVAL; |
1587 | } | 1616 | } |
1588 | 1617 | ||
@@ -1696,14 +1725,14 @@ static int rtm_to_route_config(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1696 | case RTA_NEWDST: | 1725 | case RTA_NEWDST: |
1697 | if (nla_get_labels(nla, MAX_NEW_LABELS, | 1726 | if (nla_get_labels(nla, MAX_NEW_LABELS, |
1698 | &cfg->rc_output_labels, | 1727 | &cfg->rc_output_labels, |
1699 | cfg->rc_output_label)) | 1728 | cfg->rc_output_label, NULL)) |
1700 | goto errout; | 1729 | goto errout; |
1701 | break; | 1730 | break; |
1702 | case RTA_DST: | 1731 | case RTA_DST: |
1703 | { | 1732 | { |
1704 | u8 label_count; | 1733 | u8 label_count; |
1705 | if (nla_get_labels(nla, 1, &label_count, | 1734 | if (nla_get_labels(nla, 1, &label_count, |
1706 | &cfg->rc_label)) | 1735 | &cfg->rc_label, NULL)) |
1707 | goto errout; | 1736 | goto errout; |
1708 | 1737 | ||
1709 | /* Reserved labels may not be set */ | 1738 | /* Reserved labels may not be set */ |