@@ -196,23 +196,54 @@ func (s *Session) startRelinker(ctx context.Context) error {
196
196
case event := <- linkEvents :
197
197
switch event := event .(type ) {
198
198
case pwLinkAdd :
199
- if event .DeviceName == s .targetName {
200
- catnipPort := "input_" + strings .TrimPrefix (event .PortName , "output_" )
201
- catnipPortID := catnipPorts [catnipPort ]
202
- targetPortID := event .ID
203
-
204
- // Link the catnip node to the device node.
205
- if err := pwLink (targetPortID , catnipPortID ); err != nil {
206
- log .Printf (
207
- "failed to link catnip port %d to device port %d: %v" ,
208
- catnipPortID , targetPortID , err )
209
- }
199
+ if event .DeviceName != s .targetName {
200
+ break
201
+ }
202
+
203
+ catnipPort , ok := matchPort (event , catnipPorts )
204
+ if ! ok {
205
+ log .Printf (
206
+ "device port %s (%d) cannot be matched to catnip (ports: %v)" ,
207
+ event .PortName , event .PortID , catnipPorts )
208
+ break
209
+ }
210
+
211
+ if err := pwLink (event .PortID , catnipPort .PortID ); err != nil {
212
+ log .Printf (
213
+ "failed to link catnip port %s (%d) to device port %s (%d): %v" ,
214
+ catnipPort .PortName , catnipPort .PortID ,
215
+ event .PortName , event .PortID , err )
210
216
}
211
217
}
212
218
}
213
219
}
214
220
}
215
221
222
+ // matchPort tries to match the given link event to the catnip input ports. It
223
+ // returns the catnip port to link to, and whether the event was matched.
224
+ func matchPort (event pwLinkAdd , ourPorts map [string ]pwObjectID ) (pwLinkObject , bool ) {
225
+ if len (ourPorts ) == 1 {
226
+ // We only have one port, so we're probably in mono mode.
227
+ for name , id := range ourPorts {
228
+ return pwLinkObject {PortID : id , PortName : name }, true
229
+ }
230
+ }
231
+
232
+ // Try directly matching the port channel with the event's. This usually
233
+ // works if the number of ports is the same.
234
+ _ , channel , ok := strings .Cut (event .PortName , "_" )
235
+ if ok {
236
+ port := "input_" + channel
237
+ portID , ok := ourPorts [port ]
238
+ if ok {
239
+ return pwLinkObject {PortID : portID , PortName : port }, true
240
+ }
241
+ }
242
+
243
+ // TODO: use more sophisticated matching here.
244
+ return pwLinkObject {}, false
245
+ }
246
+
216
247
func findCatnipPorts (ctx context.Context , ourProps catnipProps ) (map [string ]pwObjectID , error ) {
217
248
objs , err := pwDump (ctx )
218
249
if err != nil {
0 commit comments