]>
git.proxmox.com Git - mirror_iproute2.git/blob - ip/link_vti6.c
2 * link_vti6.c VTI driver module
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Authors: Herbert Xu <herbert@gondor.apana.org.au>
10 * Saurabh Mohan <saurabh.mohan@vyatta.com> Modified link_gre.c for VTI
11 * Steffen Klassert <steffen.klassert@secunet.com> Modified link_vti.c for IPv6
16 #include <sys/types.h>
17 #include <sys/socket.h>
18 #include <arpa/inet.h>
21 #include <linux/if_tunnel.h>
24 #include "ip_common.h"
28 static void usage(void) __attribute__((noreturn
));
29 static void usage(void)
31 fprintf(stderr
, "Usage: ip link { add | set | change | replace | del } NAME\n");
32 fprintf(stderr
, " type { vti6 } [ remote ADDR ] [ local ADDR ]\n");
33 fprintf(stderr
, " [ [i|o]key KEY ]\n");
34 fprintf(stderr
, " [ dev PHYS_DEV ]\n");
35 fprintf(stderr
, " [ fwmark MARK ]\n");
36 fprintf(stderr
, "\n");
37 fprintf(stderr
, "Where: NAME := STRING\n");
38 fprintf(stderr
, " ADDR := { IPV6_ADDRESS }\n");
39 fprintf(stderr
, " KEY := { DOTTED_QUAD | NUMBER }\n");
40 fprintf(stderr
, " MARK := { 0x0..0xffffffff }\n");
44 static int vti6_parse_opt(struct link_util
*lu
, int argc
, char **argv
,
47 struct ifinfomsg
*ifi
= (struct ifinfomsg
*)(n
+ 1);
52 .n
.nlmsg_len
= NLMSG_LENGTH(sizeof(*ifi
)),
53 .n
.nlmsg_flags
= NLM_F_REQUEST
,
54 .n
.nlmsg_type
= RTM_GETLINK
,
55 .i
.ifi_family
= preferred_family
,
56 .i
.ifi_index
= ifi
->ifi_index
,
58 struct nlmsghdr
*answer
;
59 struct rtattr
*tb
[IFLA_MAX
+ 1];
60 struct rtattr
*linkinfo
[IFLA_INFO_MAX
+1];
61 struct rtattr
*vtiinfo
[IFLA_VTI_MAX
+ 1];
62 struct in6_addr saddr
= IN6ADDR_ANY_INIT
;
63 struct in6_addr daddr
= IN6ADDR_ANY_INIT
;
66 unsigned int link
= 0;
70 if (!(n
->nlmsg_flags
& NLM_F_CREATE
)) {
71 if (rtnl_talk(&rth
, &req
.n
, &answer
) < 0) {
74 "Failed to get existing tunnel info.\n");
78 len
= answer
->nlmsg_len
;
79 len
-= NLMSG_LENGTH(sizeof(*ifi
));
83 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(NLMSG_DATA(answer
)), len
);
85 if (!tb
[IFLA_LINKINFO
])
88 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
[IFLA_LINKINFO
]);
90 if (!linkinfo
[IFLA_INFO_DATA
])
93 parse_rtattr_nested(vtiinfo
, IFLA_VTI_MAX
,
94 linkinfo
[IFLA_INFO_DATA
]);
96 if (vtiinfo
[IFLA_VTI_IKEY
])
97 ikey
= rta_getattr_u32(vtiinfo
[IFLA_VTI_IKEY
]);
99 if (vtiinfo
[IFLA_VTI_OKEY
])
100 okey
= rta_getattr_u32(vtiinfo
[IFLA_VTI_OKEY
]);
102 if (vtiinfo
[IFLA_VTI_LOCAL
])
103 memcpy(&saddr
, RTA_DATA(vtiinfo
[IFLA_VTI_LOCAL
]), sizeof(saddr
));
105 if (vtiinfo
[IFLA_VTI_REMOTE
])
106 memcpy(&daddr
, RTA_DATA(vtiinfo
[IFLA_VTI_REMOTE
]), sizeof(daddr
));
108 if (vtiinfo
[IFLA_VTI_LINK
])
109 link
= rta_getattr_u8(vtiinfo
[IFLA_VTI_LINK
]);
111 if (vtiinfo
[IFLA_VTI_FWMARK
])
112 fwmark
= rta_getattr_u32(vtiinfo
[IFLA_VTI_FWMARK
]);
118 if (!matches(*argv
, "key")) {
120 ikey
= okey
= tnl_parse_key("key", *argv
);
121 } else if (!matches(*argv
, "ikey")) {
123 ikey
= tnl_parse_key("ikey", *argv
);
124 } else if (!matches(*argv
, "okey")) {
126 okey
= tnl_parse_key("okey", *argv
);
127 } else if (!matches(*argv
, "remote")) {
131 get_addr(&addr
, *argv
, AF_INET6
);
132 memcpy(&daddr
, addr
.data
, sizeof(daddr
));
133 } else if (!matches(*argv
, "local")) {
137 get_addr(&addr
, *argv
, AF_INET6
);
138 memcpy(&saddr
, addr
.data
, sizeof(saddr
));
139 } else if (!matches(*argv
, "dev")) {
141 link
= if_nametoindex(*argv
);
144 } else if (strcmp(*argv
, "fwmark") == 0) {
146 if (get_u32(&fwmark
, *argv
, 0))
147 invarg("invalid fwmark\n", *argv
);
153 addattr32(n
, 1024, IFLA_VTI_IKEY
, ikey
);
154 addattr32(n
, 1024, IFLA_VTI_OKEY
, okey
);
156 addattr_l(n
, 1024, IFLA_VTI_LOCAL
, &saddr
, sizeof(saddr
));
157 addattr_l(n
, 1024, IFLA_VTI_REMOTE
, &daddr
, sizeof(daddr
));
158 addattr32(n
, 1024, IFLA_VTI_FWMARK
, fwmark
);
160 addattr32(n
, 1024, IFLA_VTI_LINK
, link
);
165 static void vti6_print_opt(struct link_util
*lu
, FILE *f
, struct rtattr
*tb
[])
167 const char *local
= "any";
168 const char *remote
= "any";
169 struct in6_addr saddr
;
170 struct in6_addr daddr
;
177 if (tb
[IFLA_VTI_REMOTE
]) {
178 memcpy(&daddr
, RTA_DATA(tb
[IFLA_VTI_REMOTE
]), sizeof(daddr
));
180 remote
= format_host(AF_INET6
, 16, &daddr
);
183 print_string(PRINT_ANY
, "remote", "remote %s ", remote
);
185 if (tb
[IFLA_VTI_LOCAL
]) {
186 memcpy(&saddr
, RTA_DATA(tb
[IFLA_VTI_LOCAL
]), sizeof(saddr
));
188 local
= format_host(AF_INET6
, 16, &saddr
);
191 print_string(PRINT_ANY
, "local", "local %s ", local
);
193 if (tb
[IFLA_VTI_LINK
] && (link
= rta_getattr_u32(tb
[IFLA_VTI_LINK
]))) {
194 const char *n
= if_indextoname(link
, s2
);
197 print_string(PRINT_ANY
, "link", "dev %s ", n
);
199 print_uint(PRINT_ANY
, "link_index", "dev %u ", link
);
202 if (tb
[IFLA_VTI_IKEY
]) {
203 inet_ntop(AF_INET
, RTA_DATA(tb
[IFLA_VTI_IKEY
]), s2
, sizeof(s2
));
204 print_string(PRINT_ANY
, "ikey", "ikey %s ", s2
);
207 if (tb
[IFLA_VTI_OKEY
]) {
208 inet_ntop(AF_INET
, RTA_DATA(tb
[IFLA_VTI_OKEY
]), s2
, sizeof(s2
));
209 print_string(PRINT_ANY
, "okey", "okey %s ", s2
);
212 if (tb
[IFLA_VTI_FWMARK
]) {
213 __u32 fwmark
= rta_getattr_u32(tb
[IFLA_VTI_FWMARK
]);
216 snprintf(s2
, sizeof(s2
), "0x%x", fwmark
);
218 print_string(PRINT_ANY
, "fwmark", "fwmark %s ", s2
);
223 struct link_util vti6_link_util
= {
225 .maxattr
= IFLA_VTI_MAX
,
226 .parse_opt
= vti6_parse_opt
,
227 .print_opt
= vti6_print_opt
,