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 a Wasm plugin (Plugin A) modifies request headers in a way that triggers a reroute to a different route, subsequent Wasm plugins (Plugin B) may fail to correctly apply their match_rule configurations associated with the new route. This results in Plugin B operating with the configuration intended for the original route, leading to unexpected behavior and potentially incorrect request processing.
Root Cause Analysis
The root cause of this issue lies in how Higress (specifically, the underlying Envoy proxy) resolves the ROUTE_NAME property within the Wasm plugin context. When Plugin A reroutes the request, the clearRouteCache() function is called. However, this function only clears the cached route within the ActiveStream, but it doesn't update the streamInfo().route_, which is used by the getRouteName() function. Consequently, when Plugin B attempts to retrieve the route name, it retrieves the stale, original route name instead of the newly resolved route name.
The critical code snippet in context.cc is:
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() (Path 1) always returns the stale route name, the correct path (Path 2), which would re-evaluate the route, is never reached.
Proposed Solution
The proposed solution involves prioritizing the filter_callbacks->route() call when resolving the ROUTE_NAME. This ensures that the route is re-evaluated after a reroute event, allowing subsequent plugins to operate with the correct route configuration.
The corrected code snippet would be:
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;
By moving the filter_callbacks check to the top, the code prioritizes obtaining the route from the current filter callbacks, which will reflect the updated route after a reroute has occurred. The original info->getRouteName() call is retained as a fallback for cases where filter_callbacks is unavailable.
Practical Considerations and Best Practices
- Version Compatibility: Be aware of this issue when using Higress 2.2.0. If you rely on Wasm plugins and request rerouting, consider downgrading to version 2.1.11 as a temporary workaround or applying the patch described above.
- Testing: Thoroughly test your Wasm plugin configurations, especially when using rerouting. Ensure that plugins are behaving as expected after a reroute event.
- Logging and Monitoring: Implement robust logging and monitoring to track route changes and identify any discrepancies in plugin behavior. This will help you quickly detect and diagnose issues related to incorrect route resolution.
- Configuration Review: Carefully review your Wasm plugin configurations to ensure that
match_ruledefinitions are correctly associated with the intended routes, especially after a reroute.
By understanding the root cause and implementing the proposed solution, you can mitigate the risk of encountering this issue and ensure the correct and consistent operation of your Wasm plugins in Higress.