apache / apache/apisix

refactor: Standardise listener IPv6 support across endpoints

Open
#13,112 3 comments 0 reactions 0 assignees View on GitHub
enhancement
Dominant language
Lua
Stars
17.1k
Forks
2.9k
Avg merge
3d 16h
Merged PRs (30d)
63

Description

### Description

## Description

APISIX handles listener configuration inconsistently across its endpoints. `node_listen` and `ssl.listen` support flexible object/list-based definitions and automatically generate proper dual-stack (IPv4 + IPv6) listen directives when `enable_ipv6` is true. Other endpoints do not:

| Listener | Config Key | IPv6 support | Multi-port | Uses `listen_table_insert` |
|---|---|---|---|---|
| HTTP proxy | `apisix.node_listen` | Yes | Yes | Yes |
| HTTPS/SSL | `apisix.ssl.listen` | Yes | Yes | Yes |
| PROXY Protocol | `apisix.proxy_protocol` | Global only (added in #12859) | No | No |
| Admin API | `deployment.admin.admin_listen` | No | No | No |
| Control API | `apisix.control` | No | No | No |
| Status API | `apisix.status` | No | No | No |
| Prometheus | `plugin_attr.prometheus.export_addr` | No | No | No |

### The problem in practice

In IPv6 environments like Kubernetes, deployers currently work around this by either setting the listener IP directly to `[::]` (relying on OS-level dual-stack behavior, which isn't guaranteed) or injecting raw Nginx configuration snippets. For example, a Helm values workaround to get IPv6 working on admin, status, and proxy_protocol:

```yaml
admin:
ip: '"[::]"'
status:
ip: '"[::]"'
nginx:
configurationSnippet:
httpSrv: |
listen [::]:9182 ssl default_server proxy_protocol;
```

This should be unnecessary, setting `enable_ipv6: true` should be enough for all endpoints to generate proper dual-stack listen directives, just as it already does for `node_listen` and `ssl.listen`.

## Proposed Change

Route all listener processing through `listen_table_insert` in `ops.lua`, which already handles IPv4/IPv6 expansion, IP validation, and duplicate detection. This would:

1. **For `proxy_protocol`**: Add full alignment with `node_listen`/`ssl.listen`, list-based `listen_http`/`listen_https` keys with IP binding and multi-port support (backward compatible with `listen_http_port`/`listen_https_port`).
2. **For `admin`, `control`, `status`, `prometheus`**: Process through `listen_table_insert` to gain automatic IPv6 support via `enable_ipv6`. No multi-port support needed, these remain single-endpoint listeners.

The result is one code path for all listeners instead of the current 4-5 different patterns, and `enable_ipv6: true` works consistently everywhere.

## Implementation approach

The bulk of the work involves making `listen_table_insert` generic enough to handle all listener types (it currently assumes HTTP/HTTPS proxy semantics). The template changes in `ngx_tpl.lua` are minimal, iterating over processed listener lists instead of raw config values. Most of the diff will likely be in tests, updating them to validate IPv6 generation and the new schema for `proxy_protocol`. The core logic change is small since the patterns already exist in `node_listen`/`ssl.listen` processing.

## Context

This was originally part of #12859, which was simplified per reviewer feedback to only add IPv6 support for PROXY Protocol. A reference implementation for the `proxy_protocol` portion exists on branch [`refactor/proxy-protocol-listener-standardization`](https://github.com/twellck/apisix/tree/refactor/proxy-protocol-listener-standardization).

---
*Note: AI helped format this Issue.*

Contributor guide

Open the contributing guide

Research direction

Start by reading listen_table_insert in ops.lua and compare its existing node_listen and ssl.listen processing with the listener paths for proxy_protocol, admin, control, status, and prometheus. Inspect ngx_tpl.lua and the existing listener tests; done means all targeted listeners use the shared processing path and tests verify IPv6 expansion, validation, duplicate detection, and the proposed proxy_protocol schema.

Written by the indexing model from the issue text.

Assessment

Tech stack
lua, nginx
Domain
api, backend, networking
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.