ipgre.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. /*
  2. * lib/route/link/ipgre.c IPGRE Link Info
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation version 2.1
  7. * of the License.
  8. *
  9. * Copyright (c) 2014 Susant Sahani <susant@redhat.com>
  10. */
  11. /**
  12. * @ingroup link
  13. * @defgroup ipgre IPGRE
  14. * ipgre link module
  15. *
  16. * @details
  17. * \b Link Type Name: "ipgre"
  18. *
  19. * @route_doc{link_ipgre, IPGRE Documentation}
  20. *
  21. * @{
  22. */
  23. #include <netlink-private/netlink.h>
  24. #include <netlink/netlink.h>
  25. #include <netlink/attr.h>
  26. #include <netlink/utils.h>
  27. #include <netlink/object.h>
  28. #include <netlink/route/rtnl.h>
  29. #include <netlink-private/route/link/api.h>
  30. #include <linux/if_tunnel.h>
  31. #define IPGRE_ATTR_LINK (1 << 0)
  32. #define IPGRE_ATTR_IFLAGS (1 << 1)
  33. #define IPGRE_ATTR_OFLAGS (1 << 2)
  34. #define IPGRE_ATTR_IKEY (1 << 3)
  35. #define IPGRE_ATTR_OKEY (1 << 4)
  36. #define IPGRE_ATTR_LOCAL (1 << 5)
  37. #define IPGRE_ATTR_REMOTE (1 << 6)
  38. #define IPGRE_ATTR_TTL (1 << 7)
  39. #define IPGRE_ATTR_TOS (1 << 8)
  40. #define IPGRE_ATTR_PMTUDISC (1 << 9)
  41. struct ipgre_info
  42. {
  43. uint8_t ttl;
  44. uint8_t tos;
  45. uint8_t pmtudisc;
  46. uint16_t iflags;
  47. uint16_t oflags;
  48. uint32_t ikey;
  49. uint32_t okey;
  50. uint32_t link;
  51. uint32_t local;
  52. uint32_t remote;
  53. uint32_t ipgre_mask;
  54. };
  55. static struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = {
  56. [IFLA_GRE_LINK] = { .type = NLA_U32 },
  57. [IFLA_GRE_IFLAGS] = { .type = NLA_U16 },
  58. [IFLA_GRE_OFLAGS] = { .type = NLA_U16 },
  59. [IFLA_GRE_IKEY] = { .type = NLA_U32 },
  60. [IFLA_GRE_OKEY] = { .type = NLA_U32 },
  61. [IFLA_GRE_LOCAL] = { .type = NLA_U32 },
  62. [IFLA_GRE_REMOTE] = { .type = NLA_U32 },
  63. [IFLA_GRE_TTL] = { .type = NLA_U8 },
  64. [IFLA_GRE_TOS] = { .type = NLA_U8 },
  65. [IFLA_GRE_PMTUDISC] = { .type = NLA_U8 },
  66. };
  67. static int ipgre_alloc(struct rtnl_link *link)
  68. {
  69. struct ipgre_info *ipgre;
  70. ipgre = calloc(1, sizeof(*ipgre));
  71. if (!ipgre)
  72. return -NLE_NOMEM;
  73. link->l_info = ipgre;
  74. return 0;
  75. }
  76. static int ipgre_parse(struct rtnl_link *link, struct nlattr *data,
  77. struct nlattr *xstats)
  78. {
  79. struct nlattr *tb[IFLA_IPTUN_MAX + 1];
  80. struct ipgre_info *ipgre;
  81. int err;
  82. NL_DBG(3, "Parsing IPGRE link info");
  83. err = nla_parse_nested(tb, IFLA_GRE_MAX, data, ipgre_policy);
  84. if (err < 0)
  85. goto errout;
  86. err = ipgre_alloc(link);
  87. if (err < 0)
  88. goto errout;
  89. ipgre = link->l_info;
  90. if (tb[IFLA_GRE_LINK]) {
  91. ipgre->link = nla_get_u32(tb[IFLA_GRE_LINK]);
  92. ipgre->ipgre_mask |= IPGRE_ATTR_LINK;
  93. }
  94. if (tb[IFLA_GRE_IFLAGS]) {
  95. ipgre->iflags = nla_get_u16(tb[IFLA_GRE_IFLAGS]);
  96. ipgre->ipgre_mask |= IPGRE_ATTR_IFLAGS;
  97. }
  98. if (tb[IFLA_GRE_OFLAGS]) {
  99. ipgre->oflags = nla_get_u16(tb[IFLA_GRE_OFLAGS]);
  100. ipgre->ipgre_mask |= IPGRE_ATTR_OFLAGS;
  101. }
  102. if (tb[IFLA_GRE_IKEY]) {
  103. ipgre->ikey = nla_get_u32(tb[IFLA_GRE_IKEY]);
  104. ipgre->ipgre_mask |= IPGRE_ATTR_IKEY;
  105. }
  106. if (tb[IFLA_GRE_OKEY]) {
  107. ipgre->okey = nla_get_u32(tb[IFLA_GRE_OKEY]);
  108. ipgre->ipgre_mask |= IPGRE_ATTR_OKEY;
  109. }
  110. if (tb[IFLA_GRE_LOCAL]) {
  111. ipgre->local = nla_get_u32(tb[IFLA_GRE_LOCAL]);
  112. ipgre->ipgre_mask |= IPGRE_ATTR_LOCAL;
  113. }
  114. if (tb[IFLA_GRE_LOCAL]) {
  115. ipgre->remote = nla_get_u32(tb[IFLA_GRE_LOCAL]);
  116. ipgre->ipgre_mask |= IPGRE_ATTR_REMOTE;
  117. }
  118. if (tb[IFLA_GRE_TTL]) {
  119. ipgre->ttl = nla_get_u8(tb[IFLA_GRE_TTL]);
  120. ipgre->ipgre_mask |= IPGRE_ATTR_TTL;
  121. }
  122. if (tb[IFLA_GRE_TOS]) {
  123. ipgre->tos = nla_get_u8(tb[IFLA_GRE_TOS]);
  124. ipgre->ipgre_mask |= IPGRE_ATTR_TOS;
  125. }
  126. if (tb[IFLA_GRE_PMTUDISC]) {
  127. ipgre->pmtudisc = nla_get_u8(tb[IFLA_GRE_PMTUDISC]);
  128. ipgre->ipgre_mask |= IPGRE_ATTR_PMTUDISC;
  129. }
  130. err = 0;
  131. errout:
  132. return err;
  133. }
  134. static int ipgre_put_attrs(struct nl_msg *msg, struct rtnl_link *link)
  135. {
  136. struct ipgre_info *ipgre = link->l_info;
  137. struct nlattr *data;
  138. data = nla_nest_start(msg, IFLA_INFO_DATA);
  139. if (!data)
  140. return -NLE_MSGSIZE;
  141. if (ipgre->ipgre_mask & IPGRE_ATTR_LINK)
  142. NLA_PUT_U32(msg, IFLA_GRE_LINK, ipgre->link);
  143. if (ipgre->ipgre_mask & IFLA_GRE_IFLAGS)
  144. NLA_PUT_U16(msg, IFLA_GRE_IFLAGS, ipgre->iflags);
  145. if (ipgre->ipgre_mask & IFLA_GRE_OFLAGS)
  146. NLA_PUT_U16(msg, IFLA_GRE_OFLAGS, ipgre->oflags);
  147. if (ipgre->ipgre_mask & IPGRE_ATTR_IKEY)
  148. NLA_PUT_U32(msg, IFLA_GRE_IKEY, ipgre->ikey);
  149. if (ipgre->ipgre_mask & IPGRE_ATTR_OKEY)
  150. NLA_PUT_U32(msg, IFLA_GRE_OKEY, ipgre->okey);
  151. if (ipgre->ipgre_mask & IPGRE_ATTR_LOCAL)
  152. NLA_PUT_U32(msg, IFLA_GRE_LOCAL, ipgre->local);
  153. if (ipgre->ipgre_mask & IPGRE_ATTR_REMOTE)
  154. NLA_PUT_U32(msg, IFLA_GRE_REMOTE, ipgre->remote);
  155. if (ipgre->ipgre_mask & IPGRE_ATTR_TTL)
  156. NLA_PUT_U8(msg, IFLA_GRE_TTL, ipgre->ttl);
  157. if (ipgre->ipgre_mask & IPGRE_ATTR_TOS)
  158. NLA_PUT_U8(msg, IFLA_GRE_TOS, ipgre->tos);
  159. if (ipgre->ipgre_mask & IPGRE_ATTR_PMTUDISC)
  160. NLA_PUT_U8(msg, IFLA_GRE_PMTUDISC, ipgre->pmtudisc);
  161. nla_nest_end(msg, data);
  162. nla_put_failure:
  163. return 0;
  164. }
  165. static void ipgre_free(struct rtnl_link *link)
  166. {
  167. struct ipgre_info *ipgre = link->l_info;
  168. free(ipgre);
  169. link->l_info = NULL;
  170. }
  171. static void ipgre_dump_line(struct rtnl_link *link, struct nl_dump_params *p)
  172. {
  173. nl_dump(p, "ipgre : %s", link->l_name);
  174. }
  175. static void ipgre_dump_details(struct rtnl_link *link, struct nl_dump_params *p)
  176. {
  177. struct ipgre_info *ipgre = link->l_info;
  178. char *name, addr[INET_ADDRSTRLEN];
  179. if (ipgre->ipgre_mask & IPGRE_ATTR_LINK) {
  180. nl_dump(p, " link ");
  181. name = rtnl_link_get_name(link);
  182. if (name)
  183. nl_dump_line(p, "%s\n", name);
  184. else
  185. nl_dump_line(p, "%u\n", ipgre->link);
  186. }
  187. if (ipgre->ipgre_mask & IPGRE_ATTR_IFLAGS) {
  188. nl_dump(p, " iflags ");
  189. nl_dump_line(p, "%x\n", ipgre->iflags);
  190. }
  191. if (ipgre->ipgre_mask & IPGRE_ATTR_OFLAGS) {
  192. nl_dump(p, " oflags ");
  193. nl_dump_line(p, "%x\n", ipgre->oflags);
  194. }
  195. if (ipgre->ipgre_mask & IPGRE_ATTR_IKEY) {
  196. nl_dump(p, " ikey ");
  197. nl_dump_line(p, "%x\n",ipgre->ikey);
  198. }
  199. if (ipgre->ipgre_mask & IPGRE_ATTR_OKEY) {
  200. nl_dump(p, " okey ");
  201. nl_dump_line(p, "%x\n", ipgre->okey);
  202. }
  203. if (ipgre->ipgre_mask & IPGRE_ATTR_LOCAL) {
  204. nl_dump(p, " local ");
  205. if(inet_ntop(AF_INET, &ipgre->local, addr, sizeof(addr)))
  206. nl_dump_line(p, "%s\n", addr);
  207. else
  208. nl_dump_line(p, "%#x\n", ntohs(ipgre->local));
  209. }
  210. if (ipgre->ipgre_mask & IPGRE_ATTR_REMOTE) {
  211. nl_dump(p, " remote ");
  212. if(inet_ntop(AF_INET, &ipgre->remote, addr, sizeof(addr)))
  213. nl_dump_line(p, "%s\n", addr);
  214. else
  215. nl_dump_line(p, "%#x\n", ntohs(ipgre->remote));
  216. }
  217. if (ipgre->ipgre_mask & IPGRE_ATTR_TTL) {
  218. nl_dump(p, " ttl ");
  219. nl_dump_line(p, "%u\n", ipgre->ttl);
  220. }
  221. if (ipgre->ipgre_mask & IPGRE_ATTR_TOS) {
  222. nl_dump(p, " tos ");
  223. nl_dump_line(p, "%u\n", ipgre->tos);
  224. }
  225. if (ipgre->ipgre_mask & IPGRE_ATTR_PMTUDISC) {
  226. nl_dump(p, " pmtudisc ");
  227. nl_dump_line(p, "enabled (%#x)\n", ipgre->pmtudisc);
  228. }
  229. }
  230. static int ipgre_clone(struct rtnl_link *dst, struct rtnl_link *src)
  231. {
  232. struct ipgre_info *ipgre_dst, *ipgre_src = src->l_info;
  233. int err;
  234. dst->l_info = NULL;
  235. err = rtnl_link_set_type(dst, "gre");
  236. if (err < 0)
  237. return err;
  238. ipgre_dst = dst->l_info;
  239. if (!ipgre_dst || !ipgre_src)
  240. BUG();
  241. memcpy(ipgre_dst, ipgre_src, sizeof(struct ipgre_info));
  242. return 0;
  243. }
  244. static struct rtnl_link_info_ops ipgre_info_ops = {
  245. .io_name = "gre",
  246. .io_alloc = ipgre_alloc,
  247. .io_parse = ipgre_parse,
  248. .io_dump = {
  249. [NL_DUMP_LINE] = ipgre_dump_line,
  250. [NL_DUMP_DETAILS] = ipgre_dump_details,
  251. },
  252. .io_clone = ipgre_clone,
  253. .io_put_attrs = ipgre_put_attrs,
  254. .io_free = ipgre_free,
  255. };
  256. #define IS_IPGRE_LINK_ASSERT(link) \
  257. if ((link)->l_info_ops != &ipgre_info_ops) { \
  258. APPBUG("Link is not a ipgre link. set type \"gre\" first.");\
  259. return -NLE_OPNOTSUPP; \
  260. }
  261. struct rtnl_link *rtnl_link_ipgre_alloc(void)
  262. {
  263. struct rtnl_link *link;
  264. int err;
  265. link = rtnl_link_alloc();
  266. if (!link)
  267. return NULL;
  268. err = rtnl_link_set_type(link, "gre");
  269. if (err < 0) {
  270. rtnl_link_put(link);
  271. return NULL;
  272. }
  273. return link;
  274. }
  275. /**
  276. * Check if link is a IPGRE link
  277. * @arg link Link object
  278. *
  279. * @return True if link is a IPGRE link, otherwise 0 is returned.
  280. */
  281. int rtnl_link_is_ipgre(struct rtnl_link *link)
  282. {
  283. return link->l_info_ops && !strcmp(link->l_info_ops->io_name, "gre");
  284. }
  285. /**
  286. * Create a new ipip tunnel device
  287. * @arg sock netlink socket
  288. * @arg name name of the tunnel deviceL
  289. *
  290. * Creates a new ipip tunnel device in the kernel
  291. * @return 0 on success or a negative error code
  292. */
  293. int rtnl_link_ipgre_add(struct nl_sock *sk, const char *name)
  294. {
  295. struct rtnl_link *link;
  296. int err;
  297. link = rtnl_link_ipgre_alloc();
  298. if (!link)
  299. return -NLE_NOMEM;
  300. if(name)
  301. rtnl_link_set_name(link, name);
  302. err = rtnl_link_add(sk, link, NLM_F_CREATE);
  303. rtnl_link_put(link);
  304. return err;
  305. }
  306. /**
  307. * Set IPGRE tunnel interface index
  308. * @arg link Link object
  309. * @arg index interface index
  310. *
  311. * @return 0 on success or a negative error code
  312. */
  313. int rtnl_link_ipgre_set_link(struct rtnl_link *link, uint32_t index)
  314. {
  315. struct ipgre_info *ipgre = link->l_info;
  316. IS_IPGRE_LINK_ASSERT(link);
  317. ipgre->link = index;
  318. ipgre->ipgre_mask |= IPGRE_ATTR_LINK;
  319. return 0;
  320. }
  321. /**
  322. * Get IPGRE tunnel interface index
  323. * @arg link Link object
  324. *
  325. * @return interface index
  326. */
  327. uint32_t rtnl_link_ipgre_get_link(struct rtnl_link *link)
  328. {
  329. struct ipgre_info *ipgre = link->l_info;
  330. IS_IPGRE_LINK_ASSERT(link);
  331. return ipgre->link;
  332. }
  333. /**
  334. * Set IPGRE tunnel set iflags
  335. * @arg link Link object
  336. * @arg iflags gre iflags
  337. *
  338. * @return 0 on success or a negative error code
  339. */
  340. int rtnl_link_ipgre_set_iflags(struct rtnl_link *link, uint16_t iflags)
  341. {
  342. struct ipgre_info *ipgre = link->l_info;
  343. IS_IPGRE_LINK_ASSERT(link);
  344. ipgre->iflags = iflags;
  345. ipgre->ipgre_mask |= IPGRE_ATTR_IFLAGS;
  346. return 0;
  347. }
  348. /**
  349. * Get IPGRE tunnel iflags
  350. * @arg link Link object
  351. *
  352. * @return iflags
  353. */
  354. uint16_t rtnl_link_ipgre_get_iflags(struct rtnl_link *link)
  355. {
  356. struct ipgre_info *ipgre = link->l_info;
  357. IS_IPGRE_LINK_ASSERT(link);
  358. return ipgre->iflags;
  359. }
  360. /**
  361. * Set IPGRE tunnel set oflags
  362. * @arg link Link object
  363. * @arg iflags gre oflags
  364. *
  365. * @return 0 on success or a negative error code
  366. */
  367. int rtnl_link_ipgre_set_oflags(struct rtnl_link *link, uint16_t oflags)
  368. {
  369. struct ipgre_info *ipgre = link->l_info;
  370. IS_IPGRE_LINK_ASSERT(link);
  371. ipgre->oflags = oflags;
  372. ipgre->ipgre_mask |= IPGRE_ATTR_OFLAGS;
  373. return 0;
  374. }
  375. /**
  376. * Get IPGRE tunnel oflags
  377. * @arg link Link object
  378. *
  379. * @return oflags
  380. */
  381. uint16_t rtnl_link_ipgre_get_oflags(struct rtnl_link *link)
  382. {
  383. struct ipgre_info *ipgre = link->l_info;
  384. IS_IPGRE_LINK_ASSERT(link);
  385. return ipgre->oflags;
  386. }
  387. /**
  388. * Set IPGRE tunnel set ikey
  389. * @arg link Link object
  390. * @arg ikey gre ikey
  391. *
  392. * @return 0 on success or a negative error code
  393. */
  394. int rtnl_link_ipgre_set_ikey(struct rtnl_link *link, uint32_t ikey)
  395. {
  396. struct ipgre_info *ipgre = link->l_info;
  397. IS_IPGRE_LINK_ASSERT(link);
  398. ipgre->ikey = ikey;
  399. ipgre->ipgre_mask |= IPGRE_ATTR_IKEY;
  400. return 0;
  401. }
  402. /**
  403. * Get IPGRE tunnel ikey
  404. * @arg link Link object
  405. *
  406. * @return ikey
  407. */
  408. uint32_t rtnl_link_ipgre_get_ikey(struct rtnl_link *link)
  409. {
  410. struct ipgre_info *ipgre = link->l_info;
  411. IS_IPGRE_LINK_ASSERT(link);
  412. return ipgre->ikey;
  413. }
  414. /**
  415. * Set IPGRE tunnel set okey
  416. * @arg link Link object
  417. * @arg okey gre okey
  418. *
  419. * @return 0 on success or a negative error code
  420. */
  421. int rtnl_link_ipgre_set_okey(struct rtnl_link *link, uint32_t okey)
  422. {
  423. struct ipgre_info *ipgre = link->l_info;
  424. IS_IPGRE_LINK_ASSERT(link);
  425. ipgre->okey = okey;
  426. ipgre->ipgre_mask |= IPGRE_ATTR_OKEY;
  427. return 0;
  428. }
  429. /**
  430. * Get IPGRE tunnel okey
  431. * @arg link Link object
  432. *
  433. * @return okey value
  434. */
  435. uint32_t rtnl_link_ipgre_get_okey(struct rtnl_link *link)
  436. {
  437. struct ipgre_info *ipgre = link->l_info;
  438. IS_IPGRE_LINK_ASSERT(link);
  439. return ipgre->okey;
  440. }
  441. /**
  442. * Set IPGRE tunnel local address
  443. * @arg link Link object
  444. * @arg addr local address
  445. *
  446. * @return 0 on success or a negative error code
  447. */
  448. int rtnl_link_ipgre_set_local(struct rtnl_link *link, uint32_t addr)
  449. {
  450. struct ipgre_info *ipgre = link->l_info;
  451. IS_IPGRE_LINK_ASSERT(link);
  452. ipgre->local = addr;
  453. ipgre->ipgre_mask |= IPGRE_ATTR_LOCAL;
  454. return 0;
  455. }
  456. /**
  457. * Get IPGRE tunnel local address
  458. * @arg link Link object
  459. *
  460. * @return local address
  461. */
  462. uint32_t rtnl_link_ipgre_get_local(struct rtnl_link *link)
  463. {
  464. struct ipgre_info *ipgre = link->l_info;
  465. IS_IPGRE_LINK_ASSERT(link);
  466. return ipgre->local;
  467. }
  468. /**
  469. * Set IPGRE tunnel remote address
  470. * @arg link Link object
  471. * @arg remote remote address
  472. *
  473. * @return 0 on success or a negative error code
  474. */
  475. int rtnl_link_ipgre_set_remote(struct rtnl_link *link, uint32_t remote)
  476. {
  477. struct ipgre_info *ipgre = link->l_info;
  478. IS_IPGRE_LINK_ASSERT(link);
  479. ipgre->remote = remote;
  480. ipgre->ipgre_mask |= IPGRE_ATTR_REMOTE;
  481. return 0;
  482. }
  483. /**
  484. * Get IPGRE tunnel remote address
  485. * @arg link Link object
  486. *
  487. * @return remote address on success or a negative error code
  488. */
  489. uint32_t rtnl_link_ipgre_get_remote(struct rtnl_link *link)
  490. {
  491. struct ipgre_info *ipgre = link->l_info;
  492. IS_IPGRE_LINK_ASSERT(link);
  493. return ipgre->remote;
  494. }
  495. /**
  496. * Set IPGRE tunnel ttl
  497. * @arg link Link object
  498. * @arg ttl tunnel ttl
  499. *
  500. * @return 0 on success or a negative error code
  501. */
  502. int rtnl_link_ipgre_set_ttl(struct rtnl_link *link, uint8_t ttl)
  503. {
  504. struct ipgre_info *ipgre = link->l_info;
  505. IS_IPGRE_LINK_ASSERT(link);
  506. ipgre->ttl = ttl;
  507. ipgre->ipgre_mask |= IPGRE_ATTR_TTL;
  508. return 0;
  509. }
  510. /**
  511. * Set IPGRE tunnel ttl
  512. * @arg link Link object
  513. *
  514. * @return ttl value
  515. */
  516. uint8_t rtnl_link_ipgre_get_ttl(struct rtnl_link *link)
  517. {
  518. struct ipgre_info *ipgre = link->l_info;
  519. IS_IPGRE_LINK_ASSERT(link);
  520. return ipgre->ttl;
  521. }
  522. /**
  523. * Set IPGRE tunnel tos
  524. * @arg link Link object
  525. * @arg tos tunnel tos
  526. *
  527. * @return 0 on success or a negative error code
  528. */
  529. int rtnl_link_ipgre_set_tos(struct rtnl_link *link, uint8_t tos)
  530. {
  531. struct ipgre_info *ipgre = link->l_info;
  532. IS_IPGRE_LINK_ASSERT(link);
  533. ipgre->tos = tos;
  534. ipgre->ipgre_mask |= IPGRE_ATTR_TOS;
  535. return 0;
  536. }
  537. /**
  538. * Get IPGRE tunnel tos
  539. * @arg link Link object
  540. *
  541. * @return tos value
  542. */
  543. uint8_t rtnl_link_ipgre_get_tos(struct rtnl_link *link)
  544. {
  545. struct ipgre_info *ipgre = link->l_info;
  546. IS_IPGRE_LINK_ASSERT(link);
  547. return ipgre->tos;
  548. }
  549. /**
  550. * Set IPGRE tunnel path MTU discovery
  551. * @arg link Link object
  552. * @arg pmtudisc path MTU discovery
  553. *
  554. * @return 0 on success or a negative error code
  555. */
  556. int rtnl_link_ipgre_set_pmtudisc(struct rtnl_link *link, uint8_t pmtudisc)
  557. {
  558. struct ipgre_info *ipgre = link->l_info;
  559. IS_IPGRE_LINK_ASSERT(link);
  560. ipgre->pmtudisc = pmtudisc;
  561. ipgre->ipgre_mask |= IPGRE_ATTR_PMTUDISC;
  562. return 0;
  563. }
  564. /**
  565. * Get IPGRE path MTU discovery
  566. * @arg link Link object
  567. *
  568. * @return pmtudisc value
  569. */
  570. uint8_t rtnl_link_get_pmtudisc(struct rtnl_link *link)
  571. {
  572. struct ipgre_info *ipgre = link->l_info;
  573. IS_IPGRE_LINK_ASSERT(link);
  574. return ipgre->pmtudisc;
  575. }
  576. static void __init ipgre_init(void)
  577. {
  578. rtnl_link_register_info(&ipgre_info_ops);
  579. }
  580. static void __exit ipgre_exit(void)
  581. {
  582. rtnl_link_unregister_info(&ipgre_info_ops);
  583. }