1use errno::Errno;
2use libc::{c_int, c_uchar, c_uint, c_ushort, sa_family_t};
3use std::{
4 mem,
5 net::{Ipv4Addr, Ipv6Addr},
6};
7
8use mnl::{Attr, AttrTbl, MsgVec, Result};
9use netlink::{self, Nlmsghdr};
10
11pub const RTNL_FAMILY_IPMR: u8 = 128;
14pub const RTNL_FAMILY_IP6MR: u8 = 129;
15pub const RTNL_FAMILY_MAX: u8 = 129;
16
17#[repr(u16)]
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20pub enum Rtm {
21 Newlink = 16,
23 Dellink = 17,
24 Getlink = 18,
25 Tbllink = 19,
26 Newaddr = 20,
27 Deladdr = 21,
28 Getaddr = 22,
29 Newroute = 24,
30 Delroute = 25,
31 Getroute = 26,
32 Newneigh = 28,
33 Delneigh = 29,
34 Getneigh = 30,
35 Newrule = 32,
36 Delrule = 33,
37 Getrule = 34,
38 Newqdisc = 36,
39 Delqdisc = 37,
40 Getqdisc = 38,
41 Newtclass = 40,
42 Deltclass = 41,
43 Gettclass = 42,
44 Newtfilter = 44,
45 Deltfilter = 45,
46 Gettfilter = 46,
47 Newaction = 48,
48 Delaction = 49,
49 Getaction = 50,
50 Newprefix = 52,
51 Getmulticast = 58,
52 Getanycast = 62,
53 Newneightbl = 64,
54 Getneightbl = 66,
55 Tblneightbl = 67,
56 Newnduseropt = 68,
57 Newaddrlabel = 72,
58 Deladdrlabel = 73,
59 Getaddrlabel = 74,
60 Getdcb = 78,
61 Tbldcb = 79,
62 Newnetconf = 80,
63 Delnetconf = 81,
64 Getnetconf = 82,
65 Newmdb = 84,
66 Delmdb = 85,
67 Getmdb = 86,
68 Newnsid = 88,
69 Delnsid = 89,
70 Getnsid = 90,
71 Newstats = 92,
72 Getstats = 94,
73 Newcachereport = 96,
74 Newchain = 100,
75 Delchain = 101,
76 Getchain = 102,
77 Newnexthop = 104,
78 Delnexthop = 105,
79 Getnexthop = 106,
80 Newlinkprop = 108,
81 Dellinkprop = 109,
82 Getlinkprop = 110,
83 Newvlan = 112,
84 Delvlan = 113,
85 Getvlan = 114,
86 _MAX,
87}
88pub const RTM_BASE: u16 = Rtm::Newlink as u16; pub const RTM_NEWLINK: u16 = Rtm::Newlink as u16;
90pub const RTM_DELLINK: u16 = Rtm::Dellink as u16;
91pub const RTM_GETLINK: u16 = Rtm::Getlink as u16;
92pub const RTM_SETLINK: u16 = Rtm::Tbllink as u16;
93pub const RTM_NEWADDR: u16 = Rtm::Newaddr as u16;
94pub const RTM_DELADDR: u16 = Rtm::Deladdr as u16;
95pub const RTM_GETADDR: u16 = Rtm::Getaddr as u16;
96pub const RTM_NEWROUTE: u16 = Rtm::Newroute as u16;
97pub const RTM_DELROUTE: u16 = Rtm::Delroute as u16;
98pub const RTM_GETROUTE: u16 = Rtm::Getroute as u16;
99pub const RTM_NEWNEIGH: u16 = Rtm::Newneigh as u16;
100pub const RTM_DELNEIGH: u16 = Rtm::Delneigh as u16;
101pub const RTM_GETNEIGH: u16 = Rtm::Getneigh as u16;
102pub const RTM_NEWRULE: u16 = Rtm::Newrule as u16;
103pub const RTM_DELRULE: u16 = Rtm::Delrule as u16;
104pub const RTM_GETRULE: u16 = Rtm::Getrule as u16;
105pub const RTM_NEWQDISC: u16 = Rtm::Newqdisc as u16;
106pub const RTM_DELQDISC: u16 = Rtm::Delqdisc as u16;
107pub const RTM_GETQDISC: u16 = Rtm::Getqdisc as u16;
108pub const RTM_NEWTCLASS: u16 = Rtm::Newtclass as u16;
109pub const RTM_DELTCLASS: u16 = Rtm::Deltclass as u16;
110pub const RTM_GETTCLASS: u16 = Rtm::Gettclass as u16;
111pub const RTM_NEWTFILTER: u16 = Rtm::Newtfilter as u16;
112pub const RTM_DELTFILTER: u16 = Rtm::Deltfilter as u16;
113pub const RTM_GETTFILTER: u16 = Rtm::Gettfilter as u16;
114pub const RTM_NEWACTION: u16 = Rtm::Newaction as u16;
115pub const RTM_DELACTION: u16 = Rtm::Delaction as u16;
116pub const RTM_GETACTION: u16 = Rtm::Getaction as u16;
117pub const RTM_NEWPREFIX: u16 = Rtm::Newprefix as u16;
118pub const RTM_GETMULTICAST: u16 = Rtm::Getmulticast as u16;
119pub const RTM_GETANYCAST: u16 = Rtm::Getanycast as u16;
120pub const RTM_NEWNEIGHTBL: u16 = Rtm::Newneightbl as u16;
121pub const RTM_GETNEIGHTBL: u16 = Rtm::Getneightbl as u16;
122pub const RTM_SETNEIGHTBL: u16 = Rtm::Tblneightbl as u16;
123pub const RTM_NEWNDUSEROPT: u16 = Rtm::Newnduseropt as u16;
124pub const RTM_NEWADDRLABEL: u16 = Rtm::Newaddrlabel as u16;
125pub const RTM_DELADDRLABEL: u16 = Rtm::Deladdrlabel as u16;
126pub const RTM_GETADDRLABEL: u16 = Rtm::Getaddrlabel as u16;
127pub const RTM_GETDCB: u16 = Rtm::Getdcb as u16;
128pub const RTM_SETDCB: u16 = Rtm::Tbldcb as u16;
129pub const RTM_NEWNETCONF: u16 = Rtm::Newnetconf as u16;
130pub const RTM_DELNETCONF: u16 = Rtm::Delnetconf as u16;
131pub const RTM_GETNETCONF: u16 = Rtm::Getnetconf as u16;
132pub const RTM_NEWMDB: u16 = Rtm::Newmdb as u16;
133pub const RTM_DELMDB: u16 = Rtm::Delmdb as u16;
134pub const RTM_GETMDB: u16 = Rtm::Getmdb as u16;
135pub const RTM_NEWNSID: u16 = Rtm::Newnsid as u16;
136pub const RTM_DELNSID: u16 = Rtm::Delnsid as u16;
137pub const RTM_GETNSID: u16 = Rtm::Getnsid as u16;
138pub const RTM_NEWSTATS: u16 = Rtm::Newstats as u16;
139pub const RTM_GETSTATS: u16 = Rtm::Getstats as u16;
140pub const RTM_NEWCACHEREPORT: u16 = Rtm::Newcachereport as u16;
141pub const RTM_NEWCHAIN: u16 = Rtm::Newchain as u16;
142pub const RTM_DELCHAIN: u16 = Rtm::Delchain as u16;
143pub const RTM_GETCHAIN: u16 = Rtm::Getchain as u16;
144pub const RTM_NEWNEXTHOP: u16 = Rtm::Newnexthop as u16;
145pub const RTM_DELNEXTHOP: u16 = Rtm::Delnexthop as u16;
146pub const RTM_GETNEXTHOP: u16 = Rtm::Getnexthop as u16;
147pub const RTM_NEWLINKPROP: u16 = Rtm::Newlinkprop as u16;
148pub const RTM_DELLINKPROP: u16 = Rtm::Dellinkprop as u16;
149pub const RTM_GETLINKPROP: u16 = Rtm::Getlinkprop as u16;
150pub const RTM_NEWNVLAN: u16 = Rtm::Newvlan as u16;
151pub const RTM_DELVLAN: u16 = Rtm::Delvlan as u16;
152pub const RTM_GETVLAN: u16 = Rtm::Getvlan as u16;
153pub const __RTM_MAX: u16 = Rtm::_MAX as u16;
154pub const RTM_MAX: u16 = ((__RTM_MAX as u16 + 3) & !3) - 1;
155
156pub const RTM_NR_MSGTYPES: u16 = RTM_MAX + 1 - RTM_BASE;
157pub const RTM_NR_FAMILIES: u16 = RTM_NR_MSGTYPES >> 2;
158pub const fn rtm_fam(cmd: u16) -> u16 {
159 (cmd - RTM_BASE) >> 2
160}
161
162#[repr(C)]
166#[derive(Debug, Clone, Copy)]
167pub struct Rtattr {
168 pub rta_len: c_ushort,
169 pub rta_type: c_ushort,
170}
171
172pub const RTA_ALIGNTO: u16 = 4;
174pub const fn rta_align(len: u16) -> u16 {
175 (len + RTA_ALIGNTO - 1) & !(RTA_ALIGNTO - 1)
176}
177pub const fn rta_ok(rta: &Rtattr, len: u16) -> bool {
178 len >= mem::size_of::<Rtattr>() as u16
179 && rta.rta_len >= mem::size_of::<Rtattr>() as c_ushort
180 && rta.rta_len <= len
181}
182pub unsafe fn rta_next<'a>(rta: &'a mut Rtattr, attrlen: &mut u16) -> &'a mut Rtattr {
183 *attrlen -= rta_align(rta.rta_len);
184 &mut *((rta as *mut _ as *mut u8).offset(rta.rta_len as isize) as *mut Rtattr)
185}
186pub const fn rta_length(len: u16) -> u16 {
187 rta_align(mem::size_of::<Rtattr>() as u16 + len)
188}
189pub const fn rta_space(len: u16) -> u16 {
190 rta_align(rta_length(len))
191}
192pub unsafe fn rta_data<T>(rta: &mut Rtattr) -> &mut T {
193 &mut *((rta as *mut _ as *mut u8).offset(rta_length(0) as isize) as *mut T)
194}
195pub const fn rta_payload(rta: &Rtattr) -> u16 {
196 rta.rta_len - rta_length(0)
197}
198
199#[repr(C)]
201#[derive(Debug, Clone, Copy)]
202pub struct Rtmsg {
203 pub rtm_family: c_uchar,
204 pub rtm_dst_len: c_uchar,
205 pub rtm_src_len: c_uchar,
206 pub rtm_tos: c_uchar,
207 pub rtm_table: c_uchar, pub rtm_protocol: c_uchar, pub rtm_scope: c_uchar, pub rtm_type: c_uchar, pub rtm_flags: c_uint,
212}
213
214#[repr(u8)]
216#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
217pub enum Rtn {
218 Unspec = 0,
219 Unicast, Local, Broadcast, Anycast, Multicast, Blackhole, Unreachable, Prohibit, Throw, Nat, Xresolve, _MAX,
233}
234pub const RTN_UNSPEC: u8 = Rtn::Unspec as u8;
235pub const RTN_UNICAST: u8 = Rtn::Unicast as u8;
236pub const RTN_LOCAL: u8 = Rtn::Local as u8;
237pub const RTN_BROADCAST: u8 = Rtn::Broadcast as u8;
238pub const RTN_ANYCAST: u8 = Rtn::Anycast as u8;
239pub const RTN_MULTICAST: u8 = Rtn::Multicast as u8;
240pub const RTN_BLACKHOLE: u8 = Rtn::Blackhole as u8;
241pub const RTN_UNREACHABLE: u8 = Rtn::Unreachable as u8;
242pub const RTN_PROHIBIT: u8 = Rtn::Prohibit as u8;
243pub const RTN_THROW: u8 = Rtn::Throw as u8;
244pub const RTN_NAT: u8 = Rtn::Nat as u8;
245pub const RTN_XRESOLVE: u8 = Rtn::Xresolve as u8;
246pub const __RTN_MAX: u8 = Rtn::_MAX as u8;
247pub const RTN_MAX: u8 = __RTN_MAX - 1;
248
249pub const RTPROT_UNSPEC: u8 = 0;
251pub const RTPROT_REDIRECT: u8 = 1; pub const RTPROT_KERNEL: u8 = 2; pub const RTPROT_BOOT: u8 = 3; pub const RTPROT_STATIC: u8 = 4; pub const RTPROT_GATED: u8 = 8; pub const RTPROT_RA: u8 = 9; pub const RTPROT_MRT: u8 = 10; pub const RTPROT_ZEBRA: u8 = 11; pub const RTPROT_BIRD: u8 = 12; pub const RTPROT_DNROUTED: u8 = 13; pub const RTPROT_XORP: u8 = 14; pub const RTPROT_NTK: u8 = 15; pub const RTPROT_DHCP: u8 = 16; pub const RTPROT_MROUTED: u8 = 17; pub const RTPROT_BABEL: u8 = 42; #[repr(u8)]
285#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
286pub enum RtScope {
287 Universe = 0,
288 Site = 200,
290 Link = 253,
291 Host = 254,
292 Nowhere = 255,
293}
294pub const RT_SCOPE_UNIVERSE: u8 = RtScope::Universe as u8;
295pub const RT_SCOPE_SITE: u8 = RtScope::Site as u8;
296pub const RT_SCOPE_LINK: u8 = RtScope::Link as u8;
297pub const RT_SCOPE_HOST: u8 = RtScope::Host as u8;
298pub const RT_SCOPE_NOWHERE: u8 = RtScope::Nowhere as u8;
299
300pub const RTM_F_NOTIFY: u32 = 0x100; pub const RTM_F_CLONED: u32 = 0x200; pub const RTM_F_EQUALIZE: u32 = 0x400; pub const RTM_F_PREFIX: u32 = 0x800; pub const RTM_F_LOOKUP_TABLE: u32 = 0x1000; pub const RTM_F_FIB_MATCH: u32 = 0x2000; #[repr(u32)]
309#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
310pub enum RtClass {
311 Unspec = 0,
312 Compat = 252,
314 Default = 253,
315 Main = 254,
316 Local = 255,
317 Max = 0xFFFFFFFF,
318}
319pub const RT_TABLE_UNSPEC: u32 = RtClass::Unspec as u32;
320pub const RT_TABLE_COMPAT: u32 = RtClass::Compat as u32;
321pub const RT_TABLE_DEFAULT: u32 = RtClass::Default as u32;
322pub const RT_TABLE_MAIN: u32 = RtClass::Main as u32;
323pub const RT_TABLE_LOCAL: u32 = RtClass::Local as u32;
324pub const RT_TABLE_MAX: u32 = RtClass::Max as u32;
325
326#[repr(u16)]
328#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, NlaType)]
329#[tbname = "RtattrTypeTbl"]
330pub enum RtattrType {
331 Unspec = 0,
332
333 #[nla_type(Ipv4Addr, v4dst)]
334 #[nla_type(Ipv6Addr, v6dst)]
335 Dst,
336
337 #[nla_type(Ipv4Addr, v4src)]
338 #[nla_type(Ipv6Addr, v6src)]
339 Src,
340
341 #[nla_type(u32, iif)]
342 Iif,
343
344 #[nla_type(u32, oif)]
345 Oif,
346
347 #[nla_type(Ipv4Addr, v4gateway)]
348 #[nla_type(Ipv6Addr, v6gateway)]
349 Gateway,
350
351 #[nla_type(u32, priority)]
352 Priority,
353
354 #[nla_type(Ipv4Addr, v4prefsrc)]
355 #[nla_type(Ipv6Addr, v6prefsrc)]
356 Prefsrc,
357
358 #[nla_nest(RtaxTbl, metrics)]
359 Metrics,
360
361 Multipath,
362 Protoinfo, #[nla_type(u32, flow)]
365 Flow,
366
367 Cacheinfo,
368 Session, MpAlgo, #[nla_type(u32, table)]
372 Table,
373
374 Mark,
375 MfcStats,
376 Via,
377 Newdst,
378 Pref,
379 EncapType,
380 Encap,
381 Expires,
382 Pad,
383 Uid,
384 TtlPropagate,
385 IpProto,
386 Sport,
387 Dport,
388 NhId,
389 _MAX,
390}
391
392pub unsafe fn rtm_rta(r: &mut Rtmsg) -> &mut Rtattr {
393 &mut *((r as *mut _ as *mut u8)
394 .offset(netlink::nlmsg_align(mem::size_of::<Rtmsg>() as u32) as isize)
395 as *mut Rtattr)
396}
397pub const fn rtm_payload(n: &Nlmsghdr) -> u32 {
398 netlink::nlmsg_payload(n, mem::size_of::<Rtmsg>() as u32)
399}
400
401#[repr(C)]
409#[derive(Debug, Clone, Copy)]
410pub struct Rtnexthop {
411 pub rtnh_len: c_ushort,
412 pub rtnh_flags: c_uchar,
413 pub rtnh_hops: c_uchar,
414 pub rtnh_ifindex: c_int,
415}
416
417pub const RTNH_F_DEAD: u8 = 1; pub const RTNH_F_PERVASIVE: u8 = 2; pub const RTNH_F_ONLINK: u8 = 4; pub const RTNH_F_OFFLOAD: u8 = 8; pub const RTNH_F_LINKDOWN: u8 = 16; pub const RTNH_F_UNRESOLVED: u8 = 32; pub const RTNH_COMPARE_MASK: u8 = RTNH_F_DEAD | RTNH_F_LINKDOWN | RTNH_F_OFFLOAD;
426
427pub const RTNH_ALIGNTO: u16 = 4;
429pub const fn rtnh_align(len: u16) -> u16 {
430 (len + RTNH_ALIGNTO - 1) & !(RTNH_ALIGNTO - 1)
431}
432pub const fn rtnh_ok(rtnh: &Rtnexthop, len: u16) -> bool {
433 rtnh.rtnh_len >= mem::size_of::<Rtnexthop>() as u16 && rtnh.rtnh_len <= len
434}
435pub unsafe fn rtnh_next(rtnh: &mut Rtnexthop) -> &mut Rtnexthop {
436 &mut *((rtnh as *mut _ as *mut u8).offset(rtnh_align(rtnh.rtnh_len) as isize) as *mut Rtnexthop)
437}
438pub const fn rtnh_length(len: u16) -> u16 {
439 rtnh_align(mem::size_of::<Rtnexthop>() as u16 + len)
440}
441pub const fn rtnh_space(len: u16) -> u16 {
442 rtnh_align(rtnh_length(len))
443}
444pub unsafe fn rtnh_data(rtnh: &mut Rtnexthop) -> &mut Rtattr {
445 &mut *((rtnh as *mut _ as *mut u8).offset(rtnh_length(0) as isize) as *mut Rtattr)
446}
447
448#[repr(C)]
450#[derive(Debug, Clone, Copy)]
451pub struct Rtvia {
452 pub rtvia_family: sa_family_t,
453 pub rtvia_addr: [u8; 0],
454}
455
456#[repr(C)]
458#[derive(Debug, Clone, Copy)]
459pub struct RtaCacheinfo {
460 pub rta_clntref: u32,
461 pub rta_lastuse: u32,
462 pub rta_expires: i32,
463 pub rta_error: u32,
464 pub rta_used: u32,
465 pub rta_id: u32,
466 pub rta_ts: u32,
467 pub rta_tsage: u32,
468}
469pub const RTNETLINK_HAVE_PEERINFO: u32 = 1; #[repr(u16)]
473#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, NlaType)]
474#[tbname = "RtaxTbl"]
475pub enum Rtax {
476 Unspec = 0,
477
478 #[nla_type(u32, lock)]
479 Lock,
480
481 #[nla_type(u32, mtu)]
482 Mtu,
483
484 #[nla_type(u32, window)]
485 Window,
486
487 #[nla_type(u32, rtt)]
488 Rtt,
489
490 #[nla_type(u32, rttvar)]
491 Rttvar,
492
493 #[nla_type(u32, ssthresh)]
494 Ssthresh,
495
496 #[nla_type(u32, cwnd)]
497 Cwnd,
498
499 #[nla_type(u32, advmss)]
500 Advmss,
501
502 #[nla_type(u32, reordering)]
503 Reordering,
504
505 #[nla_type(u32, hoplimit)]
506 Hoplimit,
507
508 #[nla_type(u32, initcwnd)]
509 Initcwnd,
510
511 #[nla_type(u32, features)]
512 Features,
513
514 #[nla_type(u32, rto_min)]
515 RtoMin,
516
517 #[nla_type(u32, initrwnd)]
518 Initrwnd,
519
520 #[nla_type(u32, quickack)]
521 Quickack,
522
523 #[nla_type(str, cc_algo)]
524 CcAlgo,
525
526 #[nla_type(u32, fastopen_no_cookie)]
527 FastopenNoCookie,
528 _MAX,
529}
530pub const RTAX_UNSPEC: c_int = Rtax::Unspec as c_int;
531pub const RTAX_LOCK: c_int = Rtax::Lock as c_int;
532pub const RTAX_MTU: c_int = Rtax::Mtu as c_int;
533pub const RTAX_WINDOW: c_int = Rtax::Window as c_int;
534pub const RTAX_RTT: c_int = Rtax::Rtt as c_int;
535pub const RTAX_RTTVAR: c_int = Rtax::Rttvar as c_int;
536pub const RTAX_SSTHRESH: c_int = Rtax::Ssthresh as c_int;
537pub const RTAX_CWND: c_int = Rtax::Cwnd as c_int;
538pub const RTAX_ADVMSS: c_int = Rtax::Advmss as c_int;
539pub const RTAX_REORDERING: c_int = Rtax::Reordering as c_int;
540pub const RTAX_HOPLIMIT: c_int = Rtax::Hoplimit as c_int;
541pub const RTAX_INITCWND: c_int = Rtax::Initcwnd as c_int;
542pub const RTAX_FEATURES: c_int = Rtax::Features as c_int;
543pub const RTAX_RTO_MIN: c_int = Rtax::RtoMin as c_int;
544pub const RTAX_INITRWND: c_int = Rtax::Initrwnd as c_int;
545pub const RTAX_QUICKACK: c_int = Rtax::Quickack as c_int;
546pub const RTAX_CC_ALGO: c_int = Rtax::CcAlgo as c_int;
547pub const RTAX_FASTOPEN_NO_COOKIE: c_int = Rtax::FastopenNoCookie as c_int;
548pub const __RTAX_MAX: c_int = Rtax::_MAX as c_int;
549pub const RTAX_MAX: c_int = __RTAX_MAX - 1;
550
551pub const RTAX_FEATURE_ECN: u32 = 1 << 0;
552pub const RTAX_FEATURE_SACK: u32 = 1 << 1;
553pub const RTAX_FEATURE_TIMESTAMP: u32 = 1 << 2;
554pub const RTAX_FEATURE_ALLFRAG: u32 = 1 << 3;
555pub const RTAX_FEATURE_MASK: u32 =
556 RTAX_FEATURE_ECN | RTAX_FEATURE_SACK | RTAX_FEATURE_TIMESTAMP | RTAX_FEATURE_ALLFRAG;
557#[repr(C)]
558#[derive(Clone, Copy)]
560pub struct RtaSession {
561 pub proto: u8,
562 pub pad1: u8,
563 pub pad2: u16,
564 pub u: _RtaSesseionUnion,
565}
566#[repr(C)]
567#[derive(Clone, Copy)]
569pub union _RtaSesseionUnion {
570 pub ports: _RtaSessionUnionPorts,
571 pub icmpt: _RtaSesseionUnionIcmpt,
572 pub spi: u32,
573}
574#[derive(Debug, Clone, Copy)]
575pub struct _RtaSessionUnionPorts {
576 sport: u16,
577 dport: u16,
578}
579#[derive(Debug, Clone, Copy)]
580pub struct _RtaSesseionUnionIcmpt {
581 itype: u8,
582 code: u8,
583 ident: u16,
584}
585
586#[repr(C)]
587#[derive(Debug, Clone, Copy)]
588pub struct RtaMfcStats {
589 pub mfcs_packets: u64,
590 pub mfcs_bytes: u64,
591 pub mfcs_wrong_if: u64,
592}
593
594#[repr(C)]
596#[derive(Debug, Clone, Copy)]
597pub struct Rtgenmsg {
598 pub rtgen_family: c_uchar,
599}
600
601#[repr(C)]
607#[derive(Debug, Clone, Copy)]
608pub struct Ifinfomsg {
609 pub ifi_family: c_uchar,
610 pub __ifi_pad: c_uchar,
611 pub ifi_type: c_ushort, pub ifi_index: c_int, pub ifi_flags: c_uint, pub ifi_change: c_uint, }
616
617#[repr(C)]
619#[derive(Debug, Clone, Copy)]
620pub struct prefixmsg {
621 pub prefix_family: c_uchar,
622 pub prefix_pad1: c_uchar,
623 pub prefix_pad2: c_ushort,
624 pub prefix_ifindex: c_int,
625 pub prefix_type: c_uchar,
626 pub prefix_len: c_uchar,
627 pub prefix_flags: c_uchar,
628 pub prefix_pad3: c_uchar,
629}
630
631#[repr(u16)]
632#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, NlaType)]
633#[tbname = "PrefixTbl"]
634pub enum Prefix {
635 Unspec = 0,
636 Address = 1,
637 Cacheinfo = 2,
638 _MAX = 3,
639}
640
641#[repr(C)]
642#[derive(Debug, Clone, Copy)]
643pub struct PrefixCacheinfo {
644 pub preferred_time: u32,
645 pub valid_time: u32,
646}
647
648#[allow(non_snake_case)]
650#[repr(C)]
651#[derive(Debug, Clone, Copy)]
652pub struct Tcmsg {
653 pub tcm_family: c_uchar,
654 pub tcm__pad1: c_uchar,
655 pub tcm__pad2: c_uchar,
656 pub tcm_ifindex: c_uint,
657 pub tcm_handle: u32,
658
659 pub tcm_parent: u32,
663
664 pub tcm_info: u32,
665}
666
667pub const TCM_IFINDEX_MAGIC_BLOCK: c_int = -1;
672
673#[repr(u16)]
674#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, NlaType)]
675#[tbname = "TcaTbl"]
676pub enum Tca {
677 Unspec = 0,
678 Kind,
679 Options,
680 Stats,
681 Xstats,
682 Rate,
683 Fcnt,
684 Stats2,
685 Stab,
686 Pad,
687 DumpInvisible,
688 Chain,
689 HwOffload,
690 IngressBlock,
691 EgressBlock,
692 DumpFlags,
693 _MAX,
694}
695
696pub const TCA_DUMP_FLAGS_TERSE: u32 = 1 << 0; pub unsafe fn tca_rta(r: &mut Tcmsg) -> &mut Rtattr {
701 &mut *((r as *mut _ as *mut u8)
702 .offset(netlink::nlmsg_align(mem::size_of::<Tcmsg>() as u32) as isize)
703 as *mut Rtattr)
704}
705
706pub fn tca_payload(n: &netlink::Nlmsghdr) -> u32 {
707 netlink::nlmsg_payload(n, mem::size_of::<Tcmsg>() as u32)
708}
709
710#[repr(C)]
712#[derive(Debug, Clone, Copy)]
713pub struct nduseroptmsg {
714 pub nduseropt_family: c_uchar,
715 pub nduseropt_pad1: c_uchar,
716 pub nduseropt_opts_len: c_ushort, pub nduseropt_ifindex: c_int,
718 pub nduseropt_icmp_type: u8,
719 pub nduseropt_icmp_code: u8,
720 pub nduseropt_pad2: c_ushort,
721 pub nduseropt_pad3: c_uint,
722 }
724
725#[repr(u16)]
726#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, NlaType)]
727#[tbname = "NduseportTbl"]
728pub enum Nduseropt {
729 Unspec = 0,
730 Srcaddr,
731 _MAX,
732}
733
734pub const RTMGRP_LINK: u32 = 1;
736pub const RTMGRP_NOTIFY: u32 = 2;
737pub const RTMGRP_NEIGH: u32 = 4;
738pub const RTMGRP_TC: u32 = 8;
739pub const RTMGRP_IPV4_IFADDR: u32 = 0x10;
740pub const RTMGRP_IPV4_MROUTE: u32 = 0x20;
741pub const RTMGRP_IPV4_ROUTE: u32 = 0x40;
742pub const RTMGRP_IPV4_RULE: u32 = 0x80;
743pub const RTMGRP_IPV6_IFADDR: u32 = 0x100;
744pub const RTMGRP_IPV6_MROUTE: u32 = 0x200;
745pub const RTMGRP_IPV6_ROUTE: u32 = 0x400;
746pub const RTMGRP_IPV6_IFINFO: u32 = 0x800;
747#[allow(non_upper_case_globals)]
748pub const RTMGRP_DECnet_IFADDR: u32 = 0x1000;
749#[allow(non_upper_case_globals)]
750pub const RTMGRP_DECnet_ROUTE: u32 = 0x4000;
751pub const RTMGRP_IPV6_PREFIX: u32 = 0x20000;
752
753#[repr(u32)]
755#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
756pub enum RtnetlinkGroups {
757 None = 0,
758 Link,
759 Notify,
760 Neigh,
761 Tc,
762 Ipv4Ifaddr,
763 Ipv4Mroute,
764 Ipv4Route,
765 Ipv4Rule,
766 Ipv6Ifaddr,
767 Ipv6Mroute,
768 Ipv6Route,
769 Ipv6Ifinfo,
770 DecnetIfaddr,
771 Nop2,
772 DecnetRoute,
773 DecnetRule,
774 Nop4,
775 Ipv6Prefix,
776 Ipv6Rule,
777 NdUseropt,
778 PhonetIfaddr,
779 PhonetRoute,
780 Dcb,
781 Ipv4Netconf,
782 Ipv6Netconf,
783 Mdb,
784 MplsRoute,
785 Nsid,
786 MplsNetconf,
787 Ipv4MrouteR,
788 Ipv6MrouteR,
789 Nexthop,
790 Brvlan,
791 _MAX,
792}
793pub const RTNLGRP_NONE: u32 = RtnetlinkGroups::None as u32;
794pub const RTNLGRP_LINK: u32 = RtnetlinkGroups::Link as u32;
795pub const RTNLGRP_NOTIFY: u32 = RtnetlinkGroups::Notify as u32;
796pub const RTNLGRP_NEIGH: u32 = RtnetlinkGroups::Neigh as u32;
797pub const RTNLGRP_TC: u32 = RtnetlinkGroups::Tc as u32;
798pub const RTNLGRP_IPV4_IFADDR: u32 = RtnetlinkGroups::Ipv4Ifaddr as u32;
799pub const RTNLGRP_IPV4_MROUTE: u32 = RtnetlinkGroups::Ipv4Mroute as u32;
800pub const RTNLGRP_IPV4_ROUTE: u32 = RtnetlinkGroups::Ipv4Route as u32;
801pub const RTNLGRP_IPV4_RULE: u32 = RtnetlinkGroups::Ipv4Rule as u32;
802pub const RTNLGRP_IPV6_IFADDR: u32 = RtnetlinkGroups::Ipv6Ifaddr as u32;
803pub const RTNLGRP_IPV6_MROUTE: u32 = RtnetlinkGroups::Ipv6Mroute as u32;
804pub const RTNLGRP_IPV6_ROUTE: u32 = RtnetlinkGroups::Ipv6Route as u32;
805pub const RTNLGRP_IPV6_IFINFO: u32 = RtnetlinkGroups::Ipv6Ifinfo as u32;
806#[allow(non_upper_case_globals)]
807pub const RTNLGRP_DECnet_IFADDR: u32 = RtnetlinkGroups::DecnetIfaddr as u32;
808pub const RTNLGRP_NOP2: u32 = RtnetlinkGroups::Nop2 as u32;
809#[allow(non_upper_case_globals)]
810pub const RTNLGRP_DECnet_ROUTE: u32 = RtnetlinkGroups::DecnetRoute as u32;
811#[allow(non_upper_case_globals)]
812pub const RTNLGRP_DECnet_RULE: u32 = RtnetlinkGroups::DecnetRule as u32;
813pub const RTNLGRP_NOP4: u32 = RtnetlinkGroups::Nop4 as u32;
814pub const RTNLGRP_IPV6_PREFIX: u32 = RtnetlinkGroups::Ipv6Prefix as u32;
815pub const RTNLGRP_IPV6_RULE: u32 = RtnetlinkGroups::Ipv6Rule as u32;
816pub const RTNLGRP_ND_USEROPT: u32 = RtnetlinkGroups::NdUseropt as u32;
817pub const RTNLGRP_PHONET_IFADDR: u32 = RtnetlinkGroups::PhonetIfaddr as u32;
818pub const RTNLGRP_PHONET_ROUTE: u32 = RtnetlinkGroups::PhonetRoute as u32;
819pub const RTNLGRP_DCB: u32 = RtnetlinkGroups::Dcb as u32;
820pub const RTNLGRP_IPV4_NETCONF: u32 = RtnetlinkGroups::Ipv4Netconf as u32;
821pub const RTNLGRP_IPV6_NETCONF: u32 = RtnetlinkGroups::Ipv6Netconf as u32;
822pub const RTNLGRP_MDB: u32 = RtnetlinkGroups::Mdb as u32;
823pub const RTNLGRP_MPLS_ROUTE: u32 = RtnetlinkGroups::MplsRoute as u32;
824pub const RTNLGRP_NSID: u32 = RtnetlinkGroups::Nsid as u32;
825pub const RTNLGRP_MPLS_NETCONF: u32 = RtnetlinkGroups::MplsNetconf as u32;
826pub const RTNLGRP_IPV4_MROUTE_R: u32 = RtnetlinkGroups::Ipv4MrouteR as u32;
827pub const RTNLGRP_IPV6_MROUTE_R: u32 = RtnetlinkGroups::Ipv6MrouteR as u32;
828pub const RTNLGRP_NEXTHOP: u32 = RtnetlinkGroups::Nexthop as u32;
829pub const RTNLGRP_BRVLAN: u32 = RtnetlinkGroups::Brvlan as u32;
830pub const __RTNLGRP_MAX: u32 = RtnetlinkGroups::_MAX as u32;
831pub const RTNLGRP_MAX: u32 = __RTNLGRP_MAX - 1;
832
833#[allow(non_snake_case)]
835#[repr(C)]
836#[derive(Debug, Clone, Copy)]
837pub struct Tcamsg {
838 pub tca_family: c_uchar,
839 pub tca__pad1: c_uchar,
840 pub tca__pad2: c_uchar,
841}
842
843#[repr(u16)]
844#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, NlaType)]
845pub enum TcaRoot {
846 Unspec = 0,
847 Tab,
848 Flags,
849 Count,
850 TimeDelta,
851 _MAX,
852}
853
854pub unsafe fn ta_rta(r: &mut Tcamsg) -> &mut Rtattr {
855 &mut *((r as *mut _ as *mut u8)
856 .offset(netlink::nlmsg_align(mem::size_of::<Tcamsg>() as u32) as isize)
857 as *mut Rtattr)
858}
859pub fn ta_payload(n: &netlink::Nlmsghdr) -> u32 {
860 netlink::nlmsg_payload(n, mem::size_of::<Tcamsg>() as u32)
861}
862
863pub const TCA_FLAG_LARGE_DUMP_ON: u32 = 1 << 0;
869
870pub const RTEXT_FILTER_VF: u32 = 1 << 0;
872pub const RTEXT_FILTER_BRVLAN: u32 = 1 << 1;
873pub const RTEXT_FILTER_BRVLAN_COMPRESSED: u32 = 1 << 2;
874pub const RTEXT_FILTER_SKIP_STATS: u32 = 1 << 3;
875
876