00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <linux/errno.h>
00020 #include <linux/module.h>
00021 #include <linux/types.h>
00022 #include <linux/socket.h>
00023 #include <linux/kernel.h>
00024 #include <linux/timer.h>
00025 #include <linux/string.h>
00026 #include <linux/sockios.h>
00027 #include <linux/net.h>
00028 #include <linux/fcntl.h>
00029 #include <linux/mm.h>
00030 #include <linux/slab.h>
00031 #include <linux/interrupt.h>
00032 #include <linux/capability.h>
00033 #include <linux/skbuff.h>
00034 #include <linux/init.h>
00035 #include <linux/security.h>
00036 #include <linux/mutex.h>
00037 #include <linux/if_addr.h>
00038 #include <linux/nsproxy.h>
00039
00040 #include <asm/uaccess.h>
00041 #include <asm/system.h>
00042 #include <asm/string.h>
00043
00044 #include <linux/inet.h>
00045 #include <linux/netdevice.h>
00046 #include <net/ip.h>
00047 #include <net/protocol.h>
00048 #include <net/arp.h>
00049 #include <net/route.h>
00050 #include <net/udp.h>
00051 #include <net/sock.h>
00052 #include <net/pkt_sched.h>
00053 #include <net/fib_rules.h>
00054 #include <net/rtnetlink.h>
00055
00056 struct rtnl_link
00057 {
00058 rtnl_doit_func doit;
00059 rtnl_dumpit_func dumpit;
00060 };
00061
00062 static DEFINE_MUTEX(rtnl_mutex);
00063
00064 void rtnl_lock(void)
00065 {
00066 mutex_lock(&rtnl_mutex);
00067 }
00068
00069 void __rtnl_unlock(void)
00070 {
00071 mutex_unlock(&rtnl_mutex);
00072 }
00073
00074 void rtnl_unlock(void)
00075 {
00076
00077 netdev_run_todo();
00078 }
00079
00080 int rtnl_trylock(void)
00081 {
00082 return mutex_trylock(&rtnl_mutex);
00083 }
00084
00085 int rtnl_is_locked(void)
00086 {
00087 return mutex_is_locked(&rtnl_mutex);
00088 }
00089
00090 static struct rtnl_link *rtnl_msg_handlers[NPROTO];
00091
00092 static inline int rtm_msgindex(int msgtype)
00093 {
00094 int msgindex = msgtype - RTM_BASE;
00095
00096
00097
00098
00099
00100
00101 BUG_ON(msgindex < 0 || msgindex >= RTM_NR_MSGTYPES);
00102
00103 return msgindex;
00104 }
00105
00106 static rtnl_doit_func rtnl_get_doit(int protocol, int msgindex)
00107 {
00108 struct rtnl_link *tab;
00109
00110 tab = rtnl_msg_handlers[protocol];
00111 if (tab == NULL || tab[msgindex].doit == NULL)
00112 tab = rtnl_msg_handlers[PF_UNSPEC];
00113
00114 return tab ? tab[msgindex].doit : NULL;
00115 }
00116
00117 static rtnl_dumpit_func rtnl_get_dumpit(int protocol, int msgindex)
00118 {
00119 struct rtnl_link *tab;
00120
00121 tab = rtnl_msg_handlers[protocol];
00122 if (tab == NULL || tab[msgindex].dumpit == NULL)
00123 tab = rtnl_msg_handlers[PF_UNSPEC];
00124
00125 return tab ? tab[msgindex].dumpit : NULL;
00126 }
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 int __rtnl_register(int protocol, int msgtype,
00146 rtnl_doit_func doit, rtnl_dumpit_func dumpit)
00147 {
00148 struct rtnl_link *tab;
00149 int msgindex;
00150
00151 BUG_ON(protocol < 0 || protocol >= NPROTO);
00152 msgindex = rtm_msgindex(msgtype);
00153
00154 tab = rtnl_msg_handlers[protocol];
00155 if (tab == NULL) {
00156 tab = kcalloc(RTM_NR_MSGTYPES, sizeof(*tab), GFP_KERNEL);
00157 if (tab == NULL)
00158 return -ENOBUFS;
00159
00160 rtnl_msg_handlers[protocol] = tab;
00161 }
00162
00163 if (doit)
00164 tab[msgindex].doit = doit;
00165
00166 if (dumpit)
00167 tab[msgindex].dumpit = dumpit;
00168
00169 return 0;
00170 }
00171
00172 EXPORT_SYMBOL_GPL(__rtnl_register);
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 void rtnl_register(int protocol, int msgtype,
00184 rtnl_doit_func doit, rtnl_dumpit_func dumpit)
00185 {
00186 if (__rtnl_register(protocol, msgtype, doit, dumpit) < 0)
00187 panic("Unable to register rtnetlink message handler, "
00188 "protocol = %d, message type = %d\n",
00189 protocol, msgtype);
00190 }
00191
00192 EXPORT_SYMBOL_GPL(rtnl_register);
00193
00194
00195
00196
00197
00198
00199
00200
00201 int rtnl_unregister(int protocol, int msgtype)
00202 {
00203 int msgindex;
00204
00205 BUG_ON(protocol < 0 || protocol >= NPROTO);
00206 msgindex = rtm_msgindex(msgtype);
00207
00208 if (rtnl_msg_handlers[protocol] == NULL)
00209 return -ENOENT;
00210
00211 rtnl_msg_handlers[protocol][msgindex].doit = NULL;
00212 rtnl_msg_handlers[protocol][msgindex].dumpit = NULL;
00213
00214 return 0;
00215 }
00216
00217 EXPORT_SYMBOL_GPL(rtnl_unregister);
00218
00219
00220
00221
00222
00223
00224
00225
00226 void rtnl_unregister_all(int protocol)
00227 {
00228 BUG_ON(protocol < 0 || protocol >= NPROTO);
00229
00230 kfree(rtnl_msg_handlers[protocol]);
00231 rtnl_msg_handlers[protocol] = NULL;
00232 }
00233
00234 EXPORT_SYMBOL_GPL(rtnl_unregister_all);
00235
00236 static LIST_HEAD(link_ops);
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 int __rtnl_link_register(struct rtnl_link_ops *ops)
00249 {
00250 if (!ops->dellink)
00251 ops->dellink = unregister_netdevice;
00252
00253 list_add_tail(&ops->list, &link_ops);
00254 return 0;
00255 }
00256
00257 EXPORT_SYMBOL_GPL(__rtnl_link_register);
00258
00259
00260
00261
00262
00263
00264
00265 int rtnl_link_register(struct rtnl_link_ops *ops)
00266 {
00267 int err;
00268
00269 rtnl_lock();
00270 err = __rtnl_link_register(ops);
00271 rtnl_unlock();
00272 return err;
00273 }
00274
00275 EXPORT_SYMBOL_GPL(rtnl_link_register);
00276
00277 static void __rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops)
00278 {
00279 struct net_device *dev;
00280 restart:
00281 for_each_netdev(net, dev) {
00282 if (dev->rtnl_link_ops == ops) {
00283 ops->dellink(dev);
00284 goto restart;
00285 }
00286 }
00287 }
00288
00289 void rtnl_kill_links(struct net *net, struct rtnl_link_ops *ops)
00290 {
00291 rtnl_lock();
00292 __rtnl_kill_links(net, ops);
00293 rtnl_unlock();
00294 }
00295 EXPORT_SYMBOL_GPL(rtnl_kill_links);
00296
00297
00298
00299
00300
00301
00302
00303 void __rtnl_link_unregister(struct rtnl_link_ops *ops)
00304 {
00305 struct net *net;
00306
00307 for_each_net(net) {
00308 __rtnl_kill_links(net, ops);
00309 }
00310 list_del(&ops->list);
00311 }
00312
00313 EXPORT_SYMBOL_GPL(__rtnl_link_unregister);
00314
00315
00316
00317
00318
00319 void rtnl_link_unregister(struct rtnl_link_ops *ops)
00320 {
00321 rtnl_lock();
00322 __rtnl_link_unregister(ops);
00323 rtnl_unlock();
00324 }
00325
00326 EXPORT_SYMBOL_GPL(rtnl_link_unregister);
00327
00328 static const struct rtnl_link_ops *rtnl_link_ops_get(const char *kind)
00329 {
00330 const struct rtnl_link_ops *ops;
00331
00332 list_for_each_entry(ops, &link_ops, list) {
00333 if (!strcmp(ops->kind, kind))
00334 return ops;
00335 }
00336 return NULL;
00337 }
00338
00339 static size_t rtnl_link_get_size(const struct net_device *dev)
00340 {
00341 const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
00342 size_t size;
00343
00344 if (!ops)
00345 return 0;
00346
00347 size = nlmsg_total_size(sizeof(struct nlattr)) +
00348 nlmsg_total_size(strlen(ops->kind) + 1);
00349
00350 if (ops->get_size)
00351
00352 size += nlmsg_total_size(sizeof(struct nlattr)) +
00353 ops->get_size(dev);
00354
00355 if (ops->get_xstats_size)
00356 size += ops->get_xstats_size(dev);
00357
00358 return size;
00359 }
00360
00361 static int rtnl_link_fill(struct sk_buff *skb, const struct net_device *dev)
00362 {
00363 const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
00364 struct nlattr *linkinfo, *data;
00365 int err = -EMSGSIZE;
00366
00367 linkinfo = nla_nest_start(skb, IFLA_LINKINFO);
00368 if (linkinfo == NULL)
00369 goto out;
00370
00371 if (nla_put_string(skb, IFLA_INFO_KIND, ops->kind) < 0)
00372 goto err_cancel_link;
00373 if (ops->fill_xstats) {
00374 err = ops->fill_xstats(skb, dev);
00375 if (err < 0)
00376 goto err_cancel_link;
00377 }
00378 if (ops->fill_info) {
00379 data = nla_nest_start(skb, IFLA_INFO_DATA);
00380 if (data == NULL)
00381 goto err_cancel_link;
00382 err = ops->fill_info(skb, dev);
00383 if (err < 0)
00384 goto err_cancel_data;
00385 nla_nest_end(skb, data);
00386 }
00387
00388 nla_nest_end(skb, linkinfo);
00389 return 0;
00390
00391 err_cancel_data:
00392 nla_nest_cancel(skb, data);
00393 err_cancel_link:
00394 nla_nest_cancel(skb, linkinfo);
00395 out:
00396 return err;
00397 }
00398
00399 static const int rtm_min[RTM_NR_FAMILIES] =
00400 {
00401 [RTM_FAM(RTM_NEWLINK)] = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
00402 [RTM_FAM(RTM_NEWADDR)] = NLMSG_LENGTH(sizeof(struct ifaddrmsg)),
00403 [RTM_FAM(RTM_NEWROUTE)] = NLMSG_LENGTH(sizeof(struct rtmsg)),
00404 [RTM_FAM(RTM_NEWRULE)] = NLMSG_LENGTH(sizeof(struct fib_rule_hdr)),
00405 [RTM_FAM(RTM_NEWQDISC)] = NLMSG_LENGTH(sizeof(struct tcmsg)),
00406 [RTM_FAM(RTM_NEWTCLASS)] = NLMSG_LENGTH(sizeof(struct tcmsg)),
00407 [RTM_FAM(RTM_NEWTFILTER)] = NLMSG_LENGTH(sizeof(struct tcmsg)),
00408 [RTM_FAM(RTM_NEWACTION)] = NLMSG_LENGTH(sizeof(struct tcamsg)),
00409 [RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
00410 [RTM_FAM(RTM_GETANYCAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
00411 };
00412
00413 static const int rta_max[RTM_NR_FAMILIES] =
00414 {
00415 [RTM_FAM(RTM_NEWLINK)] = IFLA_MAX,
00416 [RTM_FAM(RTM_NEWADDR)] = IFA_MAX,
00417 [RTM_FAM(RTM_NEWROUTE)] = RTA_MAX,
00418 [RTM_FAM(RTM_NEWRULE)] = FRA_MAX,
00419 [RTM_FAM(RTM_NEWQDISC)] = TCA_MAX,
00420 [RTM_FAM(RTM_NEWTCLASS)] = TCA_MAX,
00421 [RTM_FAM(RTM_NEWTFILTER)] = TCA_MAX,
00422 [RTM_FAM(RTM_NEWACTION)] = TCAA_MAX,
00423 };
00424
00425 #ifndef DDE_LINUX
00426 void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data)
00427 {
00428 struct rtattr *rta;
00429 int size = RTA_LENGTH(attrlen);
00430
00431 rta = (struct rtattr*)skb_put(skb, RTA_ALIGN(size));
00432 rta->rta_type = attrtype;
00433 rta->rta_len = size;
00434 memcpy(RTA_DATA(rta), data, attrlen);
00435 memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size);
00436 }
00437
00438 int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, unsigned group, int echo)
00439 {
00440 struct sock *rtnl = net->rtnl;
00441 int err = 0;
00442
00443 NETLINK_CB(skb).dst_group = group;
00444 if (echo)
00445 atomic_inc(&skb->users);
00446 netlink_broadcast(rtnl, skb, pid, group, GFP_KERNEL);
00447 if (echo)
00448 err = netlink_unicast(rtnl, skb, pid, MSG_DONTWAIT);
00449 return err;
00450 }
00451
00452 int rtnl_unicast(struct sk_buff *skb, struct net *net, u32 pid)
00453 {
00454 struct sock *rtnl = net->rtnl;
00455
00456 return nlmsg_unicast(rtnl, skb, pid);
00457 }
00458
00459 int rtnl_notify(struct sk_buff *skb, struct net *net, u32 pid, u32 group,
00460 struct nlmsghdr *nlh, gfp_t flags)
00461 {
00462 struct sock *rtnl = net->rtnl;
00463 int report = 0;
00464
00465 if (nlh)
00466 report = nlmsg_report(nlh);
00467
00468 return nlmsg_notify(rtnl, skb, pid, group, report, flags);
00469 }
00470
00471 void rtnl_set_sk_err(struct net *net, u32 group, int error)
00472 {
00473 struct sock *rtnl = net->rtnl;
00474
00475 netlink_set_err(rtnl, 0, group, error);
00476 }
00477
00478 int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics)
00479 {
00480 struct nlattr *mx;
00481 int i, valid = 0;
00482
00483 mx = nla_nest_start(skb, RTA_METRICS);
00484 if (mx == NULL)
00485 return -ENOBUFS;
00486
00487 for (i = 0; i < RTAX_MAX; i++) {
00488 if (metrics[i]) {
00489 valid++;
00490 NLA_PUT_U32(skb, i+1, metrics[i]);
00491 }
00492 }
00493
00494 if (!valid) {
00495 nla_nest_cancel(skb, mx);
00496 return 0;
00497 }
00498
00499 return nla_nest_end(skb, mx);
00500
00501 nla_put_failure:
00502 nla_nest_cancel(skb, mx);
00503 return -EMSGSIZE;
00504 }
00505
00506 int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst, u32 id,
00507 u32 ts, u32 tsage, long expires, u32 error)
00508 {
00509 struct rta_cacheinfo ci = {
00510 .rta_lastuse = jiffies_to_clock_t(jiffies - dst->lastuse),
00511 .rta_used = dst->__use,
00512 .rta_clntref = atomic_read(&(dst->__refcnt)),
00513 .rta_error = error,
00514 .rta_id = id,
00515 .rta_ts = ts,
00516 .rta_tsage = tsage,
00517 };
00518
00519 if (expires)
00520 ci.rta_expires = jiffies_to_clock_t(expires);
00521
00522 return nla_put(skb, RTA_CACHEINFO, sizeof(ci), &ci);
00523 }
00524
00525 EXPORT_SYMBOL_GPL(rtnl_put_cacheinfo);
00526
00527 static void set_operstate(struct net_device *dev, unsigned char transition)
00528 {
00529 unsigned char operstate = dev->operstate;
00530
00531 switch(transition) {
00532 case IF_OPER_UP:
00533 if ((operstate == IF_OPER_DORMANT ||
00534 operstate == IF_OPER_UNKNOWN) &&
00535 !netif_dormant(dev))
00536 operstate = IF_OPER_UP;
00537 break;
00538
00539 case IF_OPER_DORMANT:
00540 if (operstate == IF_OPER_UP ||
00541 operstate == IF_OPER_UNKNOWN)
00542 operstate = IF_OPER_DORMANT;
00543 break;
00544 }
00545
00546 if (dev->operstate != operstate) {
00547 write_lock_bh(&dev_base_lock);
00548 dev->operstate = operstate;
00549 write_unlock_bh(&dev_base_lock);
00550 netdev_state_change(dev);
00551 }
00552 }
00553
00554 static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
00555 const struct net_device_stats *b)
00556 {
00557 a->rx_packets = b->rx_packets;
00558 a->tx_packets = b->tx_packets;
00559 a->rx_bytes = b->rx_bytes;
00560 a->tx_bytes = b->tx_bytes;
00561 a->rx_errors = b->rx_errors;
00562 a->tx_errors = b->tx_errors;
00563 a->rx_dropped = b->rx_dropped;
00564 a->tx_dropped = b->tx_dropped;
00565
00566 a->multicast = b->multicast;
00567 a->collisions = b->collisions;
00568
00569 a->rx_length_errors = b->rx_length_errors;
00570 a->rx_over_errors = b->rx_over_errors;
00571 a->rx_crc_errors = b->rx_crc_errors;
00572 a->rx_frame_errors = b->rx_frame_errors;
00573 a->rx_fifo_errors = b->rx_fifo_errors;
00574 a->rx_missed_errors = b->rx_missed_errors;
00575
00576 a->tx_aborted_errors = b->tx_aborted_errors;
00577 a->tx_carrier_errors = b->tx_carrier_errors;
00578 a->tx_fifo_errors = b->tx_fifo_errors;
00579 a->tx_heartbeat_errors = b->tx_heartbeat_errors;
00580 a->tx_window_errors = b->tx_window_errors;
00581
00582 a->rx_compressed = b->rx_compressed;
00583 a->tx_compressed = b->tx_compressed;
00584 };
00585
00586 static inline size_t if_nlmsg_size(const struct net_device *dev)
00587 {
00588 return NLMSG_ALIGN(sizeof(struct ifinfomsg))
00589 + nla_total_size(IFNAMSIZ)
00590 + nla_total_size(IFALIASZ)
00591 + nla_total_size(IFNAMSIZ)
00592 + nla_total_size(sizeof(struct rtnl_link_ifmap))
00593 + nla_total_size(sizeof(struct rtnl_link_stats))
00594 + nla_total_size(MAX_ADDR_LEN)
00595 + nla_total_size(MAX_ADDR_LEN)
00596 + nla_total_size(4)
00597 + nla_total_size(4)
00598 + nla_total_size(4)
00599 + nla_total_size(4)
00600 + nla_total_size(4)
00601 + nla_total_size(1)
00602 + nla_total_size(1)
00603 + rtnl_link_get_size(dev);
00604 }
00605
00606 static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
00607 int type, u32 pid, u32 seq, u32 change,
00608 unsigned int flags)
00609 {
00610 struct netdev_queue *txq;
00611 struct ifinfomsg *ifm;
00612 struct nlmsghdr *nlh;
00613 const struct net_device_stats *stats;
00614 struct nlattr *attr;
00615
00616 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
00617 if (nlh == NULL)
00618 return -EMSGSIZE;
00619
00620 ifm = nlmsg_data(nlh);
00621 ifm->ifi_family = AF_UNSPEC;
00622 ifm->__ifi_pad = 0;
00623 ifm->ifi_type = dev->type;
00624 ifm->ifi_index = dev->ifindex;
00625 ifm->ifi_flags = dev_get_flags(dev);
00626 ifm->ifi_change = change;
00627
00628 NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name);
00629 NLA_PUT_U32(skb, IFLA_TXQLEN, dev->tx_queue_len);
00630 NLA_PUT_U8(skb, IFLA_OPERSTATE,
00631 netif_running(dev) ? dev->operstate : IF_OPER_DOWN);
00632 NLA_PUT_U8(skb, IFLA_LINKMODE, dev->link_mode);
00633 NLA_PUT_U32(skb, IFLA_MTU, dev->mtu);
00634
00635 if (dev->ifindex != dev->iflink)
00636 NLA_PUT_U32(skb, IFLA_LINK, dev->iflink);
00637
00638 if (dev->master)
00639 NLA_PUT_U32(skb, IFLA_MASTER, dev->master->ifindex);
00640
00641 txq = netdev_get_tx_queue(dev, 0);
00642 if (txq->qdisc_sleeping)
00643 NLA_PUT_STRING(skb, IFLA_QDISC, txq->qdisc_sleeping->ops->id);
00644
00645 if (dev->ifalias)
00646 NLA_PUT_STRING(skb, IFLA_IFALIAS, dev->ifalias);
00647
00648 if (1) {
00649 struct rtnl_link_ifmap map = {
00650 .mem_start = dev->mem_start,
00651 .mem_end = dev->mem_end,
00652 .base_addr = dev->base_addr,
00653 .irq = dev->irq,
00654 .dma = dev->dma,
00655 .port = dev->if_port,
00656 };
00657 NLA_PUT(skb, IFLA_MAP, sizeof(map), &map);
00658 }
00659
00660 if (dev->addr_len) {
00661 NLA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr);
00662 NLA_PUT(skb, IFLA_BROADCAST, dev->addr_len, dev->broadcast);
00663 }
00664
00665 attr = nla_reserve(skb, IFLA_STATS,
00666 sizeof(struct rtnl_link_stats));
00667 if (attr == NULL)
00668 goto nla_put_failure;
00669
00670 stats = dev_get_stats(dev);
00671 copy_rtnl_link_stats(nla_data(attr), stats);
00672
00673 if (dev->rtnl_link_ops) {
00674 if (rtnl_link_fill(skb, dev) < 0)
00675 goto nla_put_failure;
00676 }
00677
00678 return nlmsg_end(skb, nlh);
00679
00680 nla_put_failure:
00681 nlmsg_cancel(skb, nlh);
00682 return -EMSGSIZE;
00683 }
00684
00685 static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
00686 {
00687 struct net *net = sock_net(skb->sk);
00688 int idx;
00689 int s_idx = cb->args[0];
00690 struct net_device *dev;
00691
00692 idx = 0;
00693 for_each_netdev(net, dev) {
00694 if (idx < s_idx)
00695 goto cont;
00696 if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
00697 NETLINK_CB(cb->skb).pid,
00698 cb->nlh->nlmsg_seq, 0, NLM_F_MULTI) <= 0)
00699 break;
00700 cont:
00701 idx++;
00702 }
00703 cb->args[0] = idx;
00704
00705 return skb->len;
00706 }
00707
00708 const struct nla_policy ifla_policy[IFLA_MAX+1] = {
00709 [IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 },
00710 [IFLA_ADDRESS] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
00711 [IFLA_BROADCAST] = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
00712 [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) },
00713 [IFLA_MTU] = { .type = NLA_U32 },
00714 [IFLA_LINK] = { .type = NLA_U32 },
00715 [IFLA_TXQLEN] = { .type = NLA_U32 },
00716 [IFLA_WEIGHT] = { .type = NLA_U32 },
00717 [IFLA_OPERSTATE] = { .type = NLA_U8 },
00718 [IFLA_LINKMODE] = { .type = NLA_U8 },
00719 [IFLA_LINKINFO] = { .type = NLA_NESTED },
00720 [IFLA_NET_NS_PID] = { .type = NLA_U32 },
00721 [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 },
00722 };
00723
00724 static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
00725 [IFLA_INFO_KIND] = { .type = NLA_STRING },
00726 [IFLA_INFO_DATA] = { .type = NLA_NESTED },
00727 };
00728
00729 static struct net *get_net_ns_by_pid(pid_t pid)
00730 {
00731 struct task_struct *tsk;
00732 struct net *net;
00733
00734
00735 net = ERR_PTR(-ESRCH);
00736 rcu_read_lock();
00737 tsk = find_task_by_vpid(pid);
00738 if (tsk) {
00739 struct nsproxy *nsproxy;
00740 nsproxy = task_nsproxy(tsk);
00741 if (nsproxy)
00742 net = get_net(nsproxy->net_ns);
00743 }
00744 rcu_read_unlock();
00745 return net;
00746 }
00747
00748 static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
00749 {
00750 if (dev) {
00751 if (tb[IFLA_ADDRESS] &&
00752 nla_len(tb[IFLA_ADDRESS]) < dev->addr_len)
00753 return -EINVAL;
00754
00755 if (tb[IFLA_BROADCAST] &&
00756 nla_len(tb[IFLA_BROADCAST]) < dev->addr_len)
00757 return -EINVAL;
00758 }
00759
00760 return 0;
00761 }
00762
00763 static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
00764 struct nlattr **tb, char *ifname, int modified)
00765 {
00766 const struct net_device_ops *ops = dev->netdev_ops;
00767 int send_addr_notify = 0;
00768 int err;
00769
00770 if (tb[IFLA_NET_NS_PID]) {
00771 struct net *net;
00772 net = get_net_ns_by_pid(nla_get_u32(tb[IFLA_NET_NS_PID]));
00773 if (IS_ERR(net)) {
00774 err = PTR_ERR(net);
00775 goto errout;
00776 }
00777 err = dev_change_net_namespace(dev, net, ifname);
00778 put_net(net);
00779 if (err)
00780 goto errout;
00781 modified = 1;
00782 }
00783
00784 if (tb[IFLA_MAP]) {
00785 struct rtnl_link_ifmap *u_map;
00786 struct ifmap k_map;
00787
00788 if (!ops->ndo_set_config) {
00789 err = -EOPNOTSUPP;
00790 goto errout;
00791 }
00792
00793 if (!netif_device_present(dev)) {
00794 err = -ENODEV;
00795 goto errout;
00796 }
00797
00798 u_map = nla_data(tb[IFLA_MAP]);
00799 k_map.mem_start = (unsigned long) u_map->mem_start;
00800 k_map.mem_end = (unsigned long) u_map->mem_end;
00801 k_map.base_addr = (unsigned short) u_map->base_addr;
00802 k_map.irq = (unsigned char) u_map->irq;
00803 k_map.dma = (unsigned char) u_map->dma;
00804 k_map.port = (unsigned char) u_map->port;
00805
00806 err = ops->ndo_set_config(dev, &k_map);
00807 if (err < 0)
00808 goto errout;
00809
00810 modified = 1;
00811 }
00812
00813 if (tb[IFLA_ADDRESS]) {
00814 struct sockaddr *sa;
00815 int len;
00816
00817 if (!ops->ndo_set_mac_address) {
00818 err = -EOPNOTSUPP;
00819 goto errout;
00820 }
00821
00822 if (!netif_device_present(dev)) {
00823 err = -ENODEV;
00824 goto errout;
00825 }
00826
00827 len = sizeof(sa_family_t) + dev->addr_len;
00828 sa = kmalloc(len, GFP_KERNEL);
00829 if (!sa) {
00830 err = -ENOMEM;
00831 goto errout;
00832 }
00833 sa->sa_family = dev->type;
00834 memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]),
00835 dev->addr_len);
00836 err = ops->ndo_set_mac_address(dev, sa);
00837 kfree(sa);
00838 if (err)
00839 goto errout;
00840 send_addr_notify = 1;
00841 modified = 1;
00842 }
00843
00844 if (tb[IFLA_MTU]) {
00845 err = dev_set_mtu(dev, nla_get_u32(tb[IFLA_MTU]));
00846 if (err < 0)
00847 goto errout;
00848 modified = 1;
00849 }
00850
00851
00852
00853
00854
00855
00856 if (ifm->ifi_index > 0 && ifname[0]) {
00857 err = dev_change_name(dev, ifname);
00858 if (err < 0)
00859 goto errout;
00860 modified = 1;
00861 }
00862
00863 if (tb[IFLA_IFALIAS]) {
00864 err = dev_set_alias(dev, nla_data(tb[IFLA_IFALIAS]),
00865 nla_len(tb[IFLA_IFALIAS]));
00866 if (err < 0)
00867 goto errout;
00868 modified = 1;
00869 }
00870
00871 if (tb[IFLA_BROADCAST]) {
00872 nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len);
00873 send_addr_notify = 1;
00874 }
00875
00876 if (ifm->ifi_flags || ifm->ifi_change) {
00877 unsigned int flags = ifm->ifi_flags;
00878
00879
00880 if (ifm->ifi_change)
00881 flags = (flags & ifm->ifi_change) |
00882 (dev->flags & ~ifm->ifi_change);
00883 err = dev_change_flags(dev, flags);
00884 if (err < 0)
00885 goto errout;
00886 }
00887
00888 if (tb[IFLA_TXQLEN])
00889 dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
00890
00891 if (tb[IFLA_OPERSTATE])
00892 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
00893
00894 if (tb[IFLA_LINKMODE]) {
00895 write_lock_bh(&dev_base_lock);
00896 dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
00897 write_unlock_bh(&dev_base_lock);
00898 }
00899
00900 err = 0;
00901
00902 errout:
00903 if (err < 0 && modified && net_ratelimit())
00904 printk(KERN_WARNING "A link change request failed with "
00905 "some changes comitted already. Interface %s may "
00906 "have been left with an inconsistent configuration, "
00907 "please check.\n", dev->name);
00908
00909 if (send_addr_notify)
00910 call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
00911 return err;
00912 }
00913
00914 static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
00915 {
00916 struct net *net = sock_net(skb->sk);
00917 struct ifinfomsg *ifm;
00918 struct net_device *dev;
00919 int err;
00920 struct nlattr *tb[IFLA_MAX+1];
00921 char ifname[IFNAMSIZ];
00922
00923 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
00924 if (err < 0)
00925 goto errout;
00926
00927 if (tb[IFLA_IFNAME])
00928 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
00929 else
00930 ifname[0] = '\0';
00931
00932 err = -EINVAL;
00933 ifm = nlmsg_data(nlh);
00934 if (ifm->ifi_index > 0)
00935 dev = dev_get_by_index(net, ifm->ifi_index);
00936 else if (tb[IFLA_IFNAME])
00937 dev = dev_get_by_name(net, ifname);
00938 else
00939 goto errout;
00940
00941 if (dev == NULL) {
00942 err = -ENODEV;
00943 goto errout;
00944 }
00945
00946 if ((err = validate_linkmsg(dev, tb)) < 0)
00947 goto errout_dev;
00948
00949 err = do_setlink(dev, ifm, tb, ifname, 0);
00950 errout_dev:
00951 dev_put(dev);
00952 errout:
00953 return err;
00954 }
00955
00956 static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
00957 {
00958 struct net *net = sock_net(skb->sk);
00959 const struct rtnl_link_ops *ops;
00960 struct net_device *dev;
00961 struct ifinfomsg *ifm;
00962 char ifname[IFNAMSIZ];
00963 struct nlattr *tb[IFLA_MAX+1];
00964 int err;
00965
00966 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
00967 if (err < 0)
00968 return err;
00969
00970 if (tb[IFLA_IFNAME])
00971 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
00972
00973 ifm = nlmsg_data(nlh);
00974 if (ifm->ifi_index > 0)
00975 dev = __dev_get_by_index(net, ifm->ifi_index);
00976 else if (tb[IFLA_IFNAME])
00977 dev = __dev_get_by_name(net, ifname);
00978 else
00979 return -EINVAL;
00980
00981 if (!dev)
00982 return -ENODEV;
00983
00984 ops = dev->rtnl_link_ops;
00985 if (!ops)
00986 return -EOPNOTSUPP;
00987
00988 ops->dellink(dev);
00989 return 0;
00990 }
00991
00992 struct net_device *rtnl_create_link(struct net *net, char *ifname,
00993 const struct rtnl_link_ops *ops, struct nlattr *tb[])
00994 {
00995 int err;
00996 struct net_device *dev;
00997
00998 err = -ENOMEM;
00999 dev = alloc_netdev(ops->priv_size, ifname, ops->setup);
01000 if (!dev)
01001 goto err;
01002
01003 if (strchr(dev->name, '%')) {
01004 err = dev_alloc_name(dev, dev->name);
01005 if (err < 0)
01006 goto err_free;
01007 }
01008
01009 dev_net_set(dev, net);
01010 dev->rtnl_link_ops = ops;
01011
01012 if (tb[IFLA_MTU])
01013 dev->mtu = nla_get_u32(tb[IFLA_MTU]);
01014 if (tb[IFLA_ADDRESS])
01015 memcpy(dev->dev_addr, nla_data(tb[IFLA_ADDRESS]),
01016 nla_len(tb[IFLA_ADDRESS]));
01017 if (tb[IFLA_BROADCAST])
01018 memcpy(dev->broadcast, nla_data(tb[IFLA_BROADCAST]),
01019 nla_len(tb[IFLA_BROADCAST]));
01020 if (tb[IFLA_TXQLEN])
01021 dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
01022 if (tb[IFLA_OPERSTATE])
01023 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
01024 if (tb[IFLA_LINKMODE])
01025 dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
01026
01027 return dev;
01028
01029 err_free:
01030 free_netdev(dev);
01031 err:
01032 return ERR_PTR(err);
01033 }
01034
01035 static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
01036 {
01037 struct net *net = sock_net(skb->sk);
01038 const struct rtnl_link_ops *ops;
01039 struct net_device *dev;
01040 struct ifinfomsg *ifm;
01041 char kind[MODULE_NAME_LEN];
01042 char ifname[IFNAMSIZ];
01043 struct nlattr *tb[IFLA_MAX+1];
01044 struct nlattr *linkinfo[IFLA_INFO_MAX+1];
01045 int err;
01046
01047 #ifdef CONFIG_MODULES
01048 replay:
01049 #endif
01050 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
01051 if (err < 0)
01052 return err;
01053
01054 if (tb[IFLA_IFNAME])
01055 nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
01056 else
01057 ifname[0] = '\0';
01058
01059 ifm = nlmsg_data(nlh);
01060 if (ifm->ifi_index > 0)
01061 dev = __dev_get_by_index(net, ifm->ifi_index);
01062 else if (ifname[0])
01063 dev = __dev_get_by_name(net, ifname);
01064 else
01065 dev = NULL;
01066
01067 if ((err = validate_linkmsg(dev, tb)) < 0)
01068 return err;
01069
01070 if (tb[IFLA_LINKINFO]) {
01071 err = nla_parse_nested(linkinfo, IFLA_INFO_MAX,
01072 tb[IFLA_LINKINFO], ifla_info_policy);
01073 if (err < 0)
01074 return err;
01075 } else
01076 memset(linkinfo, 0, sizeof(linkinfo));
01077
01078 if (linkinfo[IFLA_INFO_KIND]) {
01079 nla_strlcpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind));
01080 ops = rtnl_link_ops_get(kind);
01081 } else {
01082 kind[0] = '\0';
01083 ops = NULL;
01084 }
01085
01086 if (1) {
01087 struct nlattr *attr[ops ? ops->maxtype + 1 : 0], **data = NULL;
01088
01089 if (ops) {
01090 if (ops->maxtype && linkinfo[IFLA_INFO_DATA]) {
01091 err = nla_parse_nested(attr, ops->maxtype,
01092 linkinfo[IFLA_INFO_DATA],
01093 ops->policy);
01094 if (err < 0)
01095 return err;
01096 data = attr;
01097 }
01098 if (ops->validate) {
01099 err = ops->validate(tb, data);
01100 if (err < 0)
01101 return err;
01102 }
01103 }
01104
01105 if (dev) {
01106 int modified = 0;
01107
01108 if (nlh->nlmsg_flags & NLM_F_EXCL)
01109 return -EEXIST;
01110 if (nlh->nlmsg_flags & NLM_F_REPLACE)
01111 return -EOPNOTSUPP;
01112
01113 if (linkinfo[IFLA_INFO_DATA]) {
01114 if (!ops || ops != dev->rtnl_link_ops ||
01115 !ops->changelink)
01116 return -EOPNOTSUPP;
01117
01118 err = ops->changelink(dev, tb, data);
01119 if (err < 0)
01120 return err;
01121 modified = 1;
01122 }
01123
01124 return do_setlink(dev, ifm, tb, ifname, modified);
01125 }
01126
01127 if (!(nlh->nlmsg_flags & NLM_F_CREATE))
01128 return -ENODEV;
01129
01130 if (ifm->ifi_index || ifm->ifi_flags || ifm->ifi_change)
01131 return -EOPNOTSUPP;
01132 if (tb[IFLA_MAP] || tb[IFLA_MASTER] || tb[IFLA_PROTINFO])
01133 return -EOPNOTSUPP;
01134
01135 if (!ops) {
01136 #ifdef CONFIG_MODULES
01137 if (kind[0]) {
01138 __rtnl_unlock();
01139 request_module("rtnl-link-%s", kind);
01140 rtnl_lock();
01141 ops = rtnl_link_ops_get(kind);
01142 if (ops)
01143 goto replay;
01144 }
01145 #endif
01146 return -EOPNOTSUPP;
01147 }
01148
01149 if (!ifname[0])
01150 snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind);
01151
01152 dev = rtnl_create_link(net, ifname, ops, tb);
01153
01154 if (IS_ERR(dev))
01155 err = PTR_ERR(dev);
01156 else if (ops->newlink)
01157 err = ops->newlink(dev, tb, data);
01158 else
01159 err = register_netdevice(dev);
01160
01161 if (err < 0 && !IS_ERR(dev))
01162 free_netdev(dev);
01163 return err;
01164 }
01165 }
01166
01167 static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
01168 {
01169 struct net *net = sock_net(skb->sk);
01170 struct ifinfomsg *ifm;
01171 struct nlattr *tb[IFLA_MAX+1];
01172 struct net_device *dev = NULL;
01173 struct sk_buff *nskb;
01174 int err;
01175
01176 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
01177 if (err < 0)
01178 return err;
01179
01180 ifm = nlmsg_data(nlh);
01181 if (ifm->ifi_index > 0) {
01182 dev = dev_get_by_index(net, ifm->ifi_index);
01183 if (dev == NULL)
01184 return -ENODEV;
01185 } else
01186 return -EINVAL;
01187
01188 nskb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL);
01189 if (nskb == NULL) {
01190 err = -ENOBUFS;
01191 goto errout;
01192 }
01193
01194 err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).pid,
01195 nlh->nlmsg_seq, 0, 0);
01196 if (err < 0) {
01197
01198 WARN_ON(err == -EMSGSIZE);
01199 kfree_skb(nskb);
01200 goto errout;
01201 }
01202 err = rtnl_unicast(nskb, net, NETLINK_CB(skb).pid);
01203 errout:
01204 dev_put(dev);
01205
01206 return err;
01207 }
01208
01209 static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
01210 {
01211 int idx;
01212 int s_idx = cb->family;
01213
01214 if (s_idx == 0)
01215 s_idx = 1;
01216 for (idx=1; idx<NPROTO; idx++) {
01217 int type = cb->nlh->nlmsg_type-RTM_BASE;
01218 if (idx < s_idx || idx == PF_PACKET)
01219 continue;
01220 if (rtnl_msg_handlers[idx] == NULL ||
01221 rtnl_msg_handlers[idx][type].dumpit == NULL)
01222 continue;
01223 if (idx > s_idx)
01224 memset(&cb->args[0], 0, sizeof(cb->args));
01225 if (rtnl_msg_handlers[idx][type].dumpit(skb, cb))
01226 break;
01227 }
01228 cb->family = idx;
01229
01230 return skb->len;
01231 }
01232 #endif
01233
01234 void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
01235 {
01236 struct net *net = dev_net(dev);
01237 #ifndef DDE_LINUX
01238 struct sk_buff *skb;
01239 int err = -ENOBUFS;
01240
01241 skb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL);
01242 if (skb == NULL)
01243 goto errout;
01244
01245 err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0);
01246 if (err < 0) {
01247
01248 WARN_ON(err == -EMSGSIZE);
01249 kfree_skb(skb);
01250 goto errout;
01251 }
01252 err = rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
01253 errout:
01254 if (err < 0)
01255 rtnl_set_sk_err(net, RTNLGRP_LINK, err);
01256 #endif
01257 }
01258
01259 #ifndef DDE_LINUX
01260
01261 static struct rtattr **rta_buf;
01262 static int rtattr_max;
01263
01264
01265
01266 static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
01267 {
01268 struct net *net = sock_net(skb->sk);
01269 rtnl_doit_func doit;
01270 int sz_idx, kind;
01271 int min_len;
01272 int family;
01273 int type;
01274 int err;
01275
01276 type = nlh->nlmsg_type;
01277 if (type > RTM_MAX)
01278 return -EOPNOTSUPP;
01279
01280 type -= RTM_BASE;
01281
01282
01283 if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(struct rtgenmsg)))
01284 return 0;
01285
01286 family = ((struct rtgenmsg*)NLMSG_DATA(nlh))->rtgen_family;
01287 if (family >= NPROTO)
01288 return -EAFNOSUPPORT;
01289
01290 sz_idx = type>>2;
01291 kind = type&3;
01292
01293 if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN))
01294 return -EPERM;
01295
01296 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
01297 struct sock *rtnl;
01298 rtnl_dumpit_func dumpit;
01299
01300 dumpit = rtnl_get_dumpit(family, type);
01301 if (dumpit == NULL)
01302 return -EOPNOTSUPP;
01303
01304 __rtnl_unlock();
01305 rtnl = net->rtnl;
01306 err = netlink_dump_start(rtnl, skb, nlh, dumpit, NULL);
01307 rtnl_lock();
01308 return err;
01309 }
01310
01311 memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *)));
01312
01313 min_len = rtm_min[sz_idx];
01314 if (nlh->nlmsg_len < min_len)
01315 return -EINVAL;
01316
01317 if (nlh->nlmsg_len > min_len) {
01318 int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len);
01319 struct rtattr *attr = (void*)nlh + NLMSG_ALIGN(min_len);
01320
01321 while (RTA_OK(attr, attrlen)) {
01322 unsigned flavor = attr->rta_type;
01323 if (flavor) {
01324 if (flavor > rta_max[sz_idx])
01325 return -EINVAL;
01326 rta_buf[flavor-1] = attr;
01327 }
01328 attr = RTA_NEXT(attr, attrlen);
01329 }
01330 }
01331
01332 doit = rtnl_get_doit(family, type);
01333 if (doit == NULL)
01334 return -EOPNOTSUPP;
01335
01336 return doit(skb, nlh, (void *)&rta_buf[0]);
01337 }
01338
01339 static void rtnetlink_rcv(struct sk_buff *skb)
01340 {
01341 rtnl_lock();
01342 netlink_rcv_skb(skb, &rtnetlink_rcv_msg);
01343 rtnl_unlock();
01344 }
01345
01346 static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr)
01347 {
01348 struct net_device *dev = ptr;
01349
01350 switch (event) {
01351 case NETDEV_UNREGISTER:
01352 rtmsg_ifinfo(RTM_DELLINK, dev, ~0U);
01353 break;
01354 case NETDEV_REGISTER:
01355 rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U);
01356 break;
01357 case NETDEV_UP:
01358 case NETDEV_DOWN:
01359 rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING);
01360 break;
01361 case NETDEV_CHANGE:
01362 case NETDEV_GOING_DOWN:
01363 break;
01364 default:
01365 rtmsg_ifinfo(RTM_NEWLINK, dev, 0);
01366 break;
01367 }
01368 return NOTIFY_DONE;
01369 }
01370
01371 static struct notifier_block rtnetlink_dev_notifier = {
01372 .notifier_call = rtnetlink_event,
01373 };
01374
01375
01376 static int rtnetlink_net_init(struct net *net)
01377 {
01378 struct sock *sk;
01379 sk = netlink_kernel_create(net, NETLINK_ROUTE, RTNLGRP_MAX,
01380 rtnetlink_rcv, &rtnl_mutex, THIS_MODULE);
01381 if (!sk)
01382 return -ENOMEM;
01383 net->rtnl = sk;
01384 return 0;
01385 }
01386
01387 static void rtnetlink_net_exit(struct net *net)
01388 {
01389 netlink_kernel_release(net->rtnl);
01390 net->rtnl = NULL;
01391 }
01392
01393 static struct pernet_operations rtnetlink_net_ops = {
01394 .init = rtnetlink_net_init,
01395 .exit = rtnetlink_net_exit,
01396 };
01397
01398 void __init rtnetlink_init(void)
01399 {
01400 int i;
01401
01402 rtattr_max = 0;
01403 for (i = 0; i < ARRAY_SIZE(rta_max); i++)
01404 if (rta_max[i] > rtattr_max)
01405 rtattr_max = rta_max[i];
01406 rta_buf = kmalloc(rtattr_max * sizeof(struct rtattr *), GFP_KERNEL);
01407 if (!rta_buf)
01408 panic("rtnetlink_init: cannot allocate rta_buf\n");
01409
01410 if (register_pernet_subsys(&rtnetlink_net_ops))
01411 panic("rtnetlink_init: cannot initialize rtnetlink\n");
01412
01413 netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV);
01414 register_netdevice_notifier(&rtnetlink_dev_notifier);
01415
01416 rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink, rtnl_dump_ifinfo);
01417 rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL);
01418 rtnl_register(PF_UNSPEC, RTM_NEWLINK, rtnl_newlink, NULL);
01419 rtnl_register(PF_UNSPEC, RTM_DELLINK, rtnl_dellink, NULL);
01420
01421 rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all);
01422 rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all);
01423 }
01424
01425 EXPORT_SYMBOL(__rta_fill);
01426 EXPORT_SYMBOL(rtnetlink_put_metrics);
01427 EXPORT_SYMBOL(rtnl_lock);
01428 EXPORT_SYMBOL(rtnl_trylock);
01429 EXPORT_SYMBOL(rtnl_unlock);
01430 EXPORT_SYMBOL(rtnl_is_locked);
01431 EXPORT_SYMBOL(rtnl_unicast);
01432 EXPORT_SYMBOL(rtnl_notify);
01433 EXPORT_SYMBOL(rtnl_set_sk_err);
01434 EXPORT_SYMBOL(rtnl_create_link);
01435 EXPORT_SYMBOL(ifla_policy);
01436 #endif