API de VLANs, IPs e rotas
Estes endpoints gerenciam as interfaces VLAN do roteador, os endereços das suas interfaces, as rotas estáticas que ele mantém entre reinicializações e seus pools de NAT dinâmico (de origem). URL base, autenticação e formato de erro estão descritos na visão geral da API.
Tudo o que é criado aqui é persistido pelo roteador e restaurado na inicialização. As mudanças são registradas com o endereço de quem fez a chamada. Uma resposta 5xx pode trazer broken_data_files, com o nome dos arquivos de dados do roteador que não podem ser interpretados.
O nome da interface de uma VLAN decorre do seu pai e do protocolo: vlan100 para uma VLAN 802.1Q em uma porta ou bond, svlan500 para uma S-VLAN 802.1ad, svlan500.20 para uma C-VLAN dentro de uma S-VLAN.
GET /vlans
Seção intitulada “GET /vlans”Todas as VLANs que o roteador gerencia, com seu estado atual.
curl -H "X-API-Key: YOUR_API_KEY" http://ROUTER-IP:8880/vlans{ "count": 1, "vlans": [ { "name": "vlan110", "parent": "bond0", "vlan_id": 108, "protocol": "802.1Q", "ips": ["100.64.8.1/24"], "ips6": ["XXXX:XXXX:110::1/64"], "label": "OLT 1 PON 0/1/3", "added": "2026-09-01 10:00:00", "enabled": true, "live": true, "status": "UP", "live_ips": ["100.64.8.1/24"], "live_ips6": ["XXXX:XXXX:110::1/64"] } ]}status é o estado do link, DISABLED para uma VLAN desativada, ou NOT CREATED quando a interface não existe.
POST /vlans
Seção intitulada “POST /vlans”Cria a VLAN, a ativa e adiciona seus endereços. A menos que serve esteja desligado, cada endereço é então servido: IPv4 com DHCP (POST /net), IPv6 com DHCPv6 e um pool (POST /net6, POST /net6/pool) e prefix delegation (POST /pd). Cada etapa de atendimento é informada separadamente; uma etapa com falha não desfaz a VLAN.
| Nome | Em | Tipo | Observações |
|---|---|---|---|
parent |
body | string | Interface pai existente: uma porta, bond ou S-VLAN. |
vlan_id |
body | integer | 1–4094. |
protocol |
body | string | 802.1Q (padrão) ou 802.1ad. |
ip |
body | CIDR | Endereço de gateway IPv4 opcional, p. ex. 100.64.8.1/24. Um endereço de rede é corrigido para o primeiro host (com uma observação). |
ipv6 |
body | CIDR | Endereço IPv6 opcional, p. ex. XXXX:XXXX:110::1/64. |
label |
body | string | Descrição opcional. |
serve |
body | boolean | 0, false ou no cria apenas o link. Ligado por padrão. |
force |
body | boolean | Permite um endereço que se sobreponha a outro já existente em outra interface. |
curl -X POST -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \ -d '{"parent":"bond0","vlan_id":108,"ip":"100.64.8.1/24","ipv6":"XXXX:XXXX:110::1/64","label":"OLT 1 PON 0/1/3"}' \ http://ROUTER-IP:8880/vlans{ "ok": true, "code": 201, "message": "VLAN vlan110 created on bond0 (100.64.8.1/24) (XXXX:XXXX:110::1/64)", "name": "vlan110", "parent": "bond0", "vlan_id": 108, "protocol": "802.1Q", "ip": "100.64.8.1/24", "ipv6": "XXXX:XXXX:110::1/64", "served": { "net": { "network": "100.64.8.0/24" }, "net6": { "network": "XXXX:XXXX:110::/64", "pool": "XXXX:XXXX:110::1000 - XXXX:XXXX:110::ffff" }, "pd": { "pool": "XXXX:XXXX:a:1000:: - XXXX:XXXX:a:10ff::", "capacity": 256 } }}Uma etapa de atendimento com falha aparece como {"error": "…", "retry": "dtvsol net add vlan110"} sob a sua chave, e warning informa que a VLAN não está totalmente servida. Com serve desligado, served é null e note indica quais comandos a servem depois.
Erros: 400 ID, endereço ou protocolo inválido; 404 pai não encontrado; 409 VLAN já existe, tag já usada nesse pai, ou conflito de endereço (a resposta traz conflict; passe force para ignorar).
DELETE /vlans
Seção intitulada “DELETE /vlans”O nome da VLAN é lido do corpo.
| Nome | Em | Tipo | Observações |
|---|---|---|---|
name |
body | string | Nome da interface VLAN, p. ex. vlan110. |
curl -X DELETE -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \ -d '{"name":"vlan110"}' http://ROUTER-IP:8880/vlans{ "ok": true, "code": 200, "message": "VLAN vlan110 deleted", "name": "vlan110", "removed_subnets": ["subnet 100.64.8.0"], "removed_pd_pool": null, "removed_routes": [], "removed_nat": null, "removed_forwards": [], "kept": { "rrd": "data/rrd/iface_vlan110.rrd (traffic history; delete by hand if not wanted)" }}Erros: 404 não é uma VLAN gerenciada; 409 quando outra VLAN a usa como pai, ainda há clientes cadastrados nela, ou o CGNAT traduz através dela (a resposta traz um fix).
POST /vlans/disable
Seção intitulada “POST /vlans/disable”Desliga uma VLAN sem liberar nada; POST /vlans/enable a restaura exatamente como estava. GET /vlans/disable recebe os parâmetros pela query string.
| Nome | Em | Tipo | Observações |
|---|---|---|---|
name |
body | string | Nome da interface VLAN. |
reason |
body | string | Observação opcional guardada com a VLAN. |
curl -X POST -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \ -d '{"name":"vlan110","reason":"OLT maintenance"}' http://ROUTER-IP:8880/vlans/disable{ "ok": true, "code": 200, "message": "VLAN vlan110 disabled", "name": "vlan110", "enabled": false, "disabled_at": "2026-09-27 10:00:00", "reason": "OLT maintenance", "took_offline": ["dhcp4", "dhcp6", "radvd", "link down"], "kept": "delegation range, subnet blocks, NAT pool, port forwards, routes, client reservations and addresses — all restored by: dtvsol vlan enable vlan110", "forwards_still_active": []}Erros: 404 não encontrada; 409 já desativada, uma VLAN ativa roda sobre ela, ou o CGNAT traduz através dela.
POST /vlans/enable
Seção intitulada “POST /vlans/enable”| Nome | Em | Tipo | Observações |
|---|---|---|---|
name |
body | string | Nome da interface VLAN. |
curl -X POST -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \ -d '{"name":"vlan110"}' http://ROUTER-IP:8880/vlans/enable{ "ok": true, "code": 200, "message": "VLAN vlan110 enabled", "name": "vlan110", "enabled": true, "restored": ["link up", "addresses", "dhcp4", "dhcp6 + radvd"], "forwards_active": [], "was_disabled_at": "2026-09-27 10:00:00", "was_disabled_reason": "OLT maintenance"}Erros: 404 não encontrada; 409 já ativa ou sua VLAN pai está desativada.
Endereços de interface
Seção intitulada “Endereços de interface”POST /ip
Seção intitulada “POST /ip”Adiciona um endereço IPv4 ou IPv6 a uma interface existente. Em uma VLAN gerenciada, ele é armazenado com a VLAN; em uma porta física ou bond, é armazenado na configuração de rede do roteador. Adicionar um endereço que já está ativo apenas o persiste. O endereço não é servido automaticamente — use POST /net ou POST /net6.
| Nome | Em | Tipo | Observações |
|---|---|---|---|
iface |
body | string | Nome da interface. |
ip |
body | CIDR | Endereço IPv4 ou IPv6 com o comprimento do prefixo. Um endereço de rede é corrigido para o primeiro host. |
curl -X POST -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \ -d '{"iface":"vlan110","ip":"100.64.9.1/24"}' http://ROUTER-IP:8880/ip{ "ok": true, "code": 201, "message": "IP 100.64.9.1/24 added to vlan110", "persisted": true }Quando o endereço foi corrigido, a resposta também traz requested, assigned e note. Erros: 400 endereço inválido; 404 interface não encontrada; 409 quando a sub-rede já está em outra interface (via REST não há como ignorar; a action API aceita force=1).
DELETE /ip
Seção intitulada “DELETE /ip”| Nome | Em | Tipo | Observações |
|---|---|---|---|
iface |
body | string | Nome da interface. |
ip |
body | CIDR | Endereço a remover, como foi atribuído. |
curl -X DELETE -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \ -d '{"iface":"vlan110","ip":"100.64.9.1/24"}' http://ROUTER-IP:8880/ip{ "ok": true, "code": 200, "message": "IP 100.64.9.1/24 removed from vlan110", "warning": "no interface is served in that network any more, so subnet 100.64.9.0 in dhcpd.conf is now unused — kept because it may hold hand-tuned options; remove it deliberately if not wanted", "unused_subnet": { "kind": "subnet", "block": "100.64.9.0", "file": "/etc/dhcp/dhcpd.conf" }}Uma sub-rede DHCP ou faixa de delegação que fique sem uso é indicada (unused_subnet, unused_pd_pool, pd_warning), nunca removida. Erros: 400 endereço inválido; 404 interface não encontrada; 409 quando o endereço é o gateway de um cliente cadastrado. Outros métodos em /ip respondem 400 Use POST /ip or DELETE /ip.
Rotas estáticas
Seção intitulada “Rotas estáticas”GET /routes
Seção intitulada “GET /routes”As rotas que o roteador gerencia (restauradas na inicialização) e as tabelas de roteamento IPv4 e IPv6 atuais do kernel.
curl -H "X-API-Key: YOUR_API_KEY" http://ROUTER-IP:8880/routes{ "count": 1, "managed": [ { "prefix": "default", "via": "XXX.XXX.XXX.1", "dev": "vlan90", "family": "ipv4", "comment": "upstream", "created": "2026-09-01 10:00:00" } ], "live_ipv4": ["default via XXX.XXX.XXX.1 dev vlan90"], "live_ipv6": []}POST /routes
Seção intitulada “POST /routes”| Nome | Em | Tipo | Observações |
|---|---|---|---|
prefix |
body | string | CIDR (10.50.0.0/24, XXXX:XXXX::/48) ou default. |
via |
body | IP | Gateway, da mesma família do prefixo. via e/ou dev é obrigatório. |
dev |
body | string | Interface de saída. |
comment |
body | string | Opcional. |
curl -X POST -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \ -d '{"prefix":"default","via":"XXX.XXX.XXX.1","dev":"vlan90","comment":"upstream"}' \ http://ROUTER-IP:8880/routes{ "ok": true, "code": 201, "message": "Route added", "route": { "prefix": "default", "via": "XXX.XXX.XXX.1", "dev": "vlan90", "family": "ipv4", "comment": "upstream", "created": "2026-09-28 09:00:00" }}Erros: 400 prefixo, gateway ou nome de interface inválido; 409 Route already managed; 500 quando o kernel recusa a rota.
DELETE /routes
Seção intitulada “DELETE /routes”É removida a primeira rota gerenciada com este prefixo (e, quando informados, com este via/dev).
| Nome | Em | Tipo | Observações |
|---|---|---|---|
prefix |
body | string | Prefixo da rota, ou default. |
via |
body | IP | Opcional, para escolher uma entre várias rotas. |
dev |
body | string | Opcional, para escolher uma entre várias rotas. |
curl -X DELETE -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \ -d '{"prefix":"default"}' http://ROUTER-IP:8880/routes{ "ok": true, "code": 200, "message": "Route removed", "route": { "prefix": "default", "via": "XXX.XXX.XXX.1", "dev": "vlan90", "family": "ipv4" }, "kernel_removed": true}Erros: 404 Route … is not managed by DTVSOL.
Pools de NAT dinâmico
Seção intitulada “Pools de NAT dinâmico”NAT de origem para o tráfego que sai por uma interface, traduzido para um único endereço público ou para uma faixa. Para CGNAT com blocos de portas determinísticos, veja a API de CGNAT.
GET /nat
Seção intitulada “GET /nat”Os pools configurados e as regras NAT POSTROUTING atuais.
curl -H "X-API-Key: YOUR_API_KEY" http://ROUTER-IP:8880/nat{ "count": 1, "pools": [ { "iface": "vlan90", "pool_start": "XXX.XXX.XXX.10", "pool_end": "XXX.XXX.XXX.20", "exempt": ["10.0.0.0/8"], "comment": "", "created": "2026-09-01 10:00:00" } ], "live_postrouting": ["-P POSTROUTING ACCEPT", "-A POSTROUTING -o vlan90 -j SNAT --to-source XXX.XXX.XXX.10-XXX.XXX.XXX.20 …"]}POST /nat
Seção intitulada “POST /nat”| Nome | Em | Tipo | Observações |
|---|---|---|---|
iface |
body | string | Interface de saída. |
pool_start |
body | IPv4 | Primeiro endereço público. |
pool_end |
body | IPv4 | Último endereço público, opcional; omita para um único endereço. |
exempt |
body | list ou string | Redes IPv4 (CIDR) opcionais que não são traduzidas; uma lista ou uma string separada por vírgulas. |
comment |
body | string | Opcional. |
curl -X POST -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \ -d '{"iface":"vlan90","pool_start":"XXX.XXX.XXX.10","pool_end":"XXX.XXX.XXX.20","exempt":["10.0.0.0/8"]}' \ http://ROUTER-IP:8880/nat{ "ok": true, "code": 201, "message": "Dynamic NAT pool configured", "pool": { "iface": "vlan90", "pool_start": "XXX.XXX.XXX.10", "pool_end": "XXX.XXX.XXX.20", "exempt": ["10.0.0.0/8"], "comment": "", "created": "2026-09-28 09:00:00" }}Erros: 400 nome de interface, endereço do pool, faixa invertida ou rede isenta inválidos; 404 interface não encontrada; 500 quando uma regra não pode ser instalada.
DELETE /nat
Seção intitulada “DELETE /nat”| Nome | Em | Tipo | Observações |
|---|---|---|---|
iface |
body | string | Interface cujo pool é removido. |
curl -X DELETE -H "X-API-Key: YOUR_API_KEY" -H "Content-Type: application/json" \ -d '{"iface":"vlan90"}' http://ROUTER-IP:8880/nat{ "ok": true, "code": 200, "message": "NAT pool removed", "iface": "vlan90", "rules_removed": 1, "pool": { "iface": "vlan90", "pool_start": "XXX.XXX.XXX.10", "pool_end": "XXX.XXX.XXX.20" }}Erros: 400 sem iface; 404 No DTVSOL NAT pool on ….
Equivalentes na action API
Seção intitulada “Equivalentes na action API”| Ação | Parâmetros de query | Equivale a |
|---|---|---|
action=vlan-list |
— | GET /vlans |
action=vlan-add |
parent, vlan_id, protocol, ip, ipv6, label, force=1, serve=0 |
POST /vlans |
action=vlan-del |
name |
DELETE /vlans |
action=vlan-disable |
name, reason |
POST /vlans/disable |
action=vlan-enable |
name |
POST /vlans/enable |
action=ip-add |
iface, ip, force=1 |
POST /ip (com override) |
action=ip-del |
iface, ip |
DELETE /ip |
action=route-list |
— | GET /routes |
action=route-add |
prefix, via, dev, comment |
POST /routes |
action=route-del |
prefix, via, dev |
DELETE /routes |
action=nat-list |
— | GET /nat |
action=nat-add |
iface, pool_start, pool_end, exempt, comment |
POST /nat |
action=nat-del |
iface |
DELETE /nat |
Este site foi escrito com a ajuda de IA e revisado pela nossa equipe.