|
40 | 40 | #define IP6_TNL_ATTR_PROTO (1 << 7) |
41 | 41 | #define IP6_TNL_ATTR_FLOWINFO (1 << 8) |
42 | 42 | #define IP6_TNL_ATTR_FWMARK (1 << 9) |
| 43 | +#define IP6_TNL_ATTR_CMTD (1 << 10) |
43 | 44 |
|
44 | 45 | struct ip6_tnl_info |
45 | 46 | { |
@@ -67,6 +68,7 @@ static struct nla_policy ip6_tnl_policy[IFLA_IPTUN_MAX + 1] = { |
67 | 68 | [IFLA_IPTUN_FLAGS] = { .type = NLA_U32 }, |
68 | 69 | [IFLA_IPTUN_PROTO] = { .type = NLA_U8 }, |
69 | 70 | [IFLA_IPTUN_FWMARK] = { .type = NLA_U32 }, |
| 71 | + [IFLA_IPTUN_COLLECT_METADATA] = { .type = NLA_FLAG }, |
70 | 72 | }; |
71 | 73 |
|
72 | 74 | static int ip6_tnl_alloc(struct rtnl_link *link) |
@@ -155,6 +157,9 @@ static int ip6_tnl_parse(struct rtnl_link *link, struct nlattr *data, |
155 | 157 | ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_FWMARK; |
156 | 158 | } |
157 | 159 |
|
| 160 | + if (tb[IFLA_IPTUN_COLLECT_METADATA]) |
| 161 | + ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_CMTD; |
| 162 | + |
158 | 163 | err = 0; |
159 | 164 |
|
160 | 165 | errout: |
@@ -203,6 +208,9 @@ static int ip6_tnl_put_attrs(struct nl_msg *msg, struct rtnl_link *link) |
203 | 208 | if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_FWMARK) |
204 | 209 | NLA_PUT_U32(msg, IFLA_IPTUN_FWMARK, ip6_tnl->fwmark); |
205 | 210 |
|
| 211 | + if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_CMTD) |
| 212 | + NLA_PUT_FLAG(msg, IFLA_IPTUN_COLLECT_METADATA); |
| 213 | + |
206 | 214 | nla_nest_end(msg, data); |
207 | 215 |
|
208 | 216 | nla_put_failure: |
@@ -288,6 +296,10 @@ static void ip6_tnl_dump_details(struct rtnl_link *link, struct nl_dump_params * |
288 | 296 | nl_dump(p, " fwmark "); |
289 | 297 | nl_dump_line(p, "%x\n", ip6_tnl->fwmark); |
290 | 298 | } |
| 299 | + |
| 300 | + if (ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_CMTD) { |
| 301 | + nl_dump(p, " collect-metadata\n"); |
| 302 | + } |
291 | 303 | } |
292 | 304 |
|
293 | 305 | static int ip6_tnl_clone(struct rtnl_link *dst, struct rtnl_link *src) |
@@ -661,6 +673,51 @@ uint32_t rtnl_link_ip6_tnl_get_flags(struct rtnl_link *link) |
661 | 673 | return ip6_tnl->flags; |
662 | 674 | } |
663 | 675 |
|
| 676 | +/** |
| 677 | + * Set IP6_TNL collect-metadata flag |
| 678 | + * @arg link Link object |
| 679 | + * @arg enable 0 to disable, non-zero to enable |
| 680 | + * |
| 681 | + * Enable or disable the collect-metadata mode on the ip6tnl link. |
| 682 | + * |
| 683 | + * @return 0 on success or a negative error code |
| 684 | + */ |
| 685 | +int rtnl_link_ip6_tnl_set_collect_metadata(struct rtnl_link *link, int enable) |
| 686 | +{ |
| 687 | + struct ip6_tnl_info *ip6_tnl = link->l_info; |
| 688 | + |
| 689 | + IS_IP6_TNL_LINK_ASSERT(link); |
| 690 | + |
| 691 | + if (enable) |
| 692 | + ip6_tnl->ip6_tnl_mask |= IP6_TNL_ATTR_CMTD; |
| 693 | + else |
| 694 | + ip6_tnl->ip6_tnl_mask &= ~IP6_TNL_ATTR_CMTD; |
| 695 | + |
| 696 | + return 0; |
| 697 | +} |
| 698 | + |
| 699 | +/** |
| 700 | + * Get IP6_TNL collect-metadata flag |
| 701 | + * @arg link Link object |
| 702 | + * @arg enable Pointer to int which will be set to the current state |
| 703 | + * (0 if disabled, non-zero if enabled) |
| 704 | + * |
| 705 | + * @return 0 on success or a negative error code |
| 706 | + */ |
| 707 | +int rtnl_link_ip6_tnl_get_collect_metadata(struct rtnl_link *link, int *enable) |
| 708 | +{ |
| 709 | + struct ip6_tnl_info *ip6_tnl = link->l_info; |
| 710 | + |
| 711 | + IS_IP6_TNL_LINK_ASSERT(link); |
| 712 | + |
| 713 | + if (!enable) |
| 714 | + return -NLE_INVAL; |
| 715 | + |
| 716 | + *enable = !!(ip6_tnl->ip6_tnl_mask & IP6_TNL_ATTR_CMTD); |
| 717 | + |
| 718 | + return 0; |
| 719 | +} |
| 720 | + |
664 | 721 | /** |
665 | 722 | * Set IP6_TNL tunnel proto |
666 | 723 | * @arg link Link object |
|
0 commit comments