@@ -27,8 +27,7 @@ import (
2727)
2828
2929const (
30- DefaultInterface = "eth0" // FIXME: Discover the veth endpoint name instead of using default "eth0". See: https://github.com/urunc-dev/urunc/issues/14
31- DefaultTap = "tapX_urunc"
30+ DefaultTap = "tapX_urunc"
3231)
3332
3433var netlog = logrus .WithField ("subsystem" , "network" )
@@ -120,21 +119,6 @@ func createTapDevice(name string, mtu int, ownerUID, ownerGID uint32) (netlink.L
120119 return tapLink , nil
121120}
122121
123- // ensureEth0Exists checks all network interfaces in current netns and returns
124- // nil if eth0 is present or ErrEth0NotFound if not
125- func ensureEth0Exists () error {
126- ifaces , err := net .Interfaces ()
127- if err != nil {
128- return err
129- }
130- for _ , iface := range ifaces {
131- if iface .Name == DefaultInterface {
132- return nil
133- }
134- }
135- return errors .New ("eth0 device not found" )
136- }
137-
138122func getInterfaceInfo (iface string ) (Interface , error ) {
139123 ief , err := net .InterfaceByName (iface )
140124 if err != nil {
@@ -163,7 +147,7 @@ func getInterfaceInfo(iface string) (Interface, error) {
163147 }
164148 }
165149 if mask == "" {
166- return Interface {}, fmt .Errorf ("failed to find mask for %q" , DefaultInterface )
150+ return Interface {}, fmt .Errorf ("failed to find mask for %q" , iface )
167151 }
168152 // convert to decimal notation
169153 decimalParts := make ([]string , len (netMask ))
@@ -172,7 +156,7 @@ func getInterfaceInfo(iface string) (Interface, error) {
172156 }
173157 mask = strings .Join (decimalParts , "." )
174158 if ipAddress == "" {
175- return Interface {}, fmt .Errorf ("failed to find IPv4 address for %q" , DefaultInterface )
159+ return Interface {}, fmt .Errorf ("failed to find IPv4 address for %q" , iface )
176160 }
177161 gateway , err := gateway .DiscoverGateway ()
178162 if err != nil {
@@ -182,7 +166,7 @@ func getInterfaceInfo(iface string) (Interface, error) {
182166 IP : ipAddress ,
183167 DefaultGateway : gateway .String (),
184168 Mask : mask ,
185- Interface : DefaultInterface ,
169+ Interface : iface ,
186170 MAC : IfMAC ,
187171 }, nil
188172}
@@ -219,14 +203,6 @@ func addRedirectFilter(source netlink.Link, target netlink.Link) error {
219203func networkSetup (tapName string , ipAddress string , redirectLink netlink.Link , addTCRules bool , uid uint32 , gid uint32 ) (netlink.Link , error ) {
220204 netlog .Debugf ("starting for tapName=%s ipAddress=%s redirectLink=%s addTCRules=%v" ,
221205 tapName , ipAddress , redirectLink .Attrs ().Name , addTCRules )
222-
223- // Sanity check: ensure eth0 exists in this namespace
224- err := ensureEth0Exists ()
225- if err != nil {
226- netlog .Warnf ("eth0 interface not found in namespace (unikernel may have been spawned using ctr): %v" , err )
227- return nil , nil
228- }
229-
230206 // Create TAP
231207 netlog .Debugf ("creating tap device %s (mtu=%d)" , tapName , redirectLink .Attrs ().MTU )
232208 newTapDevice , err := createTapDevice (tapName , redirectLink .Attrs ().MTU , uid , gid )
@@ -333,12 +309,69 @@ func deleteIngressQdisc(link netlink.Link) error {
333309 return nil
334310}
335311
312+ // discoverContainerIface discovers the container's network interface by
313+ // scanning all links in the current network namespace and returning the first
314+ // non-loopback link that has an IP address and a default route.
315+ func discoverContainerIface () (netlink.Link , error ) {
316+ handle , err := netlink .NewHandle ()
317+ if err != nil {
318+ return nil , err
319+ }
320+ defer handle .Close ()
321+ links , err := handle .LinkList ()
322+ if err != nil {
323+ return nil , err
324+ }
325+ for _ , link := range links {
326+ attrs := link .Attrs ()
327+ if attrs == nil {
328+ netlog .Debug ("skipping link with nil attributes" )
329+ continue
330+ }
331+ // skip loopback
332+ if (attrs .Flags & net .FlagLoopback ) != 0 {
333+ netlog .Debugf ("skipping loopback interface %s" , attrs .Name )
334+ continue
335+ }
336+ // must have addresses configured
337+ addrs , err := handle .AddrList (link , netlink .FAMILY_ALL )
338+ if err != nil {
339+ netlog .Debugf ("skipping interface %s: failed to list addresses: %v" , attrs .Name , err )
340+ continue
341+ }
342+ if len (addrs ) == 0 {
343+ netlog .Debugf ("skipping interface %s: no addresses configured" , attrs .Name )
344+ continue
345+ }
346+ // look for a default route on this interface
347+ routes , err := handle .RouteList (link , netlink .FAMILY_ALL )
348+ if err != nil {
349+ netlog .Debugf ("skipping interface %s: failed to list routes: %v" , attrs .Name , err )
350+ continue
351+ }
352+ for _ , r := range routes {
353+ // default route: Dst == nil OR represented as 0.0.0.0/0 or ::/0
354+ if r .Dst == nil {
355+ return link , nil
356+ }
357+ if r .Dst != nil {
358+ dstStr := r .Dst .String ()
359+ if dstStr == "0.0.0.0/0" || dstStr == "::/0" {
360+ return link , nil
361+ }
362+ }
363+ }
364+ netlog .Debugf ("skipping interface %s: no default route found" , attrs .Name )
365+ }
366+ return nil , errors .New ("no suitable network interface found in namespace" )
367+ }
368+
336369func deleteAllQDiscs (device netlink.Link ) error {
337370 err := deleteIngressQdisc (device )
338371 if err != nil {
339372 return err
340373 }
341- device , err = netlink . LinkByName ( DefaultInterface )
374+ device , err = discoverContainerIface ( )
342375 if err != nil {
343376 return err
344377 }
@@ -357,8 +390,7 @@ func deleteAllTCFilters(device netlink.Link) error {
357390 return nil
358391 }
359392 allFilters = append (allFilters , tapFilters ... )
360-
361- device , err = netlink .LinkByName (DefaultInterface )
393+ device , err = discoverContainerIface ()
362394 if err != nil {
363395 return err
364396 }
0 commit comments