RDKBNETWOR-76 : Add WireGuard VPN manager with IPv4/IPv6 support - #5
RDKBNETWOR-76 : Add WireGuard VPN manager with IPv4/IPv6 support#5sameerunnisa9 wants to merge 1 commit into
Conversation
|
I have read the CLA Document and I hereby sign the CLA |
There was a problem hiding this comment.
Pull request overview
This PR introduces a new RdkVpnManager component that manages WireGuard tunnels via a TR-181 data model, including syscfg persistence and a helper shell script for bringing up/down interfaces and syncing peers.
Changes:
- Adds a new
vpnmanagerCCSP component (ssp_* glue) that registers a TR-181 data model and connects to the CCSP message bus. - Implements TR-181 middle-layer DML + backend manager for WireGuard interface and peer/tunnel configuration (IPv4/IPv6, ports, keys).
- Adds packaging/build integration, systemd service unit, XML data model, and
vpn_config.shscript.
Reviewed changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 21 comments.
Show a summary per file
| File | Description |
|---|---|
| source/VpnManager/ssp_messagebus_interface.h | Declares message bus engagement/teardown hooks. |
| source/VpnManager/ssp_messagebus_interface.c | Implements CCSP message bus init/register logic and callbacks. |
| source/VpnManager/ssp_main.c | Adds daemon entrypoint, signal handling, and bus/component startup. |
| source/VpnManager/ssp_internal.h | Defines component IDs/paths and internal interfaces. |
| source/VpnManager/ssp_global.h | Provides global CCSP/ANSC includes for the component. |
| source/VpnManager/ssp_action.c | Creates/engages/cancels CCSP controller + data model registration. |
| source/VpnManager/Makefile.am | Builds the vpnmanager binary and links middle-layer library. |
| source/TR-181/middle_layer_src/vpn_manager_internal.h | Internal WireGuard DM object and helper macros/constants. |
| source/TR-181/middle_layer_src/vpn_manager_internal.c | WireGuard DM object creation/init/remove and public key retrieval. |
| source/TR-181/middle_layer_src/vpn_manager_dml.h | Declares TR-181 DML getters/setters/commit/rollback for WireGuard. |
| source/TR-181/middle_layer_src/vpn_manager_dml.c | Implements TR-181 DML logic and commit/apply behavior. |
| source/TR-181/middle_layer_src/vpn_manager_dml_apis.h | Declares backend “CosaDml_*” APIs and helpers used by DML. |
| source/TR-181/middle_layer_src/vpn_manager_dml_apis.c | Implements syscfg-backed persistence, wg show status, config generation, and peer sync. |
| source/TR-181/middle_layer_src/plugin_main.h | Plugin version/export definitions for TR-181 integration. |
| source/TR-181/middle_layer_src/plugin_main.c | Registers DML functions and initializes backend manager via plugin API. |
| source/TR-181/middle_layer_src/plugin_main_apis.h | Defines backend manager + WireGuard data structures and enums. |
| source/TR-181/middle_layer_src/plugin_main_apis.c | Implements backend manager create/init/remove lifecycle. |
| source/TR-181/middle_layer_src/Makefile.am | Builds middle-layer static library for the component. |
| source/TR-181/Makefile.am | Adds TR-181 subdir build wiring. |
| source/Makefile.am | Adds TR-181 and VpnManager subdirs to build. |
| Makefile.am | Top-level automake wiring to build source/. |
| files/vpn_config.sh | Shell helper to generate wg0.conf, bring interface up/down, and sync peers. |
| configure.ac | Autotools configuration to generate Makefiles for new subdirs. |
| config/RdkVpnManager.xml | TR-181 data model XML definition for X_RDK_Wireguard and Tunnel table. |
| config/RdkVPNManager.service | Systemd unit to start the vpnmanager daemon. |
Suppressed comments (2)
source/TR-181/middle_layer_src/vpn_manager_dml_apis.c:99
VpnDmlInitialize()is declared to returnANSC_STATUSbut falls off the end without returning a value, which is a build error with-Werror=return-type.
{
pMyObject->WireguardPort = atoi(string);
}
}
}
files/vpn_config.sh:99
- Same issue as above: this logs the config file contents (including secrets) and also uses
WG_CONFIG_FILEwithout$. Redact secrets before logging or avoid logging the config entirely.
echo "*********************************" >> $WG_DEBUG_FILE
cat WG_CONFIG_FILE >> $WG_DEBUG_FILE
echo "*********************************" >> $WG_DEBUG_FILE
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| extern PBACKEND_MANAGER_OBJECT g_pBEManager; | ||
|
|
||
| static BOOL g_Wireguard_Enabled; |
| if (fp = popen("wg show", "r")) | ||
| { |
| char syscfg_var[MAX_SIZE +1]={0}; | ||
| char buf[BUF_SIZE]={0}; | ||
|
|
||
| sprintf(buf, "%d", val); |
| fgets(pubKey,64,fPtr); | ||
| keylen = strlen(pubKey); | ||
|
|
||
| if(pubKey[keylen-1] == '\n') | ||
| pubKey[keylen-1] = '\0'; | ||
|
|
||
| fclose(fPtr); | ||
|
|
||
| CcspTraceInfo(("%s %d-Got the public key from publickey_wg.\n",__FUNCTION__, __LINE__)); | ||
| } |
| if ( tmpSubsystemPrefix = g_GetSubsystemPrefix(g_pDslhDmlAgent) ) | ||
| { |
| g_pComponentCommonVpnManager->Health = RDK_COMMON_COMPONENT_HEALTH_Green; | ||
| } | ||
|
|
||
| return ANSC_STATUS_SUCCESS; |
| if ( pSsdCcdIf ) AnscFreeMemory(pSsdCcdIf); | ||
| if ( g_pComponentCommonVpnManager ) AnscFreeMemory( g_pComponentCommonVpnManager); | ||
|
|
||
| g_pComponentCommonVpnManager = NULL; | ||
| pSsdCcdIf = NULL; | ||
| pDslhCpeController = NULL; |
| { | ||
| BOOL bRunAsDaemon = TRUE; | ||
| int idx = 0; | ||
| int ind = -1; |
| int ind = -1; | ||
| int cmdChar = 0; | ||
| int err; | ||
| char *subSys = NULL; |
| echo "*********************************" >> $WG_DEBUG_FILE | ||
| cat WG_CONFIG_FILE >> $WG_DEBUG_FILE | ||
| echo "*********************************" >> $WG_DEBUG_FILE |
mhughesacn
left a comment
There was a problem hiding this comment.
Hi @sameerunnisa9 : Please will you change the header line in these new files:
"If not stated otherwise in this file or this component's Licenses.txt file"
change "Licenses.txt" to "LICENSE" as the older form is no longer used.
The files should scan clean on the update.
Thank you
MartinH, RDK CMF Compliance Team
Reason for change: Introduce RdkVpnManager to manage WireGuard tunnels over
TR-181 (X_RDK.Wireguard), including interface bring-up/tear-down, peer
configuration, ListenPort, and IPv4/IPv6 address and AllowedIPs handling via
vpn_config.sh and syscfg (wireguard_enabled, wireguard_local_ipv4,
wireguard_local_ipv6, wireguard_subnet).
Test Procedure:
1. Enable WireGuard via TR-181 and verify wg0.conf is created with IPv4 and IPv6 Address, ListenPort, and PrivateKey.
2. Create a peer tunnel and confirm PublicKey, Endpoint, and IPv4/IPv6 AllowedIPs are written correctly.
3. Bring the tunnel UP/DOWN and verify syscfg wireguard_enabled and firewall-restart are updated.
4. Confirm public key retrieval and tunnel status through the data model.
Testing Done : Results are captured in RDKBNETWOR-76
Risks: None.
Signed-off-by: Sameerunnisa S <sameerunnisa.s@telekom-digital.com>
47c5c8b to
694636c
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 25 out of 25 changed files in this pull request and generated 13 comments.
Suppressed comments (7)
source/TR-181/middle_layer_src/vpn_manager_dml.c:807
insis declared but never used, which will fail compilation under-Wall -Werror(-Wunused-variable).
}
ULONG ins = pWireGuardTu->InstanceNumber;
pWireGuardTu->Enable = FALSE;
source/VpnManager/ssp_main.c:60
- On
setsid()failure,daemonize()exits with status 0, which can mask startup failures. This should exit non-zero.
if (setsid() < 0)
{
CcspTraceInfo(("Error demonizing (setsid)! %d - %s\n", errno, strerror(errno)));
exit(0);
}
files/vpn_config.sh:61
- In the UP command, this
catuses the literal filenameWG_CONFIG_FILEinstead of the$WG_CONFIG_FILEvariable, so the debug log won’t show the actual config (and may fail if no such file exists).
elif [ "$COMMAND" = "UP" ]; then
echo "*********************************" >> $WG_DEBUG_FILE
cat WG_CONFIG_FILE >> $WG_DEBUG_FILE
echo "*********************************" >> $WG_DEBUG_FILE
files/vpn_config.sh:99
- In the SYNC command, this
catuses the literal filenameWG_CONFIG_FILEinstead of the$WG_CONFIG_FILEvariable, so the debug log won’t show the actual config (and may fail if no such file exists).
elif [ "$COMMAND" = "SYNC" ]; then
echo "*********************************" >> $WG_DEBUG_FILE
cat WG_CONFIG_FILE >> $WG_DEBUG_FILE
echo "*********************************" >> $WG_DEBUG_FILE
source/VpnManager/ssp_messagebus_interface.c:75
- If
component_idorpathis NULL, the function logs an error but continues and passes NULL intoCCSP_Message_Bus_Init/Register_Path, which can crash or mis-register the component. This should fail fast and return an error status.
if ( ! component_id || ! path )
{
CcspTraceError((" !!! ssp_Mbi_MessageBusEngage: component_id or path is NULL !!!\n"));
}
source/VpnManager/ssp_main.c:51
- On fork failure,
daemonize()exits with status 0, which makes service managers treat startup as successful even though daemonization failed. This should exit non-zero.
This issue also appears on line 56 of the same file.
case -1:{
// Error
CcspTraceInfo(("Error daemonizing (fork)! %d - %s\n", errno, strerror(
errno)));
exit(0);
break;}
source/VpnManager/ssp_main.c:274
SIGKILLcannot be caught or handled; registering a handler for it is ineffective and can confuse maintenance/troubleshooting.
signal(SIGSEGV, sig_handler);
signal(SIGBUS, sig_handler);
signal(SIGKILL, sig_handler);
signal(SIGFPE, sig_handler);
signal(SIGILL, sig_handler);
| if [ -z "$3" ] || [ -z "$4" ]; then | ||
| echo "No end point or remote needed as its configure as server" >> $WG_DEBUG_FILE | ||
| else | ||
| echo "Endpoint = $3:$4" >> $WG_DEBUG_FILE | ||
| fi |
| ANSC_STATUS | ||
| WireGuard_GetPublicKey | ||
| ( | ||
| char *pubKey | ||
| ) | ||
| { | ||
| size_t keylen = 0; | ||
| FILE *fPtr = fopen(WG_PUB_KEY_FILE,"r"); | ||
|
|
||
| if (NULL == fPtr) | ||
| return ANSC_STATUS_FAILURE; | ||
|
|
||
| fgets(pubKey,64,fPtr); | ||
| keylen = strlen(pubKey); | ||
|
|
||
| if(pubKey[keylen-1] == '\n') | ||
| pubKey[keylen-1] = '\0'; | ||
|
|
||
| fclose(fPtr); | ||
|
|
||
| CcspTraceInfo(("%s %d-Got the public key from publickey_wg.\n",__FUNCTION__, __LINE__)); | ||
| } |
| EXIT: | ||
| return returnStatus; |
| ANSC_STATUS VpnDmlInitialize() | ||
| { | ||
| PDML_VPN_IF_CFG pMyObject = (PDML_VPN_IF_CFG) g_pBEManager->pVpnConfig; | ||
|
|
||
| if (NULL != pMyObject) | ||
| { | ||
| syscfg_init(); | ||
| CcspTraceInfo(("syscfg_init done !\n")); | ||
|
|
||
| char value[VALUE_MAX_LEN], string[STRING_MAX_LEN] = {0}; | ||
| bzero(value, sizeof(value)); | ||
|
|
||
| if (0 == syscfg_get(NULL, "wireguard_enabled", value, sizeof(value))) | ||
| { | ||
| if (1 == atoi(value)) | ||
| { | ||
| pMyObject->Enable = TRUE; | ||
| } | ||
| else | ||
| { | ||
| pMyObject->Enable = FALSE; | ||
| } | ||
| } | ||
|
|
||
| if (0 == syscfg_get(NULL, "wireguard_local_ipv4", string, sizeof(string))) | ||
| { | ||
| strncpy(pMyObject->LocalIP,string,sizeof(pMyObject->LocalIP)); | ||
| } | ||
|
|
||
| if (0 == syscfg_get(NULL, "wireguard_local_ipv6", string, sizeof(string))) | ||
| { | ||
| strncpy(pMyObject->LocalIPv6,string,sizeof(pMyObject->LocalIPv6)); | ||
| } | ||
|
|
||
| if (0 == syscfg_get(NULL, "wireguard_subnet", string, sizeof(string))) | ||
| { | ||
| strncpy(pMyObject->Subnet,string,sizeof(pMyObject->Subnet)); | ||
| } | ||
|
|
||
| if (0 == syscfg_get(NULL, "Wireguard_Port", string, sizeof(string))) | ||
| { | ||
| pMyObject->WireguardPort = atoi(string); | ||
| } | ||
| } | ||
| } |
| if (fp = popen("wg show", "r")) | ||
| { |
| ANSC_STATUS ssp_create() | ||
| { | ||
| int rc = ANSC_STATUS_FAILURE; | ||
|
|
||
| g_pComponentCommonVpnManager = (PCOMPONENT_COMMON_VPN_MANAGER) AnscAllocateMemory(sizeof(COMPONENT_COMMON_VPN_MANAGER)); |
| BOOL bRunAsDaemon = TRUE; | ||
| int idx = 0; | ||
| int ind = -1; | ||
| int cmdChar = 0; |
| int cmdChar = 0; | ||
| int err; | ||
| char *subSys = NULL; | ||
|
|
| #ifdef _COSA_SIM_ | ||
| subSys = ""; /* PC simu use empty string as subsystem */ | ||
| #else | ||
| subSys = NULL; /* use default sub-system */ | ||
| #endif |
| extern PBACKEND_MANAGER_OBJECT g_pBEManager; | ||
|
|
||
| static BOOL g_Wireguard_Enabled; | ||
|
|
WireGuard VPN manager with IPv4/IPv6 support
Reason for change: Introduce RdkVpnManager to manage WireGuard tunnels over
TR-181 (X_RDK.Wireguard), including interface bring-up/tear-down, peer
configuration, ListenPort, and IPv4/IPv6 address and AllowedIPs handling via
vpn_config.sh and syscfg (wireguard_enabled, wireguard_local_ipv4,
wireguard_local_ipv6, wireguard_subnet).
Test Procedure:
Testing Done : Results are captured in RDKBNETWOR-76
Risks: None.