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-private/route/link/api.h>
32 #include <linux/if_tunnel.h>
34 #define IPGRE_ATTR_LINK (1 << 0)
35 #define IPGRE_ATTR_IFLAGS (1 << 1)
36 #define IPGRE_ATTR_OFLAGS (1 << 2)
37 #define IPGRE_ATTR_IKEY (1 << 3)
38 #define IPGRE_ATTR_OKEY (1 << 4)
39 #define IPGRE_ATTR_LOCAL (1 << 5)
40 #define IPGRE_ATTR_REMOTE (1 << 6)
41 #define IPGRE_ATTR_TTL (1 << 7)
42 #define IPGRE_ATTR_TOS (1 << 8)
43 #define IPGRE_ATTR_PMTUDISC (1 << 9)
60 static struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = {
62 [IFLA_GRE_IFLAGS] = { .type =
NLA_U16 },
63 [IFLA_GRE_OFLAGS] = { .type =
NLA_U16 },
64 [IFLA_GRE_IKEY] = { .type =
NLA_U32 },
65 [IFLA_GRE_OKEY] = { .type =
NLA_U32 },
66 [IFLA_GRE_LOCAL] = { .type =
NLA_U32 },
67 [IFLA_GRE_REMOTE] = { .type =
NLA_U32 },
68 [IFLA_GRE_TTL] = { .type =
NLA_U8 },
69 [IFLA_GRE_TOS] = { .type =
NLA_U8 },
70 [IFLA_GRE_PMTUDISC] = { .type =
NLA_U8 },
73 static int ipgre_alloc(
struct rtnl_link *link)
77 ipgre = calloc(1,
sizeof(*ipgre));
86 static int ipgre_parse(
struct rtnl_link *link,
struct nlattr *data,
87 struct nlattr *xstats)
89 struct nlattr *tb[IFLA_IPTUN_MAX + 1];
93 NL_DBG(3,
"Parsing IPGRE link info");
99 err = ipgre_alloc(link);
103 ipgre = link->l_info;
105 if (tb[IFLA_GRE_LINK]) {
107 ipgre->ipgre_mask |= IPGRE_ATTR_LINK;
110 if (tb[IFLA_GRE_IFLAGS]) {
112 ipgre->ipgre_mask |= IPGRE_ATTR_IFLAGS;
115 if (tb[IFLA_GRE_OFLAGS]) {
117 ipgre->ipgre_mask |= IPGRE_ATTR_OFLAGS;
120 if (tb[IFLA_GRE_IKEY]) {
122 ipgre->ipgre_mask |= IPGRE_ATTR_IKEY;
125 if (tb[IFLA_GRE_OKEY]) {
127 ipgre->ipgre_mask |= IPGRE_ATTR_OKEY;
130 if (tb[IFLA_GRE_LOCAL]) {
132 ipgre->ipgre_mask |= IPGRE_ATTR_LOCAL;
135 if (tb[IFLA_GRE_LOCAL]) {
137 ipgre->ipgre_mask |= IPGRE_ATTR_REMOTE;
140 if (tb[IFLA_GRE_TTL]) {
142 ipgre->ipgre_mask |= IPGRE_ATTR_TTL;
145 if (tb[IFLA_GRE_TOS]) {
147 ipgre->ipgre_mask |= IPGRE_ATTR_TOS;
150 if (tb[IFLA_GRE_PMTUDISC]) {
151 ipgre->pmtudisc =
nla_get_u8(tb[IFLA_GRE_PMTUDISC]);
152 ipgre->ipgre_mask |= IPGRE_ATTR_PMTUDISC;
161 static int ipgre_put_attrs(
struct nl_msg *msg,
struct rtnl_link *link)
170 if (ipgre->ipgre_mask & IPGRE_ATTR_LINK)
173 if (ipgre->ipgre_mask & IFLA_GRE_IFLAGS)
176 if (ipgre->ipgre_mask & IFLA_GRE_OFLAGS)
179 if (ipgre->ipgre_mask & IPGRE_ATTR_IKEY)
182 if (ipgre->ipgre_mask & IPGRE_ATTR_OKEY)
185 if (ipgre->ipgre_mask & IPGRE_ATTR_LOCAL)
188 if (ipgre->ipgre_mask & IPGRE_ATTR_REMOTE)
191 if (ipgre->ipgre_mask & IPGRE_ATTR_TTL)
194 if (ipgre->ipgre_mask & IPGRE_ATTR_TOS)
197 if (ipgre->ipgre_mask & IPGRE_ATTR_PMTUDISC)
198 NLA_PUT_U8(msg, IFLA_GRE_PMTUDISC, ipgre->pmtudisc);
207 static void ipgre_free(
struct rtnl_link *link)
217 nl_dump(p,
"ipgre : %s", link->l_name);
223 char *name, addr[INET_ADDRSTRLEN];
225 if (ipgre->ipgre_mask & IPGRE_ATTR_LINK) {
229 nl_dump_line(p,
"%s\n", name);
231 nl_dump_line(p,
"%u\n", ipgre->link);
234 if (ipgre->ipgre_mask & IPGRE_ATTR_IFLAGS) {
236 nl_dump_line(p,
"%x\n", ipgre->iflags);
239 if (ipgre->ipgre_mask & IPGRE_ATTR_OFLAGS) {
241 nl_dump_line(p,
"%x\n", ipgre->oflags);
244 if (ipgre->ipgre_mask & IPGRE_ATTR_IKEY) {
246 nl_dump_line(p,
"%x\n",ipgre->ikey);
249 if (ipgre->ipgre_mask & IPGRE_ATTR_OKEY) {
251 nl_dump_line(p,
"%x\n", ipgre->okey);
254 if (ipgre->ipgre_mask & IPGRE_ATTR_LOCAL) {
256 if(inet_ntop(AF_INET, &ipgre->local, addr,
sizeof(addr)))
257 nl_dump_line(p,
"%s\n", addr);
259 nl_dump_line(p,
"%#x\n", ntohs(ipgre->local));
262 if (ipgre->ipgre_mask & IPGRE_ATTR_REMOTE) {
264 if(inet_ntop(AF_INET, &ipgre->remote, addr,
sizeof(addr)))
265 nl_dump_line(p,
"%s\n", addr);
267 nl_dump_line(p,
"%#x\n", ntohs(ipgre->remote));
270 if (ipgre->ipgre_mask & IPGRE_ATTR_TTL) {
272 nl_dump_line(p,
"%u\n", ipgre->ttl);
275 if (ipgre->ipgre_mask & IPGRE_ATTR_TOS) {
277 nl_dump_line(p,
"%u\n", ipgre->tos);
280 if (ipgre->ipgre_mask & IPGRE_ATTR_PMTUDISC) {
282 nl_dump_line(p,
"enabled (%#x)\n", ipgre->pmtudisc);
288 struct ipgre_info *ipgre_dst, *ipgre_src = src->l_info;
297 ipgre_dst = dst->l_info;
299 if (!ipgre_dst || !ipgre_src)
302 memcpy(ipgre_dst, ipgre_src,
sizeof(
struct ipgre_info));
307 static struct rtnl_link_info_ops ipgre_info_ops = {
309 .io_alloc = ipgre_alloc,
310 .io_parse = ipgre_parse,
315 .io_clone = ipgre_clone,
316 .io_put_attrs = ipgre_put_attrs,
317 .io_free = ipgre_free,
320 #define IS_IPGRE_LINK_ASSERT(link) \
321 if ((link)->l_info_ops != &ipgre_info_ops) { \
322 APPBUG("Link is not a ipgre link. set type \"gre\" first.");\
323 return -NLE_OPNOTSUPP; \
326 struct rtnl_link *rtnl_link_ipgre_alloc(
void)
352 return link->l_info_ops && !strcmp(link->l_info_ops->io_name,
"gre");
367 link = rtnl_link_ipgre_alloc();
390 IS_IPGRE_LINK_ASSERT(link);
393 ipgre->ipgre_mask |= IPGRE_ATTR_LINK;
408 IS_IPGRE_LINK_ASSERT(link);
424 IS_IPGRE_LINK_ASSERT(link);
426 ipgre->iflags = iflags;
427 ipgre->ipgre_mask |= IPGRE_ATTR_IFLAGS;
442 IS_IPGRE_LINK_ASSERT(link);
444 return ipgre->iflags;
458 IS_IPGRE_LINK_ASSERT(link);
460 ipgre->oflags = oflags;
461 ipgre->ipgre_mask |= IPGRE_ATTR_OFLAGS;
476 IS_IPGRE_LINK_ASSERT(link);
478 return ipgre->oflags;
492 IS_IPGRE_LINK_ASSERT(link);
495 ipgre->ipgre_mask |= IPGRE_ATTR_IKEY;
510 IS_IPGRE_LINK_ASSERT(link);
526 IS_IPGRE_LINK_ASSERT(link);
529 ipgre->ipgre_mask |= IPGRE_ATTR_OKEY;
544 IS_IPGRE_LINK_ASSERT(link);
560 IS_IPGRE_LINK_ASSERT(link);
563 ipgre->ipgre_mask |= IPGRE_ATTR_LOCAL;
578 IS_IPGRE_LINK_ASSERT(link);
594 IS_IPGRE_LINK_ASSERT(link);
596 ipgre->remote = remote;
597 ipgre->ipgre_mask |= IPGRE_ATTR_REMOTE;
612 IS_IPGRE_LINK_ASSERT(link);
614 return ipgre->remote;
628 IS_IPGRE_LINK_ASSERT(link);
631 ipgre->ipgre_mask |= IPGRE_ATTR_TTL;
646 IS_IPGRE_LINK_ASSERT(link);
662 IS_IPGRE_LINK_ASSERT(link);
665 ipgre->ipgre_mask |= IPGRE_ATTR_TOS;
680 IS_IPGRE_LINK_ASSERT(link);
696 IS_IPGRE_LINK_ASSERT(link);
698 ipgre->pmtudisc = pmtudisc;
699 ipgre->ipgre_mask |= IPGRE_ATTR_PMTUDISC;
714 IS_IPGRE_LINK_ASSERT(link);
716 return ipgre->pmtudisc;
719 static void __init ipgre_init(
void)
724 static void __exit ipgre_exit(
void)
Dump object briefly on one line.
uint16_t nla_get_u16(struct nlattr *nla)
Return payload of 16 bit integer attribute.
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.
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.
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.
uint8_t nla_get_u8(struct nlattr *nla)
Return value of 8 bit integer 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 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.
uint32_t nla_get_u32(struct nlattr *nla)
Return payload of 32 bit integer attribute.
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.