1#ifndef __LINUX_RTNETLINK_H
2#define __LINUX_RTNETLINK_H
3
4#include <linux/netlink.h>
5#include <linux/if_link.h>
6#include <linux/if_addr.h>
7#include <linux/neighbour.h>
8
9
10
11
12
13
14
15enum {
16 RTM_BASE = 16,
17#define RTM_BASE RTM_BASE
18
19 RTM_NEWLINK = 16,
20#define RTM_NEWLINK RTM_NEWLINK
21 RTM_DELLINK,
22#define RTM_DELLINK RTM_DELLINK
23 RTM_GETLINK,
24#define RTM_GETLINK RTM_GETLINK
25 RTM_SETLINK,
26#define RTM_SETLINK RTM_SETLINK
27
28 RTM_NEWADDR = 20,
29#define RTM_NEWADDR RTM_NEWADDR
30 RTM_DELADDR,
31#define RTM_DELADDR RTM_DELADDR
32 RTM_GETADDR,
33#define RTM_GETADDR RTM_GETADDR
34
35 RTM_NEWROUTE = 24,
36#define RTM_NEWROUTE RTM_NEWROUTE
37 RTM_DELROUTE,
38#define RTM_DELROUTE RTM_DELROUTE
39 RTM_GETROUTE,
40#define RTM_GETROUTE RTM_GETROUTE
41
42 RTM_NEWNEIGH = 28,
43#define RTM_NEWNEIGH RTM_NEWNEIGH
44 RTM_DELNEIGH,
45#define RTM_DELNEIGH RTM_DELNEIGH
46 RTM_GETNEIGH,
47#define RTM_GETNEIGH RTM_GETNEIGH
48
49 RTM_NEWRULE = 32,
50#define RTM_NEWRULE RTM_NEWRULE
51 RTM_DELRULE,
52#define RTM_DELRULE RTM_DELRULE
53 RTM_GETRULE,
54#define RTM_GETRULE RTM_GETRULE
55
56 RTM_NEWQDISC = 36,
57#define RTM_NEWQDISC RTM_NEWQDISC
58 RTM_DELQDISC,
59#define RTM_DELQDISC RTM_DELQDISC
60 RTM_GETQDISC,
61#define RTM_GETQDISC RTM_GETQDISC
62
63 RTM_NEWTCLASS = 40,
64#define RTM_NEWTCLASS RTM_NEWTCLASS
65 RTM_DELTCLASS,
66#define RTM_DELTCLASS RTM_DELTCLASS
67 RTM_GETTCLASS,
68#define RTM_GETTCLASS RTM_GETTCLASS
69
70 RTM_NEWTFILTER = 44,
71#define RTM_NEWTFILTER RTM_NEWTFILTER
72 RTM_DELTFILTER,
73#define RTM_DELTFILTER RTM_DELTFILTER
74 RTM_GETTFILTER,
75#define RTM_GETTFILTER RTM_GETTFILTER
76
77 RTM_NEWACTION = 48,
78#define RTM_NEWACTION RTM_NEWACTION
79 RTM_DELACTION,
80#define RTM_DELACTION RTM_DELACTION
81 RTM_GETACTION,
82#define RTM_GETACTION RTM_GETACTION
83
84 RTM_NEWPREFIX = 52,
85#define RTM_NEWPREFIX RTM_NEWPREFIX
86
87 RTM_GETMULTICAST = 58,
88#define RTM_GETMULTICAST RTM_GETMULTICAST
89
90 RTM_GETANYCAST = 62,
91#define RTM_GETANYCAST RTM_GETANYCAST
92
93 RTM_NEWNEIGHTBL = 64,
94#define RTM_NEWNEIGHTBL RTM_NEWNEIGHTBL
95 RTM_GETNEIGHTBL = 66,
96#define RTM_GETNEIGHTBL RTM_GETNEIGHTBL
97 RTM_SETNEIGHTBL,
98#define RTM_SETNEIGHTBL RTM_SETNEIGHTBL
99
100 RTM_NEWNDUSEROPT = 68,
101#define RTM_NEWNDUSEROPT RTM_NEWNDUSEROPT
102
103 RTM_NEWADDRLABEL = 72,
104#define RTM_NEWADDRLABEL RTM_NEWADDRLABEL
105 RTM_DELADDRLABEL,
106#define RTM_NEWADDRLABEL RTM_NEWADDRLABEL
107 RTM_GETADDRLABEL,
108#define RTM_GETADDRLABEL RTM_GETADDRLABEL
109
110 __RTM_MAX,
111#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
112};
113
114#define RTM_NR_MSGTYPES (RTM_MAX + 1 - RTM_BASE)
115#define RTM_NR_FAMILIES (RTM_NR_MSGTYPES >> 2)
116#define RTM_FAM(cmd) (((cmd) - RTM_BASE) >> 2)
117
118
119
120
121
122
123
124struct rtattr
125{
126 unsigned short rta_len;
127 unsigned short rta_type;
128};
129
130
131
132#define RTA_ALIGNTO 4
133#define RTA_ALIGN(len) ( ((len)+RTA_ALIGNTO-1) & ~(RTA_ALIGNTO-1) )
134#define RTA_OK(rta,len) ((len) >= (int)sizeof(struct rtattr) && \
135 (rta)->rta_len >= sizeof(struct rtattr) && \
136 (rta)->rta_len <= (len))
137#define RTA_NEXT(rta,attrlen) ((attrlen) -= RTA_ALIGN((rta)->rta_len), \
138 (struct rtattr*)(((char*)(rta)) + RTA_ALIGN((rta)->rta_len)))
139#define RTA_LENGTH(len) (RTA_ALIGN(sizeof(struct rtattr)) + (len))
140#define RTA_SPACE(len) RTA_ALIGN(RTA_LENGTH(len))
141#define RTA_DATA(rta) ((void*)(((char*)(rta)) + RTA_LENGTH(0)))
142#define RTA_PAYLOAD(rta) ((int)((rta)->rta_len) - RTA_LENGTH(0))
143
144
145
146
147
148
149
150
151struct rtmsg
152{
153 unsigned char rtm_family;
154 unsigned char rtm_dst_len;
155 unsigned char rtm_src_len;
156 unsigned char rtm_tos;
157
158 unsigned char rtm_table;
159 unsigned char rtm_protocol;
160 unsigned char rtm_scope;
161 unsigned char rtm_type;
162
163 unsigned rtm_flags;
164};
165
166
167
168enum
169{
170 RTN_UNSPEC,
171 RTN_UNICAST,
172 RTN_LOCAL,
173 RTN_BROADCAST,
174
175 RTN_ANYCAST,
176
177 RTN_MULTICAST,
178 RTN_BLACKHOLE,
179 RTN_UNREACHABLE,
180 RTN_PROHIBIT,
181 RTN_THROW,
182 RTN_NAT,
183 RTN_XRESOLVE,
184 __RTN_MAX
185};
186
187#define RTN_MAX (__RTN_MAX - 1)
188
189
190
191
192#define RTPROT_UNSPEC 0
193#define RTPROT_REDIRECT 1
194
195#define RTPROT_KERNEL 2
196#define RTPROT_BOOT 3
197#define RTPROT_STATIC 4
198
199
200
201
202
203
204
205
206#define RTPROT_GATED 8
207#define RTPROT_RA 9
208#define RTPROT_MRT 10
209#define RTPROT_ZEBRA 11
210#define RTPROT_BIRD 12
211#define RTPROT_DNROUTED 13
212#define RTPROT_XORP 14
213#define RTPROT_NTK 15
214
215
216
217
218
219
220
221
222
223
224
225
226enum rt_scope_t
227{
228 RT_SCOPE_UNIVERSE=0,
229
230 RT_SCOPE_SITE=200,
231 RT_SCOPE_LINK=253,
232 RT_SCOPE_HOST=254,
233 RT_SCOPE_NOWHERE=255
234};
235
236
237
238#define RTM_F_NOTIFY 0x100
239#define RTM_F_CLONED 0x200
240#define RTM_F_EQUALIZE 0x400
241#define RTM_F_PREFIX 0x800
242
243
244
245enum rt_class_t
246{
247 RT_TABLE_UNSPEC=0,
248
249 RT_TABLE_COMPAT=252,
250 RT_TABLE_DEFAULT=253,
251 RT_TABLE_MAIN=254,
252 RT_TABLE_LOCAL=255,
253 RT_TABLE_MAX=0xFFFFFFFF
254};
255
256
257
258
259enum rtattr_type_t
260{
261 RTA_UNSPEC,
262 RTA_DST,
263 RTA_SRC,
264 RTA_IIF,
265 RTA_OIF,
266 RTA_GATEWAY,
267 RTA_PRIORITY,
268 RTA_PREFSRC,
269 RTA_METRICS,
270 RTA_MULTIPATH,
271 RTA_PROTOINFO,
272 RTA_FLOW,
273 RTA_CACHEINFO,
274 RTA_SESSION,
275 RTA_MP_ALGO,
276 RTA_TABLE,
277 __RTA_MAX
278};
279
280#define RTA_MAX (__RTA_MAX - 1)
281
282#define RTM_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtmsg))))
283#define RTM_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtmsg))
284
285
286
287
288
289
290
291
292
293
294struct rtnexthop
295{
296 unsigned short rtnh_len;
297 unsigned char rtnh_flags;
298 unsigned char rtnh_hops;
299 int rtnh_ifindex;
300};
301
302
303
304#define RTNH_F_DEAD 1
305#define RTNH_F_PERVASIVE 2
306#define RTNH_F_ONLINK 4
307
308
309
310#define RTNH_ALIGNTO 4
311#define RTNH_ALIGN(len) ( ((len)+RTNH_ALIGNTO-1) & ~(RTNH_ALIGNTO-1) )
312#define RTNH_OK(rtnh,len) ((rtnh)->rtnh_len >= sizeof(struct rtnexthop) && \
313 ((int)(rtnh)->rtnh_len) <= (len))
314#define RTNH_NEXT(rtnh) ((struct rtnexthop*)(((char*)(rtnh)) + RTNH_ALIGN((rtnh)->rtnh_len)))
315#define RTNH_LENGTH(len) (RTNH_ALIGN(sizeof(struct rtnexthop)) + (len))
316#define RTNH_SPACE(len) RTNH_ALIGN(RTNH_LENGTH(len))
317#define RTNH_DATA(rtnh) ((struct rtattr*)(((char*)(rtnh)) + RTNH_LENGTH(0)))
318
319
320
321struct rta_cacheinfo
322{
323 __u32 rta_clntref;
324 __u32 rta_lastuse;
325 __s32 rta_expires;
326 __u32 rta_error;
327 __u32 rta_used;
328
329#define RTNETLINK_HAVE_PEERINFO 1
330 __u32 rta_id;
331 __u32 rta_ts;
332 __u32 rta_tsage;
333};
334
335
336
337enum
338{
339 RTAX_UNSPEC,
340#define RTAX_UNSPEC RTAX_UNSPEC
341 RTAX_LOCK,
342#define RTAX_LOCK RTAX_LOCK
343 RTAX_MTU,
344#define RTAX_MTU RTAX_MTU
345 RTAX_WINDOW,
346#define RTAX_WINDOW RTAX_WINDOW
347 RTAX_RTT,
348#define RTAX_RTT RTAX_RTT
349 RTAX_RTTVAR,
350#define RTAX_RTTVAR RTAX_RTTVAR
351 RTAX_SSTHRESH,
352#define RTAX_SSTHRESH RTAX_SSTHRESH
353 RTAX_CWND,
354#define RTAX_CWND RTAX_CWND
355 RTAX_ADVMSS,
356#define RTAX_ADVMSS RTAX_ADVMSS
357 RTAX_REORDERING,
358#define RTAX_REORDERING RTAX_REORDERING
359 RTAX_HOPLIMIT,
360#define RTAX_HOPLIMIT RTAX_HOPLIMIT
361 RTAX_INITCWND,
362#define RTAX_INITCWND RTAX_INITCWND
363 RTAX_FEATURES,
364#define RTAX_FEATURES RTAX_FEATURES
365 RTAX_RTO_MIN,
366#define RTAX_RTO_MIN RTAX_RTO_MIN
367 __RTAX_MAX
368};
369
370#define RTAX_MAX (__RTAX_MAX - 1)
371
372#define RTAX_FEATURE_ECN 0x00000001
373#define RTAX_FEATURE_SACK 0x00000002
374#define RTAX_FEATURE_TIMESTAMP 0x00000004
375#define RTAX_FEATURE_ALLFRAG 0x00000008
376
377struct rta_session
378{
379 __u8 proto;
380 __u8 pad1;
381 __u16 pad2;
382
383 union {
384 struct {
385 __u16 sport;
386 __u16 dport;
387 } ports;
388
389 struct {
390 __u8 type;
391 __u8 code;
392 __u16 ident;
393 } icmpt;
394
395 __u32 spi;
396 } u;
397};
398
399
400
401
402
403struct rtgenmsg
404{
405 unsigned char rtgen_family;
406};
407
408
409
410
411
412
413
414
415
416
417struct ifinfomsg
418{
419 unsigned char ifi_family;
420 unsigned char __ifi_pad;
421 unsigned short ifi_type;
422 int ifi_index;
423 unsigned ifi_flags;
424 unsigned ifi_change;
425};
426
427
428
429
430
431struct prefixmsg
432{
433 unsigned char prefix_family;
434 unsigned char prefix_pad1;
435 unsigned short prefix_pad2;
436 int prefix_ifindex;
437 unsigned char prefix_type;
438 unsigned char prefix_len;
439 unsigned char prefix_flags;
440 unsigned char prefix_pad3;
441};
442
443enum
444{
445 PREFIX_UNSPEC,
446 PREFIX_ADDRESS,
447 PREFIX_CACHEINFO,
448 __PREFIX_MAX
449};
450
451#define PREFIX_MAX (__PREFIX_MAX - 1)
452
453struct prefix_cacheinfo
454{
455 __u32 preferred_time;
456 __u32 valid_time;
457};
458
459
460
461
462
463
464struct tcmsg
465{
466 unsigned char tcm_family;
467 unsigned char tcm__pad1;
468 unsigned short tcm__pad2;
469 int tcm_ifindex;
470 __u32 tcm_handle;
471 __u32 tcm_parent;
472 __u32 tcm_info;
473};
474
475enum
476{
477 TCA_UNSPEC,
478 TCA_KIND,
479 TCA_OPTIONS,
480 TCA_STATS,
481 TCA_XSTATS,
482 TCA_RATE,
483 TCA_FCNT,
484 TCA_STATS2,
485 TCA_STAB,
486 __TCA_MAX
487};
488
489#define TCA_MAX (__TCA_MAX - 1)
490
491#define TCA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcmsg))))
492#define TCA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcmsg))
493
494
495
496
497
498struct nduseroptmsg
499{
500 unsigned char nduseropt_family;
501 unsigned char nduseropt_pad1;
502 unsigned short nduseropt_opts_len;
503 int nduseropt_ifindex;
504 __u8 nduseropt_icmp_type;
505 __u8 nduseropt_icmp_code;
506 unsigned short nduseropt_pad2;
507 unsigned int nduseropt_pad3;
508
509};
510
511enum
512{
513 NDUSEROPT_UNSPEC,
514 NDUSEROPT_SRCADDR,
515 __NDUSEROPT_MAX
516};
517
518#define NDUSEROPT_MAX (__NDUSEROPT_MAX - 1)
519
520#ifndef __KERNEL__
521
522#define RTMGRP_LINK 1
523#define RTMGRP_NOTIFY 2
524#define RTMGRP_NEIGH 4
525#define RTMGRP_TC 8
526
527#define RTMGRP_IPV4_IFADDR 0x10
528#define RTMGRP_IPV4_MROUTE 0x20
529#define RTMGRP_IPV4_ROUTE 0x40
530#define RTMGRP_IPV4_RULE 0x80
531
532#define RTMGRP_IPV6_IFADDR 0x100
533#define RTMGRP_IPV6_MROUTE 0x200
534#define RTMGRP_IPV6_ROUTE 0x400
535#define RTMGRP_IPV6_IFINFO 0x800
536
537#define RTMGRP_DECnet_IFADDR 0x1000
538#define RTMGRP_DECnet_ROUTE 0x4000
539
540#define RTMGRP_IPV6_PREFIX 0x20000
541#endif
542
543
544enum rtnetlink_groups {
545 RTNLGRP_NONE,
546#define RTNLGRP_NONE RTNLGRP_NONE
547 RTNLGRP_LINK,
548#define RTNLGRP_LINK RTNLGRP_LINK
549 RTNLGRP_NOTIFY,
550#define RTNLGRP_NOTIFY RTNLGRP_NOTIFY
551 RTNLGRP_NEIGH,
552#define RTNLGRP_NEIGH RTNLGRP_NEIGH
553 RTNLGRP_TC,
554#define RTNLGRP_TC RTNLGRP_TC
555 RTNLGRP_IPV4_IFADDR,
556#define RTNLGRP_IPV4_IFADDR RTNLGRP_IPV4_IFADDR
557 RTNLGRP_IPV4_MROUTE,
558#define RTNLGRP_IPV4_MROUTE RTNLGRP_IPV4_MROUTE
559 RTNLGRP_IPV4_ROUTE,
560#define RTNLGRP_IPV4_ROUTE RTNLGRP_IPV4_ROUTE
561 RTNLGRP_IPV4_RULE,
562#define RTNLGRP_IPV4_RULE RTNLGRP_IPV4_RULE
563 RTNLGRP_IPV6_IFADDR,
564#define RTNLGRP_IPV6_IFADDR RTNLGRP_IPV6_IFADDR
565 RTNLGRP_IPV6_MROUTE,
566#define RTNLGRP_IPV6_MROUTE RTNLGRP_IPV6_MROUTE
567 RTNLGRP_IPV6_ROUTE,
568#define RTNLGRP_IPV6_ROUTE RTNLGRP_IPV6_ROUTE
569 RTNLGRP_IPV6_IFINFO,
570#define RTNLGRP_IPV6_IFINFO RTNLGRP_IPV6_IFINFO
571 RTNLGRP_DECnet_IFADDR,
572#define RTNLGRP_DECnet_IFADDR RTNLGRP_DECnet_IFADDR
573 RTNLGRP_NOP2,
574 RTNLGRP_DECnet_ROUTE,
575#define RTNLGRP_DECnet_ROUTE RTNLGRP_DECnet_ROUTE
576 RTNLGRP_DECnet_RULE,
577#define RTNLGRP_DECnet_RULE RTNLGRP_DECnet_RULE
578 RTNLGRP_NOP4,
579 RTNLGRP_IPV6_PREFIX,
580#define RTNLGRP_IPV6_PREFIX RTNLGRP_IPV6_PREFIX
581 RTNLGRP_IPV6_RULE,
582#define RTNLGRP_IPV6_RULE RTNLGRP_IPV6_RULE
583 RTNLGRP_ND_USEROPT,
584#define RTNLGRP_ND_USEROPT RTNLGRP_ND_USEROPT
585 RTNLGRP_PHONET_IFADDR,
586#define RTNLGRP_PHONET_IFADDR RTNLGRP_PHONET_IFADDR
587 RTNLGRP_PHONET_ROUTE,
588#define RTNLGRP_PHONET_ROUTE RTNLGRP_PHONET_ROUTE
589 __RTNLGRP_MAX
590};
591#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
592
593
594struct tcamsg
595{
596 unsigned char tca_family;
597 unsigned char tca__pad1;
598 unsigned short tca__pad2;
599};
600#define TA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct tcamsg))))
601#define TA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct tcamsg))
602#define TCA_ACT_TAB 1
603#define TCAA_MAX 1
604
605
606
607#ifdef __KERNEL__
608
609#include <linux/mutex.h>
610
611static __inline__ int rtattr_strcmp(const struct rtattr *rta, const char *str)
612{
613 int len = strlen(str) + 1;
614 return len > rta->rta_len || memcmp(RTA_DATA(rta), str, len);
615}
616
617extern int rtnetlink_send(struct sk_buff *skb, struct net *net, u32 pid, u32 group, int echo);
618extern int rtnl_unicast(struct sk_buff *skb, struct net *net, u32 pid);
619extern int rtnl_notify(struct sk_buff *skb, struct net *net, u32 pid, u32 group,
620 struct nlmsghdr *nlh, gfp_t flags);
621extern void rtnl_set_sk_err(struct net *net, u32 group, int error);
622extern int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics);
623extern int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst,
624 u32 id, u32 ts, u32 tsage, long expires,
625 u32 error);
626
627extern void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data);
628
629#define RTA_PUT(skb, attrtype, attrlen, data) \
630({ if (unlikely(skb_tailroom(skb) < (int)RTA_SPACE(attrlen))) \
631 goto rtattr_failure; \
632 __rta_fill(skb, attrtype, attrlen, data); })
633
634#define RTA_APPEND(skb, attrlen, data) \
635({ if (unlikely(skb_tailroom(skb) < (int)(attrlen))) \
636 goto rtattr_failure; \
637 memcpy(skb_put(skb, attrlen), data, attrlen); })
638
639#define RTA_PUT_NOHDR(skb, attrlen, data) \
640({ RTA_APPEND(skb, RTA_ALIGN(attrlen), data); \
641 memset(skb_tail_pointer(skb) - (RTA_ALIGN(attrlen) - attrlen), 0, \
642 RTA_ALIGN(attrlen) - attrlen); })
643
644#define RTA_PUT_U8(skb, attrtype, value) \
645({ u8 _tmp = (value); \
646 RTA_PUT(skb, attrtype, sizeof(u8), &_tmp); })
647
648#define RTA_PUT_U16(skb, attrtype, value) \
649({ u16 _tmp = (value); \
650 RTA_PUT(skb, attrtype, sizeof(u16), &_tmp); })
651
652#define RTA_PUT_U32(skb, attrtype, value) \
653({ u32 _tmp = (value); \
654 RTA_PUT(skb, attrtype, sizeof(u32), &_tmp); })
655
656#define RTA_PUT_U64(skb, attrtype, value) \
657({ u64 _tmp = (value); \
658 RTA_PUT(skb, attrtype, sizeof(u64), &_tmp); })
659
660#define RTA_PUT_SECS(skb, attrtype, value) \
661 RTA_PUT_U64(skb, attrtype, (value) / HZ)
662
663#define RTA_PUT_MSECS(skb, attrtype, value) \
664 RTA_PUT_U64(skb, attrtype, jiffies_to_msecs(value))
665
666#define RTA_PUT_STRING(skb, attrtype, value) \
667 RTA_PUT(skb, attrtype, strlen(value) + 1, value)
668
669#define RTA_PUT_FLAG(skb, attrtype) \
670 RTA_PUT(skb, attrtype, 0, NULL);
671
672#define RTA_NEST(skb, type) \
673({ struct rtattr *__start = (struct rtattr *)skb_tail_pointer(skb); \
674 RTA_PUT(skb, type, 0, NULL); \
675 __start; })
676
677#define RTA_NEST_END(skb, start) \
678({ (start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
679 (skb)->len; })
680
681#define RTA_NEST_COMPAT(skb, type, attrlen, data) \
682({ struct rtattr *__start = (struct rtattr *)skb_tail_pointer(skb); \
683 RTA_PUT(skb, type, attrlen, data); \
684 RTA_NEST(skb, type); \
685 __start; })
686
687#define RTA_NEST_COMPAT_END(skb, start) \
688({ struct rtattr *__nest = (void *)(start) + NLMSG_ALIGN((start)->rta_len); \
689 (start)->rta_len = skb_tail_pointer(skb) - (unsigned char *)(start); \
690 RTA_NEST_END(skb, __nest); \
691 (skb)->len; })
692
693#define RTA_NEST_CANCEL(skb, start) \
694({ if (start) \
695 skb_trim(skb, (unsigned char *) (start) - (skb)->data); \
696 -1; })
697
698#define RTA_GET_U8(rta) \
699({ if (!rta || RTA_PAYLOAD(rta) < sizeof(u8)) \
700 goto rtattr_failure; \
701 *(u8 *) RTA_DATA(rta); })
702
703#define RTA_GET_U16(rta) \
704({ if (!rta || RTA_PAYLOAD(rta) < sizeof(u16)) \
705 goto rtattr_failure; \
706 *(u16 *) RTA_DATA(rta); })
707
708#define RTA_GET_U32(rta) \
709({ if (!rta || RTA_PAYLOAD(rta) < sizeof(u32)) \
710 goto rtattr_failure; \
711 *(u32 *) RTA_DATA(rta); })
712
713#define RTA_GET_U64(rta) \
714({ u64 _tmp; \
715 if (!rta || RTA_PAYLOAD(rta) < sizeof(u64)) \
716 goto rtattr_failure; \
717 memcpy(&_tmp, RTA_DATA(rta), sizeof(_tmp)); \
718 _tmp; })
719
720#define RTA_GET_FLAG(rta) (!!(rta))
721
722#define RTA_GET_SECS(rta) ((unsigned long) RTA_GET_U64(rta) * HZ)
723#define RTA_GET_MSECS(rta) (msecs_to_jiffies((unsigned long) RTA_GET_U64(rta)))
724
725static inline struct rtattr *
726__rta_reserve(struct sk_buff *skb, int attrtype, int attrlen)
727{
728 struct rtattr *rta;
729 int size = RTA_LENGTH(attrlen);
730
731 rta = (struct rtattr*)skb_put(skb, RTA_ALIGN(size));
732 rta->rta_type = attrtype;
733 rta->rta_len = size;
734 memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size);
735 return rta;
736}
737
738#define __RTA_PUT(skb, attrtype, attrlen) \
739({ if (unlikely(skb_tailroom(skb) < (int)RTA_SPACE(attrlen))) \
740 goto rtattr_failure; \
741 __rta_reserve(skb, attrtype, attrlen); })
742
743extern void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change);
744
745
746extern void rtnl_lock(void);
747extern void rtnl_unlock(void);
748extern int rtnl_trylock(void);
749extern int rtnl_is_locked(void);
750
751extern void rtnetlink_init(void);
752extern void __rtnl_unlock(void);
753
754#define ASSERT_RTNL() do { \
755 if (unlikely(!rtnl_is_locked())) { \
756 printk(KERN_ERR "RTNL: assertion failed at %s (%d)\n", \
757 __FILE__, __LINE__); \
758 dump_stack(); \
759 } \
760} while(0)
761
762static inline u32 rtm_get_table(struct rtattr **rta, u8 table)
763{
764 return RTA_GET_U32(rta[RTA_TABLE-1]);
765rtattr_failure:
766 return table;
767}
768
769#endif
770
771
772#endif
773