X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=ip%2Fiproute.c;h=a43c09e6cba6a82de0a45e527780e19ff2e9befa;hb=b4a5a91c5a4ca186690479ddc0fff26644c98c93;hp=1e23e498d5577d9c594a3b02603fa0c955578038;hpb=143d7e99faac73b7f2947e37df31a75738eeadde;p=iproute2.git diff --git a/ip/iproute.c b/ip/iproute.c index 1e23e49..a43c09e 100644 --- a/ip/iproute.c +++ b/ip/iproute.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "rt_names.h" #include "utils.h" @@ -53,6 +54,7 @@ static void usage(void) fprintf(stderr, "NODE_SPEC := [ TYPE ] PREFIX [ tos TOS ]\n"); fprintf(stderr, " [ table TABLE_ID ] [ proto RTPROTO ]\n"); fprintf(stderr, " [ scope SCOPE ] [ metric METRIC ]\n"); + fprintf(stderr, " [ mpath MP_ALGO ]\n"); fprintf(stderr, "INFO_SPEC := NH OPTIONS FLAGS [ nexthop NH ]...\n"); fprintf(stderr, "NH := [ via ADDRESS ] [ dev STRING ] [ weight NUMBER ] NHFLAGS\n"); fprintf(stderr, "OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ]\n"); @@ -64,6 +66,7 @@ static void usage(void) fprintf(stderr, "TABLE_ID := [ local | main | default | all | NUMBER ]\n"); fprintf(stderr, "SCOPE := [ host | link | global | NUMBER ]\n"); fprintf(stderr, "FLAGS := [ equalize ]\n"); + fprintf(stderr, "MP_ALGO := { rr | drr | random | wrandom }\n"); fprintf(stderr, "NHFLAGS := [ onlink | pervasive ]\n"); fprintf(stderr, "RTPROTO := [ kernel | boot | static | NUMBER ]\n"); exit(-1); @@ -77,7 +80,6 @@ static struct char *flushb; int flushp; int flushe; - struct rtnl_handle *rth; int protocol, protocolmask; int scope, scopemask; int type, typemask; @@ -93,9 +95,17 @@ static struct inet_prefix msrc; } filter; +static char *mp_alg_names[IP_MP_ALG_MAX+1] = { + [IP_MP_ALG_NONE] = "none", + [IP_MP_ALG_RR] = "rr", + [IP_MP_ALG_DRR] = "drr", + [IP_MP_ALG_RANDOM] = "random", + [IP_MP_ALG_WRANDOM] = "wrandom" +}; + static int flush_update(void) { - if (rtnl_send(filter.rth, filter.flushb, filter.flushp) < 0) { + if (rtnl_send(&rth, filter.flushb, filter.flushp) < 0) { perror("Failed to send flush request\n"); return -1; } @@ -206,13 +216,13 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) memset(&via, 0, sizeof(via)); via.family = r->rtm_family; if (tb[RTA_GATEWAY]) - memcpy(&via.data, RTA_DATA(tb[RTA_GATEWAY]), host_len); + memcpy(&via.data, RTA_DATA(tb[RTA_GATEWAY]), host_len/8); } if (filter.rprefsrc.bitlen>0) { memset(&prefsrc, 0, sizeof(prefsrc)); prefsrc.family = r->rtm_family; if (tb[RTA_PREFSRC]) - memcpy(&prefsrc.data, RTA_DATA(tb[RTA_PREFSRC]), host_len); + memcpy(&prefsrc.data, RTA_DATA(tb[RTA_PREFSRC]), host_len/8); } if (filter.rdst.family && inet_addr_match(&dst, &filter.rdst, filter.rdst.bitlen)) @@ -270,7 +280,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) memcpy(fn, n, n->nlmsg_len); fn->nlmsg_type = RTM_DELROUTE; fn->nlmsg_flags = NLM_F_REQUEST; - fn->nlmsg_seq = ++filter.rth->seq; + fn->nlmsg_seq = ++rth.seq; filter.flushp = (((char*)fn) + n->nlmsg_len) - filter.flushb; filter.flushed++; if (show_stats < 2) @@ -324,6 +334,15 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) SPRINT_BUF(b1); fprintf(fp, "tos %s ", rtnl_dsfield_n2a(r->rtm_tos, b1, sizeof(b1))); } + + if (tb[RTA_MP_ALGO]) { + __u32 mp_alg = *(__u32*) RTA_DATA(tb[RTA_MP_ALGO]); + if (mp_alg > IP_MP_ALG_NONE) { + fprintf(fp, "mpath %s ", + mp_alg < IP_MP_ALG_MAX ? mp_alg_names[mp_alg] : "unknown"); + } + } + if (tb[RTA_GATEWAY] && filter.rvia.bitlen != host_len) { fprintf(fp, "via %s ", format_host(r->rtm_family, @@ -616,9 +635,6 @@ int parse_nexthops(struct nlmsghdr *n, struct rtmsg *r, int argc, char **argv) } memset(rtnh, 0, sizeof(*rtnh)); rtnh->rtnh_len = sizeof(*rtnh); - rtnh->rtnh_ifindex = 0; - rtnh->rtnh_flags = 0; - rtnh->rtnh_hops = 0; rta->rta_len += rtnh->rtnh_len; parse_one_nh(rta, rtnh, &argc, &argv); rtnh = RTNH_NEXT(rtnh); @@ -632,7 +648,6 @@ int parse_nexthops(struct nlmsghdr *n, struct rtmsg *r, int argc, char **argv) int iproute_modify(int cmd, unsigned flags, int argc, char **argv) { - struct rtnl_handle rth; struct { struct nlmsghdr n; struct rtmsg r; @@ -709,7 +724,7 @@ int iproute_modify(int cmd, unsigned flags, int argc, char **argv) invarg("\"metric\" value is invalid\n", *argv); addattr32(&req.n, sizeof(req), RTA_PRIORITY, metric); } else if (strcmp(*argv, "scope") == 0) { - int scope = 0; + __u32 scope = 0; NEXT_ARG(); if (rtnl_rtscope_a2n(&scope, *argv)) invarg("invalid \"scope\" value\n", *argv); @@ -814,14 +829,14 @@ int iproute_modify(int cmd, unsigned flags, int argc, char **argv) nhs_ok = 1; break; } else if (matches(*argv, "protocol") == 0) { - int prot; + __u32 prot; NEXT_ARG(); if (rtnl_rtprot_a2n(&prot, *argv)) invarg("\"protocol\" value is invalid\n", *argv); req.r.rtm_protocol = prot; proto_ok =1; } else if (matches(*argv, "table") == 0) { - int tid; + __u32 tid; NEXT_ARG(); if (rtnl_rttable_a2n(&tid, *argv)) invarg("\"table\" value is invalid\n", *argv); @@ -831,6 +846,18 @@ int iproute_modify(int cmd, unsigned flags, int argc, char **argv) strcmp(*argv, "oif") == 0) { NEXT_ARG(); d = *argv; + } else if (strcmp(*argv, "mpath") == 0 || + strcmp(*argv, "mp") == 0) { + int i; + __u32 mp_alg = IP_MP_ALG_NONE; + + NEXT_ARG(); + for (i = 1; i < ARRAY_SIZE(mp_alg_names); i++) + if (strcmp(*argv, mp_alg_names[i]) == 0) + mp_alg = i; + if (mp_alg == IP_MP_ALG_NONE) + invarg("\"mpath\" value is invalid\n", *argv); + addattr_l(&req.n, sizeof(req), RTA_MP_ALGO, &mp_alg, sizeof(mp_alg)); } else { int type; inet_prefix dst; @@ -860,9 +887,6 @@ int iproute_modify(int cmd, unsigned flags, int argc, char **argv) argc--; argv++; } - if (rtnl_open(&rth, 0) < 0) - exit(1); - if (d || nhs_ok) { int idx; @@ -969,7 +993,6 @@ static int iproute_flush_cache(void) static int iproute_list_or_flush(int argc, char **argv, int flush) { int do_ipv6 = preferred_family; - struct rtnl_handle rth; char *id = NULL; char *od = NULL; @@ -983,7 +1006,7 @@ static int iproute_list_or_flush(int argc, char **argv, int flush) while (argc > 0) { if (matches(*argv, "table") == 0) { - int tid; + __u32 tid; NEXT_ARG(); if (rtnl_rttable_a2n(&tid, *argv)) { if (strcmp(*argv, "all") == 0) { @@ -1009,7 +1032,7 @@ static int iproute_list_or_flush(int argc, char **argv, int flush) filter.tos = tos; filter.tosmask = -1; } else if (matches(*argv, "protocol") == 0) { - int prot = 0; + __u32 prot = 0; NEXT_ARG(); filter.protocolmask = -1; if (rtnl_rtprot_a2n(&prot, *argv)) { @@ -1020,7 +1043,7 @@ static int iproute_list_or_flush(int argc, char **argv, int flush) } filter.protocol = prot; } else if (matches(*argv, "scope") == 0) { - int scope = 0; + __u32 scope = 0; NEXT_ARG(); filter.scopemask = -1; if (rtnl_rtscope_a2n(&scope, *argv)) { @@ -1103,9 +1126,6 @@ static int iproute_list_or_flush(int argc, char **argv, int flush) if (do_ipv6 == AF_UNSPEC && filter.tb) do_ipv6 = AF_INET; - if (rtnl_open(&rth, 0) < 0) - exit(1); - ll_init_map(&rth); if (id || od) { @@ -1147,7 +1167,6 @@ static int iproute_list_or_flush(int argc, char **argv, int flush) filter.flushb = flushb; filter.flushp = 0; filter.flushe = sizeof(flushb); - filter.rth = &rth; for (;;) { if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) { @@ -1208,7 +1227,6 @@ static int iproute_list_or_flush(int argc, char **argv, int flush) int iproute_get(int argc, char **argv) { - struct rtnl_handle rth; struct { struct nlmsghdr n; struct rtmsg r; @@ -1288,9 +1306,6 @@ int iproute_get(int argc, char **argv) exit(1); } - if (rtnl_open(&rth, 0) < 0) - exit(1); - ll_init_map(&rth); if (idev || odev) {