16#include "nl-default.h"
18#include <linux/if_tunnel.h>
20#include <netlink/netlink.h>
21#include <netlink/attr.h>
22#include <netlink/utils.h>
23#include <netlink/object.h>
24#include <netlink/route/rtnl.h>
25#include <netlink/route/link/ip6vti.h>
30#define IP6VTI_ATTR_LINK (1 << 0)
31#define IP6VTI_ATTR_IKEY (1 << 1)
32#define IP6VTI_ATTR_OKEY (1 << 2)
33#define IP6VTI_ATTR_LOCAL (1 << 3)
34#define IP6VTI_ATTR_REMOTE (1 << 4)
35#define IP6VTI_ATTR_FWMARK (1 << 5)
42 struct in6_addr local;
43 struct in6_addr remote;
53 [IFLA_VTI_REMOTE] = { .minlen =
sizeof(
struct in6_addr) },
54 [IFLA_VTI_FWMARK] = { .type =
NLA_U32 },
57static int ip6vti_alloc(
struct rtnl_link *link)
62 memset(link->l_info, 0,
sizeof(*ip6vti));
64 ip6vti = calloc(1,
sizeof(*ip6vti));
68 link->l_info = ip6vti;
74static int ip6vti_parse(
struct rtnl_link *link,
struct nlattr *data,
75 struct nlattr *xstats)
77 struct nlattr *tb[IFLA_VTI_MAX + 1];
81 NL_DBG(3,
"Parsing IP6VTI link info\n");
87 err = ip6vti_alloc(link);
91 ip6vti = link->l_info;
93 if (tb[IFLA_VTI_LINK]) {
95 ip6vti->ip6vti_mask |= IP6VTI_ATTR_LINK;
98 if (tb[IFLA_VTI_IKEY]) {
100 ip6vti->ip6vti_mask |= IP6VTI_ATTR_IKEY;
103 if (tb[IFLA_VTI_OKEY]) {
105 ip6vti->ip6vti_mask |= IP6VTI_ATTR_OKEY;
108 if (tb[IFLA_VTI_LOCAL]) {
109 nla_memcpy(&ip6vti->local, tb[IFLA_VTI_LOCAL],
sizeof(
struct in6_addr));
110 ip6vti->ip6vti_mask |= IP6VTI_ATTR_LOCAL;
113 if (tb[IFLA_VTI_REMOTE]) {
114 nla_memcpy(&ip6vti->remote, tb[IFLA_VTI_REMOTE],
sizeof(
struct in6_addr));
115 ip6vti->ip6vti_mask |= IP6VTI_ATTR_REMOTE;
118 if (tb[IFLA_VTI_FWMARK]) {
120 ip6vti->ip6vti_mask |= IP6VTI_ATTR_FWMARK;
129static int ip6vti_put_attrs(
struct nl_msg *msg,
struct rtnl_link *link)
138 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_LINK)
141 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_IKEY)
144 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_OKEY)
147 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_LOCAL)
148 NLA_PUT(msg, IFLA_VTI_LOCAL,
sizeof(
struct in6_addr), &ip6vti->local);
150 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_REMOTE)
151 NLA_PUT(msg, IFLA_VTI_REMOTE,
sizeof(
struct in6_addr), &ip6vti->remote);
153 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_FWMARK)
163static void ip6vti_free(
struct rtnl_link *link)
173 nl_dump(p,
"ip6vti : %s", link->l_name);
180 char addr[INET6_ADDRSTRLEN];
182 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_LINK) {
186 nl_dump_line(p,
"%s\n", name);
188 nl_dump_line(p,
"%u\n", ip6vti->link);
191 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_IKEY) {
193 nl_dump_line(p,
"%x\n",ip6vti->ikey);
196 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_OKEY) {
198 nl_dump_line(p,
"%x\n", ip6vti->okey);
201 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_LOCAL) {
203 nl_dump_line(p,
"%s\n",
204 _nl_inet_ntop(AF_INET6, &ip6vti->local, addr));
207 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_REMOTE) {
209 nl_dump_line(p,
"%s\n",
210 _nl_inet_ntop(AF_INET6, &ip6vti->remote, addr));
213 if (ip6vti->ip6vti_mask & IP6VTI_ATTR_FWMARK) {
215 nl_dump_line(p,
"%x\n", ip6vti->fwmark);
221 struct ip6vti_info *ip6vti_dst, *ip6vti_src = src->l_info;
230 ip6vti_dst = dst->l_info;
232 if (!ip6vti_dst || !ip6vti_src)
235 memcpy(ip6vti_dst, ip6vti_src,
sizeof(
struct ip6vti_info));
242 .io_alloc = ip6vti_alloc,
243 .io_parse = ip6vti_parse,
248 .io_clone = ip6vti_clone,
249 .io_put_attrs = ip6vti_put_attrs,
250 .io_free = ip6vti_free,
253#define IS_IP6VTI_LINK_ASSERT(link) \
254 if ((link)->l_info_ops != &ip6vti_info_ops) { \
255 APPBUG("Link is not a ip6vti link. set type \"vti6\" first."); \
256 return -NLE_OPNOTSUPP; \
259#define HAS_IP6VTI_ATTR_ASSERT(ip6vti,attr) \
260 if (!((ip6vti)->ip6vti_mask & (attr))) \
263struct rtnl_link *rtnl_link_ip6vti_alloc(
void)
289 return link->l_info_ops && !strcmp(link->l_info_ops->
io_name,
"vti6");
304 link = rtnl_link_ip6vti_alloc();
327 IS_IP6VTI_LINK_ASSERT(link);
329 ip6vti->link = index;
330 ip6vti->ip6vti_mask |= IP6VTI_ATTR_LINK;
346 IS_IP6VTI_LINK_ASSERT(link);
348 HAS_IP6VTI_ATTR_ASSERT(ip6vti, IP6VTI_ATTR_LINK);
350 *index = ip6vti->link;
366 IS_IP6VTI_LINK_ASSERT(link);
369 ip6vti->ip6vti_mask |= IP6VTI_ATTR_IKEY;
385 IS_IP6VTI_LINK_ASSERT(link);
387 HAS_IP6VTI_ATTR_ASSERT(ip6vti, IP6VTI_ATTR_IKEY);
389 *ikey = ip6vti->ikey;
405 IS_IP6VTI_LINK_ASSERT(link);
408 ip6vti->ip6vti_mask |= IP6VTI_ATTR_OKEY;
424 IS_IP6VTI_LINK_ASSERT(link);
426 HAS_IP6VTI_ATTR_ASSERT(ip6vti, IP6VTI_ATTR_OKEY);
428 *okey = ip6vti->okey;
444 IS_IP6VTI_LINK_ASSERT(link);
446 memcpy(&ip6vti->local, local,
sizeof(
struct in6_addr));
447 ip6vti->ip6vti_mask |= IP6VTI_ATTR_LOCAL;
463 IS_IP6VTI_LINK_ASSERT(link);
465 HAS_IP6VTI_ATTR_ASSERT(ip6vti, IP6VTI_ATTR_LOCAL);
467 memcpy(local, &ip6vti->local,
sizeof(
struct in6_addr));
483 IS_IP6VTI_LINK_ASSERT(link);
485 memcpy(&ip6vti->remote, remote,
sizeof(
struct in6_addr));
486 ip6vti->ip6vti_mask |= IP6VTI_ATTR_REMOTE;
502 IS_IP6VTI_LINK_ASSERT(link);
504 HAS_IP6VTI_ATTR_ASSERT(ip6vti, IP6VTI_ATTR_REMOTE);
506 memcpy(remote, &ip6vti->remote,
sizeof(
struct in6_addr));
522 IS_IP6VTI_LINK_ASSERT(link);
524 ip6vti->fwmark = fwmark;
525 ip6vti->ip6vti_mask |= IP6VTI_ATTR_FWMARK;
541 IS_IP6VTI_LINK_ASSERT(link);
543 HAS_IP6VTI_ATTR_ASSERT(ip6vti, IP6VTI_ATTR_FWMARK);
545 *fwmark = ip6vti->fwmark;
550static void _nl_init ip6vti_init(
void)
555static void _nl_exit ip6vti_exit(
void)
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
#define NLA_PUT(msg, attrtype, attrlen, data)
Add unspecific attribute to netlink message.
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, const struct nla_policy *policy)
Create attribute index based on nested attribute.
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
int rtnl_link_ip6vti_add(struct nl_sock *sk, const char *name)
Create a new vti6 tunnel device.
int rtnl_link_ip6vti_get_link(struct rtnl_link *link, uint32_t *index)
Get IP6VTI tunnel interface index.
int rtnl_link_ip6vti_get_local(struct rtnl_link *link, struct in6_addr *local)
Get IP6VTI tunnel local address.
int rtnl_link_ip6vti_set_link(struct rtnl_link *link, uint32_t index)
Set IP6VTI tunnel interface index.
int rtnl_link_ip6vti_get_fwmark(struct rtnl_link *link, uint32_t *fwmark)
Get IP6VTI tunnel fwmark.
int rtnl_link_ip6vti_set_remote(struct rtnl_link *link, struct in6_addr *remote)
Set IP6VTI tunnel remote address.
int rtnl_link_ip6vti_set_fwmark(struct rtnl_link *link, uint32_t fwmark)
Set IP6VTI tunnel fwmark.
int rtnl_link_is_ip6vti(struct rtnl_link *link)
Check if link is a IP6VTI link.
int rtnl_link_ip6vti_set_local(struct rtnl_link *link, struct in6_addr *local)
Set IP6VTI tunnel local address.
int rtnl_link_ip6vti_set_okey(struct rtnl_link *link, uint32_t okey)
Set IP6VTI tunnel set okey.
int rtnl_link_ip6vti_get_remote(struct rtnl_link *link, struct in6_addr *remote)
Get IP6VTI tunnel remote address.
int rtnl_link_ip6vti_get_okey(struct rtnl_link *link, uint32_t *okey)
Get IP6VTI tunnel okey.
int rtnl_link_ip6vti_set_ikey(struct rtnl_link *link, uint32_t ikey)
Set IP6VTI tunnel set ikey.
int rtnl_link_ip6vti_get_ikey(struct rtnl_link *link, uint32_t *ikey)
Get IP6VTI tunnel ikey.
int rtnl_link_register_info(struct rtnl_link_info_ops *ops)
Register operations for a link info type.
int rtnl_link_unregister_info(struct rtnl_link_info_ops *ops)
Unregister operations for a link info type.
int rtnl_link_add(struct nl_sock *sk, struct rtnl_link *link, int flags)
Add virtual link.
struct rtnl_link * rtnl_link_alloc(void)
Allocate link object.
void rtnl_link_set_name(struct rtnl_link *link, const char *name)
Set name of link object.
char * rtnl_link_get_name(struct rtnl_link *link)
Return name of link object.
void rtnl_link_put(struct rtnl_link *link)
Release a link object reference.
int rtnl_link_set_type(struct rtnl_link *link, const char *type)
Set type of link object.
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
@ NL_DUMP_LINE
Dump object briefly on one line.
@ NL_DUMP_DETAILS
Dump all attributes but no statistics.
Attribute validation policy.
uint16_t type
Type of attribute or NLA_UNSPEC.
Available operations to modules implementing a link info type.
char * io_name
Name of link info type, must match name on kernel side.