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