Higress Wasm Plugin Match Rules Failing After Rerouting in Version 2.2.0
In Higress version 2.2.0, a critical issue arises when using Wasm plugins in conjunction with request rerouting. Specifically, if one Wasm plugin (Plugin A) modifies the request in a way that triggers a reroute to a different backend service, subsequent Wasm plugins (Plugin B) might not correctly apply their match_rule configurations based on the new route. This can lead to unexpected behavior, where Plugin B processes the request as if it were still destined for the original route, ignoring any specific configurations intended for the rerouted request.
Understanding the Problem
Imagine you have two Wasm plugins, A and B, configured to run sequentially. Plugin A examines the incoming request and, based on certain conditions, modifies a header that causes Higress to route the request to a different service. Plugin B is configured with a match_rule that should only apply when requests are routed to this new service. However, due to a bug in Higress 2.2.0, Plugin B incorrectly identifies the route, causing its match_rule to fail and potentially leading to incorrect processing.
The Root Cause: Stale Route Information
The underlying cause lies in how Higress handles route information after a reroute. When Plugin A triggers a reroute, Higress clears the route cache for the current request. However, the streamInfo().route_, which stores the initial route, is not updated. Consequently, when Plugin B attempts to retrieve the route name, it retrieves the stale, original route name instead of the correct, rerouted route name. As pointed out in the community discussion, the issue originates in the context.cc file within the Higress codebase.
The problematic code block looks like this:
case PropertyToken::ROUTE_NAME:
if (info && !info->getRouteName().empty()) { // ← Path 1: STALE
return CelValue::CreateString(&info->getRouteName());
}
if (filter_callbacks) {
auto route = filter_callbacks->route(); // ← Path 2: CORRECT (never reached)
if (route) {
return CelValue::CreateString(&route->routeName());
}
}
break;
Because info->getRouteName() returns the old route name, the second, correct path is never reached.
The Solution: Prioritize the Correct Route
The suggested solution involves modifying the order in which Higress retrieves the route name. By prioritizing the filter_callbacks->route() method, which correctly identifies the rerouted route, we can ensure that Plugin B uses the correct match_rule configuration. The proposed code change is as follows:
case PropertyToken::ROUTE_NAME:
if (filter_callbacks) {
auto route = filter_callbacks->route();
if (route) {
return CelValue::CreateString(&route->routeName());
}
}
if (info && !info->getRouteName().empty()) {
return CelValue::CreateString(&info->getRouteName());
}
break;
This change prioritizes obtaining the route information from the filter_callbacks, ensuring that the correct route name is used after a reroute. The original logic is retained as a fallback for scenarios where filter_callbacks is unavailable.
Practical Considerations and Workarounds
If you are using Higress 2.2.0 and encountering this issue, applying the code change described above is the recommended solution. Alternatively, downgrading to Higress version 2.1.11, as suggested in the original issue, can serve as a temporary workaround. To downgrade, use the following Helm command:
helm upgrade higress -n higress-system higress.io/higress --create-namespace --render-subchart-notes --set global.local=true --set global.o11y.enabled=false --version 2.1.11
Remember to thoroughly test any changes or workarounds in a non-production environment before deploying them to production.