Main Page | Class List | File List | Class Members | File Members

rtnetlink.c File Reference

#include <linux/config.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/string.h>
#include <linux/sockios.h>
#include <linux/net.h>
#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/capability.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/string.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <net/ip.h>
#include <net/protocol.h>
#include <net/arp.h>
#include <net/route.h>
#include <net/udp.h>
#include <net/sock.h>
#include <net/pkt_sched.h>

Go to the source code of this file.

Functions

 DECLARE_MUTEX (rtnl_sem)
void rtnl_lock (void)
void rtnl_unlock (void)
int rtattr_parse (struct rtattr *tb[], int maxattr, struct rtattr *rta, int len)
void __rta_fill (struct sk_buff *skb, int attrtype, int attrlen, const void *data)
int rtnetlink_send (struct sk_buff *skb, u32 pid, unsigned group, int echo)
int rtnetlink_put_metrics (struct sk_buff *skb, unsigned *metrics)
int rtnetlink_fill_ifinfo (struct sk_buff *skb, struct net_device *dev, int type, u32 pid, u32 seq, u32 change)
int rtnetlink_dump_ifinfo (struct sk_buff *skb, struct netlink_callback *cb)
int rtnetlink_dump_all (struct sk_buff *skb, struct netlink_callback *cb)
void rtmsg_ifinfo (int type, struct net_device *dev, unsigned change)
int rtnetlink_done (struct netlink_callback *cb)
__inline__ int rtnetlink_rcv_msg (struct sk_buff *skb, struct nlmsghdr *nlh, int *errp)
int rtnetlink_rcv_skb (struct sk_buff *skb)
void rtnetlink_rcv (struct sock *sk, int len)
int rtnetlink_event (struct notifier_block *this, unsigned long event, void *ptr)
void __init rtnetlink_init (void)

Variables

sockrtnl
rtnetlink_link * rtnetlink_links [NPROTO]
const int rtm_min [(RTM_MAX+1-RTM_BASE)/4]
const int rta_max [(RTM_MAX+1-RTM_BASE)/4]
rtnetlink_link link_rtnetlink_table [RTM_MAX-RTM_BASE+1]
notifier_block rtnetlink_dev_notifier


Function Documentation

void __rta_fill struct sk_buff skb,
int  attrtype,
int  attrlen,
const void *  data
 

Definition at line 107 of file rtnetlink.c.

References skb_put().

00108 { 00109 struct rtattr *rta; 00110 int size = RTA_LENGTH(attrlen); 00111 00112 rta = (struct rtattr*)skb_put(skb, RTA_ALIGN(size)); 00113 rta->rta_type = attrtype; 00114 rta->rta_len = size; 00115 memcpy(RTA_DATA(rta), data, attrlen); 00116 }

DECLARE_MUTEX rtnl_sem   ) 
 

int rtattr_parse struct rtattr *  tb[],
int  maxattr,
struct rtattr *  rta,
int  len
 

Definition at line 66 of file rtnetlink.c.

00067 { 00068 memset(tb, 0, sizeof(struct rtattr*)*maxattr); 00069 00070 while (RTA_OK(rta, len)) { 00071 unsigned flavor = rta->rta_type; 00072 if (flavor && flavor <= maxattr) 00073 tb[flavor-1] = rta; 00074 rta = RTA_NEXT(rta, len); 00075 } 00076 return 0; 00077 }

void rtmsg_ifinfo int  type,
struct net_device dev,
unsigned  change
 

Definition at line 247 of file rtnetlink.c.

References alloc_skb(), kfree_skb(), netlink_broadcast(), NETLINK_CB, NLMSG_GOODSIZE, rtnetlink_fill_ifinfo(), and rtnl.

Referenced by dev_change_flags(), netdev_set_master(), netdev_state_change(), and rtnetlink_event().

00248 { 00249 struct sk_buff *skb; 00250 int size = NLMSG_GOODSIZE; 00251 00252 skb = alloc_skb(size, GFP_KERNEL); 00253 if (!skb) 00254 return; 00255 00256 if (rtnetlink_fill_ifinfo(skb, dev, type, 0, 0, change) < 0) { 00257 kfree_skb(skb); 00258 return; 00259 } 00260 NETLINK_CB(skb).dst_groups = RTMGRP_LINK; 00261 netlink_broadcast(rtnl, skb, 0, RTMGRP_LINK, GFP_KERNEL); 00262 }

int rtnetlink_done struct netlink_callback cb  )  [static]
 

Definition at line 264 of file rtnetlink.c.

Referenced by rtnetlink_rcv_msg().

00265 { 00266 return 0; 00267 }

int rtnetlink_dump_all struct sk_buff skb,
struct netlink_callback cb
 

Definition at line 223 of file rtnetlink.c.

References netlink_callback::args, netlink_callback::family, sk_buff::len, netlink_callback::nlh, nlmsghdr::nlmsg_type, NPROTO, and rtnetlink_links.

00224 { 00225 int idx; 00226 int s_idx = cb->family; 00227 00228 if (s_idx == 0) 00229 s_idx = 1; 00230 for (idx=1; idx<NPROTO; idx++) { 00231 int type = cb->nlh->nlmsg_type-RTM_BASE; 00232 if (idx < s_idx || idx == PF_PACKET) 00233 continue; 00234 if (rtnetlink_links[idx] == NULL || 00235 rtnetlink_links[idx][type].dumpit == NULL) 00236 continue; 00237 if (idx > s_idx) 00238 memset(&cb->args[0], 0, sizeof(cb->args)); 00239 if (rtnetlink_links[idx][type].dumpit(skb, cb)) 00240 break; 00241 } 00242 cb->family = idx; 00243 00244 return skb->len; 00245 }

int rtnetlink_dump_ifinfo struct sk_buff skb,
struct netlink_callback cb
 

Definition at line 204 of file rtnetlink.c.

References netlink_callback::args, dev_base, dev_base_lock, sk_buff::len, NETLINK_CB, net_device::next, netlink_callback::nlh, nlmsghdr::nlmsg_seq, rtnetlink_fill_ifinfo(), and netlink_callback::skb.

00205 { 00206 int idx; 00207 int s_idx = cb->args[0]; 00208 struct net_device *dev; 00209 00210 read_lock(&dev_base_lock); 00211 for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) { 00212 if (idx < s_idx) 00213 continue; 00214 if (rtnetlink_fill_ifinfo(skb, dev, RTM_NEWLINK, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, 0) <= 0) 00215 break; 00216 } 00217 read_unlock(&dev_base_lock); 00218 cb->args[0] = idx; 00219 00220 return skb->len; 00221 }

int rtnetlink_event struct notifier_block *  this,
unsigned long  event,
void *  ptr
[static]
 

Definition at line 487 of file rtnetlink.c.

References rtmsg_ifinfo().

00488 { 00489 struct net_device *dev = ptr; 00490 switch (event) { 00491 case NETDEV_UNREGISTER: 00492 rtmsg_ifinfo(RTM_DELLINK, dev, ~0U); 00493 break; 00494 case NETDEV_REGISTER: 00495 rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); 00496 break; 00497 case NETDEV_UP: 00498 case NETDEV_DOWN: 00499 rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); 00500 break; 00501 case NETDEV_CHANGE: 00502 case NETDEV_GOING_DOWN: 00503 break; 00504 default: 00505 rtmsg_ifinfo(RTM_NEWLINK, dev, 0); 00506 break; 00507 } 00508 return NOTIFY_DONE; 00509 }

int rtnetlink_fill_ifinfo struct sk_buff skb,
struct net_device dev,
int  type,
u32  pid,
u32  seq,
u32  change
[static]
 

Definition at line 152 of file rtnetlink.c.

References net_device::addr_len, net_device::broadcast, sk_buff::data, net_device::dev_addr, net_device::flags, net_device::get_stats, Qdisc_ops::id, net_device::ifindex, net_device::iflink, sk_buff::len, net_device::master, net_device::mtu, net_device::name, netif_carrier_ok(), netif_running(), NLM_F_MULTI, NLMSG_DATA, NLMSG_PUT, Qdisc::ops, net_device::qdisc_sleeping, skb_trim(), sk_buff::tail, and net_device::type.

Referenced by rtmsg_ifinfo(), and rtnetlink_dump_ifinfo().

00154 { 00155 struct ifinfomsg *r; 00156 struct nlmsghdr *nlh; 00157 unsigned char *b = skb->tail; 00158 00159 nlh = NLMSG_PUT(skb, pid, seq, type, sizeof(*r)); 00160 if (pid) nlh->nlmsg_flags |= NLM_F_MULTI; 00161 r = NLMSG_DATA(nlh); 00162 r->ifi_family = AF_UNSPEC; 00163 r->ifi_type = dev->type; 00164 r->ifi_index = dev->ifindex; 00165 r->ifi_flags = dev->flags; 00166 r->ifi_change = change; 00167 00168 if (!netif_running(dev) || !netif_carrier_ok(dev)) 00169 r->ifi_flags &= ~IFF_RUNNING; 00170 else 00171 r->ifi_flags |= IFF_RUNNING; 00172 00173 RTA_PUT(skb, IFLA_IFNAME, strlen(dev->name)+1, dev->name); 00174 if (dev->addr_len) { 00175 RTA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr); 00176 RTA_PUT(skb, IFLA_BROADCAST, dev->addr_len, dev->broadcast); 00177 } 00178 if (1) { 00179 unsigned mtu = dev->mtu; 00180 RTA_PUT(skb, IFLA_MTU, sizeof(mtu), &mtu); 00181 } 00182 if (dev->ifindex != dev->iflink) 00183 RTA_PUT(skb, IFLA_LINK, sizeof(int), &dev->iflink); 00184 if (dev->qdisc_sleeping) 00185 RTA_PUT(skb, IFLA_QDISC, 00186 strlen(dev->qdisc_sleeping->ops->id) + 1, 00187 dev->qdisc_sleeping->ops->id); 00188 if (dev->master) 00189 RTA_PUT(skb, IFLA_MASTER, sizeof(int), &dev->master->ifindex); 00190 if (dev->get_stats) { 00191 struct net_device_stats *stats = dev->get_stats(dev); 00192 if (stats) 00193 RTA_PUT(skb, IFLA_STATS, sizeof(*stats), stats); 00194 } 00195 nlh->nlmsg_len = skb->tail - b; 00196 return skb->len; 00197 00198 nlmsg_failure: 00199 rtattr_failure: 00200 skb_trim(skb, b - skb->data); 00201 return -1; 00202 }

void __init rtnetlink_init void   ) 
 

Definition at line 518 of file rtnetlink.c.

References link_rtnetlink_table, netlink_kernel_create(), NETLINK_ROUTE, netlink_set_nonroot(), NL_NONROOT_RECV, register_netdevice_notifier(), rtnetlink_dev_notifier, rtnetlink_links, rtnetlink_rcv(), and rtnl.

Referenced by sock_init().

00519 { 00520 #ifdef RTNL_DEBUG 00521 printk("Initializing RT netlink socket\n"); 00522 #endif 00523 rtnl = netlink_kernel_create(NETLINK_ROUTE, rtnetlink_rcv); 00524 if (rtnl == NULL) 00525 panic("rtnetlink_init: cannot initialize rtnetlink\n"); 00526 netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV); 00527 register_netdevice_notifier(&rtnetlink_dev_notifier); 00528 rtnetlink_links[PF_UNSPEC] = link_rtnetlink_table; 00529 rtnetlink_links[PF_PACKET] = link_rtnetlink_table; 00530 }

int rtnetlink_put_metrics struct sk_buff skb,
unsigned *  metrics
 

Definition at line 131 of file rtnetlink.c.

References sk_buff::data, skb_trim(), and sk_buff::tail.

Referenced by fib_dump_info(), and rt_fill_info().

00132 { 00133 struct rtattr *mx = (struct rtattr*)skb->tail; 00134 int i; 00135 00136 RTA_PUT(skb, RTA_METRICS, 0, NULL); 00137 for (i=0; i<RTAX_MAX; i++) { 00138 if (metrics[i]) 00139 RTA_PUT(skb, i+1, sizeof(unsigned), metrics+i); 00140 } 00141 mx->rta_len = skb->tail - (u8*)mx; 00142 if (mx->rta_len == RTA_LENGTH(0)) 00143 skb_trim(skb, (u8*)mx - skb->data); 00144 return 0; 00145 00146 rtattr_failure: 00147 skb_trim(skb, (u8*)mx - skb->data); 00148 return -1; 00149 }

void rtnetlink_rcv struct sock sk,
int  len
[static]
 

Definition at line 435 of file rtnetlink.c.

References kfree_skb(), sk_buff_head::qlen, sock::receive_queue, rtnetlink_rcv_skb(), rtnl, skb_dequeue(), and skb_queue_head().

Referenced by rtnetlink_init().

00436 { 00437 do { 00438 struct sk_buff *skb; 00439 00440 if (rtnl_shlock_nowait()) 00441 return; 00442 00443 while ((skb = skb_dequeue(&sk->receive_queue)) != NULL) { 00444 if (rtnetlink_rcv_skb(skb)) { 00445 if (skb->len) 00446 skb_queue_head(&sk->receive_queue, skb); 00447 else 00448 kfree_skb(skb); 00449 break; 00450 } 00451 kfree_skb(skb); 00452 } 00453 00454 up(&rtnl_sem); 00455 } while (rtnl && rtnl->receive_queue.qlen); 00456 }

__inline__ int rtnetlink_rcv_msg struct sk_buff skb,
struct nlmsghdr nlh,
int *  errp
[static]
 

Definition at line 272 of file rtnetlink.c.

References sk_buff::len, NETLINK_CB, netlink_dump_start(), NLM_F_DUMP, NLM_F_REQUEST, NLMSG_ALIGN, NLMSG_DATA, nlmsghdr::nlmsg_flags, nlmsghdr::nlmsg_len, NLMSG_LENGTH, nlmsghdr::nlmsg_type, NPROTO, rta_max, rtm_min, rtnetlink_done(), rtnetlink_links, rtnl, and skb_pull().

Referenced by rtnetlink_rcv_skb().

00273 { 00274 struct rtnetlink_link *link; 00275 struct rtnetlink_link *link_tab; 00276 struct rtattr *rta[RTATTR_MAX]; 00277 00278 int exclusive = 0; 00279 int sz_idx, kind; 00280 int min_len; 00281 int family; 00282 int type; 00283 int err; 00284 00285 /* Only requests are handled by kernel now */ 00286 if (!(nlh->nlmsg_flags&NLM_F_REQUEST)) 00287 return 0; 00288 00289 type = nlh->nlmsg_type; 00290 00291 /* A control message: ignore them */ 00292 if (type < RTM_BASE) 00293 return 0; 00294 00295 /* Unknown message: reply with EINVAL */ 00296 if (type > RTM_MAX) 00297 goto err_inval; 00298 00299 type -= RTM_BASE; 00300 00301 /* All the messages must have at least 1 byte length */ 00302 if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(struct rtgenmsg))) 00303 return 0; 00304 00305 family = ((struct rtgenmsg*)NLMSG_DATA(nlh))->rtgen_family; 00306 if (family > NPROTO) { 00307 *errp = -EAFNOSUPPORT; 00308 return -1; 00309 } 00310 00311 link_tab = rtnetlink_links[family]; 00312 if (link_tab == NULL) 00313 link_tab = rtnetlink_links[PF_UNSPEC]; 00314 link = &link_tab[type]; 00315 00316 sz_idx = type>>2; 00317 kind = type&3; 00318 00319 if (kind != 2 && !cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) { 00320 *errp = -EPERM; 00321 return -1; 00322 } 00323 00324 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { 00325 u32 rlen; 00326 00327 if (link->dumpit == NULL) 00328 link = &(rtnetlink_links[PF_UNSPEC][type]); 00329 00330 if (link->dumpit == NULL) 00331 goto err_inval; 00332 00333 if ((*errp = netlink_dump_start(rtnl, skb, nlh, 00334 link->dumpit, 00335 rtnetlink_done)) != 0) { 00336 return -1; 00337 } 00338 rlen = NLMSG_ALIGN(nlh->nlmsg_len); 00339 if (rlen > skb->len) 00340 rlen = skb->len; 00341 skb_pull(skb, rlen); 00342 return -1; 00343 } 00344 00345 if (kind != 2) { 00346 if (rtnl_exlock_nowait()) { 00347 *errp = 0; 00348 return -1; 00349 } 00350 exclusive = 1; 00351 } 00352 00353 memset(&rta, 0, sizeof(rta)); 00354 00355 min_len = rtm_min[sz_idx]; 00356 if (nlh->nlmsg_len < min_len) 00357 goto err_inval; 00358 00359 if (nlh->nlmsg_len > min_len) { 00360 int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); 00361 struct rtattr *attr = (void*)nlh + NLMSG_ALIGN(min_len); 00362 00363 while (RTA_OK(attr, attrlen)) { 00364 unsigned flavor = attr->rta_type; 00365 if (flavor) { 00366 if (flavor > rta_max[sz_idx]) 00367 goto err_inval; 00368 rta[flavor-1] = attr; 00369 } 00370 attr = RTA_NEXT(attr, attrlen); 00371 } 00372 } 00373 00374 if (link->doit == NULL) 00375 link = &(rtnetlink_links[PF_UNSPEC][type]); 00376 if (link->doit == NULL) 00377 goto err_inval; 00378 err = link->doit(skb, nlh, (void *)&rta); 00379 00380 if (exclusive) 00381 rtnl_exunlock(); 00382 *errp = err; 00383 return err; 00384 00385 err_inval: 00386 if (exclusive) 00387 rtnl_exunlock(); 00388 *errp = -EINVAL; 00389 return -1; 00390 }

int rtnetlink_rcv_skb struct sk_buff skb  )  [inline, static]
 

Definition at line 397 of file rtnetlink.c.

References sk_buff::data, sk_buff::len, netlink_ack(), NLM_F_ACK, NLMSG_ALIGN, NLMSG_SPACE, rtnetlink_rcv_msg(), and skb_pull().

Referenced by rtnetlink_rcv().

00398 { 00399 int err; 00400 struct nlmsghdr * nlh; 00401 00402 while (skb->len >= NLMSG_SPACE(0)) { 00403 u32 rlen; 00404 00405 nlh = (struct nlmsghdr *)skb->data; 00406 if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) 00407 return 0; 00408 rlen = NLMSG_ALIGN(nlh->nlmsg_len); 00409 if (rlen > skb->len) 00410 rlen = skb->len; 00411 if (rtnetlink_rcv_msg(skb, nlh, &err)) { 00412 /* Not error, but we must interrupt processing here: 00413 * Note, that in this case we do not pull message 00414 * from skb, it will be processed later. 00415 */ 00416 if (err == 0) 00417 return -1; 00418 netlink_ack(skb, nlh, err); 00419 } else if (nlh->nlmsg_flags&NLM_F_ACK) 00420 netlink_ack(skb, nlh, 0); 00421 skb_pull(skb, rlen); 00422 } 00423 00424 return 0; 00425 }

int rtnetlink_send struct sk_buff skb,
u32  pid,
unsigned  group,
int  echo
 

Definition at line 118 of file rtnetlink.c.

References netlink_broadcast(), NETLINK_CB, netlink_unicast(), rtnl, and sk_buff::users.

00119 { 00120 int err = 0; 00121 00122 NETLINK_CB(skb).dst_groups = group; 00123 if (echo) 00124 atomic_inc(&skb->users); 00125 netlink_broadcast(rtnl, skb, pid, group, GFP_KERNEL); 00126 if (echo) 00127 err = netlink_unicast(rtnl, skb, pid, MSG_DONTWAIT); 00128 return err; 00129 }

void rtnl_lock void   ) 
 

Definition at line 54 of file rtnetlink.c.

Referenced by arp_ioctl(), dev_ioctl(), devinet_ioctl(), ip_mc_drop_socket(), ip_mc_leave_group(), ip_mroute_setsockopt(), ip_rt_ioctl(), mrtsock_destruct(), and setup_inject().

00055 { 00056 rtnl_shlock(); 00057 rtnl_exlock(); 00058 }

void rtnl_unlock void   ) 
 

Definition at line 60 of file rtnetlink.c.

Referenced by arp_ioctl(), dev_ioctl(), devinet_ioctl(), ip_mc_drop_socket(), ip_mc_leave_group(), ip_mroute_setsockopt(), ip_rt_ioctl(), mrtsock_destruct(), and setup_inject().

00061 { 00062 rtnl_exunlock(); 00063 rtnl_shunlock(); 00064 }


Variable Documentation

struct rtnetlink_link link_rtnetlink_table[RTM_MAX-RTM_BASE+1] [static]
 

Initial value:

{ { NULL, NULL, }, { NULL, NULL, }, { NULL, rtnetlink_dump_ifinfo, }, { NULL, NULL, }, { NULL, NULL, }, { NULL, NULL, }, { NULL, rtnetlink_dump_all, }, { NULL, NULL, }, { NULL, NULL, }, { NULL, NULL, }, { NULL, rtnetlink_dump_all, }, { NULL, NULL, }, { neigh_add, NULL, }, { neigh_delete, NULL, }, { NULL, neigh_dump_info, }, { NULL, NULL, }, { NULL, NULL, }, { NULL, NULL, }, { NULL, NULL, }, { NULL, NULL, }, }
Definition at line 458 of file rtnetlink.c.

Referenced by rtnetlink_init().

const int rta_max[(RTM_MAX+1-RTM_BASE)/4] [static]
 

Initial value:

{ IFLA_MAX, IFA_MAX, RTA_MAX, NDA_MAX, RTA_MAX, TCA_MAX, TCA_MAX, TCA_MAX }
Definition at line 95 of file rtnetlink.c.

Referenced by rtnetlink_rcv_msg().

const int rtm_min[(RTM_MAX+1-RTM_BASE)/4] [static]
 

Initial value:

{ NLMSG_LENGTH(sizeof(struct ifinfomsg)), NLMSG_LENGTH(sizeof(struct ifaddrmsg)), NLMSG_LENGTH(sizeof(struct rtmsg)), NLMSG_LENGTH(sizeof(struct ndmsg)), NLMSG_LENGTH(sizeof(struct rtmsg)), NLMSG_LENGTH(sizeof(struct tcmsg)), NLMSG_LENGTH(sizeof(struct tcmsg)), NLMSG_LENGTH(sizeof(struct tcmsg)) }
Definition at line 83 of file rtnetlink.c.

Referenced by rtnetlink_rcv_msg().

struct notifier_block rtnetlink_dev_notifier
 

Initial value:

{ rtnetlink_event, NULL, 0 }
Definition at line 511 of file rtnetlink.c.

Referenced by rtnetlink_init().

struct rtnetlink_link* rtnetlink_links[NPROTO]
 

Definition at line 81 of file rtnetlink.c.

Referenced by devinet_init(), rtnetlink_dump_all(), rtnetlink_init(), and rtnetlink_rcv_msg().

struct sock* rtnl
 

Definition at line 79 of file rtnetlink.c.

Referenced by inet_rtm_getroute(), ipmr_cache_resolve(), ipmr_destroy_unres(), rtmsg_fib(), rtmsg_ifa(), rtmsg_ifinfo(), rtmsg_iwinfo(), rtnetlink_init(), rtnetlink_rcv(), rtnetlink_rcv_msg(), and rtnetlink_send().


Generated on Wed Dec 1 21:25:39 2004 for Linux 2.4.23 Networking by doxygen 1.3.8