Commit 6f7a9f4d authored by Eric W. Biederman's avatar Eric W. Biederman Committed by Stephen Hemminger

add support for the RTA_NEWDST attribute.

This attribute is like RTA_DST except it specifies the destination
address to place on a packet when it leaves the host.  For ip based
protocols this is destination NAT and not a common part of forwarding.
For protocols like MPLS label swapping is something that typically
happens on every hop.

There is likely to be a RTA_NEWSRC at some point so RTA_NEWDST
is printed as "as to"  and can be specified either as "as to"
or just "as"
Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
parent 93ae2835
...@@ -77,7 +77,7 @@ static void usage(void) ...@@ -77,7 +77,7 @@ static void usage(void)
fprintf(stderr, "INFO_SPEC := NH OPTIONS FLAGS [ nexthop NH ]...\n"); fprintf(stderr, "INFO_SPEC := NH OPTIONS FLAGS [ nexthop NH ]...\n");
fprintf(stderr, "NH := [ via [ FAMILY ] ADDRESS ] [ dev STRING ] [ weight NUMBER ] NHFLAGS\n"); fprintf(stderr, "NH := [ via [ FAMILY ] ADDRESS ] [ dev STRING ] [ weight NUMBER ] NHFLAGS\n");
fprintf(stderr, "FAMILY := [ inet | inet6 | ipx | dnet | bridge | link ]"); fprintf(stderr, "FAMILY := [ inet | inet6 | ipx | dnet | bridge | link ]");
fprintf(stderr, "OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ]\n"); fprintf(stderr, "OPTIONS := FLAGS [ mtu NUMBER ] [ advmss NUMBER ] [ as [ to ] ADDRESS ]\n");
fprintf(stderr, " [ rtt TIME ] [ rttvar TIME ] [ reordering NUMBER ]\n"); fprintf(stderr, " [ rtt TIME ] [ rttvar TIME ] [ reordering NUMBER ]\n");
fprintf(stderr, " [ window NUMBER] [ cwnd NUMBER ] [ initcwnd NUMBER ]\n"); fprintf(stderr, " [ window NUMBER] [ cwnd NUMBER ] [ initcwnd NUMBER ]\n");
fprintf(stderr, " [ ssthresh NUMBER ] [ realms REALM ] [ src ADDRESS ]\n"); fprintf(stderr, " [ ssthresh NUMBER ] [ realms REALM ] [ src ADDRESS ]\n");
...@@ -388,6 +388,13 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) ...@@ -388,6 +388,13 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
} else if (r->rtm_src_len) { } else if (r->rtm_src_len) {
fprintf(fp, "from 0/%u ", r->rtm_src_len); fprintf(fp, "from 0/%u ", r->rtm_src_len);
} }
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 (r->rtm_tos && filter.tosmask != -1) { if (r->rtm_tos && filter.tosmask != -1) {
SPRINT_BUF(b1); SPRINT_BUF(b1);
fprintf(fp, "tos %s ", rtnl_dsfield_n2a(r->rtm_tos, b1, sizeof(b1))); fprintf(fp, "tos %s ", rtnl_dsfield_n2a(r->rtm_tos, b1, sizeof(b1)));
...@@ -802,6 +809,16 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv) ...@@ -802,6 +809,16 @@ static int iproute_modify(int cmd, unsigned flags, int argc, char **argv)
if (req.r.rtm_family == AF_UNSPEC) if (req.r.rtm_family == AF_UNSPEC)
req.r.rtm_family = addr.family; req.r.rtm_family = addr.family;
addattr_l(&req.n, sizeof(req), RTA_PREFSRC, &addr.data, addr.bytelen); addattr_l(&req.n, sizeof(req), RTA_PREFSRC, &addr.data, addr.bytelen);
} else if (strcmp(*argv, "as") == 0) {
inet_prefix addr;
NEXT_ARG();
if (strcmp(*argv, "to") == 0) {
NEXT_ARG();
}
get_addr(&addr, *argv, req.r.rtm_family);
if (req.r.rtm_family == AF_UNSPEC)
req.r.rtm_family = addr.family;
addattr_l(&req.n, sizeof(req), RTA_NEWDST, &addr.data, addr.bytelen);
} else if (strcmp(*argv, "via") == 0) { } else if (strcmp(*argv, "via") == 0) {
inet_prefix addr; inet_prefix addr;
int family; int family;
......
...@@ -98,6 +98,11 @@ replace " } " ...@@ -98,6 +98,11 @@ replace " } "
.IR NUMBER " ] [ " .IR NUMBER " ] [ "
.B advmss .B advmss
.IR NUMBER " ] [ " .IR NUMBER " ] [ "
.B as
[
.B to
]
.IR ADDRESS " ]"
.B rtt .B rtt
.IR TIME " ] [ " .IR TIME " ] [ "
.B rttvar .B rttvar
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment