diff options
-rw-r--r-- | drivers/net/tun.c | 56 | ||||
-rw-r--r-- | include/uapi/linux/if_link.h | 18 |
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 | ||
2294 | static 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 | |||
2311 | static 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 | |||
2344 | nla_put_failure: | ||
2345 | return -EMSGSIZE; | ||
2346 | } | ||
2347 | |||
2294 | static struct rtnl_link_ops tun_link_ops __read_mostly = { | 2348 | static 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 | ||
2301 | static void tun_sock_write_space(struct sock *sk) | 2357 | static 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 | |||
946 | enum { | ||
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 */ |