8
8
9
9
pub mod sys;
10
10
11
- use crate :: mac:: mac_client_promisc_type_t;
12
- use crate :: mac:: mac_promisc_add;
13
- use crate :: mac:: mac_rx_fn;
11
+ use crate :: mac:: mac_client_handle;
12
+ use crate :: mac:: MacClient ;
14
13
use crate :: mac:: MacPerimeterHandle ;
15
- use crate :: mac:: MacPromiscHandle ;
16
14
use crate :: mac:: MacTxFlags ;
17
15
use crate :: mac:: MAC_DROP_ON_NO_DESC ;
18
16
use alloc:: sync:: Arc ;
19
- use core:: ffi:: c_void;
17
+ use core:: ffi:: CStr ;
18
+ use core:: fmt:: Display ;
20
19
use core:: mem:: MaybeUninit ;
21
20
use core:: ptr;
22
21
use illumos_sys_hdrs:: c_int;
23
22
use illumos_sys_hdrs:: datalink_id_t;
24
23
use illumos_sys_hdrs:: uintptr_t;
24
+ use illumos_sys_hdrs:: ENOENT ;
25
25
use opte:: engine:: packet:: Packet ;
26
26
use opte:: engine:: packet:: PacketState ;
27
27
pub use sys:: * ;
28
28
29
+ /// An integer ID used by DLS to refer to a given link.
30
+ #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
31
+ pub struct LinkId ( u32 ) ;
32
+
33
+ impl LinkId {
34
+ /// Request the link ID for a device using its name.
35
+ pub fn from_name ( name : impl AsRef < CStr > ) -> Result < Self , LinkError > {
36
+ let mut link_id = 0 ;
37
+
38
+ unsafe {
39
+ match dls_mgmt_get_linkid ( name. as_ref ( ) . as_ptr ( ) , & mut link_id) {
40
+ 0 => Ok ( LinkId ( link_id) ) ,
41
+ ENOENT => Err ( LinkError :: NotFound ) ,
42
+ err => Err ( LinkError :: Other ( err) ) ,
43
+ }
44
+ }
45
+ }
46
+ }
47
+
48
+ impl From < LinkId > for datalink_id_t {
49
+ fn from ( val : LinkId ) -> Self {
50
+ val. 0
51
+ }
52
+ }
53
+
54
+ /// Errors encountered while querying DLS for a `LinkId`.
55
+ pub enum LinkError {
56
+ NotFound ,
57
+ Other ( i32 ) ,
58
+ }
59
+
60
+ impl Display for LinkError {
61
+ fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
62
+ match self {
63
+ LinkError :: NotFound => write ! ( f, "link not found" ) ,
64
+ LinkError :: Other ( e) => write ! ( f, "unknown error ({e})" ) ,
65
+ }
66
+ }
67
+ }
68
+
69
+ /// A hold on an existing link managed by DLS.
29
70
#[ derive( Debug ) ]
30
71
pub struct DlsLink {
31
72
inner : Option < DlsLinkInner > ,
73
+ link : LinkId ,
32
74
}
33
75
34
76
#[ derive( Debug ) ]
35
- pub struct DlsLinkInner {
77
+ struct DlsLinkInner {
36
78
dlp : * mut dls_link ,
37
79
dlh : dls_dl_handle ,
38
- link : datalink_id_t ,
39
80
}
40
81
41
82
impl DlsLink {
83
+ /// Place a hold on an existing link,
42
84
pub fn hold ( mph : & MacPerimeterHandle ) -> Result < Self , c_int > {
43
85
let mut dlp = ptr:: null_mut ( ) ;
44
86
let mut dlh = ptr:: null_mut ( ) ;
45
- let link = mph. linkid ( ) ;
87
+ let link = mph. link_id ( ) ;
46
88
47
- let res = unsafe { dls_devnet_hold_link ( link, & mut dlh, & mut dlp) } ;
89
+ let res =
90
+ unsafe { dls_devnet_hold_link ( link. into ( ) , & mut dlh, & mut dlp) } ;
48
91
if res == 0 {
49
- Ok ( Self { inner : Some ( DlsLinkInner { dlp, dlh, link } ) } )
92
+ Ok ( Self { inner : Some ( DlsLinkInner { dlp, dlh } ) , link } )
50
93
} else {
51
94
Err ( res)
52
95
}
53
96
}
54
97
98
+ pub fn link_id ( & self ) -> LinkId {
99
+ self . link
100
+ }
101
+
55
102
// XXX: cleanup REQUIRES that we hold the MAC perimeter handle.
56
103
pub fn release ( mut self , mph : & MacPerimeterHandle ) {
57
104
if let Some ( inner) = self . inner . take ( ) {
58
- if mph. linkid ( ) != inner . link {
59
- panic ! ( "Tried to free link hold with the wrong MAC perimeter: saw {}, wanted {}" ,
60
- mph. linkid ( ) , inner . link) ;
105
+ if mph. link_id ( ) != self . link {
106
+ panic ! ( "Tried to free link hold with the wrong MAC perimeter: saw {:? }, wanted {:? }" ,
107
+ mph. link_id ( ) , self . link) ;
61
108
}
62
109
unsafe {
63
110
dls_devnet_rele_link ( inner. dlh , inner. dlp ) ;
@@ -73,9 +120,9 @@ impl DlsLink {
73
120
return Err ( -1 ) ;
74
121
} ;
75
122
76
- if mph. linkid ( ) != inner . link {
77
- panic ! ( "Tried to open stream with the wrong MAC perimeter: saw {}, wanted {}" ,
78
- mph. linkid ( ) , inner . link) ;
123
+ if mph. link_id ( ) != self . link {
124
+ panic ! ( "Tried to open stream with the wrong MAC perimeter: saw {:? }, wanted {:? }" ,
125
+ mph. link_id ( ) , self . link) ;
79
126
}
80
127
81
128
let mut stream = MaybeUninit :: zeroed ( ) ;
@@ -86,7 +133,8 @@ impl DlsLink {
86
133
_ = self . inner . take ( ) ;
87
134
let dld_str = unsafe { stream. assume_init ( ) } ;
88
135
Ok ( DldStream {
89
- inner : Some ( DldStreamInner { dld_str, link : mph. linkid ( ) } ) ,
136
+ inner : Some ( DldStreamInner { dld_str } ) ,
137
+ link : mph. link_id ( ) ,
90
138
}
91
139
. into ( ) )
92
140
} else {
@@ -98,58 +146,30 @@ impl DlsLink {
98
146
99
147
impl Drop for DlsLink {
100
148
fn drop ( & mut self ) {
101
- if let Some ( inner ) = self . inner . take ( ) {
149
+ if self . inner . take ( ) . is_some ( ) {
102
150
opte:: engine:: err!(
103
- "dropped hold on link {} without releasing!!" ,
104
- inner . link
151
+ "dropped hold on link {:? } without releasing!!" ,
152
+ self . link
105
153
) ;
106
154
}
107
155
}
108
156
}
109
157
158
+ /// A DLS message stream derived from a
110
159
#[ derive( Debug ) ]
111
160
pub struct DldStream {
112
161
inner : Option < DldStreamInner > ,
162
+ link : LinkId ,
113
163
}
114
164
115
165
#[ derive( Debug ) ]
116
- pub struct DldStreamInner {
166
+ struct DldStreamInner {
117
167
dld_str : dld_str_s ,
118
- link : datalink_id_t ,
119
168
}
120
169
121
170
impl DldStream {
122
- /// Register promiscuous callback to receive packets on the underlying MAC.
123
- pub fn add_promisc (
124
- self : & Arc < Self > ,
125
- ptype : mac_client_promisc_type_t ,
126
- promisc_fn : mac_rx_fn ,
127
- flags : u16 ,
128
- ) -> Result < MacPromiscHandle < Self > , c_int > {
129
- let Some ( inner) = self . inner . as_ref ( ) else {
130
- return Err ( -1 ) ;
131
- } ;
132
-
133
- let mut mph = ptr:: null_mut ( ) ;
134
-
135
- // `MacPromiscHandle` keeps a reference to this `MacClientHandle`
136
- // until it is removed and so we can safely access it from the
137
- // callback via the `arg` pointer.
138
- let _parent = self . clone ( ) ;
139
- let parent = Arc :: into_raw ( _parent) as * mut _ ;
140
- let arg = parent as * mut c_void ;
141
- let mch = inner. dld_str . ds_mch ;
142
- let ret = unsafe {
143
- // NOTE: arg is reinterpreted as `mac_resource_handle` -> `mac_ring`
144
- // in `mac_rx_common`. Is what we've been doing here and before even safe?
145
- mac_promisc_add ( mch, ptype, promisc_fn, arg, & mut mph, flags)
146
- } ;
147
-
148
- if ret == 0 {
149
- Ok ( MacPromiscHandle { mph, parent } )
150
- } else {
151
- Err ( ret)
152
- }
171
+ pub fn link_id ( & self ) -> LinkId {
172
+ self . link
153
173
}
154
174
155
175
pub fn tx_drop_on_no_desc (
@@ -180,9 +200,9 @@ impl DldStream {
180
200
// XXX: cleanup REQUIRES that we hold the MAC perimeter handle.
181
201
pub fn release ( mut self , mph : & MacPerimeterHandle ) {
182
202
if let Some ( mut inner) = self . inner . take ( ) {
183
- if mph. linkid ( ) != inner . link {
184
- opte:: engine:: err!( "Tried to free link hold with the wrong MAC perimeter: saw {}, wanted {}" ,
185
- mph. linkid ( ) , inner . link) ;
203
+ if mph. link_id ( ) != self . link {
204
+ opte:: engine:: err!( "Tried to free link hold with the wrong MAC perimeter: saw {:? }, wanted {:? }" ,
205
+ mph. link_id ( ) , self . link) ;
186
206
}
187
207
unsafe {
188
208
dls_close ( & mut inner. dld_str ) ;
@@ -191,12 +211,22 @@ impl DldStream {
191
211
}
192
212
}
193
213
214
+ impl MacClient for DldStream {
215
+ fn mac_client_handle ( & self ) -> Result < * mut mac_client_handle , c_int > {
216
+ let Some ( inner) = self . inner . as_ref ( ) else {
217
+ return Err ( -1 ) ;
218
+ } ;
219
+
220
+ Ok ( inner. dld_str . ds_mch )
221
+ }
222
+ }
223
+
194
224
impl Drop for DldStream {
195
225
fn drop ( & mut self ) {
196
- if let Some ( inner ) = self . inner . take ( ) {
226
+ if self . inner . take ( ) . is_some ( ) {
197
227
opte:: engine:: err!(
198
- "dropped stream on link {} without releasing!!" ,
199
- inner . link
228
+ "dropped stream on link {:? } without releasing!!" ,
229
+ self . link,
200
230
) ;
201
231
}
202
232
}
0 commit comments