]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
ip route: add mpls multipath support
authorRoopa Prabhu <roopa@cumulusnetworks.com>
Mon, 8 Feb 2016 00:28:16 +0000 (16:28 -0800)
committerStephen Hemminger <stephen@networkplumber.org>
Tue, 9 Feb 2016 18:43:16 +0000 (10:43 -0800)
This patch adds support to add mpls multipath
routes.

example:
ip -f mpls route add 100 \
nexthop as 200 via inet 10.1.1.2 dev swp1 \
nexthop as 700 via inet 10.1.1.6 dev swp2

Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
ip/iproute.c

index afe70e123cc4ddb40f51c6fb53dcb1387ddaba9a..051fc12d197eb66b064797f2aca6edc1073679d0 100644 (file)
@@ -646,7 +646,13 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
                                        lwt_print_encap(fp,
                                                        tb[RTA_ENCAP_TYPE],
                                                        tb[RTA_ENCAP]);
-
+                               if (tb[RTA_NEWDST]) {
+                                       fprintf(fp, " as to %s ",
+                                               format_host(r->rtm_family,
+                                               RTA_PAYLOAD(tb[RTA_NEWDST]),
+                                               RTA_DATA(tb[RTA_NEWDST]),
+                                               abuf, sizeof(abuf)));
+                               }
                                if (tb[RTA_GATEWAY]) {
                                        fprintf(fp, " via %s ",
                                                format_host(r->rtm_family,
@@ -681,7 +687,9 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
                                        fprintf(fp, "(ttl>%d)", nh->rtnh_hops);
                        } else {
                                fprintf(fp, " dev %s", ll_index_to_name(nh->rtnh_ifindex));
-                               fprintf(fp, " weight %d", nh->rtnh_hops+1);
+                               if (r->rtm_family != AF_MPLS)
+                                       fprintf(fp, " weight %d",
+                                               nh->rtnh_hops+1);
                        }
                        if (nh->rtnh_flags & RTNH_F_DEAD)
                                fprintf(fp, " dead");
@@ -743,7 +751,7 @@ static int parse_one_nh(struct nlmsghdr *n, struct rtmsg *r,
                                rtnh->rtnh_len += sizeof(struct rtattr) + addr.bytelen;
                        } else {
                                rta_addattr_l(rta, 4096, RTA_VIA, &addr.family, addr.bytelen+2);
-                               rtnh->rtnh_len += sizeof(struct rtattr) + addr.bytelen+2;
+                               rtnh->rtnh_len += RTA_SPACE(addr.bytelen+2);
                        }
                } else if (strcmp(*argv, "dev") == 0) {
                        NEXT_ARG();
@@ -771,6 +779,16 @@ static int parse_one_nh(struct nlmsghdr *n, struct rtmsg *r,
 
                        lwt_parse_encap(rta, 4096, &argc, &argv);
                        rtnh->rtnh_len += rta->rta_len - len;
+               } else if (strcmp(*argv, "as") == 0) {
+                       inet_prefix addr;
+
+                       NEXT_ARG();
+                       if (strcmp(*argv, "to") == 0)
+                               NEXT_ARG();
+                       get_addr(&addr, *argv, r->rtm_family);
+                       rta_addattr_l(rta, 4096, RTA_NEWDST, &addr.data,
+                                     addr.bytelen);
+                       rtnh->rtnh_len += sizeof(struct rtattr) + addr.bytelen;
                } else
                        break;
        }
@@ -881,9 +899,11 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
                        if (req.r.rtm_family == AF_UNSPEC)
                                req.r.rtm_family = addr.family;
                        if (addr.family == req.r.rtm_family)
-                               addattr_l(&req.n, sizeof(req), RTA_GATEWAY, &addr.data, addr.bytelen);
+                               addattr_l(&req.n, sizeof(req), RTA_GATEWAY,
+                                         &addr.data, addr.bytelen);
                        else
-                               addattr_l(&req.n, sizeof(req), RTA_VIA, &addr.family, addr.bytelen+2);
+                               addattr_l(&req.n, sizeof(req), RTA_VIA,
+                                         &addr.family, addr.bytelen+2);
                } else if (strcmp(*argv, "from") == 0) {
                        inet_prefix addr;
                        NEXT_ARG();