8
8
"fmt"
9
9
"net"
10
10
"net/netip"
11
+ "os/exec"
12
+ "runtime"
13
+ "strconv"
11
14
"strings"
12
15
"syscall"
13
16
"testing"
@@ -158,8 +161,8 @@ func TestAddVPNRoute(t *testing.T) {
158
161
159
162
// validate it's pointing to the WireGuard interface
160
163
require .NoError (t , err )
161
- nextHop , err := GetNextHop ( testCase . prefix . Addr ())
162
- require . NoError (t , err )
164
+
165
+ nextHop := getNextHop (t , testCase . prefix . Addr () )
163
166
assert .Equal (t , wgInterface .Name (), nextHop .Intf .Name , "next hop interface should be WireGuard interface" )
164
167
165
168
// remove route again
@@ -174,6 +177,53 @@ func TestAddVPNRoute(t *testing.T) {
174
177
})
175
178
}
176
179
}
180
+
181
+ func getNextHop (t * testing.T , addr netip.Addr ) Nexthop {
182
+ t .Helper ()
183
+
184
+ if runtime .GOOS == "windows" || runtime .GOOS == "linux" {
185
+ nextHop , err := GetNextHop (addr )
186
+ require .NoError (t , err )
187
+ require .NotNil (t , nextHop .Intf , "next hop interface should not be nil for %s" , addr )
188
+
189
+ return nextHop
190
+ }
191
+
192
+ // GetNextHop for bsd is buggy and returns the wrong interface for the default route.
193
+ cmd := exec .Command ("route" , "-n" , "get" , addr .String ())
194
+ output , err := cmd .Output ()
195
+ require .NoError (t , err , "route get failed" )
196
+
197
+ lines := strings .Split (string (output ), "\n " )
198
+ var intf string
199
+ var gateway string
200
+
201
+ for _ , line := range lines {
202
+ line = strings .TrimSpace (line )
203
+ if strings .HasPrefix (line , "interface:" ) {
204
+ intf = strings .TrimSpace (strings .TrimPrefix (line , "interface:" ))
205
+ } else if strings .HasPrefix (line , "gateway:" ) {
206
+ gateway = strings .TrimSpace (strings .TrimPrefix (line , "gateway:" ))
207
+ }
208
+ }
209
+
210
+ require .NotEmpty (t , intf , "interface should be found in route output" )
211
+
212
+ iface , err := net .InterfaceByName (intf )
213
+ require .NoError (t , err , "interface %s should exist" , intf )
214
+
215
+ nexthop := Nexthop {Intf : iface }
216
+
217
+ if gateway != "" && gateway != "link#" + strconv .Itoa (iface .Index ) {
218
+ addr , err := netip .ParseAddr (gateway )
219
+ if err == nil {
220
+ nexthop .IP = addr
221
+ }
222
+ }
223
+
224
+ return nexthop
225
+ }
226
+
177
227
func TestAddRouteToNonVPNIntf (t * testing.T ) {
178
228
testCases := []struct {
179
229
name string
0 commit comments