aboutsummaryrefslogtreecommitdiffstats
path: root/net/mpls
diff options
context:
space:
mode:
authorRobert Shearman <rshearma@brocade.com>2015-12-10 14:30:51 -0500
committerDavid S. Miller <davem@davemloft.net>2015-12-12 00:43:44 -0500
commitf20367df1af8f6a4e85b7e586213b8508796fe79 (patch)
treeb078d7f3dd5461b90a74c8cd9bc6c5a41e434cbd /net/mpls
parenteb7809f093b109a7db7454dc775423675d075653 (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.c22
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);