Skip to content

Commit

Permalink
Fix interface selection for IPv6-only hosts
Browse files Browse the repository at this point in the history
Instead of considering the full IPv4 routing table, we only look for
IPv4 default route and IPv6 routes shorter or equal /8 (for instance
`2000::/3`). Since the `conf.route6` is not ready yet when we first run,
we reload `conf.ifaces` after loading `route6.py`.

This fixes #4304

Signed-off-by: Ondřej Caletka <ondrej@caletka.cz>
  • Loading branch information
oskar456 committed May 7, 2024
1 parent 8cea357 commit f655438
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 5 deletions.
19 changes: 14 additions & 5 deletions scapy/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,11 +372,20 @@ def get_if_list():
def get_working_if():
# type: () -> NetworkInterface
"""Return an interface that works"""
# return the interface associated with the route with smallest
# mask (route by default if it exists)
routes = conf.route.routes[:]
routes.sort(key=lambda x: x[1])
ifaces = (x[3] for x in routes)
# return the interface associated with the default route
# IPv4 default route is preferred, then IPv6 route
# shorter or equal than /8 or any interface as a fallback
default_routes_v4 = (x for x in conf.route.routes if x[1] == 0)
if conf.route6:
default_routes_v6 = (x for x in conf.route6.routes if x[1] <= 8)
default_routes_v6 = sorted(default_routes_v6, key=lambda x: x[1])
else:
default_routes_v6 = []

ifaces = (x[3] for x in itertools.chain(
default_routes_v4,
default_routes_v6)
)
# First check the routing ifaces from best to worse,
# then check all the available ifaces as backup.
for ifname in itertools.chain(ifaces, conf.ifaces.values()):
Expand Down
2 changes: 2 additions & 0 deletions scapy/route6.py
Original file line number Diff line number Diff line change
Expand Up @@ -360,3 +360,5 @@ def route(self, dst="", dev=None, verbose=conf.verb):


conf.route6 = Route6()
# IPv6 routing table can influence default interface selection
conf.ifaces.reload()

0 comments on commit f655438

Please sign in to comment.