25 #include <netlink-private/netlink.h>
26 #include <netlink/netlink.h>
27 #include <netlink/attr.h>
28 #include <netlink/utils.h>
29 #include <netlink/object.h>
30 #include <netlink/route/rtnl.h>
31 #include <netlink/route/link/ipgre.h>
32 #include <netlink-private/route/link/api.h>
33 #include <linux/if_tunnel.h>
35 #define IPGRE_ATTR_LINK (1 << 0)
36 #define IPGRE_ATTR_IFLAGS (1 << 1)
37 #define IPGRE_ATTR_OFLAGS (1 << 2)
38 #define IPGRE_ATTR_IKEY (1 << 3)
39 #define IPGRE_ATTR_OKEY (1 << 4)
40 #define IPGRE_ATTR_LOCAL (1 << 5)
41 #define IPGRE_ATTR_REMOTE (1 << 6)
42 #define IPGRE_ATTR_TTL (1 << 7)
43 #define IPGRE_ATTR_TOS (1 << 8)
44 #define IPGRE_ATTR_PMTUDISC (1 << 9)
61 static struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = {
63 [IFLA_GRE_IFLAGS] = { .type =
NLA_U16 },
64 [IFLA_GRE_OFLAGS] = { .type =
NLA_U16 },
65 [IFLA_GRE_IKEY] = { .type =
NLA_U32 },
66 [IFLA_GRE_OKEY] = { .type =
NLA_U32 },
67 [IFLA_GRE_LOCAL] = { .type =
NLA_U32 },
68 [IFLA_GRE_REMOTE] = { .type =
NLA_U32 },
69 [IFLA_GRE_TTL] = { .type =
NLA_U8 },
70 [IFLA_GRE_TOS] = { .type =
NLA_U8 },
71 [IFLA_GRE_PMTUDISC] = { .type =
NLA_U8 },
74 static int ipgre_alloc(
struct rtnl_link *link)
79 memset(link->l_info, 0,
sizeof(*ipgre));
81 ipgre = calloc(1,
sizeof(*ipgre));
91 static int ipgre_parse(
struct rtnl_link *link,
struct nlattr *data,
92 struct nlattr *xstats)
94 struct nlattr *tb[IFLA_IPTUN_MAX + 1];
98 NL_DBG(3,
"Parsing IPGRE link info\n");
104 err = ipgre_alloc(link);
108 ipgre = link->l_info;
110 if (tb[IFLA_GRE_LINK]) {
112 ipgre->ipgre_mask |= IPGRE_ATTR_LINK;
115 if (tb[IFLA_GRE_IFLAGS]) {
117 ipgre->ipgre_mask |= IPGRE_ATTR_IFLAGS;
120 if (tb[IFLA_GRE_OFLAGS]) {
122 ipgre->ipgre_mask |= IPGRE_ATTR_OFLAGS;
125 if (tb[IFLA_GRE_IKEY]) {
127 ipgre->ipgre_mask |= IPGRE_ATTR_IKEY;
130 if (tb[IFLA_GRE_OKEY]) {
132 ipgre->ipgre_mask |= IPGRE_ATTR_OKEY;
135 if (tb[IFLA_GRE_LOCAL]) {
137 ipgre->ipgre_mask |= IPGRE_ATTR_LOCAL;
140 if (tb[IFLA_GRE_LOCAL]) {
142 ipgre->ipgre_mask |= IPGRE_ATTR_REMOTE;
145 if (tb[IFLA_GRE_TTL]) {
147 ipgre->ipgre_mask |= IPGRE_ATTR_TTL;
150 if (tb[IFLA_GRE_TOS]) {
152 ipgre->ipgre_mask |= IPGRE_ATTR_TOS;
155 if (tb[IFLA_GRE_PMTUDISC]) {
156 ipgre->pmtudisc =
nla_get_u8(tb[IFLA_GRE_PMTUDISC]);
157 ipgre->ipgre_mask |= IPGRE_ATTR_PMTUDISC;
166 static int ipgre_put_attrs(
struct nl_msg *msg,
struct rtnl_link *link)
175 if (ipgre->ipgre_mask & IPGRE_ATTR_LINK)
178 if (ipgre->ipgre_mask & IFLA_GRE_IFLAGS)
181 if (ipgre->ipgre_mask & IFLA_GRE_OFLAGS)
184 if (ipgre->ipgre_mask & IPGRE_ATTR_IKEY)
187 if (ipgre->ipgre_mask & IPGRE_ATTR_OKEY)
190 if (ipgre->ipgre_mask & IPGRE_ATTR_LOCAL)
193 if (ipgre->ipgre_mask & IPGRE_ATTR_REMOTE)
196 if (ipgre->ipgre_mask & IPGRE_ATTR_TTL)
199 if (ipgre->ipgre_mask & IPGRE_ATTR_TOS)
202 if (ipgre->ipgre_mask & IPGRE_ATTR_PMTUDISC)
203 NLA_PUT_U8(msg, IFLA_GRE_PMTUDISC, ipgre->pmtudisc);
212 static void ipgre_free(
struct rtnl_link *link)
222 nl_dump(p,
"ipgre : %s", link->l_name);
228 char *name, addr[INET_ADDRSTRLEN];
230 if (ipgre->ipgre_mask & IPGRE_ATTR_LINK) {
234 nl_dump_line(p,
"%s\n", name);
236 nl_dump_line(p,
"%u\n", ipgre->link);
239 if (ipgre->ipgre_mask & IPGRE_ATTR_IFLAGS) {
241 nl_dump_line(p,
"%x\n", ipgre->iflags);
244 if (ipgre->ipgre_mask & IPGRE_ATTR_OFLAGS) {
246 nl_dump_line(p,
"%x\n", ipgre->oflags);
249 if (ipgre->ipgre_mask & IPGRE_ATTR_IKEY) {
251 nl_dump_line(p,
"%x\n",ipgre->ikey);
254 if (ipgre->ipgre_mask & IPGRE_ATTR_OKEY) {
256 nl_dump_line(p,
"%x\n", ipgre->okey);
259 if (ipgre->ipgre_mask & IPGRE_ATTR_LOCAL) {
261 if(inet_ntop(AF_INET, &ipgre->local, addr,
sizeof(addr)))
262 nl_dump_line(p,
"%s\n", addr);
264 nl_dump_line(p,
"%#x\n", ntohs(ipgre->local));
267 if (ipgre->ipgre_mask & IPGRE_ATTR_REMOTE) {
269 if(inet_ntop(AF_INET, &ipgre->remote, addr,
sizeof(addr)))
270 nl_dump_line(p,
"%s\n", addr);
272 nl_dump_line(p,
"%#x\n", ntohs(ipgre->remote));
275 if (ipgre->ipgre_mask & IPGRE_ATTR_TTL) {
277 nl_dump_line(p,
"%u\n", ipgre->ttl);
280 if (ipgre->ipgre_mask & IPGRE_ATTR_TOS) {
282 nl_dump_line(p,
"%u\n", ipgre->tos);
285 if (ipgre->ipgre_mask & IPGRE_ATTR_PMTUDISC) {
287 nl_dump_line(p,
"enabled (%#x)\n", ipgre->pmtudisc);
293 struct ipgre_info *ipgre_dst, *ipgre_src = src->l_info;
302 ipgre_dst = dst->l_info;
304 if (!ipgre_dst || !ipgre_src)
307 memcpy(ipgre_dst, ipgre_src,
sizeof(
struct ipgre_info));
312 static struct rtnl_link_info_ops ipgre_info_ops = {
314 .io_alloc = ipgre_alloc,
315 .io_parse = ipgre_parse,
320 .io_clone = ipgre_clone,
321 .io_put_attrs = ipgre_put_attrs,
322 .io_free = ipgre_free,
325 #define IS_IPGRE_LINK_ASSERT(link) \
326 if ((link)->l_info_ops != &ipgre_info_ops) { \
327 APPBUG("Link is not a ipgre link. set type \"gre\" first.");\
328 return -NLE_OPNOTSUPP; \
331 struct rtnl_link *rtnl_link_ipgre_alloc(
void)
357 return link->l_info_ops && !strcmp(link->l_info_ops->io_name,
"gre");
372 link = rtnl_link_ipgre_alloc();
395 IS_IPGRE_LINK_ASSERT(link);
398 ipgre->ipgre_mask |= IPGRE_ATTR_LINK;
413 IS_IPGRE_LINK_ASSERT(link);
429 IS_IPGRE_LINK_ASSERT(link);
431 ipgre->iflags = iflags;
432 ipgre->ipgre_mask |= IPGRE_ATTR_IFLAGS;
447 IS_IPGRE_LINK_ASSERT(link);
449 return ipgre->iflags;
463 IS_IPGRE_LINK_ASSERT(link);
465 ipgre->oflags = oflags;
466 ipgre->ipgre_mask |= IPGRE_ATTR_OFLAGS;
481 IS_IPGRE_LINK_ASSERT(link);
483 return ipgre->oflags;
497 IS_IPGRE_LINK_ASSERT(link);
500 ipgre->ipgre_mask |= IPGRE_ATTR_IKEY;
515 IS_IPGRE_LINK_ASSERT(link);
531 IS_IPGRE_LINK_ASSERT(link);
534 ipgre->ipgre_mask |= IPGRE_ATTR_OKEY;
549 IS_IPGRE_LINK_ASSERT(link);
565 IS_IPGRE_LINK_ASSERT(link);
568 ipgre->ipgre_mask |= IPGRE_ATTR_LOCAL;
583 IS_IPGRE_LINK_ASSERT(link);
599 IS_IPGRE_LINK_ASSERT(link);
601 ipgre->remote = remote;
602 ipgre->ipgre_mask |= IPGRE_ATTR_REMOTE;
617 IS_IPGRE_LINK_ASSERT(link);
619 return ipgre->remote;
633 IS_IPGRE_LINK_ASSERT(link);
636 ipgre->ipgre_mask |= IPGRE_ATTR_TTL;
651 IS_IPGRE_LINK_ASSERT(link);
667 IS_IPGRE_LINK_ASSERT(link);
670 ipgre->ipgre_mask |= IPGRE_ATTR_TOS;
685 IS_IPGRE_LINK_ASSERT(link);
701 IS_IPGRE_LINK_ASSERT(link);
703 ipgre->pmtudisc = pmtudisc;
704 ipgre->ipgre_mask |= IPGRE_ATTR_PMTUDISC;
719 IS_IPGRE_LINK_ASSERT(link);
721 return ipgre->pmtudisc;
724 static void __init ipgre_init(
void)
729 static void __exit ipgre_exit(
void)
Dump object briefly on one line.
uint8_t rtnl_link_ipgre_get_ttl(struct rtnl_link *link)
Set IPGRE tunnel ttl.
int rtnl_link_is_ipgre(struct rtnl_link *link)
Check if link is a IPGRE link.
int rtnl_link_ipgre_set_tos(struct rtnl_link *link, uint8_t tos)
Set IPGRE tunnel tos.
int rtnl_link_ipgre_set_ikey(struct rtnl_link *link, uint32_t ikey)
Set IPGRE tunnel set ikey.
int rtnl_link_register_info(struct rtnl_link_info_ops *ops)
Register operations for a link info type.
Attribute validation policy.
uint8_t nla_get_u8(const struct nlattr *nla)
Return value of 8 bit integer attribute.
int rtnl_link_ipgre_set_link(struct rtnl_link *link, uint32_t index)
Set IPGRE tunnel interface index.
struct rtnl_link * rtnl_link_alloc(void)
Allocate link object.
uint32_t rtnl_link_ipgre_get_ikey(struct rtnl_link *link)
Get IPGRE tunnel ikey.
uint32_t rtnl_link_ipgre_get_link(struct rtnl_link *link)
Get IPGRE tunnel interface index.
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
uint8_t rtnl_link_ipgre_get_tos(struct rtnl_link *link)
Get IPGRE tunnel tos.
int rtnl_link_ipgre_set_iflags(struct rtnl_link *link, uint16_t iflags)
Set IPGRE tunnel set iflags.
#define NLA_PUT_U8(msg, attrtype, value)
Add 8 bit integer attribute to netlink message.
uint16_t rtnl_link_ipgre_get_oflags(struct rtnl_link *link)
Get IPGRE tunnel oflags.
Dump all attributes but no statistics.
char * rtnl_link_get_name(struct rtnl_link *link)
Return name of link object.
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
uint32_t rtnl_link_ipgre_get_local(struct rtnl_link *link)
Get IPGRE tunnel local address.
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, struct nla_policy *policy)
Create attribute index based on nested attribute.
void rtnl_link_set_name(struct rtnl_link *link, const char *name)
Set name of link object.
int rtnl_link_ipgre_set_local(struct rtnl_link *link, uint32_t addr)
Set IPGRE tunnel local address.
int rtnl_link_set_type(struct rtnl_link *link, const char *type)
Set type of link object.
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
uint32_t rtnl_link_ipgre_get_okey(struct rtnl_link *link)
Get IPGRE tunnel okey.
int rtnl_link_ipgre_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc)
Set IPGRE tunnel path MTU discovery.
int rtnl_link_ipgre_add(struct nl_sock *sk, const char *name)
Create a new ipip tunnel device.
uint32_t rtnl_link_ipgre_get_remote(struct rtnl_link *link)
Get IPGRE tunnel remote address.
int rtnl_link_ipgre_set_okey(struct rtnl_link *link, uint32_t okey)
Set IPGRE tunnel set okey.
int rtnl_link_unregister_info(struct rtnl_link_info_ops *ops)
Unregister operations for a link info type.
uint16_t type
Type of attribute or NLA_UNSPEC.
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
uint16_t rtnl_link_ipgre_get_iflags(struct rtnl_link *link)
Get IPGRE tunnel iflags.
#define NLA_PUT_U16(msg, attrtype, value)
Add 16 bit integer attribute to netlink message.
int rtnl_link_ipgre_set_ttl(struct rtnl_link *link, uint8_t ttl)
Set IPGRE tunnel ttl.
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
uint8_t rtnl_link_get_pmtudisc(struct rtnl_link *link)
Get IPGRE path MTU discovery.
void rtnl_link_put(struct rtnl_link *link)
Return a link object reference.
int rtnl_link_add(struct nl_sock *sk, struct rtnl_link *link, int flags)
Add virtual link.
int rtnl_link_ipgre_set_remote(struct rtnl_link *link, uint32_t remote)
Set IPGRE tunnel remote address.
int rtnl_link_ipgre_set_oflags(struct rtnl_link *link, uint16_t oflags)
Set IPGRE tunnel set oflags.
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.