aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/tun.c56
-rw-r--r--include/uapi/linux/if_link.h18
2 files changed, 74 insertions, 0 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 8e9a0ac644d2..86b16013e9c5 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -2291,11 +2291,67 @@ static int tun_validate(struct nlattr *tb[], struct nlattr *data[],
2291 return -EINVAL; 2291 return -EINVAL;
2292} 2292}
2293 2293
2294static size_t tun_get_size(const struct net_device *dev)
2295{
2296 BUILD_BUG_ON(sizeof(u32) != sizeof(uid_t));
2297 BUILD_BUG_ON(sizeof(u32) != sizeof(gid_t));
2298
2299 return nla_total_size(sizeof(uid_t)) + /* OWNER */
2300 nla_total_size(sizeof(gid_t)) + /* GROUP */
2301 nla_total_size(sizeof(u8)) + /* TYPE */
2302 nla_total_size(sizeof(u8)) + /* PI */
2303 nla_total_size(sizeof(u8)) + /* VNET_HDR */
2304 nla_total_size(sizeof(u8)) + /* PERSIST */
2305 nla_total_size(sizeof(u8)) + /* MULTI_QUEUE */
2306 nla_total_size(sizeof(u32)) + /* NUM_QUEUES */
2307 nla_total_size(sizeof(u32)) + /* NUM_DISABLED_QUEUES */
2308 0;
2309}
2310
2311static int tun_fill_info(struct sk_buff *skb, const struct net_device *dev)
2312{
2313 struct tun_struct *tun = netdev_priv(dev);
2314
2315 if (nla_put_u8(skb, IFLA_TUN_TYPE, tun->flags & TUN_TYPE_MASK))
2316 goto nla_put_failure;
2317 if (uid_valid(tun->owner) &&
2318 nla_put_u32(skb, IFLA_TUN_OWNER,
2319 from_kuid_munged(current_user_ns(), tun->owner)))
2320 goto nla_put_failure;
2321 if (gid_valid(tun->group) &&
2322 nla_put_u32(skb, IFLA_TUN_GROUP,
2323 from_kgid_munged(current_user_ns(), tun->group)))
2324 goto nla_put_failure;
2325 if (nla_put_u8(skb, IFLA_TUN_PI, !(tun->flags & IFF_NO_PI)))
2326 goto nla_put_failure;
2327 if (nla_put_u8(skb, IFLA_TUN_VNET_HDR, !!(tun->flags & IFF_VNET_HDR)))
2328 goto nla_put_failure;
2329 if (nla_put_u8(skb, IFLA_TUN_PERSIST, !!(tun->flags & IFF_PERSIST)))
2330 goto nla_put_failure;
2331 if (nla_put_u8(skb, IFLA_TUN_MULTI_QUEUE,
2332 !!(tun->flags & IFF_MULTI_QUEUE)))
2333 goto nla_put_failure;
2334 if (tun->flags & IFF_MULTI_QUEUE) {
2335 if (nla_put_u32(skb, IFLA_TUN_NUM_QUEUES, tun->numqueues))
2336 goto nla_put_failure;
2337 if (nla_put_u32(skb, IFLA_TUN_NUM_DISABLED_QUEUES,
2338 tun->numdisabled))
2339 goto nla_put_failure;
2340 }
2341
2342 return 0;
2343
2344nla_put_failure:
2345 return -EMSGSIZE;
2346}
2347
2294static struct rtnl_link_ops tun_link_ops __read_mostly = { 2348static struct rtnl_link_ops tun_link_ops __read_mostly = {
2295 .kind = DRV_NAME, 2349 .kind = DRV_NAME,
2296 .priv_size = sizeof(struct tun_struct), 2350 .priv_size = sizeof(struct tun_struct),
2297 .setup = tun_setup, 2351 .setup = tun_setup,
2298 .validate = tun_validate, 2352 .validate = tun_validate,
2353 .get_size = tun_get_size,
2354 .fill_info = tun_fill_info,
2299}; 2355};
2300 2356
2301static void tun_sock_write_space(struct sock *sk) 2357static void tun_sock_write_space(struct sock *sk)
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index 6d9447700e18..11d0c0ea2bfa 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -941,4 +941,22 @@ enum {
941 IFLA_EVENT_BONDING_OPTIONS, /* change in bonding options */ 941 IFLA_EVENT_BONDING_OPTIONS, /* change in bonding options */
942}; 942};
943 943
944/* tun section */
945
946enum {
947 IFLA_TUN_UNSPEC,
948 IFLA_TUN_OWNER,
949 IFLA_TUN_GROUP,
950 IFLA_TUN_TYPE,
951 IFLA_TUN_PI,
952 IFLA_TUN_VNET_HDR,
953 IFLA_TUN_PERSIST,
954 IFLA_TUN_MULTI_QUEUE,
955 IFLA_TUN_NUM_QUEUES,
956 IFLA_TUN_NUM_DISABLED_QUEUES,
957 __IFLA_TUN_MAX,
958};
959
960#define IFLA_TUN_MAX (__IFLA_TUN_MAX - 1)
961
944#endif /* _UAPI_LINUX_IF_LINK_H */ 962#endif /* _UAPI_LINUX_IF_LINK_H */