@@ -90,7 +90,25 @@ def get_base_chains_for_hook(hook: str, family: str = "ip") -> list:
9090
9191def get_table_for_hook (hook : str , family : str = "ip" ) -> str :
9292 chains = get_base_chains_for_hook (hook , family )
93- table = chains .pop ()["chain" ]["table" ]
93+ if not chains :
94+ raise Exception (f"Could not find any base chain for hook '{ hook } '" )
95+
96+ # Sort by priority, lowest-to-highest
97+ chains .sort (key = lambda x : x ["chain" ].get ("prio" , 0 ))
98+
99+ if hook == "prerouting" :
100+ # For prerouting (DNAT), we MUST use the 'nat' type hook.
101+ # Filter for 'nat' type chains and pick the one with the highest priority (last in list).
102+ nat_chains = [c for c in chains if c ["chain" ].get ("type" ) == "nat" ]
103+ if not nat_chains :
104+ # Fallback: maybe only the 'raw' chain exists. This will fail, but it's what the log shows.
105+ logger .warning (f"No 'nat' type prerouting chain found. Falling back to highest prio chain." )
106+ table = chains [- 1 ]["chain" ]["table" ]
107+ else :
108+ table = nat_chains [- 1 ]["chain" ]["table" ] # Pick highest prio 'nat' chain
109+ else :
110+ # For forward/postrouting, use the lowest priority (earliest)
111+ table = chains [0 ]["chain" ]["table" ]
94112 return table
95113
96114
@@ -230,9 +248,21 @@ def initialize_nftables() -> None:
230248 new_chain = {"chain" : chain }
231249 commands .append ({"add" : new_chain })
232250 chains .append (new_chain )
233- # If multiple base chain for the hook, use the less priority one
251+
252+ # Sort by priority, lowest-to-highest
234253 chains .sort (key = lambda x : x ["chain" ]["prio" ])
235- base_chains [hook ] = chains [0 ]["chain" ]
254+
255+ if hook == "prerouting" :
256+ # For prerouting, we MUST use the 'nat' type hook which has a higher priority than the 'raw' hook,
257+ # We filter for 'nat' type, and if multiple, pick the one with highest priority (last in list).
258+ nat_chains = [c for c in chains if c ["chain" ].get ("type" ) == "nat" ]
259+ if not nat_chains :
260+ raise Exception ("Failed to find or create a 'nat' type prerouting chain" )
261+ base_chains [hook ] = nat_chains [- 1 ]["chain" ] # Pick highest prio 'nat' chain
262+ else :
263+ # For other hooks (forward, postrouting), use the original logic:
264+ # the one with the lowest priority (earliest).
265+ base_chains [hook ] = chains [0 ]["chain" ]
236266
237267 # Add chain aleph-supervisor-nat
238268 commands += add_entity_if_not_present (
0 commit comments