at v2.6.19-rc3 857 lines 21 kB view raw
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/errno.h> 20#include <linux/module.h> 21#include <linux/types.h> 22#include <linux/socket.h> 23#include <linux/kernel.h> 24#include <linux/sched.h> 25#include <linux/timer.h> 26#include <linux/string.h> 27#include <linux/sockios.h> 28#include <linux/net.h> 29#include <linux/fcntl.h> 30#include <linux/mm.h> 31#include <linux/slab.h> 32#include <linux/interrupt.h> 33#include <linux/capability.h> 34#include <linux/skbuff.h> 35#include <linux/init.h> 36#include <linux/security.h> 37#include <linux/mutex.h> 38#include <linux/if_addr.h> 39 40#include <asm/uaccess.h> 41#include <asm/system.h> 42#include <asm/string.h> 43 44#include <linux/inet.h> 45#include <linux/netdevice.h> 46#include <net/ip.h> 47#include <net/protocol.h> 48#include <net/arp.h> 49#include <net/route.h> 50#include <net/udp.h> 51#include <net/sock.h> 52#include <net/pkt_sched.h> 53#include <net/fib_rules.h> 54#include <net/netlink.h> 55#ifdef CONFIG_NET_WIRELESS_RTNETLINK 56#include <linux/wireless.h> 57#include <net/iw_handler.h> 58#endif /* CONFIG_NET_WIRELESS_RTNETLINK */ 59 60static DEFINE_MUTEX(rtnl_mutex); 61static struct sock *rtnl; 62 63void rtnl_lock(void) 64{ 65 mutex_lock(&rtnl_mutex); 66} 67 68void __rtnl_unlock(void) 69{ 70 mutex_unlock(&rtnl_mutex); 71} 72 73void rtnl_unlock(void) 74{ 75 mutex_unlock(&rtnl_mutex); 76 if (rtnl && rtnl->sk_receive_queue.qlen) 77 rtnl->sk_data_ready(rtnl, 0); 78 netdev_run_todo(); 79} 80 81int rtnl_trylock(void) 82{ 83 return mutex_trylock(&rtnl_mutex); 84} 85 86int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len) 87{ 88 memset(tb, 0, sizeof(struct rtattr*)*maxattr); 89 90 while (RTA_OK(rta, len)) { 91 unsigned flavor = rta->rta_type; 92 if (flavor && flavor <= maxattr) 93 tb[flavor-1] = rta; 94 rta = RTA_NEXT(rta, len); 95 } 96 return 0; 97} 98 99struct rtnetlink_link * rtnetlink_links[NPROTO]; 100 101static const int rtm_min[RTM_NR_FAMILIES] = 102{ 103 [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)), 104 [RTM_FAM(RTM_NEWADDR)] = NLMSG_LENGTH(sizeof(struct ifaddrmsg)), 105 [RTM_FAM(RTM_NEWROUTE)] = NLMSG_LENGTH(sizeof(struct rtmsg)), 106 [RTM_FAM(RTM_NEWRULE)] = NLMSG_LENGTH(sizeof(struct fib_rule_hdr)), 107 [RTM_FAM(RTM_NEWQDISC)] = NLMSG_LENGTH(sizeof(struct tcmsg)), 108 [RTM_FAM(RTM_NEWTCLASS)] = NLMSG_LENGTH(sizeof(struct tcmsg)), 109 [RTM_FAM(RTM_NEWTFILTER)] = NLMSG_LENGTH(sizeof(struct tcmsg)), 110 [RTM_FAM(RTM_NEWACTION)] = NLMSG_LENGTH(sizeof(struct tcamsg)), 111 [RTM_FAM(RTM_NEWPREFIX)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), 112 [RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), 113 [RTM_FAM(RTM_GETANYCAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), 114}; 115 116static const int rta_max[RTM_NR_FAMILIES] = 117{ 118 [RTM_FAM(RTM_NEWLINK)] = IFLA_MAX, 119 [RTM_FAM(RTM_NEWADDR)] = IFA_MAX, 120 [RTM_FAM(RTM_NEWROUTE)] = RTA_MAX, 121 [RTM_FAM(RTM_NEWRULE)] = FRA_MAX, 122 [RTM_FAM(RTM_NEWQDISC)] = TCA_MAX, 123 [RTM_FAM(RTM_NEWTCLASS)] = TCA_MAX, 124 [RTM_FAM(RTM_NEWTFILTER)] = TCA_MAX, 125 [RTM_FAM(RTM_NEWACTION)] = TCAA_MAX, 126}; 127 128void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data) 129{ 130 struct rtattr *rta; 131 int size = RTA_LENGTH(attrlen); 132 133 rta = (struct rtattr*)skb_put(skb, RTA_ALIGN(size)); 134 rta->rta_type = attrtype; 135 rta->rta_len = size; 136 memcpy(RTA_DATA(rta), data, attrlen); 137 memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size); 138} 139 140size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size) 141{ 142 size_t ret = RTA_PAYLOAD(rta); 143 char *src = RTA_DATA(rta); 144 145 if (ret > 0 && src[ret - 1] == '\0') 146 ret--; 147 if (size > 0) { 148 size_t len = (ret >= size) ? size - 1 : ret; 149 memset(dest, 0, size); 150 memcpy(dest, src, len); 151 } 152 return ret; 153} 154 155int rtnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo) 156{ 157 int err = 0; 158 159 NETLINK_CB(skb).dst_group = group; 160 if (echo) 161 atomic_inc(&skb->users); 162 netlink_broadcast(rtnl, skb, pid, group, GFP_KERNEL); 163 if (echo) 164 err = netlink_unicast(rtnl, skb, pid, MSG_DONTWAIT); 165 return err; 166} 167 168int rtnl_unicast(struct sk_buff *skb, u32 pid) 169{ 170 return nlmsg_unicast(rtnl, skb, pid); 171} 172 173int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group, 174 struct nlmsghdr *nlh, gfp_t flags) 175{ 176 int report = 0; 177 178 if (nlh) 179 report = nlmsg_report(nlh); 180 181 return nlmsg_notify(rtnl, skb, pid, group, report, flags); 182} 183 184void rtnl_set_sk_err(u32 group, int error) 185{ 186 netlink_set_err(rtnl, 0, group, error); 187} 188 189int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics) 190{ 191 struct nlattr *mx; 192 int i, valid = 0; 193 194 mx = nla_nest_start(skb, RTA_METRICS); 195 if (mx == NULL) 196 return -ENOBUFS; 197 198 for (i = 0; i < RTAX_MAX; i++) { 199 if (metrics[i]) { 200 valid++; 201 NLA_PUT_U32(skb, i+1, metrics[i]); 202 } 203 } 204 205 if (!valid) { 206 nla_nest_cancel(skb, mx); 207 return 0; 208 } 209 210 return nla_nest_end(skb, mx); 211 212nla_put_failure: 213 return nla_nest_cancel(skb, mx); 214} 215 216 217static void set_operstate(struct net_device *dev, unsigned char transition) 218{ 219 unsigned char operstate = dev->operstate; 220 221 switch(transition) { 222 case IF_OPER_UP: 223 if ((operstate == IF_OPER_DORMANT || 224 operstate == IF_OPER_UNKNOWN) && 225 !netif_dormant(dev)) 226 operstate = IF_OPER_UP; 227 break; 228 229 case IF_OPER_DORMANT: 230 if (operstate == IF_OPER_UP || 231 operstate == IF_OPER_UNKNOWN) 232 operstate = IF_OPER_DORMANT; 233 break; 234 }; 235 236 if (dev->operstate != operstate) { 237 write_lock_bh(&dev_base_lock); 238 dev->operstate = operstate; 239 write_unlock_bh(&dev_base_lock); 240 netdev_state_change(dev); 241 } 242} 243 244static void copy_rtnl_link_stats(struct rtnl_link_stats *a, 245 struct net_device_stats *b) 246{ 247 a->rx_packets = b->rx_packets; 248 a->tx_packets = b->tx_packets; 249 a->rx_bytes = b->rx_bytes; 250 a->tx_bytes = b->tx_bytes; 251 a->rx_errors = b->rx_errors; 252 a->tx_errors = b->tx_errors; 253 a->rx_dropped = b->rx_dropped; 254 a->tx_dropped = b->tx_dropped; 255 256 a->multicast = b->multicast; 257 a->collisions = b->collisions; 258 259 a->rx_length_errors = b->rx_length_errors; 260 a->rx_over_errors = b->rx_over_errors; 261 a->rx_crc_errors = b->rx_crc_errors; 262 a->rx_frame_errors = b->rx_frame_errors; 263 a->rx_fifo_errors = b->rx_fifo_errors; 264 a->rx_missed_errors = b->rx_missed_errors; 265 266 a->tx_aborted_errors = b->tx_aborted_errors; 267 a->tx_carrier_errors = b->tx_carrier_errors; 268 a->tx_fifo_errors = b->tx_fifo_errors; 269 a->tx_heartbeat_errors = b->tx_heartbeat_errors; 270 a->tx_window_errors = b->tx_window_errors; 271 272 a->rx_compressed = b->rx_compressed; 273 a->tx_compressed = b->tx_compressed; 274}; 275 276static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, 277 void *iwbuf, int iwbuflen, int type, u32 pid, 278 u32 seq, u32 change, unsigned int flags) 279{ 280 struct ifinfomsg *ifm; 281 struct nlmsghdr *nlh; 282 283 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags); 284 if (nlh == NULL) 285 return -ENOBUFS; 286 287 ifm = nlmsg_data(nlh); 288 ifm->ifi_family = AF_UNSPEC; 289 ifm->__ifi_pad = 0; 290 ifm->ifi_type = dev->type; 291 ifm->ifi_index = dev->ifindex; 292 ifm->ifi_flags = dev_get_flags(dev); 293 ifm->ifi_change = change; 294 295 NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name); 296 NLA_PUT_U32(skb, IFLA_TXQLEN, dev->tx_queue_len); 297 NLA_PUT_U32(skb, IFLA_WEIGHT, dev->weight); 298 NLA_PUT_U8(skb, IFLA_OPERSTATE, 299 netif_running(dev) ? dev->operstate : IF_OPER_DOWN); 300 NLA_PUT_U8(skb, IFLA_LINKMODE, dev->link_mode); 301 NLA_PUT_U32(skb, IFLA_MTU, dev->mtu); 302 303 if (dev->ifindex != dev->iflink) 304 NLA_PUT_U32(skb, IFLA_LINK, dev->iflink); 305 306 if (dev->master) 307 NLA_PUT_U32(skb, IFLA_MASTER, dev->master->ifindex); 308 309 if (dev->qdisc_sleeping) 310 NLA_PUT_STRING(skb, IFLA_QDISC, dev->qdisc_sleeping->ops->id); 311 312 if (1) { 313 struct rtnl_link_ifmap map = { 314 .mem_start = dev->mem_start, 315 .mem_end = dev->mem_end, 316 .base_addr = dev->base_addr, 317 .irq = dev->irq, 318 .dma = dev->dma, 319 .port = dev->if_port, 320 }; 321 NLA_PUT(skb, IFLA_MAP, sizeof(map), &map); 322 } 323 324 if (dev->addr_len) { 325 NLA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr); 326 NLA_PUT(skb, IFLA_BROADCAST, dev->addr_len, dev->broadcast); 327 } 328 329 if (dev->get_stats) { 330 struct net_device_stats *stats = dev->get_stats(dev); 331 if (stats) { 332 struct nlattr *attr; 333 334 attr = nla_reserve(skb, IFLA_STATS, 335 sizeof(struct rtnl_link_stats)); 336 if (attr == NULL) 337 goto nla_put_failure; 338 339 copy_rtnl_link_stats(nla_data(attr), stats); 340 } 341 } 342 343 if (iwbuf) 344 NLA_PUT(skb, IFLA_WIRELESS, iwbuflen, iwbuf); 345 346 return nlmsg_end(skb, nlh); 347 348nla_put_failure: 349 return nlmsg_cancel(skb, nlh); 350} 351 352static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) 353{ 354 int idx; 355 int s_idx = cb->args[0]; 356 struct net_device *dev; 357 358 read_lock(&dev_base_lock); 359 for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { 360 if (idx < s_idx) 361 continue; 362 if (rtnl_fill_ifinfo(skb, dev, NULL, 0, RTM_NEWLINK, 363 NETLINK_CB(cb->skb).pid, 364 cb->nlh->nlmsg_seq, 0, NLM_F_MULTI) <= 0) 365 break; 366 } 367 read_unlock(&dev_base_lock); 368 cb->args[0] = idx; 369 370 return skb->len; 371} 372 373static struct nla_policy ifla_policy[IFLA_MAX+1] __read_mostly = { 374 [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 }, 375 [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, 376 [IFLA_MTU] = { .type = NLA_U32 }, 377 [IFLA_TXQLEN] = { .type = NLA_U32 }, 378 [IFLA_WEIGHT] = { .type = NLA_U32 }, 379 [IFLA_OPERSTATE] = { .type = NLA_U8 }, 380 [IFLA_LINKMODE] = { .type = NLA_U8 }, 381}; 382 383static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 384{ 385 struct ifinfomsg *ifm; 386 struct net_device *dev; 387 int err, send_addr_notify = 0, modified = 0; 388 struct nlattr *tb[IFLA_MAX+1]; 389 char ifname[IFNAMSIZ]; 390 391 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); 392 if (err < 0) 393 goto errout; 394 395 if (tb[IFLA_IFNAME]) 396 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); 397 else 398 ifname[0] = '\0'; 399 400 err = -EINVAL; 401 ifm = nlmsg_data(nlh); 402 if (ifm->ifi_index >= 0) 403 dev = dev_get_by_index(ifm->ifi_index); 404 else if (tb[IFLA_IFNAME]) 405 dev = dev_get_by_name(ifname); 406 else 407 goto errout; 408 409 if (dev == NULL) { 410 err = -ENODEV; 411 goto errout; 412 } 413 414 if (tb[IFLA_ADDRESS] && 415 nla_len(tb[IFLA_ADDRESS]) < dev->addr_len) 416 goto errout_dev; 417 418 if (tb[IFLA_BROADCAST] && 419 nla_len(tb[IFLA_BROADCAST]) < dev->addr_len) 420 goto errout_dev; 421 422 if (tb[IFLA_MAP]) { 423 struct rtnl_link_ifmap *u_map; 424 struct ifmap k_map; 425 426 if (!dev->set_config) { 427 err = -EOPNOTSUPP; 428 goto errout_dev; 429 } 430 431 if (!netif_device_present(dev)) { 432 err = -ENODEV; 433 goto errout_dev; 434 } 435 436 u_map = nla_data(tb[IFLA_MAP]); 437 k_map.mem_start = (unsigned long) u_map->mem_start; 438 k_map.mem_end = (unsigned long) u_map->mem_end; 439 k_map.base_addr = (unsigned short) u_map->base_addr; 440 k_map.irq = (unsigned char) u_map->irq; 441 k_map.dma = (unsigned char) u_map->dma; 442 k_map.port = (unsigned char) u_map->port; 443 444 err = dev->set_config(dev, &k_map); 445 if (err < 0) 446 goto errout_dev; 447 448 modified = 1; 449 } 450 451 if (tb[IFLA_ADDRESS]) { 452 struct sockaddr *sa; 453 int len; 454 455 if (!dev->set_mac_address) { 456 err = -EOPNOTSUPP; 457 goto errout_dev; 458 } 459 460 if (!netif_device_present(dev)) { 461 err = -ENODEV; 462 goto errout_dev; 463 } 464 465 len = sizeof(sa_family_t) + dev->addr_len; 466 sa = kmalloc(len, GFP_KERNEL); 467 if (!sa) { 468 err = -ENOMEM; 469 goto errout_dev; 470 } 471 sa->sa_family = dev->type; 472 memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]), 473 dev->addr_len); 474 err = dev->set_mac_address(dev, sa); 475 kfree(sa); 476 if (err) 477 goto errout_dev; 478 send_addr_notify = 1; 479 modified = 1; 480 } 481 482 if (tb[IFLA_MTU]) { 483 err = dev_set_mtu(dev, nla_get_u32(tb[IFLA_MTU])); 484 if (err < 0) 485 goto errout_dev; 486 modified = 1; 487 } 488 489 /* 490 * Interface selected by interface index but interface 491 * name provided implies that a name change has been 492 * requested. 493 */ 494 if (ifm->ifi_index >= 0 && ifname[0]) { 495 err = dev_change_name(dev, ifname); 496 if (err < 0) 497 goto errout_dev; 498 modified = 1; 499 } 500 501#ifdef CONFIG_NET_WIRELESS_RTNETLINK 502 if (tb[IFLA_WIRELESS]) { 503 /* Call Wireless Extensions. 504 * Various stuff checked in there... */ 505 err = wireless_rtnetlink_set(dev, nla_data(tb[IFLA_WIRELESS]), 506 nla_len(tb[IFLA_WIRELESS])); 507 if (err < 0) 508 goto errout_dev; 509 } 510#endif /* CONFIG_NET_WIRELESS_RTNETLINK */ 511 512 if (tb[IFLA_BROADCAST]) { 513 nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len); 514 send_addr_notify = 1; 515 } 516 517 518 if (ifm->ifi_flags) 519 dev_change_flags(dev, ifm->ifi_flags); 520 521 if (tb[IFLA_TXQLEN]) 522 dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]); 523 524 if (tb[IFLA_WEIGHT]) 525 dev->weight = nla_get_u32(tb[IFLA_WEIGHT]); 526 527 if (tb[IFLA_OPERSTATE]) 528 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE])); 529 530 if (tb[IFLA_LINKMODE]) { 531 write_lock_bh(&dev_base_lock); 532 dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]); 533 write_unlock_bh(&dev_base_lock); 534 } 535 536 err = 0; 537 538errout_dev: 539 if (err < 0 && modified && net_ratelimit()) 540 printk(KERN_WARNING "A link change request failed with " 541 "some changes comitted already. Interface %s may " 542 "have been left with an inconsistent configuration, " 543 "please check.\n", dev->name); 544 545 if (send_addr_notify) 546 call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); 547 548 dev_put(dev); 549errout: 550 return err; 551} 552 553static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) 554{ 555 struct ifinfomsg *ifm; 556 struct nlattr *tb[IFLA_MAX+1]; 557 struct net_device *dev = NULL; 558 struct sk_buff *nskb; 559 char *iw_buf = NULL, *iw = NULL; 560 int iw_buf_len = 0; 561 int err, payload; 562 563 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); 564 if (err < 0) 565 return err; 566 567 ifm = nlmsg_data(nlh); 568 if (ifm->ifi_index >= 0) { 569 dev = dev_get_by_index(ifm->ifi_index); 570 if (dev == NULL) 571 return -ENODEV; 572 } else 573 return -EINVAL; 574 575 576#ifdef CONFIG_NET_WIRELESS_RTNETLINK 577 if (tb[IFLA_WIRELESS]) { 578 /* Call Wireless Extensions. We need to know the size before 579 * we can alloc. Various stuff checked in there... */ 580 err = wireless_rtnetlink_get(dev, nla_data(tb[IFLA_WIRELESS]), 581 nla_len(tb[IFLA_WIRELESS]), 582 &iw_buf, &iw_buf_len); 583 if (err < 0) 584 goto errout; 585 586 iw += IW_EV_POINT_OFF; 587 } 588#endif /* CONFIG_NET_WIRELESS_RTNETLINK */ 589 590 payload = NLMSG_ALIGN(sizeof(struct ifinfomsg) + 591 nla_total_size(iw_buf_len)); 592 nskb = nlmsg_new(nlmsg_total_size(payload), GFP_KERNEL); 593 if (nskb == NULL) { 594 err = -ENOBUFS; 595 goto errout; 596 } 597 598 err = rtnl_fill_ifinfo(nskb, dev, iw, iw_buf_len, RTM_NEWLINK, 599 NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, 0); 600 if (err <= 0) { 601 kfree_skb(nskb); 602 goto errout; 603 } 604 605 err = rtnl_unicast(nskb, NETLINK_CB(skb).pid); 606errout: 607 kfree(iw_buf); 608 dev_put(dev); 609 610 return err; 611} 612 613static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb) 614{ 615 int idx; 616 int s_idx = cb->family; 617 618 if (s_idx == 0) 619 s_idx = 1; 620 for (idx=1; idx<NPROTO; idx++) { 621 int type = cb->nlh->nlmsg_type-RTM_BASE; 622 if (idx < s_idx || idx == PF_PACKET) 623 continue; 624 if (rtnetlink_links[idx] == NULL || 625 rtnetlink_links[idx][type].dumpit == NULL) 626 continue; 627 if (idx > s_idx) 628 memset(&cb->args[0], 0, sizeof(cb->args)); 629 if (rtnetlink_links[idx][type].dumpit(skb, cb)) 630 break; 631 } 632 cb->family = idx; 633 634 return skb->len; 635} 636 637void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change) 638{ 639 struct sk_buff *skb; 640 int err = -ENOBUFS; 641 642 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 643 if (skb == NULL) 644 goto errout; 645 646 err = rtnl_fill_ifinfo(skb, dev, NULL, 0, type, 0, 0, change, 0); 647 if (err < 0) { 648 kfree_skb(skb); 649 goto errout; 650 } 651 652 err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_KERNEL); 653errout: 654 if (err < 0) 655 rtnl_set_sk_err(RTNLGRP_LINK, err); 656} 657 658/* Protected by RTNL sempahore. */ 659static struct rtattr **rta_buf; 660static int rtattr_max; 661 662/* Process one rtnetlink message. */ 663 664static __inline__ int 665rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) 666{ 667 struct rtnetlink_link *link; 668 struct rtnetlink_link *link_tab; 669 int sz_idx, kind; 670 int min_len; 671 int family; 672 int type; 673 int err; 674 675 /* Only requests are handled by kernel now */ 676 if (!(nlh->nlmsg_flags&NLM_F_REQUEST)) 677 return 0; 678 679 type = nlh->nlmsg_type; 680 681 /* A control message: ignore them */ 682 if (type < RTM_BASE) 683 return 0; 684 685 /* Unknown message: reply with EINVAL */ 686 if (type > RTM_MAX) 687 goto err_inval; 688 689 type -= RTM_BASE; 690 691 /* All the messages must have at least 1 byte length */ 692 if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(struct rtgenmsg))) 693 return 0; 694 695 family = ((struct rtgenmsg*)NLMSG_DATA(nlh))->rtgen_family; 696 if (family >= NPROTO) { 697 *errp = -EAFNOSUPPORT; 698 return -1; 699 } 700 701 link_tab = rtnetlink_links[family]; 702 if (link_tab == NULL) 703 link_tab = rtnetlink_links[PF_UNSPEC]; 704 link = &link_tab[type]; 705 706 sz_idx = type>>2; 707 kind = type&3; 708 709 if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN)) { 710 *errp = -EPERM; 711 return -1; 712 } 713 714 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { 715 if (link->dumpit == NULL) 716 link = &(rtnetlink_links[PF_UNSPEC][type]); 717 718 if (link->dumpit == NULL) 719 goto err_inval; 720 721 if ((*errp = netlink_dump_start(rtnl, skb, nlh, 722 link->dumpit, NULL)) != 0) { 723 return -1; 724 } 725 726 netlink_queue_skip(nlh, skb); 727 return -1; 728 } 729 730 memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *))); 731 732 min_len = rtm_min[sz_idx]; 733 if (nlh->nlmsg_len < min_len) 734 goto err_inval; 735 736 if (nlh->nlmsg_len > min_len) { 737 int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); 738 struct rtattr *attr = (void*)nlh + NLMSG_ALIGN(min_len); 739 740 while (RTA_OK(attr, attrlen)) { 741 unsigned flavor = attr->rta_type; 742 if (flavor) { 743 if (flavor > rta_max[sz_idx]) 744 goto err_inval; 745 rta_buf[flavor-1] = attr; 746 } 747 attr = RTA_NEXT(attr, attrlen); 748 } 749 } 750 751 if (link->doit == NULL) 752 link = &(rtnetlink_links[PF_UNSPEC][type]); 753 if (link->doit == NULL) 754 goto err_inval; 755 err = link->doit(skb, nlh, (void *)&rta_buf[0]); 756 757 *errp = err; 758 return err; 759 760err_inval: 761 *errp = -EINVAL; 762 return -1; 763} 764 765static void rtnetlink_rcv(struct sock *sk, int len) 766{ 767 unsigned int qlen = 0; 768 769 do { 770 mutex_lock(&rtnl_mutex); 771 netlink_run_queue(sk, &qlen, &rtnetlink_rcv_msg); 772 mutex_unlock(&rtnl_mutex); 773 774 netdev_run_todo(); 775 } while (qlen); 776} 777 778static struct rtnetlink_link link_rtnetlink_table[RTM_NR_MSGTYPES] = 779{ 780 [RTM_GETLINK - RTM_BASE] = { .doit = rtnl_getlink, 781 .dumpit = rtnl_dump_ifinfo }, 782 [RTM_SETLINK - RTM_BASE] = { .doit = rtnl_setlink }, 783 [RTM_GETADDR - RTM_BASE] = { .dumpit = rtnl_dump_all }, 784 [RTM_GETROUTE - RTM_BASE] = { .dumpit = rtnl_dump_all }, 785 [RTM_NEWNEIGH - RTM_BASE] = { .doit = neigh_add }, 786 [RTM_DELNEIGH - RTM_BASE] = { .doit = neigh_delete }, 787 [RTM_GETNEIGH - RTM_BASE] = { .dumpit = neigh_dump_info }, 788#ifdef CONFIG_FIB_RULES 789 [RTM_NEWRULE - RTM_BASE] = { .doit = fib_nl_newrule }, 790 [RTM_DELRULE - RTM_BASE] = { .doit = fib_nl_delrule }, 791#endif 792 [RTM_GETRULE - RTM_BASE] = { .dumpit = rtnl_dump_all }, 793 [RTM_GETNEIGHTBL - RTM_BASE] = { .dumpit = neightbl_dump_info }, 794 [RTM_SETNEIGHTBL - RTM_BASE] = { .doit = neightbl_set }, 795}; 796 797static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr) 798{ 799 struct net_device *dev = ptr; 800 switch (event) { 801 case NETDEV_UNREGISTER: 802 rtmsg_ifinfo(RTM_DELLINK, dev, ~0U); 803 break; 804 case NETDEV_REGISTER: 805 rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); 806 break; 807 case NETDEV_UP: 808 case NETDEV_DOWN: 809 rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); 810 break; 811 case NETDEV_CHANGE: 812 case NETDEV_GOING_DOWN: 813 break; 814 default: 815 rtmsg_ifinfo(RTM_NEWLINK, dev, 0); 816 break; 817 } 818 return NOTIFY_DONE; 819} 820 821static struct notifier_block rtnetlink_dev_notifier = { 822 .notifier_call = rtnetlink_event, 823}; 824 825void __init rtnetlink_init(void) 826{ 827 int i; 828 829 rtattr_max = 0; 830 for (i = 0; i < ARRAY_SIZE(rta_max); i++) 831 if (rta_max[i] > rtattr_max) 832 rtattr_max = rta_max[i]; 833 rta_buf = kmalloc(rtattr_max * sizeof(struct rtattr *), GFP_KERNEL); 834 if (!rta_buf) 835 panic("rtnetlink_init: cannot allocate rta_buf\n"); 836 837 rtnl = netlink_kernel_create(NETLINK_ROUTE, RTNLGRP_MAX, rtnetlink_rcv, 838 THIS_MODULE); 839 if (rtnl == NULL) 840 panic("rtnetlink_init: cannot initialize rtnetlink\n"); 841 netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV); 842 register_netdevice_notifier(&rtnetlink_dev_notifier); 843 rtnetlink_links[PF_UNSPEC] = link_rtnetlink_table; 844 rtnetlink_links[PF_PACKET] = link_rtnetlink_table; 845} 846 847EXPORT_SYMBOL(__rta_fill); 848EXPORT_SYMBOL(rtattr_strlcpy); 849EXPORT_SYMBOL(rtattr_parse); 850EXPORT_SYMBOL(rtnetlink_links); 851EXPORT_SYMBOL(rtnetlink_put_metrics); 852EXPORT_SYMBOL(rtnl_lock); 853EXPORT_SYMBOL(rtnl_trylock); 854EXPORT_SYMBOL(rtnl_unlock); 855EXPORT_SYMBOL(rtnl_unicast); 856EXPORT_SYMBOL(rtnl_notify); 857EXPORT_SYMBOL(rtnl_set_sk_err);