Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

rtnetlink.h

Go to the documentation of this file.
00001 #ifndef __LINUX_RTNETLINK_H
00002 #define __LINUX_RTNETLINK_H
00003 
00004 #ifdef __KERNEL__
00005 #include <linux/config.h>
00006 #endif
00007 #include <linux/netlink.h>
00008 
00009 #define RTNL_DEBUG 1
00010 
00011 
00012 /****
00013  *              Routing/neighbour discovery messages.
00014  ****/
00015 
00016 /* Types of messages */
00017 
00018 #define RTM_BASE        0x10
00019 
00020 #define RTM_NEWLINK     (RTM_BASE+0)
00021 #define RTM_DELLINK     (RTM_BASE+1)
00022 #define RTM_GETLINK     (RTM_BASE+2)
00023 
00024 #define RTM_NEWADDR     (RTM_BASE+4)
00025 #define RTM_DELADDR     (RTM_BASE+5)
00026 #define RTM_GETADDR     (RTM_BASE+6)
00027 
00028 #define RTM_NEWROUTE    (RTM_BASE+8)
00029 #define RTM_DELROUTE    (RTM_BASE+9)
00030 #define RTM_GETROUTE    (RTM_BASE+10)
00031 
00032 #define RTM_NEWNEIGH    (RTM_BASE+12)
00033 #define RTM_DELNEIGH    (RTM_BASE+13)
00034 #define RTM_GETNEIGH    (RTM_BASE+14)
00035 
00036 #define RTM_NEWRULE     (RTM_BASE+16)
00037 #define RTM_DELRULE     (RTM_BASE+17)
00038 #define RTM_GETRULE     (RTM_BASE+18)
00039 
00040 #define RTM_NEWQDISC    (RTM_BASE+20)
00041 #define RTM_DELQDISC    (RTM_BASE+21)
00042 #define RTM_GETQDISC    (RTM_BASE+22)
00043 
00044 #define RTM_NEWTCLASS   (RTM_BASE+24)
00045 #define RTM_DELTCLASS   (RTM_BASE+25)
00046 #define RTM_GETTCLASS   (RTM_BASE+26)
00047 
00048 #define RTM_NEWTFILTER  (RTM_BASE+28)
00049 #define RTM_DELTFILTER  (RTM_BASE+29)
00050 #define RTM_GETTFILTER  (RTM_BASE+30)
00051 
00052 #define RTM_MAX         (RTM_BASE+31)
00053 
00054 /* 
00055    Generic structure for encapsulation optional route information.
00056    It is reminiscent of sockaddr, but with sa_family replaced
00057    with attribute type.
00058  */
00059 
00060 struct rtattr
00061 {
00062         unsigned short  rta_len;
00063         unsigned short  rta_type;
00064 };
00065 
00066 /* Macros to handle rtattributes */
00067 
00068 #define RTA_ALIGNTO     4
00069 #define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) )
00070 #define RTA_OK(rta,len) ((len) > 0 && (rta)->rta_len >= sizeof(struct rtattr) && \
00071                          (rta)->rta_len <= (len))
00072 #define RTA_NEXT(rta,attrlen)   ((attrlen) -= RTA_ALIGN((rta)->rta_len), \
00073                                  (struct rtattr*)(((char*)(rta)) + RTA_ALIGN((rta)->rta_len)))
00074 #define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
00075 #define RTA_SPACE(len)  RTA_ALIGN(RTA_LENGTH(len))
00076 #define RTA_DATA(rta)   ((void*)(((char*)(rta)) + RTA_LENGTH(0)))
00077 #define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
00078 
00079 
00080 
00081 
00082 /******************************************************************************
00083  *              Definitions used in routing table administation.
00084  ****/
00085 
00086 struct rtmsg
00087 {
00088         unsigned char           rtm_family;
00089         unsigned char           rtm_dst_len;
00090         unsigned char           rtm_src_len;
00091         unsigned char           rtm_tos;
00092 
00093         unsigned char           rtm_table;      /* Routing table id */
00094         unsigned char           rtm_protocol;   /* Routing protocol; see below  */
00095         unsigned char           rtm_scope;      /* See below */ 
00096         unsigned char           rtm_type;       /* See below    */
00097 
00098         unsigned                rtm_flags;
00099 };
00100 
00101 /* rtm_type */
00102 
00103 enum
00104 {
00105         RTN_UNSPEC,
00106         RTN_UNICAST,            /* Gateway or direct route      */
00107         RTN_LOCAL,              /* Accept locally               */
00108         RTN_BROADCAST,          /* Accept locally as broadcast,
00109                                    send as broadcast */
00110         RTN_ANYCAST,            /* Accept locally as broadcast,
00111                                    but send as unicast */
00112         RTN_MULTICAST,          /* Multicast route              */
00113         RTN_BLACKHOLE,          /* Drop                         */
00114         RTN_UNREACHABLE,        /* Destination is unreachable   */
00115         RTN_PROHIBIT,           /* Administratively prohibited  */
00116         RTN_THROW,              /* Not in this table            */
00117         RTN_NAT,                /* Translate this address       */
00118         RTN_XRESOLVE,           /* Use external resolver        */
00119 };
00120 
00121 #define RTN_MAX RTN_XRESOLVE
00122 
00123 
00124 /* rtm_protocol */
00125 
00126 #define RTPROT_UNSPEC   0
00127 #define RTPROT_REDIRECT 1       /* Route installed by ICMP redirects;
00128                                    not used by current IPv4 */
00129 #define RTPROT_KERNEL   2       /* Route installed by kernel            */
00130 #define RTPROT_BOOT     3       /* Route installed during boot          */
00131 #define RTPROT_STATIC   4       /* Route installed by administrator     */
00132 
00133 /* Values of protocol >= RTPROT_STATIC are not interpreted by kernel;
00134    they just passed from user and back as is.
00135    It will be used by hypothetical multiple routing daemons.
00136    Note that protocol values should be standardized in order to
00137    avoid conflicts.
00138  */
00139 
00140 #define RTPROT_GATED    8       /* Apparently, GateD */
00141 #define RTPROT_RA       9       /* RDISC/ND router advertisments */
00142 #define RTPROT_MRT      10      /* Merit MRT */
00143 #define RTPROT_ZEBRA    11      /* Zebra */
00144 #define RTPROT_BIRD     12      /* BIRD */
00145 
00146 /* rtm_scope
00147 
00148    Really it is not scope, but sort of distance to the destination.
00149    NOWHERE are reserved for not existing destinations, HOST is our
00150    local addresses, LINK are destinations, located on directly attached
00151    link and UNIVERSE is everywhere in the Universe.
00152 
00153    Intermediate values are also possible f.e. interior routes
00154    could be assigned a value between UNIVERSE and LINK.
00155 */
00156 
00157 enum rt_scope_t
00158 {
00159         RT_SCOPE_UNIVERSE=0,
00160 /* User defined values  */
00161         RT_SCOPE_SITE=200,
00162         RT_SCOPE_LINK=253,
00163         RT_SCOPE_HOST=254,
00164         RT_SCOPE_NOWHERE=255
00165 };
00166 
00167 /* rtm_flags */
00168 
00169 #define RTM_F_NOTIFY            0x100   /* Notify user of route change  */
00170 #define RTM_F_CLONED            0x200   /* This route is cloned         */
00171 #define RTM_F_EQUALIZE          0x400   /* Multipath equalizer: NI      */
00172 
00173 /* Reserved table identifiers */
00174 
00175 enum rt_class_t
00176 {
00177         RT_TABLE_UNSPEC=0,
00178 /* User defined values */
00179         RT_TABLE_DEFAULT=253,
00180         RT_TABLE_MAIN=254,
00181         RT_TABLE_LOCAL=255
00182 };
00183 #define RT_TABLE_MAX RT_TABLE_LOCAL
00184 
00185 
00186 
00187 /* Routing message attributes */
00188 
00189 enum rtattr_type_t
00190 {
00191         RTA_UNSPEC,
00192         RTA_DST,
00193         RTA_SRC,
00194         RTA_IIF,
00195         RTA_OIF,
00196         RTA_GATEWAY,
00197         RTA_PRIORITY,
00198         RTA_PREFSRC,
00199         RTA_METRICS,
00200         RTA_MULTIPATH,
00201         RTA_PROTOINFO,
00202         RTA_FLOW,
00203         RTA_CACHEINFO
00204 };
00205 
00206 #define RTA_MAX RTA_CACHEINFO
00207 
00208 #define RTM_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtmsg))))
00209 #define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtmsg))
00210 
00211 /* RTM_MULTIPATH --- array of struct rtnexthop.
00212  *
00213  * "struct rtnexthop" describres all necessary nexthop information,
00214  * i.e. parameters of path to a destination via this nextop.
00215  *
00216  * At the moment it is impossible to set different prefsrc, mtu, window
00217  * and rtt for different paths from multipath.
00218  */
00219 
00220 struct rtnexthop
00221 {
00222         unsigned short          rtnh_len;
00223         unsigned char           rtnh_flags;
00224         unsigned char           rtnh_hops;
00225         int                     rtnh_ifindex;
00226 };
00227 
00228 /* rtnh_flags */
00229 
00230 #define RTNH_F_DEAD             1       /* Nexthop is dead (used by multipath)  */
00231 #define RTNH_F_PERVASIVE        2       /* Do recursive gateway lookup  */
00232 #define RTNH_F_ONLINK           4       /* Gateway is forced on link    */
00233 
00234 /* Macros to handle hexthops */
00235 
00236 #define RTNH_ALIGNTO    4
00237 #define RTNH_ALIGN(len) ( ((len)+RTNH_ALIGNTO-1) & ~(RTNH_ALIGNTO-1) )
00238 #define RTNH_OK(rtnh,len) ((rtnh)->rtnh_len >= sizeof(struct rtnexthop) && \
00239                            ((int)(rtnh)->rtnh_len) <= (len))
00240 #define RTNH_NEXT(rtnh) ((struct rtnexthop*)(((char*)(rtnh)) + RTNH_ALIGN((rtnh)->rtnh_len)))
00241 #define RTNH_LENGTH(len) (RTNH_ALIGN(sizeof(struct rtnexthop)) + (len))
00242 #define RTNH_SPACE(len) RTNH_ALIGN(RTNH_LENGTH(len))
00243 #define RTNH_DATA(rtnh)   ((struct rtattr*)(((char*)(rtnh)) + RTNH_LENGTH(0)))
00244 
00245 /* RTM_CACHEINFO */
00246 
00247 struct rta_cacheinfo
00248 {
00249         __u32   rta_clntref;
00250         __u32   rta_lastuse;
00251         __s32   rta_expires;
00252         __u32   rta_error;
00253         __u32   rta_used;
00254 };
00255 
00256 /* RTM_METRICS --- array of struct rtattr with types of RTAX_* */
00257 
00258 enum
00259 {
00260         RTAX_UNSPEC,
00261         RTAX_LOCK,
00262         RTAX_MTU,
00263         RTAX_WINDOW,
00264         RTAX_RTT,
00265         RTAX_HOPS,
00266         RTAX_SSTHRESH,
00267         RTAX_CWND,
00268 };
00269 
00270 #define RTAX_MAX RTAX_CWND
00271 
00272 
00273 
00274 /*********************************************************
00275  *              Interface address.
00276  ****/
00277 
00278 struct ifaddrmsg
00279 {
00280         unsigned char   ifa_family;
00281         unsigned char   ifa_prefixlen;  /* The prefix length            */
00282         unsigned char   ifa_flags;      /* Flags                        */
00283         unsigned char   ifa_scope;      /* See above                    */
00284         int             ifa_index;      /* Link index                   */
00285 };
00286 
00287 enum
00288 {
00289         IFA_UNSPEC,
00290         IFA_ADDRESS,
00291         IFA_LOCAL,
00292         IFA_LABEL,
00293         IFA_BROADCAST,
00294         IFA_ANYCAST,
00295         IFA_CACHEINFO
00296 };
00297 
00298 #define IFA_MAX IFA_CACHEINFO
00299 
00300 /* ifa_flags */
00301 
00302 #define IFA_F_SECONDARY         0x01
00303 
00304 #define IFA_F_DEPRECATED        0x20
00305 #define IFA_F_TENTATIVE         0x40
00306 #define IFA_F_PERMANENT         0x80
00307 
00308 struct ifa_cacheinfo
00309 {
00310         __s32   ifa_prefered;
00311         __s32   ifa_valid;
00312 };
00313 
00314 
00315 #define IFA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
00316 #define IFA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifaddrmsg))
00317 
00318 /*
00319    Important comment:
00320    IFA_ADDRESS is prefix address, rather than local interface address.
00321    It makes no difference for normally configured broadcast interfaces,
00322    but for point-to-point IFA_ADDRESS is DESTINATION address,
00323    local address is supplied in IFA_LOCAL attribute.
00324  */
00325 
00326 /**************************************************************
00327  *              Neighbour discovery.
00328  ****/
00329 
00330 struct ndmsg
00331 {
00332         unsigned char   ndm_family;
00333         unsigned char   ndm_pad1;
00334         unsigned short  ndm_pad2;
00335         int             ndm_ifindex;    /* Link index                   */
00336         __u16           ndm_state;
00337         __u8            ndm_flags;
00338         __u8            ndm_type;
00339 };
00340 
00341 enum
00342 {
00343         NDA_UNSPEC,
00344         NDA_DST,
00345         NDA_LLADDR,
00346         NDA_CACHEINFO
00347 };
00348 
00349 #define NDA_MAX NDA_CACHEINFO
00350 
00351 #define NDA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
00352 #define NDA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ndmsg))
00353 
00354 /*
00355  *      Neighbor Cache Entry Flags
00356  */
00357 
00358 #define NTF_PROXY       0x08    /* == ATF_PUBL */
00359 #define NTF_ROUTER      0x80
00360 
00361 /*
00362  *      Neighbor Cache Entry States.
00363  */
00364 
00365 #define NUD_INCOMPLETE  0x01
00366 #define NUD_REACHABLE   0x02
00367 #define NUD_STALE       0x04
00368 #define NUD_DELAY       0x08
00369 #define NUD_PROBE       0x10
00370 #define NUD_FAILED      0x20
00371 
00372 /* Dummy states */
00373 #define NUD_NOARP       0x40
00374 #define NUD_PERMANENT   0x80
00375 #define NUD_NONE        0x00
00376 
00377 
00378 struct nda_cacheinfo
00379 {
00380         __u32           ndm_confirmed;
00381         __u32           ndm_used;
00382         __u32           ndm_updated;
00383         __u32           ndm_refcnt;
00384 };
00385 
00386 /****
00387  *              General form of address family dependent message.
00388  ****/
00389 
00390 struct rtgenmsg
00391 {
00392         unsigned char           rtgen_family;
00393 };
00394 
00395 /*****************************************************************
00396  *              Link layer specific messages.
00397  ****/
00398 
00399 /* struct ifinfomsg
00400  * passes link level specific information, not dependent
00401  * on network protocol.
00402  */
00403 
00404 struct ifinfomsg
00405 {
00406         unsigned char   ifi_family;
00407         unsigned char   __ifi_pad;
00408         unsigned short  ifi_type;               /* ARPHRD_* */
00409         int             ifi_index;              /* Link index   */
00410         unsigned        ifi_flags;              /* IFF_* flags  */
00411         unsigned        ifi_change;             /* IFF_* change mask */
00412 };
00413 
00414 enum
00415 {
00416         IFLA_UNSPEC,
00417         IFLA_ADDRESS,
00418         IFLA_BROADCAST,
00419         IFLA_IFNAME,
00420         IFLA_MTU,
00421         IFLA_LINK,
00422         IFLA_QDISC,
00423         IFLA_STATS
00424 };
00425 
00426 
00427 #define IFLA_MAX IFLA_STATS
00428 
00429 #define IFLA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
00430 #define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
00431 
00432 /* ifi_flags.
00433 
00434    IFF_* flags.
00435 
00436    The only change is:
00437    IFF_LOOPBACK, IFF_BROADCAST and IFF_POINTOPOINT are
00438    more not changeable by user. They describe link media
00439    characteristics and set by device driver.
00440 
00441    Comments:
00442    - Combination IFF_BROADCAST|IFF_POINTOPOINT is invalid
00443    - If neiher of these three flags are set;
00444      the interface is NBMA.
00445 
00446    - IFF_MULTICAST does not mean anything special:
00447    multicasts can be used on all not-NBMA links.
00448    IFF_MULTICAST means that this media uses special encapsulation
00449    for multicast frames. Apparently, all IFF_POINTOPOINT and
00450    IFF_BROADCAST devices are able to use multicasts too.
00451  */
00452 
00453 /* ifi_link.
00454    For usual devices it is equal ifi_index.
00455    If it is a "virtual interface" (f.e. tunnel), ifi_link
00456    can point to real physical interface (f.e. for bandwidth calculations),
00457    or maybe 0, what means, that real media is unknown (usual
00458    for IPIP tunnels, when route to endpoint is allowed to change)
00459  */
00460 
00461 /*****************************************************************
00462  *              Traffic control messages.
00463  ****/
00464 
00465 struct tcmsg
00466 {
00467         unsigned char   tcm_family;
00468         unsigned char   tcm__pad1;
00469         unsigned short  tcm__pad2;
00470         int             tcm_ifindex;
00471         __u32           tcm_handle;
00472         __u32           tcm_parent;
00473         __u32           tcm_info;
00474 };
00475 
00476 enum
00477 {
00478         TCA_UNSPEC,
00479         TCA_KIND,
00480         TCA_OPTIONS,
00481         TCA_STATS,
00482         TCA_XSTATS,
00483         TCA_RATE,
00484 };
00485 
00486 #define TCA_MAX TCA_RATE
00487 
00488 #define TCA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
00489 #define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
00490 
00491 
00492 /* SUMMARY: maximal rtattr understood by kernel */
00493 
00494 #define RTATTR_MAX              RTA_MAX
00495 
00496 /* RTnetlink multicast groups */
00497 
00498 #define RTMGRP_LINK             1
00499 #define RTMGRP_NOTIFY           2
00500 #define RTMGRP_NEIGH            4
00501 #define RTMGRP_TC               8
00502 
00503 #define RTMGRP_IPV4_IFADDR      0x10
00504 #define RTMGRP_IPV4_MROUTE      0x20
00505 #define RTMGRP_IPV4_ROUTE       0x40
00506 
00507 #define RTMGRP_IPV6_IFADDR      0x100
00508 #define RTMGRP_IPV6_MROUTE      0x200
00509 #define RTMGRP_IPV6_ROUTE       0x400
00510 
00511 /* End of information exported to user level */
00512 
00513 #ifdef __KERNEL__
00514 
00515 extern atomic_t rtnl_rlockct;
00516 extern struct wait_queue *rtnl_wait;
00517 
00518 extern __inline__ int rtattr_strcmp(struct rtattr *rta, char *str)
00519 {
00520         int len = strlen(str) + 1;
00521         return len > rta->rta_len || memcmp(RTA_DATA(rta), str, len);
00522 }
00523 
00524 extern int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len);
00525 
00526 #ifdef CONFIG_RTNETLINK
00527 extern struct sock *rtnl;
00528 
00529 struct rtnetlink_link
00530 {
00531         int (*doit)(struct sk_buff *, struct nlmsghdr*, void *attr);
00532         int (*dumpit)(struct sk_buff *, struct netlink_callback *cb);
00533 };
00534 
00535 extern struct rtnetlink_link * rtnetlink_links[NPROTO];
00536 extern int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb);
00537 extern int rtnetlink_send(struct sk_buff *skb, u32 pid, u32 group, int echo);
00538 
00539 extern void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data);
00540 
00541 #define RTA_PUT(skb, attrtype, attrlen, data) \
00542 ({ if (skb_tailroom(skb) < (int)RTA_SPACE(attrlen)) goto rtattr_failure; \
00543    __rta_fill(skb, attrtype, attrlen, data); })
00544 
00545 extern unsigned long rtnl_wlockct;
00546 
00547 /* NOTE: these locks are not interrupt safe, are not SMP safe,
00548  * they are even not atomic. 8)8)8) ... and it is not a bug.
00549  * Really, if these locks will be programmed correctly,
00550  * all the addressing/routing machine would become SMP safe,
00551  * but is absolutely useless at the moment, because all the kernel
00552  * is not reenterable in any case. --ANK
00553  *
00554  * Well, atomic_* and set_bit provide the only thing here:
00555  * gcc is confused not to overoptimize them, that's all.
00556  * I remember as gcc splitted ++ operation, but cannot reproduce
00557  * it with gcc-2.7.*. --ANK
00558  *
00559  * One more note: rwlock facility should be written and put
00560  * to a kernel wide location: f.e. current implementation of semaphores
00561  * (especially, for x86) looks like a wonder. It would be good
00562  * to have something similar for rwlock. Recursive lock could be also
00563  * useful thing. --ANK
00564  */
00565 
00566 extern __inline__ int rtnl_shlock_nowait(void)
00567 {
00568         atomic_inc(&rtnl_rlockct);
00569         if (test_bit(0, &rtnl_wlockct)) {
00570                 atomic_dec(&rtnl_rlockct);
00571                 return -EAGAIN;
00572         }
00573         return 0;
00574 }
00575 
00576 extern __inline__ void rtnl_shlock(void)
00577 {
00578         while (rtnl_shlock_nowait())
00579                 sleep_on(&rtnl_wait);
00580 }
00581 
00582 /* Check for possibility to PROMOTE shared lock to exclusive.
00583    Shared lock must be already grabbed with rtnl_shlock*().
00584  */
00585 
00586 extern __inline__ int rtnl_exlock_nowait(void)
00587 {
00588         if (atomic_read(&rtnl_rlockct) > 1)
00589                 return -EAGAIN;
00590         if (test_and_set_bit(0, &rtnl_wlockct))
00591                 return -EAGAIN;
00592         return 0;
00593 }
00594 
00595 extern __inline__ void rtnl_exlock(void)
00596 {
00597         while (rtnl_exlock_nowait())
00598                 sleep_on(&rtnl_wait);
00599 }
00600 
00601 #if 0
00602 extern __inline__ void rtnl_shunlock(void)
00603 {
00604         atomic_dec(&rtnl_rlockct);
00605         if (atomic_read(&rtnl_rlockct) <= 1) {
00606                 wake_up(&rtnl_wait);
00607                 if (rtnl && rtnl->receive_queue.qlen)
00608                         rtnl->data_ready(rtnl, 0);
00609         }
00610 }
00611 #else
00612 
00613 /* The problem: inline requires to include <net/sock.h> and, hence,
00614    almost all of net includes :-(
00615  */
00616 
00617 #define rtnl_shunlock() ({ \
00618         atomic_dec(&rtnl_rlockct); \
00619         if (atomic_read(&rtnl_rlockct) <= 1) { \
00620                 wake_up(&rtnl_wait); \
00621                 if (rtnl && rtnl->receive_queue.qlen) \
00622                         rtnl->data_ready(rtnl, 0); \
00623         } \
00624 })
00625 #endif
00626 
00627 /* Release exclusive lock. Note, that we do not wake up rtnetlink socket,
00628  * it will be done later after releasing shared lock.
00629  */
00630 
00631 extern __inline__ void rtnl_exunlock(void)
00632 {
00633         clear_bit(0, &rtnl_wlockct);
00634         wake_up(&rtnl_wait);
00635 }
00636 
00637 #else
00638 
00639 extern __inline__ void rtnl_shlock(void)
00640 {
00641         while (atomic_read(&rtnl_rlockct))
00642                 sleep_on(&rtnl_wait);
00643         atomic_inc(&rtnl_rlockct);
00644 }
00645 
00646 extern __inline__ void rtnl_shunlock(void)
00647 {
00648         if (atomic_dec_and_test(&rtnl_rlockct))
00649                 wake_up(&rtnl_wait);
00650 }
00651 
00652 extern __inline__ void rtnl_exlock(void)
00653 {
00654 }
00655 
00656 extern __inline__ void rtnl_exunlock(void)
00657 {
00658 }
00659 
00660 #endif
00661 
00662 extern void rtnl_lock(void);
00663 extern void rtnl_unlock(void);
00664 extern void rtnetlink_init(void);
00665 
00666 #endif /* __KERNEL__ */
00667 
00668 
00669 #endif  /* __LINUX_RTNETLINK_H */