Skip to content

when restart, sync the toplogy vlan/bw state from connections out of db#498

Merged
YufengXin merged 16 commits intomainfrom
495-failed-to-recover-vlan-when-deleting-l2vpn-after-controller-restarts
Dec 10, 2025
Merged

when restart, sync the toplogy vlan/bw state from connections out of db#498
YufengXin merged 16 commits intomainfrom
495-failed-to-recover-vlan-when-deleting-l2vpn-after-controller-restarts

Conversation

@YufengXin
Copy link
Collaborator

No description provided.

@YufengXin YufengXin self-assigned this Sep 30, 2025
@YufengXin YufengXin linked an issue Sep 30, 2025 that may be closed by this pull request
@YufengXin YufengXin marked this pull request as draft September 30, 2025 16:57
@coveralls
Copy link

coveralls commented Sep 30, 2025

Pull Request Test Coverage Report for Build 20110929781

Details

  • 11 of 81 (13.58%) changed or added relevant lines in 2 files are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage decreased (-1.4%) to 53.895%

Changes Missing Coverage Covered Lines Changed/Added Lines %
sdx_controller/handlers/connection_handler.py 1 4 25.0%
sdx_controller/messaging/rpc_queue_consumer.py 10 77 12.99%
Files with Coverage Reduction New Missed Lines %
sdx_controller/handlers/connection_handler.py 1 66.08%
Totals Coverage Status
Change from base Build 19898968760: -1.4%
Covered Lines: 1266
Relevant Lines: 2349

💛 - Coveralls

Yufeng Xin and others added 11 commits October 1, 2025 09:45
Merge branch '492-include-domain-status' into 495-failed-to-recover-vlan-when-deleting-l2vpn-after-controller-restarts
Merge branch 'main' into 495-failed-to-recover-vlan-when-deleting-l2vpn-after-controller-restarts
@YufengXin
Copy link
Collaborator Author

[rocky@Node1 sdx-end-to-end-tests]$ docker compose up -d --pull never
[+] Running 11/11
 ✔ Network sdx-end-to-end-tests_default             Created                                                                                            0.1s 
 ✔ Container sdx-end-to-end-tests-mq1-1             Healthy                                                                                            7.0s 
 ✔ Container sdx-end-to-end-tests-mongo-1           Healthy                                                                                            6.0s 
 ✔ Container sdx-end-to-end-tests-sax-1             Started                                                                                            6.4s 
 ✔ Container sdx-end-to-end-tests-sax-lc-1          Started                                                                                            7.5s 
 ✔ Container sdx-end-to-end-tests-ampath-lc-1       Started                                                                                            7.6s 
 ✔ Container sdx-end-to-end-tests-sdx-controller-1  Started                                                                                            7.5s 
 ✔ Container sdx-end-to-end-tests-tenet-lc-1        Started                                                                                            7.5s 
 ✔ Container sdx-end-to-end-tests-ampath-1          Started                                                                                            6.4s 
 ✔ Container sdx-end-to-end-tests-tenet-1           Started                                                                                            6.3s 
 ✔ Container sdx-end-to-end-tests-mininet-1         Started                                                                                            6.7s 
[rocky@Node1 sdx-end-to-end-tests]$ ./wait-mininet-ready.sh
Waiting mininet to be ready.....ok
[rocky@Node1 sdx-end-to-end-tests]$ ./scripts/run-mininet-interactive.sh 
-> starting mininet
-> waiting switches to connect
...............................switches connected
[rocky@Node1 sdx-end-to-end-tests]$ docker compose exec -it mininet curl -s -X POST -H 'Content-type: application/json' http://sdx-controller:8080/SDX-Controller/l2vpn/1.0 -d '{"name": "L2VPN-Ampath3-Tenet03-vlan-4001", "endpoints": [{"port_id": "urn:sdx:port:ampath.net:Ampath3:50", "vlan": "4001"}, {"port_id": "urn:sdx:port:tenet.ac.za:Tenet01:50", "vlan": "4001"}]}'
`{`
  "reason": "Connection published",
  "service_id": "a05cf8ae-c1af-4f70-af0c-bd2a63a38d6b",
  "status": "under provisioning"
}
[rocky@Node1 sdx-end-to-end-tests]$ docker compose up -d sdx-controller --force-recreate --pull never
[+] Running 3/3
 ✔ Container sdx-end-to-end-tests-mq1-1             Healthy                                                                                            1.5s 
 ✔ Container sdx-end-to-end-tests-mongo-1           Healthy                                                                                            1.5s 
 ✔ Container sdx-end-to-end-tests-sdx-controller-1  Started                                                                                            1.8s 
[rocky@Node1 sdx-end-to-end-tests]$ for ID in $(docker compose exec -it mininet curl -s http://sdx-controller:8080/SDX-Controller/l2vpn/1.0 | jq -r '.[].service_id'); do docker compose exec -it mininet curl -s -X DELETE http://sdx-controller:8080/SDX-Controller/l2vpn/1.0/$ID; done
"OK"

After the sdx-controller restarted, deleting the connection returns the used vlan.

[rocky@Node1 sdx-end-to-end-tests]$ ./scripts/show-sdx-controller.sh ports
ID                                   STATUS  STATE    L2VPN-VLAN-RANGE
--                                   ------  -----    ----------------
urn:sdx:port:sax.net:Sax01:41        up      enabled  ["2-4094","1"]
urn:sdx:port:sax.net:Sax01:1         up      enabled  ["1-4094"]
urn:sdx:port:sax.net:Sax01:40        up      enabled  ["2-4094","1"]
urn:sdx:port:sax.net:Sax01:50        up      enabled  ["1-4094"]
urn:sdx:port:sax.net:Sax02:41        up      enabled  ["1-4094"]
urn:sdx:port:sax.net:Sax02:1         up      enabled  ["1-4094"]
urn:sdx:port:sax.net:Sax02:40        up      enabled  ["1-4094"]
urn:sdx:port:sax.net:Sax02:50        up      enabled  ["1-4094"]
urn:sdx:port:tenet.ac.za:Tenet01:41  up      enabled  ["2-4094","1"]
urn:sdx:port:tenet.ac.za:Tenet01:1   up      enabled  ["1-4094"]
urn:sdx:port:tenet.ac.za:Tenet01:2   up      enabled  ["1-4094"]
urn:sdx:port:tenet.ac.za:Tenet01:50  up      enabled  ["1-4000","4002-4094","4001"]
urn:sdx:port:tenet.ac.za:Tenet02:41  up      enabled  ["1-4094"]
urn:sdx:port:tenet.ac.za:Tenet02:1   up      enabled  ["1-4094"]
urn:sdx:port:tenet.ac.za:Tenet02:50  up      enabled  ["1-4094"]
urn:sdx:port:tenet.ac.za:Tenet03:50  up      enabled  ["1-4094"]
urn:sdx:port:tenet.ac.za:Tenet03:2   up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath1:1    up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath1:40   up      enabled  ["2-4094","1"]
urn:sdx:port:ampath.net:Ampath1:50   up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath1:2    up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath2:1    up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath2:50   up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath2:40   up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath2:3    up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath3:2    up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath3:50   up      enabled  ["1-4000","4002-4094","4001"]
urn:sdx:port:ampath.net:Ampath3:3    up      enabled  ["1-4094"]``

The sdx-controller log shows that the 'delete' calls to OXPs:

DEBUG:connexion.apis.abstract:Got framework response
INFO:     192.168.64.7:34080 - "DELETE /SDX-Controller/l2vpn/1.0/a05cf8ae-c1af-4f70-af0c-bd2a63a38d6b HTTP/1.1" 200 OK
DEBUG:sdx_controller.messaging.rpc_queue_consumer:MQ received message:b'{"lc_domain": "sax.net", "msg_type": "oxp_conn_response", "service_id": "a05cf8ae-c1af-4f70-af0c-bd2a63a38d6b", "operation": "delete", "oxp_response_code": 201, "oxp_response": "L2VPN Deleted"}'
INFO:sdx_controller.handlers.lc_message_handler:MQ received message:b'{"lc_domain": "sax.net", "msg_type": "oxp_conn_response", "service_id": "a05cf8ae-c1af-4f70-af0c-bd2a63a38d6b", "operation": "delete", "oxp_response_code": 201, "oxp_response": "L2VPN Deleted"}'
INFO:sdx_controller.handlers.lc_message_handler:Received OXP connection response.
DEBUG:sdx_controller.messaging.rpc_queue_consumer:MQ received message:b'{"lc_domain": "tenet.ac.za", "msg_type": "oxp_conn_response", "service_id": "a05cf8ae-c1af-4f70-af0c-bd2a63a38d6b", "operation": "delete", "oxp_response_code": 201, "oxp_response": "L2VPN Deleted"}'
INFO:sdx_controller.handlers.lc_message_handler:MQ received message:b'{"lc_domain": "tenet.ac.za", "msg_type": "oxp_conn_response", "service_id": "a05cf8ae-c1af-4f70-af0c-bd2a63a38d6b", "operation": "delete", "oxp_response_code": 201, "oxp_response": "L2VPN Deleted"}'
INFO:sdx_controller.handlers.lc_message_handler:Received OXP connection response.
DEBUG:sdx_controller.messaging.rpc_queue_consumer:MQ received message:b'{"lc_domain": "ampath.net", "msg_type": "oxp_conn_response", "service_id": "a05cf8ae-c1af-4f70-af0c-bd2a63a38d6b", "operation": "delete", "oxp_response_code": 201, "oxp_response": "L2VPN Deleted"}'
INFO:sdx_controller.handlers.lc_message_handler:MQ received message:b'{"lc_domain": "ampath.net", "msg_type": "oxp_conn_response", "service_id": "a05cf8ae-c1af-4f70-af0c-bd2a63a38d6b", "operation": "delete", "oxp_response_code": 201, "oxp_response": "L2VPN Deleted"}'
INFO:sdx_controller.handlers.lc_message_handler:Received OXP connection response.
DEBUG:connexion.apis.flask_api:Getting data and status code
DEBUG:connexion.decorators.parameter:Function Arguments: []
DEBUG:connexion.apis.abstract:Getting data and status code
DEBUG:connexion.apis.abstract:Prepared body and status code (200)

@YufengXin
Copy link
Collaborator Author

atlanticwave-sdx/pce#298

Copy link
Contributor

@italovalcy italovalcy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@YufengXin tested here with a few scenarios and regarding the VLAN state, it seems fine, but regarding bw state, it seems there is a problem. See the test below:

  1. Create a few L2VPNs without bw requirements (I'm not sure this is actually necessary):
docker compose exec -it mininet curl -s -X POST -H 'Content-type: application/json' http://sdx-controller:8080/SDX-Controller/l2vpn/1.0 -d '{"name": "l2vpn1", "endpoints": [{"port_id": "urn:sdx:port:ampath.net:Ampath3:50", "vlan": "999"}, {"port_id": "urn:sdx:port:tenet.ac.za:Tenet01:50", "vlan": "999"}]}' | tee /tmp/l2vpn1
docker compose exec -it mininet curl -s -X POST -H 'Content-type: application/json' http://sdx-controller:8080/SDX-Controller/l2vpn/1.0 -d '{"name": "l2vpn2", "endpoints": [{"port_id": "urn:sdx:port:ampath.net:Ampath3:50", "vlan": "any"}, {"port_id": "urn:sdx:port:tenet.ac.za:Tenet01:50", "vlan": "any"}]}' | tee /tmp/l2vpn2
docker compose exec -it mininet curl -s -X POST -H 'Content-type: application/json' http://sdx-controller:8080/SDX-Controller/l2vpn/1.0 -d '{"name": "l2vpn3", "endpoints": [{"port_id": "urn:sdx:port:ampath.net:Ampath1:50", "vlan": "any"}, {"port_id": "urn:sdx:port:tenet.ac.za:Tenet03:50", "vlan": "any"}]}' | tee /tmp/l2vpn3
docker compose exec -it mininet curl -s -X POST -H 'Content-type: application/json' http://sdx-controller:8080/SDX-Controller/l2vpn/1.0 -d '{"name": "l2vpn4", "endpoints": [{"port_id": "urn:sdx:port:ampath.net:Ampath2:50", "vlan": "any"}, {"port_id": "urn:sdx:port:tenet.ac.za:Tenet02:50", "vlan": "any"}]}' | tee /tmp/l2vpn4
  1. Check that all L2VPN were created:
~/sdx-end-to-end-tests$ ./scripts/show-sdx-controller.sh l2vpn
ID                                    STATUS  ENDPOINT-1                          VLAN-1  ENDPOINT-2                           VLAN-2
--                                    ------  ----------                          ------  ----------                           ------
1bab50e7-3e28-4818-ab7d-7c37f71aad5c  up      urn:sdx:port:ampath.net:Ampath2:50  4094    urn:sdx:port:tenet.ac.za:Tenet02:50  4094
1c5e6c1e-8771-4ebb-b7b8-8241bad5679b  up      urn:sdx:port:ampath.net:Ampath3:50  999     urn:sdx:port:tenet.ac.za:Tenet01:50  999
56af9336-019e-4b4f-b211-b459e293519d  up      urn:sdx:port:ampath.net:Ampath3:50  4094    urn:sdx:port:tenet.ac.za:Tenet01:50  4094
fd1b56c0-ba70-4fd4-9a36-04a3e9ad6574  up      urn:sdx:port:ampath.net:Ampath1:50  4094    urn:sdx:port:tenet.ac.za:Tenet03:50  4094
  1. check the BW to make sure we have no reservations (ie. residual bw is 100%):
~/sdx-end-to-end-tests$ docker compose exec -it mininet curl -s http://sdx-controller:8080/SDX-Controller/topology | jq -r '.links[]|.id + " " + (.residual_bandwidth|tostring)'
urn:sdx:link:interdomain:sax.net:Sax01:41:tenet.ac.za:Tenet01:41 100
urn:sdx:link:interdomain:sax.net:Sax02:41:tenet.ac.za:Tenet02:41 100
urn:sdx:link:interdomain:ampath.net:Ampath1:40:sax.net:Sax01:40 100
urn:sdx:link:interdomain:ampath.net:Ampath2:40:sax.net:Sax02:40 100
urn:sdx:link:ampath.net:Ampath1/1_Ampath2/1 100
urn:sdx:link:ampath.net:Ampath2/3_Ampath3/3 100
urn:sdx:link:ampath.net:Ampath1/2_Ampath3/2 100
urn:sdx:link:sax.net:Sax01/1_Sax02/1 100
urn:sdx:link:tenet.ac.za:Tenet01/1_Tenet02/1 100
urn:sdx:link:tenet.ac.za:Tenet01/2_Tenet03/2 100
  1. Create two L2VPN with bw 9Gbps (links are 10GE):
~/sdx-end-to-end-tests$ docker compose exec -it mininet curl -s -X POST -H 'Content-type: application/json' http://sdx-controller:8080/SDX-Controller/l2vpn/1.0 -d '{"name": "l2vpn5", "endpoints": [{"port_id": "urn:sdx:port:ampath.net:Ampath3:50", "vlan": "any"}, {"port_id": "urn:sdx:port:tenet.ac.za:Tenet03:50", "vlan": "any"}], "qos_metrics": {"min_bw": {"value": 9}}}' | tee /tmp/l2vpn5
{
  "reason": "Connection published",
  "service_id": "cbcec3b4-264e-43af-960b-cf23d840c8f2",
  "status": "under provisioning"
}
~/sdx-end-to-end-tests$ docker compose exec -it mininet curl -s -X POST -H 'Content-type: application/json' http://sdx-controller:8080/SDX-Controller/l2vpn/1.0 -d '{"name": "l2vpn6", "endpoints": [{"port_id": "urn:sdx:port:ampath.net:Ampath3:50", "vlan": "any"}, {"port_id": "urn:sdx:port:tenet.ac.za:Tenet01:50", "vlan": "any"}], "qos_metrics": {"min_bw": {"value": 9}}}' | tee /tmp/l2vpn6
{
  "reason": "Connection published",
  "service_id": "1c5acfc1-c09d-4f83-a490-1a23efe314c3",
  "status": "under provisioning"
}
  1. Check that link BW was updated correctly:
~/sdx-end-to-end-tests$ docker compose exec -it mininet curl -s http://sdx-controller:8080/SDX-Controller/topology | jq -r '.links[]|.id + " " + (.residual_bandwidth|tostring)'
urn:sdx:link:interdomain:sax.net:Sax01:41:tenet.ac.za:Tenet01:41 10
urn:sdx:link:interdomain:sax.net:Sax02:41:tenet.ac.za:Tenet02:41 10
urn:sdx:link:interdomain:ampath.net:Ampath1:40:sax.net:Sax01:40 10
urn:sdx:link:interdomain:ampath.net:Ampath2:40:sax.net:Sax02:40 10
urn:sdx:link:ampath.net:Ampath1/1_Ampath2/1 100
urn:sdx:link:ampath.net:Ampath2/3_Ampath3/3 10
urn:sdx:link:ampath.net:Ampath1/2_Ampath3/2 10
urn:sdx:link:sax.net:Sax01/1_Sax02/1 100
urn:sdx:link:tenet.ac.za:Tenet01/1_Tenet02/1 10
urn:sdx:link:tenet.ac.za:Tenet01/2_Tenet03/2 10
  1. Try to create more L2VPN with BW requirements (it should fail and it is failing correctly):
~/sdx-end-to-end-tests$ docker compose exec -it mininet curl -s -X POST -H 'Content-type: application/json' http://sdx-controller:8080/SDX-Controller/l2vpn/1.0 -d '{"name": "l2vpn-fail", "endpoints": [{"port_id": "urn:sdx:port:ampath.net:Ampath3:50", "vlan": "any"}, {"port_id": "urn:sdx:port:tenet.ac.za:Tenet02:50", "vlan": "any"}], "qos_metrics": {"min_bw": {"value": 9}}}'
{
  "reason": "Could not solve the request",
  "service_id": "a5c6f94d-002a-4c24-8a78-a999c26d77ac",
  "status": "error"
}
~/sdx-end-to-end-tests$ docker compose exec -it mininet curl -s -X POST -H 'Content-type: application/json' http://sdx-controller:8080/SDX-Controller/l2vpn/1.0 -d '{"name": "l2vpn-fail", "endpoints": [{"port_id": "urn:sdx:port:ampath.net:Ampath2:50", "vlan": "any"}, {"port_id": "urn:sdx:port:tenet.ac.za:Tenet02:50", "vlan": "any"}], "qos_metrics": {"min_bw": {"value": 9}}}'
{
  "reason": "Could not solve the request",
  "service_id": "aaf75403-33ed-4f3d-b977-2ce4ca7da5fc",
  "status": "error"
}
  1. Then restart the controller and wait for it to UP and running:
~/sdx-end-to-end-tests$ docker compose up -d sdx-controller --force-recreate
  1. Check the BW info on the links (seems correct):
~/sdx-end-to-end-tests$ docker compose exec -it mininet curl -s http://sdx-controller:8080/SDX-Controller/topology | jq -r '.links[]|.id + " " + (.residual_bandwidth|tostring)'
urn:sdx:link:interdomain:sax.net:Sax01:41:tenet.ac.za:Tenet01:41 10
urn:sdx:link:interdomain:sax.net:Sax02:41:tenet.ac.za:Tenet02:41 10
urn:sdx:link:interdomain:ampath.net:Ampath1:40:sax.net:Sax01:40 10
urn:sdx:link:interdomain:ampath.net:Ampath2:40:sax.net:Sax02:40 10
urn:sdx:link:ampath.net:Ampath1/1_Ampath2/1 100
urn:sdx:link:ampath.net:Ampath2/3_Ampath3/3 10
urn:sdx:link:ampath.net:Ampath1/2_Ampath3/2 10
urn:sdx:link:sax.net:Sax01/1_Sax02/1 100
urn:sdx:link:tenet.ac.za:Tenet01/1_Tenet02/1 10
urn:sdx:link:tenet.ac.za:Tenet01/2_Tenet03/2 10
  1. However, if we try to create a L2VPN with 9Gbps again (it should fail) it is actually passing:
~/sdx-end-to-end-tests$ docker compose exec -it mininet curl -s -X POST -H 'Content-type: application/json' http://sdx-controller:8080/SDX-Controller/l2vpn/1.0 -d '{"name": "l2vpn-fail", "endpoints": [{"port_id": "urn:sdx:port:ampath.net:Ampath2:50", "vlan": "any"}, {"port_id": "urn:sdx:port:tenet.ac.za:Tenet02:50", "vlan": "any"}], "qos_metrics": {"min_bw": {"value": 9}}}'
{
  "reason": "Connection published",
  "service_id": "fac38663-1065-4dfa-a90a-b3cf2ac487a1",
  "status": "under provisioning"
}
  1. and BW information now is super weird (sax.net:Sax01:41:tenet.ac.za:Tenet01:41 100 become 100%!!! and also ampath.net:Ampath1:40:sax.net:Sax01:40 became 100%):
~/sdx-end-to-end-tests$ docker compose exec -it mininet curl -s http://sdx-controller:8080/SDX-Controller/topology | jq -r '.links[]|.id + " " + (.residual_bandwidth|tostring)'
urn:sdx:link:sax.net:Sax01/1_Sax02/1 100
urn:sdx:link:tenet.ac.za:Tenet01/1_Tenet02/1 10
urn:sdx:link:tenet.ac.za:Tenet01/2_Tenet03/2 10
urn:sdx:link:interdomain:sax.net:Sax01:41:tenet.ac.za:Tenet01:41 100
urn:sdx:link:interdomain:sax.net:Sax02:41:tenet.ac.za:Tenet02:41 10
urn:sdx:link:ampath.net:Ampath1/1_Ampath2/1 100
urn:sdx:link:ampath.net:Ampath2/3_Ampath3/3 10
urn:sdx:link:ampath.net:Ampath1/2_Ampath3/2 10
urn:sdx:link:interdomain:ampath.net:Ampath1:40:sax.net:Sax01:40 100
urn:sdx:link:interdomain:ampath.net:Ampath2:40:sax.net:Sax02:40 10

Tests above were executed using the end-to-end repo and a custom sdx-controller docker image built with this PR applied:

$ git clone https://github.com/atlanticwave-sdx/sdx-end-to-end-tests
$ cd sdx-end-to-end-tests
$ git diff docker-compose.yml
diff --git a/docker-compose.yml b/docker-compose.yml
index 8b430f2..083ff00 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -152,8 +152,7 @@ services:
         python3 -m uvicorn sdx_lc.app:asgi_app --host 0.0.0.0 --port 8080
     command: [""]
   sdx-controller:
-    image: awsdx/sdx-controller:latest
-    pull_policy: always
+    image: sdx-controller:498
     env_file:
       - .env
     volumes:
$ docker compose up -d
$ ./wait-mininet-ready.sh
$ ./scripts/run-mininet-interactive.sh

Merge remote-tracking branch 'origin/main' into 495-failed-to-recover-vlan-when-deleting-l2vpn-after-controller-restarts
@YufengXin
Copy link
Collaborator Author

Did a quick test with one QoS connection provisioned, then re-start the sdx-controller, the BW accounting was correct.

Will do more testing

@YufengXin
Copy link
Collaborator Author

YufengXin commented Dec 7, 2025

@italovalcy

The issue was on the inter-domain link residual bw, which was reset by the OXP domain topology re-population after the controller restart. I added a few lines of code to refresh them with the maintained info out of DB.

In your above test, Steps 4, 7, 9, 10 are sufficient.

Here is my test results, after Step 4, with the new commit, that shows both bw and vlans are correct after restart and connection deletion.

[rocky@Node1 sdx-end-to-end-tests]$ docker compose up -d sdx-controller --force-recreate --pull never 
[+] Running 3/3
 ✔ Container sdx-end-to-end-tests-mongo-1           Healthy                                                                            1.5s 
 ✔ Container sdx-end-to-end-tests-mq1-1             Healthy                                                                            1.5s 
 ✔ Container sdx-end-to-end-tests-sdx-controller-1  Started                                                                            1.8s 
[rocky@Node1 sdx-end-to-end-tests]$ ./scripts/show-sdx-controller.sh ports
ID                                   STATUS  STATE    L2VPN-VLAN-RANGE
--                                   ------  -----    ----------------
urn:sdx:port:ampath.net:Ampath1:1    up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath1:40   up      enabled  ["2-4094"]
urn:sdx:port:ampath.net:Ampath1:2    up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath1:50   up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath2:1    up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath2:50   up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath2:40   up      enabled  ["2-4094"]
urn:sdx:port:ampath.net:Ampath2:3    up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath3:2    up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath3:50   up      enabled  ["1-4092"]
urn:sdx:port:ampath.net:Ampath3:3    up      enabled  ["1-4094"]
urn:sdx:port:sax.net:Sax01:41        up      enabled  ["2-4094"]
urn:sdx:port:sax.net:Sax01:1         up      enabled  ["1-4094"]
urn:sdx:port:sax.net:Sax01:40        up      enabled  ["2-4094"]
urn:sdx:port:sax.net:Sax01:50        up      enabled  ["1-4094"]
urn:sdx:port:sax.net:Sax02:41        up      enabled  ["2-4094"]
urn:sdx:port:sax.net:Sax02:1         up      enabled  ["1-4094"]
urn:sdx:port:sax.net:Sax02:40        up      enabled  ["2-4094"]
urn:sdx:port:sax.net:Sax02:50        up      enabled  ["1-4094"]
urn:sdx:port:tenet.ac.za:Tenet01:41  up      enabled  ["2-4094"]
urn:sdx:port:tenet.ac.za:Tenet01:1   up      enabled  ["1-4094"]
urn:sdx:port:tenet.ac.za:Tenet01:2   up      enabled  ["1-4094"]
urn:sdx:port:tenet.ac.za:Tenet01:50  up      enabled  ["1-4093"]
urn:sdx:port:tenet.ac.za:Tenet02:41  up      enabled  ["2-4094"]
urn:sdx:port:tenet.ac.za:Tenet02:1   up      enabled  ["1-4094"]
urn:sdx:port:tenet.ac.za:Tenet02:50  up      enabled  ["1-4094"]
urn:sdx:port:tenet.ac.za:Tenet03:50  up      enabled  ["1-4093"]
urn:sdx:port:tenet.ac.za:Tenet03:2   up      enabled  ["1-4094"]
[rocky@Node1 sdx-end-to-end-tests]$ docker compose exec -it mininet curl -s -X POST -H 'Content-type: application/json' http://sdx-controller:8080/SDX-Controller/l2vpn/1.0 -d '{"name": "l2vpn-fail", "endpoints": [{"port_id": "urn:sdx:port:ampath.net:Ampath2:50", "vlan": "any"}, {"port_id": "urn:sdx:port:tenet.ac.za:Tenet02:50", "vlan": "any"}], "qos_metrics": {"min_bw": {"value": 9}}}'
{
  "reason": "Could not solve the request",
  "service_id": "e27ef594-d252-4230-8696-f387cd3d3833",
  "status": "error"
}
[rocky@Node1 sdx-end-to-end-tests]$ docker compose exec -it mininet curl -s http://sdx-controller:8080/SDX-Controller/topology | jq -r '.links[]|.id + " " + (.residual_bandwidth|tostring)'
urn:sdx:link:interdomain:sax.net:Sax01:41:tenet.ac.za:Tenet01:41 10.0
urn:sdx:link:interdomain:sax.net:Sax02:41:tenet.ac.za:Tenet02:41 10.0
urn:sdx:link:interdomain:ampath.net:Ampath1:40:sax.net:Sax01:40 10.0
urn:sdx:link:interdomain:ampath.net:Ampath2:40:sax.net:Sax02:40 10.0
urn:sdx:link:ampath.net:Ampath1/1_Ampath2/1 100
urn:sdx:link:ampath.net:Ampath2/3_Ampath3/3 10.0
urn:sdx:link:ampath.net:Ampath1/2_Ampath3/2 10.0
urn:sdx:link:sax.net:Sax01/1_Sax02/1 100
urn:sdx:link:tenet.ac.za:Tenet01/1_Tenet02/1 10.0
urn:sdx:link:tenet.ac.za:Tenet01/2_Tenet03/2 10.0
[rocky@Node1 sdx-end-to-end-tests]$ for ID in $(docker compose exec -it mininet curl -s http://sdx-controller:8080/SDX-Controller/l2vpn/1.0 | jq -r '.[].service_id'); do docker compose exec -it mininet curl -s -X DELETE http://sdx-controller:8080/SDX-Controller/l2vpn/1.0/$ID; done
"OK"
"OK"
[rocky@Node1 sdx-end-to-end-tests]$ ./scripts/show-sdx-controller.sh ports
ID                                   STATUS  STATE    L2VPN-VLAN-RANGE
--                                   ------  -----    ----------------
urn:sdx:port:sax.net:Sax01:41        up      enabled  ["2-4094","1"]
urn:sdx:port:sax.net:Sax01:1         up      enabled  ["1-4094"]
urn:sdx:port:sax.net:Sax01:40        up      enabled  ["2-4094","1"]
urn:sdx:port:sax.net:Sax01:50        up      enabled  ["1-4094"]
urn:sdx:port:sax.net:Sax02:41        up      enabled  ["2-4094","1"]
urn:sdx:port:sax.net:Sax02:1         up      enabled  ["1-4094"]
urn:sdx:port:sax.net:Sax02:40        up      enabled  ["2-4094","1"]
urn:sdx:port:sax.net:Sax02:50        up      enabled  ["1-4094"]
urn:sdx:port:tenet.ac.za:Tenet01:41  up      enabled  ["2-4094","1"]
urn:sdx:port:tenet.ac.za:Tenet01:1   up      enabled  ["1-4094"]
urn:sdx:port:tenet.ac.za:Tenet01:2   up      enabled  ["1-4094"]
urn:sdx:port:tenet.ac.za:Tenet01:50  up      enabled  ["1-4094"]
urn:sdx:port:tenet.ac.za:Tenet02:41  up      enabled  ["2-4094","1"]
urn:sdx:port:tenet.ac.za:Tenet02:1   up      enabled  ["1-4094"]
urn:sdx:port:tenet.ac.za:Tenet02:50  up      enabled  ["1-4094"]
urn:sdx:port:tenet.ac.za:Tenet03:50  up      enabled  ["1-4094"]
urn:sdx:port:tenet.ac.za:Tenet03:2   up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath1:1    up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath1:40   up      enabled  ["2-4094","1"]
urn:sdx:port:ampath.net:Ampath1:2    up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath1:50   up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath2:1    up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath2:50   up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath2:40   up      enabled  ["2-4094","1"]
urn:sdx:port:ampath.net:Ampath2:3    up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath3:2    up      enabled  ["1-4094"]
urn:sdx:port:ampath.net:Ampath3:50   up      enabled  ["1-4092","4094","4093"]
urn:sdx:port:ampath.net:Ampath3:3    up      enabled  ["1-4094"]

@italovalcy
Copy link
Contributor

@YufengXin thanks for patching this! Indeed after your changes, the creation of new L2VPNs are more consistent and working fine after restart.

However, if I delete all L2VPN and try to create again, it seems inconsistent. I followed exactly the same steps as my previous comment, and added the following ones:

  1. Delete all L2VPNs:
for ID in $(docker compose exec -it mininet curl -s -X GET http://sdx-controller:8080/SDX-Controller/l2vpn/1.0 | jq -r '.[]|.service_id'); do docker compose exec -it mininet curl -s -X DELETE -H 'Content-type: application/json' http://sdx-controller:8080/SDX-Controller/l2vpn/1.0/$ID; done
  1. Re-create the L2VPNs:
~/sdx-end-to-end-tests$ docker compose exec -it mininet curl -s -X POST -H 'Content-type: application/json' http://sdx-controller:8080/SDX-Controller/l2vpn/1.0 -d '{"name": "l2vpn1", "endpoints": [{"port_id": "urn:sdx:port:ampath.net:Ampath3:50", "vlan": "999"}, {"port_id": "urn:sdx:port:tenet.ac.za:Tenet01:50", "vlan": "999"}]}'
{
  "reason": "Connection published",
  "service_id": "14226201-ce7e-4d7f-98a0-34f2ef4bb655",
  "status": "under provisioning"
}
~/sdx-end-to-end-tests$ docker compose exec -it mininet curl -s -X POST -H 'Content-type: application/json' http://sdx-controller:8080/SDX-Controller/l2vpn/1.0 -d '{"name": "l2vpn2", "endpoints": [{"port_id": "urn:sdx:port:ampath.net:Ampath3:50", "vlan": "4094"}, {"port_id": "urn:sdx:port:tenet.ac.za:Tenet01:50", "vlan": "4094"}]}'
{
  "reason": "Connection published",
  "service_id": "d7da1c23-abb4-4516-9331-a10d84e5cbc9",
  "status": "under provisioning"
}
~/sdx-end-to-end-tests$ docker compose exec -it mininet curl -s -X POST -H 'Content-type: application/json' http://sdx-controller:8080/SDX-Controller/l2vpn/1.0 -d '{"name": "l2vpn3", "endpoints": [{"port_id": "urn:sdx:port:ampath.net:Ampath1:50", "vlan": "4094"}, {"port_id": "urn:sdx:port:tenet.ac.za:Tenet03:50", "vlan": "4094"}]}'
{
  "reason": "Connection published",
  "service_id": "7a895856-5600-4d24-b597-e708958ae7de",
  "status": "under provisioning"
}
~/sdx-end-to-end-tests$ docker compose exec -it mininet curl -s -X POST -H 'Content-type: application/json' http://sdx-controller:8080/SDX-Controller/l2vpn/1.0 -d '{"name": "l2vpn4", "endpoints": [{"port_id": "urn:sdx:port:ampath.net:Ampath2:50", "vlan": "4094"}, {"port_id": "urn:sdx:port:tenet.ac.za:Tenet02:50", "vlan": "4094"}]}'
{
  "reason": "Connection published",
  "service_id": "65540e92-dbbf-4e81-b28f-c30bfc0ea8b4",
  "status": "under provisioning"
}
~/sdx-end-to-end-tests$ docker compose exec -it mininet curl -s -X POST -H 'Content-type: application/json' http://sdx-controller:8080/SDX-Controller/l2vpn/1.0 -d '{"name": "l2vpn5", "endpoints": [{"port_id": "urn:sdx:port:ampath.net:Ampath3:50", "vlan": "any"}, {"port_id": "urn:sdx:port:tenet.ac.za:Tenet03:50", "vlan": "any"}], "qos_metrics": {"min_bw": {"value": 9}}}'
{
  "reason": "Could not solve the request",
  "service_id": "00b42611-0995-4f17-a739-4efa58bb2f80",
  "status": "error"
}

It seems that after deleting the L2VPNs, the residual_bandwidth is inconsistent:

~/sdx-end-to-end-tests$ docker compose exec -it mininet curl -s http://sdx-controller:8080/SDX-Controller/topology | jq -r '.links[]|.id + " " + (.residual_bandwidth|tostring)'
urn:sdx:link:sax.net:Sax01/1_Sax02/1 100
urn:sdx:link:ampath.net:Ampath1/1_Ampath2/1 100
urn:sdx:link:ampath.net:Ampath1/2_Ampath3/2 10
urn:sdx:link:ampath.net:Ampath2/3_Ampath3/3 10
urn:sdx:link:interdomain:ampath.net:Ampath1:40:sax.net:Sax01:40 10
urn:sdx:link:interdomain:ampath.net:Ampath2:40:sax.net:Sax02:40 10
urn:sdx:link:tenet.ac.za:Tenet01/1_Tenet02/1 10
urn:sdx:link:tenet.ac.za:Tenet01/2_Tenet03/2 10
urn:sdx:link:interdomain:sax.net:Sax01:41:tenet.ac.za:Tenet01:41 10
urn:sdx:link:interdomain:sax.net:Sax02:41:tenet.ac.za:Tenet02:41 10

@YufengXin
Copy link
Collaborator Author

@italovalcy I added one more patch. Please re-test.

Copy link
Contributor

@italovalcy italovalcy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome @YufengXin ! great work. I've re-executed the end-to-end tests and also the manual tests documented on this PR and they all seems fine!

YufengXin added a commit to atlanticwave-sdx/pce that referenced this pull request Dec 10, 2025
…-details

separate unreserve_vlan and update_bw in delete_connection

atlanticwave-sdx/sdx-controller#498
@YufengXin YufengXin merged commit 0487369 into main Dec 10, 2025
4 checks passed
@YufengXin YufengXin deleted the 495-failed-to-recover-vlan-when-deleting-l2vpn-after-controller-restarts branch December 10, 2025 19:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Failed to recover VLAN when deleting L2VPN after controller restarts

3 participants