1 /* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * Routing netlink socket interface: protocol independent part. 7 * 8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 9 * 10 * This program is free software; you can redistribute it and/or 11 * modify it under the terms of the GNU General Public License 12 * as published by the Free Software Foundation; either version 13 * 2 of the License, or (at your option) any later version. 14 * 15 * Fixes: 16 * Vitaly E. Lavrov RTA_OK arithmetics was wrong. 17 */ 18 19 #include <linux/config.h> 20 #include <linux/errno.h> 21 #include <linux/module.h> 22 #include <linux/types.h> 23 #include <linux/socket.h> 24 #include <linux/kernel.h> 25 #include <linux/sched.h> 26 #include <linux/timer.h> 27 #include <linux/string.h> 28 #include <linux/sockios.h> 29 #include <linux/net.h> 30 #include <linux/fcntl.h> 31 #include <linux/mm.h> 32 #include <linux/slab.h> 33 #include <linux/interrupt.h> 34 #include <linux/capability.h> 35 #include <linux/skbuff.h> 36 #include <linux/init.h> 37 #include <linux/security.h> 38 39 #include <asm/uaccess.h> 40 #include <asm/system.h> 41 #include <asm/string.h> 42 43 #include <linux/inet.h> 44 #include <linux/netdevice.h> 45 #include <net/ip.h> 46 #include <net/protocol.h> 47 #include <net/arp.h> 48 #include <net/route.h> 49 #include <net/udp.h> 50 #include <net/sock.h> 51 #include <net/pkt_sched.h> 52 53 DECLARE_MUTEX(rtnl_sem); 54 55 void rtnl_lock(void) 56 { 57 rtnl_shlock(); 58 } 59 60 int rtnl_lock_interruptible(void) 61 { 62 return down_interruptible(&rtnl_sem); 63 } 64 65 void rtnl_unlock(void) 66 { 67 rtnl_shunlock(); 68 69 netdev_run_todo(); 70 } 71 72 int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len) 73 { 74 memset(tb, 0, sizeof(struct rtattr*)*maxattr); 75 76 while (RTA_OK(rta, len)) { 77 unsigned flavor = rta->rta_type; 78 if (flavor && flavor <= maxattr) 79 tb[flavor-1] = rta; 80 rta = RTA_NEXT(rta, len); 81 } 82 return 0; 83 } 84 85 struct sock *rtnl; 86 87 struct rtnetlink_link * rtnetlink_links[NPROTO]; 88 89 static const int rtm_min[RTM_NR_FAMILIES] = 90 { 91 [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)), 92 [RTM_FAM(RTM_NEWADDR)] = NLMSG_LENGTH(sizeof(struct ifaddrmsg)), 93 [RTM_FAM(RTM_NEWROUTE)] = NLMSG_LENGTH(sizeof(struct rtmsg)), 94 [RTM_FAM(RTM_NEWNEIGH)] = NLMSG_LENGTH(sizeof(struct ndmsg)), 95 [RTM_FAM(RTM_NEWRULE)] = NLMSG_LENGTH(sizeof(struct rtmsg)), 96 [RTM_FAM(RTM_NEWQDISC)] = NLMSG_LENGTH(sizeof(struct tcmsg)), 97 [RTM_FAM(RTM_NEWTCLASS)] = NLMSG_LENGTH(sizeof(struct tcmsg)), 98 [RTM_FAM(RTM_NEWTFILTER)] = NLMSG_LENGTH(sizeof(struct tcmsg)), 99 [RTM_FAM(RTM_NEWACTION)] = NLMSG_LENGTH(sizeof(struct tcamsg)), 100 [RTM_FAM(RTM_NEWPREFIX)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), 101 [RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), 102 [RTM_FAM(RTM_GETANYCAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), 103 }; 104 105 static const int rta_max[RTM_NR_FAMILIES] = 106 { 107 [RTM_FAM(RTM_NEWLINK)] = IFLA_MAX, 108 [RTM_FAM(RTM_NEWADDR)] = IFA_MAX, 109 [RTM_FAM(RTM_NEWROUTE)] = RTA_MAX, 110 [RTM_FAM(RTM_NEWNEIGH)] = NDA_MAX, 111 [RTM_FAM(RTM_NEWRULE)] = RTA_MAX, 112 [RTM_FAM(RTM_NEWQDISC)] = TCA_MAX, 113 [RTM_FAM(RTM_NEWTCLASS)] = TCA_MAX, 114 [RTM_FAM(RTM_NEWTFILTER)] = TCA_MAX, 115 [RTM_FAM(RTM_NEWACTION)] = TCAA_MAX, 116 }; 117 118 void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data) 119 { 120 struct rtattr *rta; 121 int size = RTA_LENGTH(attrlen); 122 123 rta = (struct rtattr*)skb_put(skb, RTA_ALIGN(size)); 124 rta->rta_type = attrtype; 125 rta->rta_len = size; 126 memcpy(RTA_DATA(rta), data, attrlen); 127 } 128 129 size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size) 130 { 131 size_t ret = RTA_PAYLOAD(rta); 132 char *src = RTA_DATA(rta); 133 134 if (ret > 0 && src[ret - 1] == '\0') 135 ret--; 136 if (size > 0) { 137 size_t len = (ret >= size) ? size - 1 : ret; 138 memset(dest, 0, size); 139 memcpy(dest, src, len); 140 } 141 return ret; 142 } 143 144 int rtnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo) 145 { 146 int err = 0; 147 148 NETLINK_CB(skb).dst_groups = group; 149 if (echo) 150 atomic_inc(&skb->users); 151 netlink_broadcast(rtnl, skb, pid, group, GFP_KERNEL); 152 if (echo) 153 err = netlink_unicast(rtnl, skb, pid, MSG_DONTWAIT); 154 return err; 155 } 156 157 int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics) 158 { 159 struct rtattr *mx = (struct rtattr*)skb->tail; 160 int i; 161 162 RTA_PUT(skb, RTA_METRICS, 0, NULL); 163 for (i=0; i<RTAX_MAX; i++) { 164 if (metrics[i]) 165 RTA_PUT(skb, i+1, sizeof(u32), metrics+i); 166 } 167 mx->rta_len = skb->tail - (u8*)mx; 168 if (mx->rta_len == RTA_LENGTH(0)) 169 skb_trim(skb, (u8*)mx - skb->data); 170 return 0; 171 172 rtattr_failure: 173 skb_trim(skb, (u8*)mx - skb->data); 174 return -1; 175 } 176 177 178 static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, 179 int type, u32 pid, u32 seq, u32 change) 180 { 181 struct ifinfomsg *r; 182 struct nlmsghdr *nlh; 183 unsigned char *b = skb->tail; 184 185 nlh = NLMSG_PUT(skb, pid, seq, type, sizeof(*r)); 186 if (pid) nlh->nlmsg_flags |= NLM_F_MULTI; 187 r = NLMSG_DATA(nlh); 188 r->ifi_family = AF_UNSPEC; 189 r->ifi_type = dev->type; 190 r->ifi_index = dev->ifindex; 191 r->ifi_flags = dev_get_flags(dev); 192 r->ifi_change = change; 193 194 RTA_PUT(skb, IFLA_IFNAME, strlen(dev->name)+1, dev->name); 195 196 if (1) { 197 u32 txqlen = dev->tx_queue_len; 198 RTA_PUT(skb, IFLA_TXQLEN, sizeof(txqlen), &txqlen); 199 } 200 201 if (1) { 202 u32 weight = dev->weight; 203 RTA_PUT(skb, IFLA_WEIGHT, sizeof(weight), &weight); 204 } 205 206 if (1) { 207 struct rtnl_link_ifmap map = { 208 .mem_start = dev->mem_start, 209 .mem_end = dev->mem_end, 210 .base_addr = dev->base_addr, 211 .irq = dev->irq, 212 .dma = dev->dma, 213 .port = dev->if_port, 214 }; 215 RTA_PUT(skb, IFLA_MAP, sizeof(map), &map); 216 } 217 218 if (dev->addr_len) { 219 RTA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr); 220 RTA_PUT(skb, IFLA_BROADCAST, dev->addr_len, dev->broadcast); 221 } 222 223 if (1) { 224 u32 mtu = dev->mtu; 225 RTA_PUT(skb, IFLA_MTU, sizeof(mtu), &mtu); 226 } 227 228 if (dev->ifindex != dev->iflink) { 229 u32 iflink = dev->iflink; 230 RTA_PUT(skb, IFLA_LINK, sizeof(iflink), &iflink); 231 } 232 233 if (dev->qdisc_sleeping) 234 RTA_PUT(skb, IFLA_QDISC, 235 strlen(dev->qdisc_sleeping->ops->id) + 1, 236 dev->qdisc_sleeping->ops->id); 237 238 if (dev->master) { 239 u32 master = dev->master->ifindex; 240 RTA_PUT(skb, IFLA_MASTER, sizeof(master), &master); 241 } 242 243 if (dev->get_stats) { 244 unsigned long *stats = (unsigned long*)dev->get_stats(dev); 245 if (stats) { 246 struct rtattr *a; 247 __u32 *s; 248 int i; 249 int n = sizeof(struct rtnl_link_stats)/4; 250 251 a = __RTA_PUT(skb, IFLA_STATS, n*4); 252 s = RTA_DATA(a); 253 for (i=0; i<n; i++) 254 s[i] = stats[i]; 255 } 256 } 257 nlh->nlmsg_len = skb->tail - b; 258 return skb->len; 259 260 nlmsg_failure: 261 rtattr_failure: 262 skb_trim(skb, b - skb->data); 263 return -1; 264 } 265 266 static int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) 267 { 268 int idx; 269 int s_idx = cb->args[0]; 270 struct net_device *dev; 271 272 read_lock(&dev_base_lock); 273 for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { 274 if (idx < s_idx) 275 continue; 276 if (rtnetlink_fill_ifinfo(skb, dev, RTM_NEWLINK, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, 0) <= 0) 277 break; 278 } 279 read_unlock(&dev_base_lock); 280 cb->args[0] = idx; 281 282 return skb->len; 283 } 284 285 static int do_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 286 { 287 struct ifinfomsg *ifm = NLMSG_DATA(nlh); 288 struct rtattr **ida = arg; 289 struct net_device *dev; 290 int err, send_addr_notify = 0; 291 292 if (ifm->ifi_index >= 0) 293 dev = dev_get_by_index(ifm->ifi_index); 294 else if (ida[IFLA_IFNAME - 1]) { 295 char ifname[IFNAMSIZ]; 296 297 if (rtattr_strlcpy(ifname, ida[IFLA_IFNAME - 1], 298 IFNAMSIZ) >= IFNAMSIZ) 299 return -EINVAL; 300 dev = dev_get_by_name(ifname); 301 } else 302 return -EINVAL; 303 304 if (!dev) 305 return -ENODEV; 306 307 err = -EINVAL; 308 309 if (ifm->ifi_flags) 310 dev_change_flags(dev, ifm->ifi_flags); 311 312 if (ida[IFLA_MAP - 1]) { 313 struct rtnl_link_ifmap *u_map; 314 struct ifmap k_map; 315 316 if (!dev->set_config) { 317 err = -EOPNOTSUPP; 318 goto out; 319 } 320 321 if (!netif_device_present(dev)) { 322 err = -ENODEV; 323 goto out; 324 } 325 326 if (ida[IFLA_MAP - 1]->rta_len != RTA_LENGTH(sizeof(*u_map))) 327 goto out; 328 329 u_map = RTA_DATA(ida[IFLA_MAP - 1]); 330 331 k_map.mem_start = (unsigned long) u_map->mem_start; 332 k_map.mem_end = (unsigned long) u_map->mem_end; 333 k_map.base_addr = (unsigned short) u_map->base_addr; 334 k_map.irq = (unsigned char) u_map->irq; 335 k_map.dma = (unsigned char) u_map->dma; 336 k_map.port = (unsigned char) u_map->port; 337 338 err = dev->set_config(dev, &k_map); 339 340 if (err) 341 goto out; 342 } 343 344 if (ida[IFLA_ADDRESS - 1]) { 345 if (!dev->set_mac_address) { 346 err = -EOPNOTSUPP; 347 goto out; 348 } 349 if (!netif_device_present(dev)) { 350 err = -ENODEV; 351 goto out; 352 } 353 if (ida[IFLA_ADDRESS - 1]->rta_len != RTA_LENGTH(dev->addr_len)) 354 goto out; 355 356 err = dev->set_mac_address(dev, RTA_DATA(ida[IFLA_ADDRESS - 1])); 357 if (err) 358 goto out; 359 send_addr_notify = 1; 360 } 361 362 if (ida[IFLA_BROADCAST - 1]) { 363 if (ida[IFLA_BROADCAST - 1]->rta_len != RTA_LENGTH(dev->addr_len)) 364 goto out; 365 memcpy(dev->broadcast, RTA_DATA(ida[IFLA_BROADCAST - 1]), 366 dev->addr_len); 367 send_addr_notify = 1; 368 } 369 370 if (ida[IFLA_MTU - 1]) { 371 if (ida[IFLA_MTU - 1]->rta_len != RTA_LENGTH(sizeof(u32))) 372 goto out; 373 err = dev_set_mtu(dev, *((u32 *) RTA_DATA(ida[IFLA_MTU - 1]))); 374 375 if (err) 376 goto out; 377 378 } 379 380 if (ida[IFLA_TXQLEN - 1]) { 381 if (ida[IFLA_TXQLEN - 1]->rta_len != RTA_LENGTH(sizeof(u32))) 382 goto out; 383 384 dev->tx_queue_len = *((u32 *) RTA_DATA(ida[IFLA_TXQLEN - 1])); 385 } 386 387 if (ida[IFLA_WEIGHT - 1]) { 388 if (ida[IFLA_WEIGHT - 1]->rta_len != RTA_LENGTH(sizeof(u32))) 389 goto out; 390 391 dev->weight = *((u32 *) RTA_DATA(ida[IFLA_WEIGHT - 1])); 392 } 393 394 if (ifm->ifi_index >= 0 && ida[IFLA_IFNAME - 1]) { 395 char ifname[IFNAMSIZ]; 396 397 if (rtattr_strlcpy(ifname, ida[IFLA_IFNAME - 1], 398 IFNAMSIZ) >= IFNAMSIZ) 399 goto out; 400 err = dev_change_name(dev, ifname); 401 if (err) 402 goto out; 403 } 404 405 err = 0; 406 407 out: 408 if (send_addr_notify) 409 call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); 410 411 dev_put(dev); 412 return err; 413 } 414 415 static int rtnetlink_dump_all(struct sk_buff *skb, struct netlink_callback *cb) 416 { 417 int idx; 418 int s_idx = cb->family; 419 420 if (s_idx == 0) 421 s_idx = 1; 422 for (idx=1; idx<NPROTO; idx++) { 423 int type = cb->nlh->nlmsg_type-RTM_BASE; 424 if (idx < s_idx || idx == PF_PACKET) 425 continue; 426 if (rtnetlink_links[idx] == NULL || 427 rtnetlink_links[idx][type].dumpit == NULL) 428 continue; 429 if (idx > s_idx) 430 memset(&cb->args[0], 0, sizeof(cb->args)); 431 if (rtnetlink_links[idx][type].dumpit(skb, cb)) 432 break; 433 } 434 cb->family = idx; 435 436 return skb->len; 437 } 438 439 void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) 440 { 441 struct sk_buff *skb; 442 int size = NLMSG_SPACE(sizeof(struct ifinfomsg) + 443 sizeof(struct rtnl_link_ifmap) + 444 sizeof(struct rtnl_link_stats) + 128); 445 446 skb = alloc_skb(size, GFP_KERNEL); 447 if (!skb) 448 return; 449 450 if (rtnetlink_fill_ifinfo(skb, dev, type, 0, 0, change) < 0) { 451 kfree_skb(skb); 452 return; 453 } 454 NETLINK_CB(skb).dst_groups = RTMGRP_LINK; 455 netlink_broadcast(rtnl, skb, 0, RTMGRP_LINK, GFP_KERNEL); 456 } 457 458 static int rtnetlink_done(struct netlink_callback *cb) 459 { 460 return 0; 461 } 462 463 /* Protected by RTNL sempahore. */ 464 static struct rtattr **rta_buf; 465 static int rtattr_max; 466 467 /* Process one rtnetlink message. */ 468 469 static __inline__ int 470 rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) 471 { 472 struct rtnetlink_link *link; 473 struct rtnetlink_link *link_tab; 474 int sz_idx, kind; 475 int min_len; 476 int family; 477 int type; 478 int err; 479 480 /* Only requests are handled by kernel now */ 481 if (!(nlh->nlmsg_flags&NLM_F_REQUEST)) 482 return 0; 483 484 type = nlh->nlmsg_type; 485 486 /* A control message: ignore them */ 487 if (type < RTM_BASE) 488 return 0; 489 490 /* Unknown message: reply with EINVAL */ 491 if (type > RTM_MAX) 492 goto err_inval; 493 494 type -= RTM_BASE; 495 496 /* All the messages must have at least 1 byte length */ 497 if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(struct rtgenmsg))) 498 return 0; 499 500 family = ((struct rtgenmsg*)NLMSG_DATA(nlh))->rtgen_family; 501 if (family >= NPROTO) { 502 *errp = -EAFNOSUPPORT; 503 return -1; 504 } 505 506 link_tab = rtnetlink_links[family]; 507 if (link_tab == NULL) 508 link_tab = rtnetlink_links[PF_UNSPEC]; 509 link = &link_tab[type]; 510 511 sz_idx = type>>2; 512 kind = type&3; 513 514 if (kind != 2 && security_netlink_recv(skb)) { 515 *errp = -EPERM; 516 return -1; 517 } 518 519 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { 520 u32 rlen; 521 522 if (link->dumpit == NULL) 523 link = &(rtnetlink_links[PF_UNSPEC][type]); 524 525 if (link->dumpit == NULL) 526 goto err_inval; 527 528 if ((*errp = netlink_dump_start(rtnl, skb, nlh, 529 link->dumpit, 530 rtnetlink_done)) != 0) { 531 return -1; 532 } 533 rlen = NLMSG_ALIGN(nlh->nlmsg_len); 534 if (rlen > skb->len) 535 rlen = skb->len; 536 skb_pull(skb, rlen); 537 return -1; 538 } 539 540 memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *))); 541 542 min_len = rtm_min[sz_idx]; 543 if (nlh->nlmsg_len < min_len) 544 goto err_inval; 545 546 if (nlh->nlmsg_len > min_len) { 547 int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); 548 struct rtattr *attr = (void*)nlh + NLMSG_ALIGN(min_len); 549 550 while (RTA_OK(attr, attrlen)) { 551 unsigned flavor = attr->rta_type; 552 if (flavor) { 553 if (flavor > rta_max[sz_idx]) 554 goto err_inval; 555 rta_buf[flavor-1] = attr; 556 } 557 attr = RTA_NEXT(attr, attrlen); 558 } 559 } 560 561 if (link->doit == NULL) 562 link = &(rtnetlink_links[PF_UNSPEC][type]); 563 if (link->doit == NULL) 564 goto err_inval; 565 err = link->doit(skb, nlh, (void *)&rta_buf[0]); 566 567 *errp = err; 568 return err; 569 570 err_inval: 571 *errp = -EINVAL; 572 return -1; 573 } 574 575 /* 576 * Process one packet of messages. 577 * Malformed skbs with wrong lengths of messages are discarded silently. 578 */ 579 580 static inline int rtnetlink_rcv_skb(struct sk_buff *skb) 581 { 582 int err; 583 struct nlmsghdr * nlh; 584 585 while (skb->len >= NLMSG_SPACE(0)) { 586 u32 rlen; 587 588 nlh = (struct nlmsghdr *)skb->data; 589 if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) 590 return 0; 591 rlen = NLMSG_ALIGN(nlh->nlmsg_len); 592 if (rlen > skb->len) 593 rlen = skb->len; 594 if (rtnetlink_rcv_msg(skb, nlh, &err)) { 595 /* Not error, but we must interrupt processing here: 596 * Note, that in this case we do not pull message 597 * from skb, it will be processed later. 598 */ 599 if (err == 0) 600 return -1; 601 netlink_ack(skb, nlh, err); 602 } else if (nlh->nlmsg_flags&NLM_F_ACK) 603 netlink_ack(skb, nlh, 0); 604 skb_pull(skb, rlen); 605 } 606 607 return 0; 608 } 609 610 /* 611 * rtnetlink input queue processing routine: 612 * - process as much as there was in the queue upon entry. 613 * - feed skbs to rtnetlink_rcv_skb, until it refuse a message, 614 * that will occur, when a dump started. 615 */ 616 617 static void rtnetlink_rcv(struct sock *sk, int len) 618 { 619 unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); 620 621 do { 622 struct sk_buff *skb; 623 624 rtnl_lock(); 625 626 if (qlen > skb_queue_len(&sk->sk_receive_queue)) 627 qlen = skb_queue_len(&sk->sk_receive_queue); 628 629 while (qlen--) { 630 skb = skb_dequeue(&sk->sk_receive_queue); 631 if (rtnetlink_rcv_skb(skb)) { 632 if (skb->len) { 633 skb_queue_head(&sk->sk_receive_queue, 634 skb); 635 qlen++; 636 } else 637 kfree_skb(skb); 638 break; 639 } 640 kfree_skb(skb); 641 } 642 643 up(&rtnl_sem); 644 645 netdev_run_todo(); 646 } while (qlen); 647 } 648 649 static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] = 650 { 651 [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo }, 652 [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink }, 653 [RTM_GETADDR - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, 654 [RTM_GETROUTE - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, 655 [RTM_NEWNEIGH - RTM_BASE] = { .doit = neigh_add }, 656 [RTM_DELNEIGH - RTM_BASE] = { .doit = neigh_delete }, 657 [RTM_GETNEIGH - RTM_BASE] = { .dumpit = neigh_dump_info }, 658 [RTM_GETRULE - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, 659 }; 660 661 static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr) 662 { 663 struct net_device *dev = ptr; 664 switch (event) { 665 case NETDEV_UNREGISTER: 666 rtmsg_ifinfo(RTM_DELLINK, dev, ~0U); 667 break; 668 case NETDEV_REGISTER: 669 rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); 670 break; 671 case NETDEV_UP: 672 case NETDEV_DOWN: 673 rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); 674 break; 675 case NETDEV_CHANGE: 676 case NETDEV_GOING_DOWN: 677 break; 678 default: 679 rtmsg_ifinfo(RTM_NEWLINK, dev, 0); 680 break; 681 } 682 return NOTIFY_DONE; 683 } 684 685 static struct notifier_block rtnetlink_dev_notifier = { 686 .notifier_call = rtnetlink_event, 687 }; 688 689 void __init rtnetlink_init(void) 690 { 691 int i; 692 693 rtattr_max = 0; 694 for (i = 0; i < ARRAY_SIZE(rta_max); i++) 695 if (rta_max[i] > rtattr_max) 696 rtattr_max = rta_max[i]; 697 rta_buf = kmalloc(rtattr_max * sizeof(struct rtattr *), GFP_KERNEL); 698 if (!rta_buf) 699 panic("rtnetlink_init: cannot allocate rta_buf\n"); 700 701 rtnl = netlink_kernel_create(NETLINK_ROUTE, rtnetlink_rcv); 702 if (rtnl == NULL) 703 panic("rtnetlink_init: cannot initialize rtnetlink\n"); 704 netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV); 705 register_netdevice_notifier(&rtnetlink_dev_notifier); 706 rtnetlink_links[PF_UNSPEC] = link_rtnetlink_table; 707 rtnetlink_links[PF_PACKET] = link_rtnetlink_table; 708 } 709 710 EXPORT_SYMBOL(__rta_fill); 711 EXPORT_SYMBOL(rtattr_strlcpy); 712 EXPORT_SYMBOL(rtattr_parse); 713 EXPORT_SYMBOL(rtnetlink_links); 714 EXPORT_SYMBOL(rtnetlink_put_metrics); 715 EXPORT_SYMBOL(rtnl); 716 EXPORT_SYMBOL(rtnl_lock); 717 EXPORT_SYMBOL(rtnl_lock_interruptible); 718 EXPORT_SYMBOL(rtnl_sem); 719 EXPORT_SYMBOL(rtnl_unlock); 720