1/* 2 * NETLINK Generic Netlink Family 3 * 4 * Authors: Jamal Hadi Salim 5 * Thomas Graf <tgraf@suug.ch> 6 */ 7 8#include <linux/module.h> 9#include <linux/kernel.h> 10#include <linux/errno.h> 11#include <linux/types.h> 12#include <linux/socket.h> 13#include <linux/string.h> 14#include <linux/skbuff.h> 15#include <linux/mutex.h> 16#include <net/sock.h> 17#include <net/genetlink.h> 18 19struct sock *genl_sock = NULL; 20 21static DEFINE_MUTEX(genl_mutex); /* serialization of message processing */ 22 23static void genl_lock(void) 24{ 25 mutex_lock(&genl_mutex); 26} 27 28static int genl_trylock(void) 29{ 30 return !mutex_trylock(&genl_mutex); 31} 32 33static void genl_unlock(void) 34{ 35 mutex_unlock(&genl_mutex); 36 37 if (genl_sock && genl_sock->sk_receive_queue.qlen) 38 genl_sock->sk_data_ready(genl_sock, 0); 39} 40 41#define GENL_FAM_TAB_SIZE 16 42#define GENL_FAM_TAB_MASK (GENL_FAM_TAB_SIZE - 1) 43 44static struct list_head family_ht[GENL_FAM_TAB_SIZE]; 45 46static int genl_ctrl_event(int event, void *data); 47 48static inline unsigned int genl_family_hash(unsigned int id) 49{ 50 return id & GENL_FAM_TAB_MASK; 51} 52 53static inline struct list_head *genl_family_chain(unsigned int id) 54{ 55 return &family_ht[genl_family_hash(id)]; 56} 57 58static struct genl_family *genl_family_find_byid(unsigned int id) 59{ 60 struct genl_family *f; 61 62 list_for_each_entry(f, genl_family_chain(id), family_list) 63 if (f->id == id) 64 return f; 65 66 return NULL; 67} 68 69static struct genl_family *genl_family_find_byname(char *name) 70{ 71 struct genl_family *f; 72 int i; 73 74 for (i = 0; i < GENL_FAM_TAB_SIZE; i++) 75 list_for_each_entry(f, genl_family_chain(i), family_list) 76 if (strcmp(f->name, name) == 0) 77 return f; 78 79 return NULL; 80} 81 82static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family) 83{ 84 struct genl_ops *ops; 85 86 list_for_each_entry(ops, &family->ops_list, ops_list) 87 if (ops->cmd == cmd) 88 return ops; 89 90 return NULL; 91} 92 93/* Of course we are going to have problems once we hit 94 * 2^16 alive types, but that can only happen by year 2K 95*/ 96static inline u16 genl_generate_id(void) 97{ 98 static u16 id_gen_idx; 99 int overflowed = 0; 100 101 do { 102 if (id_gen_idx == 0) 103 id_gen_idx = GENL_MIN_ID; 104 105 if (++id_gen_idx > GENL_MAX_ID) { 106 if (!overflowed) { 107 overflowed = 1; 108 id_gen_idx = 0; 109 continue; 110 } else 111 return 0; 112 } 113 114 } while (genl_family_find_byid(id_gen_idx)); 115 116 return id_gen_idx; 117} 118 119/** 120 * genl_register_ops - register generic netlink operations 121 * @family: generic netlink family 122 * @ops: operations to be registered 123 * 124 * Registers the specified operations and assigns them to the specified 125 * family. Either a doit or dumpit callback must be specified or the 126 * operation will fail. Only one operation structure per command 127 * identifier may be registered. 128 * 129 * See include/net/genetlink.h for more documenation on the operations 130 * structure. 131 * 132 * Returns 0 on success or a negative error code. 133 */ 134int genl_register_ops(struct genl_family *family, struct genl_ops *ops) 135{ 136 int err = -EINVAL; 137 138 if (ops->dumpit == NULL && ops->doit == NULL) 139 goto errout; 140 141 if (genl_get_cmd(ops->cmd, family)) { 142 err = -EEXIST; 143 goto errout; 144 } 145 146 if (ops->dumpit) 147 ops->flags |= GENL_CMD_CAP_DUMP; 148 if (ops->doit) 149 ops->flags |= GENL_CMD_CAP_DO; 150 if (ops->policy) 151 ops->flags |= GENL_CMD_CAP_HASPOL; 152 153 genl_lock(); 154 list_add_tail(&ops->ops_list, &family->ops_list); 155 genl_unlock(); 156 157 genl_ctrl_event(CTRL_CMD_NEWOPS, ops); 158 err = 0; 159errout: 160 return err; 161} 162 163/** 164 * genl_unregister_ops - unregister generic netlink operations 165 * @family: generic netlink family 166 * @ops: operations to be unregistered 167 * 168 * Unregisters the specified operations and unassigns them from the 169 * specified family. The operation blocks until the current message 170 * processing has finished and doesn't start again until the 171 * unregister process has finished. 172 * 173 * Note: It is not necessary to unregister all operations before 174 * unregistering the family, unregistering the family will cause 175 * all assigned operations to be unregistered automatically. 176 * 177 * Returns 0 on success or a negative error code. 178 */ 179int genl_unregister_ops(struct genl_family *family, struct genl_ops *ops) 180{ 181 struct genl_ops *rc; 182 183 genl_lock(); 184 list_for_each_entry(rc, &family->ops_list, ops_list) { 185 if (rc == ops) { 186 list_del(&ops->ops_list); 187 genl_unlock(); 188 genl_ctrl_event(CTRL_CMD_DELOPS, ops); 189 return 0; 190 } 191 } 192 genl_unlock(); 193 194 return -ENOENT; 195} 196 197/** 198 * genl_register_family - register a generic netlink family 199 * @family: generic netlink family 200 * 201 * Registers the specified family after validating it first. Only one 202 * family may be registered with the same family name or identifier. 203 * The family id may equal GENL_ID_GENERATE causing an unique id to 204 * be automatically generated and assigned. 205 * 206 * Return 0 on success or a negative error code. 207 */ 208int genl_register_family(struct genl_family *family) 209{ 210 int err = -EINVAL; 211 212 if (family->id && family->id < GENL_MIN_ID) 213 goto errout; 214 215 if (family->id > GENL_MAX_ID) 216 goto errout; 217 218 INIT_LIST_HEAD(&family->ops_list); 219 220 genl_lock(); 221 222 if (genl_family_find_byname(family->name)) { 223 err = -EEXIST; 224 goto errout_locked; 225 } 226 227 if (genl_family_find_byid(family->id)) { 228 err = -EEXIST; 229 goto errout_locked; 230 } 231 232 if (family->id == GENL_ID_GENERATE) { 233 u16 newid = genl_generate_id(); 234 235 if (!newid) { 236 err = -ENOMEM; 237 goto errout_locked; 238 } 239 240 family->id = newid; 241 } 242 243 if (family->maxattr) { 244 family->attrbuf = kmalloc((family->maxattr+1) * 245 sizeof(struct nlattr *), GFP_KERNEL); 246 if (family->attrbuf == NULL) { 247 err = -ENOMEM; 248 goto errout_locked; 249 } 250 } else 251 family->attrbuf = NULL; 252 253 list_add_tail(&family->family_list, genl_family_chain(family->id)); 254 genl_unlock(); 255 256 genl_ctrl_event(CTRL_CMD_NEWFAMILY, family); 257 258 return 0; 259 260errout_locked: 261 genl_unlock(); 262errout: 263 return err; 264} 265 266/** 267 * genl_unregister_family - unregister generic netlink family 268 * @family: generic netlink family 269 * 270 * Unregisters the specified family. 271 * 272 * Returns 0 on success or a negative error code. 273 */ 274int genl_unregister_family(struct genl_family *family) 275{ 276 struct genl_family *rc; 277 278 genl_lock(); 279 280 list_for_each_entry(rc, genl_family_chain(family->id), family_list) { 281 if (family->id != rc->id || strcmp(rc->name, family->name)) 282 continue; 283 284 list_del(&rc->family_list); 285 INIT_LIST_HEAD(&family->ops_list); 286 genl_unlock(); 287 288 kfree(family->attrbuf); 289 genl_ctrl_event(CTRL_CMD_DELFAMILY, family); 290 return 0; 291 } 292 293 genl_unlock(); 294 295 return -ENOENT; 296} 297 298static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) 299{ 300 struct genl_ops *ops; 301 struct genl_family *family; 302 struct genl_info info; 303 struct genlmsghdr *hdr = nlmsg_data(nlh); 304 int hdrlen, err; 305 306 family = genl_family_find_byid(nlh->nlmsg_type); 307 if (family == NULL) 308 return -ENOENT; 309 310 hdrlen = GENL_HDRLEN + family->hdrsize; 311 if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen)) 312 return -EINVAL; 313 314 ops = genl_get_cmd(hdr->cmd, family); 315 if (ops == NULL) 316 return -EOPNOTSUPP; 317 318 if ((ops->flags & GENL_ADMIN_PERM) && 319 security_netlink_recv(skb, CAP_NET_ADMIN)) 320 return -EPERM; 321 322 if (nlh->nlmsg_flags & NLM_F_DUMP) { 323 if (ops->dumpit == NULL) 324 return -EOPNOTSUPP; 325 326 return netlink_dump_start(genl_sock, skb, nlh, 327 ops->dumpit, ops->done); 328 } 329 330 if (ops->doit == NULL) 331 return -EOPNOTSUPP; 332 333 if (family->attrbuf) { 334 err = nlmsg_parse(nlh, hdrlen, family->attrbuf, family->maxattr, 335 ops->policy); 336 if (err < 0) 337 return err; 338 } 339 340 info.snd_seq = nlh->nlmsg_seq; 341 info.snd_pid = NETLINK_CB(skb).pid; 342 info.nlhdr = nlh; 343 info.genlhdr = nlmsg_data(nlh); 344 info.userhdr = nlmsg_data(nlh) + GENL_HDRLEN; 345 info.attrs = family->attrbuf; 346 347 return ops->doit(skb, &info); 348} 349 350static void genl_rcv(struct sock *sk, int len) 351{ 352 unsigned int qlen = 0; 353 354 do { 355 if (genl_trylock()) 356 return; 357 netlink_run_queue(sk, &qlen, genl_rcv_msg); 358 genl_unlock(); 359 } while (qlen && genl_sock && genl_sock->sk_receive_queue.qlen); 360} 361 362/************************************************************************** 363 * Controller 364 **************************************************************************/ 365 366static struct genl_family genl_ctrl = { 367 .id = GENL_ID_CTRL, 368 .name = "nlctrl", 369 .version = 0x2, 370 .maxattr = CTRL_ATTR_MAX, 371}; 372 373static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq, 374 u32 flags, struct sk_buff *skb, u8 cmd) 375{ 376 void *hdr; 377 378 hdr = genlmsg_put(skb, pid, seq, &genl_ctrl, flags, cmd); 379 if (hdr == NULL) 380 return -1; 381 382 NLA_PUT_STRING(skb, CTRL_ATTR_FAMILY_NAME, family->name); 383 NLA_PUT_U16(skb, CTRL_ATTR_FAMILY_ID, family->id); 384 NLA_PUT_U32(skb, CTRL_ATTR_VERSION, family->version); 385 NLA_PUT_U32(skb, CTRL_ATTR_HDRSIZE, family->hdrsize); 386 NLA_PUT_U32(skb, CTRL_ATTR_MAXATTR, family->maxattr); 387 388 if (!list_empty(&family->ops_list)) { 389 struct nlattr *nla_ops; 390 struct genl_ops *ops; 391 int idx = 1; 392 393 nla_ops = nla_nest_start(skb, CTRL_ATTR_OPS); 394 if (nla_ops == NULL) 395 goto nla_put_failure; 396 397 list_for_each_entry(ops, &family->ops_list, ops_list) { 398 struct nlattr *nest; 399 400 nest = nla_nest_start(skb, idx++); 401 if (nest == NULL) 402 goto nla_put_failure; 403 404 NLA_PUT_U32(skb, CTRL_ATTR_OP_ID, ops->cmd); 405 NLA_PUT_U32(skb, CTRL_ATTR_OP_FLAGS, ops->flags); 406 407 nla_nest_end(skb, nest); 408 } 409 410 nla_nest_end(skb, nla_ops); 411 } 412 413 return genlmsg_end(skb, hdr); 414 415nla_put_failure: 416 return genlmsg_cancel(skb, hdr); 417} 418 419static int ctrl_dumpfamily(struct sk_buff *skb, struct netlink_callback *cb) 420{ 421 422 int i, n = 0; 423 struct genl_family *rt; 424 int chains_to_skip = cb->args[0]; 425 int fams_to_skip = cb->args[1]; 426 427 if (chains_to_skip != 0) 428 genl_lock(); 429 430 for (i = 0; i < GENL_FAM_TAB_SIZE; i++) { 431 if (i < chains_to_skip) 432 continue; 433 n = 0; 434 list_for_each_entry(rt, genl_family_chain(i), family_list) { 435 if (++n < fams_to_skip) 436 continue; 437 if (ctrl_fill_info(rt, NETLINK_CB(cb->skb).pid, 438 cb->nlh->nlmsg_seq, NLM_F_MULTI, 439 skb, CTRL_CMD_NEWFAMILY) < 0) 440 goto errout; 441 } 442 443 fams_to_skip = 0; 444 } 445 446errout: 447 if (chains_to_skip != 0) 448 genl_unlock(); 449 450 cb->args[0] = i; 451 cb->args[1] = n; 452 453 return skb->len; 454} 455 456static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid, 457 int seq, u8 cmd) 458{ 459 struct sk_buff *skb; 460 int err; 461 462 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 463 if (skb == NULL) 464 return ERR_PTR(-ENOBUFS); 465 466 err = ctrl_fill_info(family, pid, seq, 0, skb, cmd); 467 if (err < 0) { 468 nlmsg_free(skb); 469 return ERR_PTR(err); 470 } 471 472 return skb; 473} 474 475static const struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] = { 476 [CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 }, 477 [CTRL_ATTR_FAMILY_NAME] = { .type = NLA_NUL_STRING, 478 .len = GENL_NAMSIZ - 1 }, 479}; 480 481static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info) 482{ 483 struct sk_buff *msg; 484 struct genl_family *res = NULL; 485 int err = -EINVAL; 486 487 if (info->attrs[CTRL_ATTR_FAMILY_ID]) { 488 u16 id = nla_get_u16(info->attrs[CTRL_ATTR_FAMILY_ID]); 489 res = genl_family_find_byid(id); 490 } 491 492 if (info->attrs[CTRL_ATTR_FAMILY_NAME]) { 493 char *name; 494 495 name = nla_data(info->attrs[CTRL_ATTR_FAMILY_NAME]); 496 res = genl_family_find_byname(name); 497 } 498 499 if (res == NULL) { 500 err = -ENOENT; 501 goto errout; 502 } 503 504 msg = ctrl_build_msg(res, info->snd_pid, info->snd_seq, 505 CTRL_CMD_NEWFAMILY); 506 if (IS_ERR(msg)) { 507 err = PTR_ERR(msg); 508 goto errout; 509 } 510 511 err = genlmsg_reply(msg, info); 512errout: 513 return err; 514} 515 516static int genl_ctrl_event(int event, void *data) 517{ 518 struct sk_buff *msg; 519 520 if (genl_sock == NULL) 521 return 0; 522 523 switch (event) { 524 case CTRL_CMD_NEWFAMILY: 525 case CTRL_CMD_DELFAMILY: 526 msg = ctrl_build_msg(data, 0, 0, event); 527 if (IS_ERR(msg)) 528 return PTR_ERR(msg); 529 530 genlmsg_multicast(msg, 0, GENL_ID_CTRL, GFP_KERNEL); 531 break; 532 } 533 534 return 0; 535} 536 537static struct genl_ops genl_ctrl_ops = { 538 .cmd = CTRL_CMD_GETFAMILY, 539 .doit = ctrl_getfamily, 540 .dumpit = ctrl_dumpfamily, 541 .policy = ctrl_policy, 542}; 543 544static int __init genl_init(void) 545{ 546 int i, err; 547 548 for (i = 0; i < GENL_FAM_TAB_SIZE; i++) 549 INIT_LIST_HEAD(&family_ht[i]); 550 551 err = genl_register_family(&genl_ctrl); 552 if (err < 0) 553 goto errout; 554 555 err = genl_register_ops(&genl_ctrl, &genl_ctrl_ops); 556 if (err < 0) 557 goto errout_register; 558 559 netlink_set_nonroot(NETLINK_GENERIC, NL_NONROOT_RECV); 560 genl_sock = netlink_kernel_create(NETLINK_GENERIC, GENL_MAX_ID, 561 genl_rcv, NULL, THIS_MODULE); 562 if (genl_sock == NULL) 563 panic("GENL: Cannot initialize generic netlink\n"); 564 565 return 0; 566 567errout_register: 568 genl_unregister_family(&genl_ctrl); 569errout: 570 panic("GENL: Cannot register controller: %d\n", err); 571} 572 573subsys_initcall(genl_init); 574 575EXPORT_SYMBOL(genl_sock); 576EXPORT_SYMBOL(genl_register_ops); 577EXPORT_SYMBOL(genl_unregister_ops); 578EXPORT_SYMBOL(genl_register_family); 579EXPORT_SYMBOL(genl_unregister_family); 580