]>
git.proxmox.com Git - mirror_iproute2.git/blob - ip/link_vti.c
2 * link_vti.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
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <arpa/inet.h>
20 #include <linux/if_tunnel.h>
23 #include "ip_common.h"
26 static void vti_print_help(struct link_util
*lu
, int argc
, char **argv
, FILE *f
)
29 "Usage: ... %-4s [ remote ADDR ]\n",
40 "Where: ADDR := { IP%s_ADDRESS }\n"
41 " KEY := { DOTTED_QUAD | NUMBER }\n"
42 " MARK := { 0x0..0xffffffff }\n",
47 static int vti_parse_opt(struct link_util
*lu
, int argc
, char **argv
,
50 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
55 .n
.nlmsg_len
= NLMSG_LENGTH(sizeof(*ifi
)),
56 .n
.nlmsg_flags
= NLM_F_REQUEST
,
57 .n
.nlmsg_type
= RTM_GETLINK
,
58 .i
.ifi_family
= preferred_family
,
59 .i
.ifi_index
= ifi
->ifi_index
,
61 struct nlmsghdr
*answer
;
62 struct rtattr
*tb
[IFLA_MAX
+ 1];
63 struct rtattr
*linkinfo
[IFLA_INFO_MAX
+1];
64 struct rtattr
*vtiinfo
[IFLA_VTI_MAX
+ 1];
67 inet_prefix saddr
, daddr
;
68 unsigned int link
= 0;
72 inet_prefix_reset(&saddr
);
73 inet_prefix_reset(&daddr
);
75 if (!(n
->nlmsg_flags
& NLM_F_CREATE
)) {
76 const struct rtattr
*rta
;
78 if (rtnl_talk(&rth
, &req
.n
, &answer
) < 0) {
81 "Failed to get existing tunnel info.\n");
85 len
= answer
->nlmsg_len
;
86 len
-= NLMSG_LENGTH(sizeof(*ifi
));
90 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(NLMSG_DATA(answer
)), len
);
92 if (!tb
[IFLA_LINKINFO
])
95 parse_rtattr_nested(linkinfo
, IFLA_INFO_MAX
, tb
[IFLA_LINKINFO
]);
97 if (!linkinfo
[IFLA_INFO_DATA
])
100 parse_rtattr_nested(vtiinfo
, IFLA_VTI_MAX
,
101 linkinfo
[IFLA_INFO_DATA
]);
103 rta
= vtiinfo
[IFLA_VTI_LOCAL
];
104 if (rta
&& get_addr_rta(&saddr
, rta
, AF_INET
))
107 rta
= vtiinfo
[IFLA_VTI_REMOTE
];
108 if (rta
&& get_addr_rta(&daddr
, rta
, AF_INET
))
111 if (vtiinfo
[IFLA_VTI_IKEY
])
112 ikey
= rta_getattr_u32(vtiinfo
[IFLA_VTI_IKEY
]);
114 if (vtiinfo
[IFLA_VTI_OKEY
])
115 okey
= rta_getattr_u32(vtiinfo
[IFLA_VTI_OKEY
]);
117 if (vtiinfo
[IFLA_VTI_LINK
])
118 link
= rta_getattr_u8(vtiinfo
[IFLA_VTI_LINK
]);
120 if (vtiinfo
[IFLA_VTI_FWMARK
])
121 fwmark
= rta_getattr_u32(vtiinfo
[IFLA_VTI_FWMARK
]);
127 if (!matches(*argv
, "key")) {
129 ikey
= okey
= tnl_parse_key("key", *argv
);
130 } else if (!matches(*argv
, "ikey")) {
132 ikey
= tnl_parse_key("ikey", *argv
);
133 } else if (!matches(*argv
, "okey")) {
135 okey
= tnl_parse_key("okey", *argv
);
136 } else if (!matches(*argv
, "remote")) {
138 get_addr(&daddr
, *argv
, AF_INET
);
139 } else if (!matches(*argv
, "local")) {
141 get_addr(&saddr
, *argv
, AF_INET
);
142 } else if (!matches(*argv
, "dev")) {
144 link
= ll_name_to_index(*argv
);
147 } else if (strcmp(*argv
, "fwmark") == 0) {
149 if (get_u32(&fwmark
, *argv
, 0))
150 invarg("invalid fwmark\n", *argv
);
152 vti_print_help(lu
, argc
, argv
, stderr
);
158 addattr32(n
, 1024, IFLA_VTI_IKEY
, ikey
);
159 addattr32(n
, 1024, IFLA_VTI_OKEY
, okey
);
160 if (is_addrtype_inet_not_unspec(&saddr
))
161 addattr_l(n
, 1024, IFLA_VTI_LOCAL
, saddr
.data
, saddr
.bytelen
);
162 if (is_addrtype_inet_not_unspec(&daddr
))
163 addattr_l(n
, 1024, IFLA_VTI_REMOTE
, daddr
.data
, daddr
.bytelen
);
164 addattr32(n
, 1024, IFLA_VTI_FWMARK
, fwmark
);
166 addattr32(n
, 1024, IFLA_VTI_LINK
, link
);
171 static void vti_print_opt(struct link_util
*lu
, FILE *f
, struct rtattr
*tb
[])
178 tnl_print_endpoint("remote", tb
[IFLA_VTI_REMOTE
], AF_INET
);
179 tnl_print_endpoint("local", tb
[IFLA_VTI_LOCAL
], AF_INET
);
181 if (tb
[IFLA_VTI_LINK
]) {
182 __u32 link
= rta_getattr_u32(tb
[IFLA_VTI_LINK
]);
185 print_string(PRINT_ANY
, "link", "dev %s ",
186 ll_index_to_name(link
));
190 if (tb
[IFLA_VTI_IKEY
]) {
191 struct rtattr
*rta
= tb
[IFLA_VTI_IKEY
];
192 __u32 key
= rta_getattr_u32(rta
);
194 if (key
&& inet_ntop(AF_INET
, RTA_DATA(rta
), s2
, sizeof(s2
)))
195 print_string(PRINT_ANY
, "ikey", "ikey %s ", s2
);
198 if (tb
[IFLA_VTI_OKEY
]) {
199 struct rtattr
*rta
= tb
[IFLA_VTI_OKEY
];
200 __u32 key
= rta_getattr_u32(rta
);
202 if (key
&& inet_ntop(AF_INET
, RTA_DATA(rta
), s2
, sizeof(s2
)))
203 print_string(PRINT_ANY
, "okey", "okey %s ", s2
);
206 if (tb
[IFLA_VTI_FWMARK
]) {
207 __u32 fwmark
= rta_getattr_u32(tb
[IFLA_VTI_FWMARK
]);
210 print_0xhex(PRINT_ANY
,
211 "fwmark", "fwmark %#llx ", fwmark
);
216 struct link_util vti_link_util
= {
218 .maxattr
= IFLA_VTI_MAX
,
219 .parse_opt
= vti_parse_opt
,
220 .print_opt
= vti_print_opt
,
221 .print_help
= vti_print_help
,