diff options
author | Robert Shearman <rshearma@brocade.com> | 2015-12-10 14:30:51 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-12-12 00:43:44 -0500 |
commit | f20367df1af8f6a4e85b7e586213b8508796fe79 (patch) | |
tree | b078d7f3dd5461b90a74c8cd9bc6c5a41e434cbd /net/mpls | |
parent | eb7809f093b109a7db7454dc775423675d075653 (diff) |
mpls: make via address optional for multipath routes
The via address is optional for a single path route, yet is mandatory
when the multipath attribute is used:
# ip -f mpls route add 100 dev lo
# ip -f mpls route add 101 nexthop dev lo
RTNETLINK answers: Invalid argument
Make them consistent by making the via address optional when the
RTA_MULTIPATH attribute is being parsed so that both forms of
specifying the route work.
Signed-off-by: Robert Shearman <rshearma@brocade.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mpls')
-rw-r--r-- | net/mpls/af_mpls.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 7bfc85f52ca8..c32fc411a911 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c | |||
@@ -604,10 +604,14 @@ static int mpls_nh_build(struct net *net, struct mpls_route *rt, | |||
604 | goto errout; | 604 | goto errout; |
605 | } | 605 | } |
606 | 606 | ||
607 | err = nla_get_via(via, &nh->nh_via_alen, &nh->nh_via_table, | 607 | if (via) { |
608 | __mpls_nh_via(rt, nh)); | 608 | err = nla_get_via(via, &nh->nh_via_alen, &nh->nh_via_table, |
609 | if (err) | 609 | __mpls_nh_via(rt, nh)); |
610 | goto errout; | 610 | if (err) |
611 | goto errout; | ||
612 | } else { | ||
613 | nh->nh_via_table = MPLS_NEIGH_TABLE_UNSPEC; | ||
614 | } | ||
611 | 615 | ||
612 | err = mpls_nh_assign_dev(net, rt, nh, oif); | 616 | err = mpls_nh_assign_dev(net, rt, nh, oif); |
613 | if (err) | 617 | if (err) |
@@ -689,9 +693,6 @@ static int mpls_nh_build_multi(struct mpls_route_config *cfg, | |||
689 | nla_newdst = nla_find(attrs, attrlen, RTA_NEWDST); | 693 | nla_newdst = nla_find(attrs, attrlen, RTA_NEWDST); |
690 | } | 694 | } |
691 | 695 | ||
692 | if (!nla_via) | ||
693 | goto errout; | ||
694 | |||
695 | err = mpls_nh_build(cfg->rc_nlinfo.nl_net, rt, nh, | 696 | err = mpls_nh_build(cfg->rc_nlinfo.nl_net, rt, nh, |
696 | rtnh->rtnh_ifindex, nla_via, | 697 | rtnh->rtnh_ifindex, nla_via, |
697 | nla_newdst); | 698 | nla_newdst); |
@@ -1271,7 +1272,8 @@ static int mpls_dump_route(struct sk_buff *skb, u32 portid, u32 seq, int event, | |||
1271 | nh->nh_labels, | 1272 | nh->nh_labels, |
1272 | nh->nh_label)) | 1273 | nh->nh_label)) |
1273 | goto nla_put_failure; | 1274 | goto nla_put_failure; |
1274 | if (nla_put_via(skb, nh->nh_via_table, | 1275 | if (nh->nh_via_table != MPLS_NEIGH_TABLE_UNSPEC && |
1276 | nla_put_via(skb, nh->nh_via_table, | ||
1275 | mpls_nh_via(rt, nh), | 1277 | mpls_nh_via(rt, nh), |
1276 | nh->nh_via_alen)) | 1278 | nh->nh_via_alen)) |
1277 | goto nla_put_failure; | 1279 | goto nla_put_failure; |
@@ -1343,7 +1345,9 @@ static inline size_t lfib_nlmsg_size(struct mpls_route *rt) | |||
1343 | 1345 | ||
1344 | for_nexthops(rt) { | 1346 | for_nexthops(rt) { |
1345 | nhsize += nla_total_size(sizeof(struct rtnexthop)); | 1347 | nhsize += nla_total_size(sizeof(struct rtnexthop)); |
1346 | nhsize += nla_total_size(2 + nh->nh_via_alen); | 1348 | /* RTA_VIA */ |
1349 | if (nh->nh_via_table != MPLS_NEIGH_TABLE_UNSPEC) | ||
1350 | nhsize += nla_total_size(2 + nh->nh_via_alen); | ||
1347 | if (nh->nh_labels) | 1351 | if (nh->nh_labels) |
1348 | nhsize += nla_total_size(nh->nh_labels * 4); | 1352 | nhsize += nla_total_size(nh->nh_labels * 4); |
1349 | } endfor_nexthops(rt); | 1353 | } endfor_nexthops(rt); |