| .. | .. |
|---|
| 34 | 34 | #define NETLINK_CREDS(skb) (&NETLINK_CB((skb)).creds) |
|---|
| 35 | 35 | |
|---|
| 36 | 36 | |
|---|
| 37 | | -extern void netlink_table_grab(void); |
|---|
| 38 | | -extern void netlink_table_ungrab(void); |
|---|
| 37 | +void netlink_table_grab(void); |
|---|
| 38 | +void netlink_table_ungrab(void); |
|---|
| 39 | 39 | |
|---|
| 40 | 40 | #define NL_CFG_F_NONROOT_RECV (1 << 0) |
|---|
| 41 | 41 | #define NL_CFG_F_NONROOT_SEND (1 << 1) |
|---|
| .. | .. |
|---|
| 51 | 51 | bool (*compare)(struct net *net, struct sock *sk); |
|---|
| 52 | 52 | }; |
|---|
| 53 | 53 | |
|---|
| 54 | | -extern struct sock *__netlink_kernel_create(struct net *net, int unit, |
|---|
| 54 | +struct sock *__netlink_kernel_create(struct net *net, int unit, |
|---|
| 55 | 55 | struct module *module, |
|---|
| 56 | 56 | struct netlink_kernel_cfg *cfg); |
|---|
| 57 | 57 | static inline struct sock * |
|---|
| .. | .. |
|---|
| 68 | 68 | * @_msg: message string to report - don't access directly, use |
|---|
| 69 | 69 | * %NL_SET_ERR_MSG |
|---|
| 70 | 70 | * @bad_attr: attribute with error |
|---|
| 71 | + * @policy: policy for a bad attribute |
|---|
| 71 | 72 | * @cookie: cookie data to return to userspace (for success) |
|---|
| 72 | 73 | * @cookie_len: actual cookie data length |
|---|
| 73 | 74 | */ |
|---|
| 74 | 75 | struct netlink_ext_ack { |
|---|
| 75 | 76 | const char *_msg; |
|---|
| 76 | 77 | const struct nlattr *bad_attr; |
|---|
| 78 | + const struct nla_policy *policy; |
|---|
| 77 | 79 | u8 cookie[NETLINK_MAX_COOKIE_LEN]; |
|---|
| 78 | 80 | u8 cookie_len; |
|---|
| 79 | 81 | }; |
|---|
| .. | .. |
|---|
| 95 | 97 | #define NL_SET_ERR_MSG_MOD(extack, msg) \ |
|---|
| 96 | 98 | NL_SET_ERR_MSG((extack), KBUILD_MODNAME ": " msg) |
|---|
| 97 | 99 | |
|---|
| 98 | | -#define NL_SET_BAD_ATTR(extack, attr) do { \ |
|---|
| 99 | | - if ((extack)) \ |
|---|
| 100 | +#define NL_SET_BAD_ATTR_POLICY(extack, attr, pol) do { \ |
|---|
| 101 | + if ((extack)) { \ |
|---|
| 100 | 102 | (extack)->bad_attr = (attr); \ |
|---|
| 101 | | -} while (0) |
|---|
| 102 | | - |
|---|
| 103 | | -#define NL_SET_ERR_MSG_ATTR(extack, attr, msg) do { \ |
|---|
| 104 | | - static const char __msg[] = msg; \ |
|---|
| 105 | | - struct netlink_ext_ack *__extack = (extack); \ |
|---|
| 106 | | - \ |
|---|
| 107 | | - if (__extack) { \ |
|---|
| 108 | | - __extack->_msg = __msg; \ |
|---|
| 109 | | - __extack->bad_attr = (attr); \ |
|---|
| 103 | + (extack)->policy = (pol); \ |
|---|
| 110 | 104 | } \ |
|---|
| 111 | 105 | } while (0) |
|---|
| 112 | 106 | |
|---|
| 113 | | -extern void netlink_kernel_release(struct sock *sk); |
|---|
| 114 | | -extern int __netlink_change_ngroups(struct sock *sk, unsigned int groups); |
|---|
| 115 | | -extern int netlink_change_ngroups(struct sock *sk, unsigned int groups); |
|---|
| 116 | | -extern void __netlink_clear_multicast_users(struct sock *sk, unsigned int group); |
|---|
| 117 | | -extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, |
|---|
| 118 | | - const struct netlink_ext_ack *extack); |
|---|
| 119 | | -extern int netlink_has_listeners(struct sock *sk, unsigned int group); |
|---|
| 107 | +#define NL_SET_BAD_ATTR(extack, attr) NL_SET_BAD_ATTR_POLICY(extack, attr, NULL) |
|---|
| 120 | 108 | |
|---|
| 121 | | -extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 portid, int nonblock); |
|---|
| 122 | | -extern int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 portid, |
|---|
| 123 | | - __u32 group, gfp_t allocation); |
|---|
| 124 | | -extern int netlink_broadcast_filtered(struct sock *ssk, struct sk_buff *skb, |
|---|
| 125 | | - __u32 portid, __u32 group, gfp_t allocation, |
|---|
| 126 | | - int (*filter)(struct sock *dsk, struct sk_buff *skb, void *data), |
|---|
| 127 | | - void *filter_data); |
|---|
| 128 | | -extern int netlink_set_err(struct sock *ssk, __u32 portid, __u32 group, int code); |
|---|
| 129 | | -extern int netlink_register_notifier(struct notifier_block *nb); |
|---|
| 130 | | -extern int netlink_unregister_notifier(struct notifier_block *nb); |
|---|
| 109 | +#define NL_SET_ERR_MSG_ATTR_POL(extack, attr, pol, msg) do { \ |
|---|
| 110 | + static const char __msg[] = msg; \ |
|---|
| 111 | + struct netlink_ext_ack *__extack = (extack); \ |
|---|
| 112 | + \ |
|---|
| 113 | + if (__extack) { \ |
|---|
| 114 | + __extack->_msg = __msg; \ |
|---|
| 115 | + __extack->bad_attr = (attr); \ |
|---|
| 116 | + __extack->policy = (pol); \ |
|---|
| 117 | + } \ |
|---|
| 118 | +} while (0) |
|---|
| 119 | + |
|---|
| 120 | +#define NL_SET_ERR_MSG_ATTR(extack, attr, msg) \ |
|---|
| 121 | + NL_SET_ERR_MSG_ATTR_POL(extack, attr, NULL, msg) |
|---|
| 122 | + |
|---|
| 123 | +static inline void nl_set_extack_cookie_u64(struct netlink_ext_ack *extack, |
|---|
| 124 | + u64 cookie) |
|---|
| 125 | +{ |
|---|
| 126 | + u64 __cookie = cookie; |
|---|
| 127 | + |
|---|
| 128 | + if (!extack) |
|---|
| 129 | + return; |
|---|
| 130 | + memcpy(extack->cookie, &__cookie, sizeof(__cookie)); |
|---|
| 131 | + extack->cookie_len = sizeof(__cookie); |
|---|
| 132 | +} |
|---|
| 133 | + |
|---|
| 134 | +static inline void nl_set_extack_cookie_u32(struct netlink_ext_ack *extack, |
|---|
| 135 | + u32 cookie) |
|---|
| 136 | +{ |
|---|
| 137 | + u32 __cookie = cookie; |
|---|
| 138 | + |
|---|
| 139 | + if (!extack) |
|---|
| 140 | + return; |
|---|
| 141 | + memcpy(extack->cookie, &__cookie, sizeof(__cookie)); |
|---|
| 142 | + extack->cookie_len = sizeof(__cookie); |
|---|
| 143 | +} |
|---|
| 144 | + |
|---|
| 145 | +void netlink_kernel_release(struct sock *sk); |
|---|
| 146 | +int __netlink_change_ngroups(struct sock *sk, unsigned int groups); |
|---|
| 147 | +int netlink_change_ngroups(struct sock *sk, unsigned int groups); |
|---|
| 148 | +void __netlink_clear_multicast_users(struct sock *sk, unsigned int group); |
|---|
| 149 | +void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err, |
|---|
| 150 | + const struct netlink_ext_ack *extack); |
|---|
| 151 | +int netlink_has_listeners(struct sock *sk, unsigned int group); |
|---|
| 152 | +bool netlink_strict_get_check(struct sk_buff *skb); |
|---|
| 153 | + |
|---|
| 154 | +int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 portid, int nonblock); |
|---|
| 155 | +int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, __u32 portid, |
|---|
| 156 | + __u32 group, gfp_t allocation); |
|---|
| 157 | +int netlink_broadcast_filtered(struct sock *ssk, struct sk_buff *skb, |
|---|
| 158 | + __u32 portid, __u32 group, gfp_t allocation, |
|---|
| 159 | + int (*filter)(struct sock *dsk, struct sk_buff *skb, void *data), |
|---|
| 160 | + void *filter_data); |
|---|
| 161 | +int netlink_set_err(struct sock *ssk, __u32 portid, __u32 group, int code); |
|---|
| 162 | +int netlink_register_notifier(struct notifier_block *nb); |
|---|
| 163 | +int netlink_unregister_notifier(struct notifier_block *nb); |
|---|
| 131 | 164 | |
|---|
| 132 | 165 | /* finegrained unicast helpers: */ |
|---|
| 133 | 166 | struct sock *netlink_getsockbyfilp(struct file *filp); |
|---|
| .. | .. |
|---|
| 176 | 209 | void *data; |
|---|
| 177 | 210 | /* the module that dump function belong to */ |
|---|
| 178 | 211 | struct module *module; |
|---|
| 212 | + struct netlink_ext_ack *extack; |
|---|
| 179 | 213 | u16 family; |
|---|
| 180 | | - u16 min_dump_alloc; |
|---|
| 214 | + u16 answer_flags; |
|---|
| 215 | + u32 min_dump_alloc; |
|---|
| 181 | 216 | unsigned int prev_seq, seq; |
|---|
| 182 | | - long args[6]; |
|---|
| 217 | + bool strict_check; |
|---|
| 218 | + union { |
|---|
| 219 | + u8 ctx[48]; |
|---|
| 220 | + |
|---|
| 221 | + /* args is deprecated. Cast a struct over ctx instead |
|---|
| 222 | + * for proper type safety. |
|---|
| 223 | + */ |
|---|
| 224 | + long args[6]; |
|---|
| 225 | + }; |
|---|
| 183 | 226 | }; |
|---|
| 184 | 227 | |
|---|
| 185 | 228 | struct netlink_notify { |
|---|
| .. | .. |
|---|
| 197 | 240 | int (*done)(struct netlink_callback *); |
|---|
| 198 | 241 | void *data; |
|---|
| 199 | 242 | struct module *module; |
|---|
| 200 | | - u16 min_dump_alloc; |
|---|
| 243 | + u32 min_dump_alloc; |
|---|
| 201 | 244 | }; |
|---|
| 202 | 245 | |
|---|
| 203 | | -extern int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, |
|---|
| 246 | +int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, |
|---|
| 204 | 247 | const struct nlmsghdr *nlh, |
|---|
| 205 | 248 | struct netlink_dump_control *control); |
|---|
| 206 | 249 | static inline int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, |
|---|
| .. | .. |
|---|
| 219 | 262 | struct list_head list; |
|---|
| 220 | 263 | }; |
|---|
| 221 | 264 | |
|---|
| 222 | | -extern int netlink_add_tap(struct netlink_tap *nt); |
|---|
| 223 | | -extern int netlink_remove_tap(struct netlink_tap *nt); |
|---|
| 265 | +int netlink_add_tap(struct netlink_tap *nt); |
|---|
| 266 | +int netlink_remove_tap(struct netlink_tap *nt); |
|---|
| 224 | 267 | |
|---|
| 225 | 268 | bool __netlink_ns_capable(const struct netlink_skb_parms *nsp, |
|---|
| 226 | 269 | struct user_namespace *ns, int cap); |
|---|