mirror of
https://github.com/rsyslog/rsyslog.git
synced 2025-12-08 07:00:41 +01:00
Compare commits
3 Commits
67d00e9456
...
8dc8a489ae
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8dc8a489ae | ||
|
|
e6db7c9fc7 | ||
|
|
367c47e38c |
24
ChangeLog
24
ChangeLog
@ -1,6 +1,30 @@
|
|||||||
----------------------------------------------------------------------------------------
|
----------------------------------------------------------------------------------------
|
||||||
Scheduled Release 8.2512.0 (aka 2025.10) 2025-12-0?
|
Scheduled Release 8.2512.0 (aka 2025.10) 2025-12-0?
|
||||||
- overall improved documentation via a large set of topic updates.
|
- overall improved documentation via a large set of topic updates.
|
||||||
|
- 2025-11-28: imtcp: add support for NetworkNamespace
|
||||||
|
This builds on
|
||||||
|
https://github.com/rsyslog/rsyslog/pull/6121
|
||||||
|
to add Network Namespace support to imtcp module. This
|
||||||
|
extends imtcp to support a wider range of Unix/Linux
|
||||||
|
environments (or any environment supporting network
|
||||||
|
namespaces).
|
||||||
|
The imtcp module is enhanced to accept a NetworkNamespace
|
||||||
|
parameter, both as a default at the module level, and
|
||||||
|
on a per-instance basis.
|
||||||
|
The tcpsrv module is enhanced to allow the NetworkNamespace
|
||||||
|
to be applied to a listener's configuration parameters.
|
||||||
|
Finally, the netstrm module is enhanced to switch namespaces
|
||||||
|
before invoking the downstream (driver specific) LstnInit
|
||||||
|
function.
|
||||||
|
A new test imtcp-netns (and associated imtcp-netns-vg) is
|
||||||
|
added to test this functionality. This must be run as root
|
||||||
|
(technically it must be run by a user with CAP_SYS_ADMIN
|
||||||
|
capabilities, as network namespace creating/change is
|
||||||
|
required).
|
||||||
|
A slight change to diag.sh is made to allow passing $RS_REDIR
|
||||||
|
to valgrind (as $RS_REDIR is used in the imtcp-netns.sh
|
||||||
|
test for some negative cases).
|
||||||
|
Thanks to Billie Alsup for the patch.
|
||||||
- 2025-11-25: mmanon: fixed data race issue in pseudonymization handling
|
- 2025-11-25: mmanon: fixed data race issue in pseudonymization handling
|
||||||
Thanks to Jan Gerhards for the patch.
|
Thanks to Jan Gerhards for the patch.
|
||||||
- 2025-11-12: omhttp: added explicit splunk HEC profile
|
- 2025-11-12: omhttp: added explicit splunk HEC profile
|
||||||
|
|||||||
@ -63,7 +63,6 @@
|
|||||||
#include "tcpsrv.h"
|
#include "tcpsrv.h"
|
||||||
#include "ruleset.h"
|
#include "ruleset.h"
|
||||||
#include "rainerscript.h"
|
#include "rainerscript.h"
|
||||||
#include "net.h"
|
|
||||||
#include "parserif.h"
|
#include "parserif.h"
|
||||||
|
|
||||||
MODULE_TYPE_INPUT;
|
MODULE_TYPE_INPUT;
|
||||||
@ -143,6 +142,7 @@ struct instanceConf_s {
|
|||||||
int bEmitMsgOnOpen;
|
int bEmitMsgOnOpen;
|
||||||
int bPreserveCase;
|
int bPreserveCase;
|
||||||
int iSynBacklog;
|
int iSynBacklog;
|
||||||
|
char *pszNetworkNamespace; /**< optional network name to use */
|
||||||
uchar *pszStrmDrvrName; /* stream driver to use */
|
uchar *pszStrmDrvrName; /* stream driver to use */
|
||||||
int iStrmDrvrMode;
|
int iStrmDrvrMode;
|
||||||
uchar *pszStrmDrvrAuthMode;
|
uchar *pszStrmDrvrAuthMode;
|
||||||
@ -188,6 +188,7 @@ struct modConfData_s {
|
|||||||
sbool bEmitMsgOnClose; /* emit an informational message on close by remote peer */
|
sbool bEmitMsgOnClose; /* emit an informational message on close by remote peer */
|
||||||
sbool bEmitMsgOnOpen; /* emit an informational message on close by remote peer */
|
sbool bEmitMsgOnOpen; /* emit an informational message on close by remote peer */
|
||||||
uchar *gnutlsPriorityString;
|
uchar *gnutlsPriorityString;
|
||||||
|
char *pszNetworkNamespace; /**< default network namespace to use */
|
||||||
uchar *pszStrmDrvrName; /* stream driver to use */
|
uchar *pszStrmDrvrName; /* stream driver to use */
|
||||||
uchar *pszStrmDrvrAuthMode; /* authentication mode to use */
|
uchar *pszStrmDrvrAuthMode; /* authentication mode to use */
|
||||||
uchar *pszStrmDrvrPermitExpiredCerts; /* control how to handly expired certificates */
|
uchar *pszStrmDrvrPermitExpiredCerts; /* control how to handly expired certificates */
|
||||||
@ -235,7 +236,8 @@ static struct cnfparamdescr modpdescr[] = {{"flowcontrol", eCmdHdlrBinary, 0},
|
|||||||
{"keepalive.time", eCmdHdlrNonNegInt, 0},
|
{"keepalive.time", eCmdHdlrNonNegInt, 0},
|
||||||
{"keepalive.interval", eCmdHdlrNonNegInt, 0},
|
{"keepalive.interval", eCmdHdlrNonNegInt, 0},
|
||||||
{"gnutlsprioritystring", eCmdHdlrString, 0},
|
{"gnutlsprioritystring", eCmdHdlrString, 0},
|
||||||
{"preservecase", eCmdHdlrBinary, 0}};
|
{"preservecase", eCmdHdlrBinary, 0},
|
||||||
|
{"networknamespace", eCmdHdlrString, 0}};
|
||||||
static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr};
|
static struct cnfparamblk modpblk = {CNFPARAMBLK_VERSION, sizeof(modpdescr) / sizeof(struct cnfparamdescr), modpdescr};
|
||||||
|
|
||||||
/* input instance parameters */
|
/* input instance parameters */
|
||||||
@ -278,7 +280,8 @@ static struct cnfparamdescr inppdescr[] = {{"port", eCmdHdlrString, CNFPARAM_REQ
|
|||||||
{"ratelimit.interval", eCmdHdlrInt, 0},
|
{"ratelimit.interval", eCmdHdlrInt, 0},
|
||||||
{"framingfix.cisco.asa", eCmdHdlrBinary, 0},
|
{"framingfix.cisco.asa", eCmdHdlrBinary, 0},
|
||||||
{"ratelimit.burst", eCmdHdlrInt, 0},
|
{"ratelimit.burst", eCmdHdlrInt, 0},
|
||||||
{"socketbacklog", eCmdHdlrNonNegInt, 0}};
|
{"socketbacklog", eCmdHdlrNonNegInt, 0},
|
||||||
|
{"networknamespace", eCmdHdlrString, 0}};
|
||||||
static struct cnfparamblk inppblk = {CNFPARAMBLK_VERSION, sizeof(inppdescr) / sizeof(struct cnfparamdescr), inppdescr};
|
static struct cnfparamblk inppblk = {CNFPARAMBLK_VERSION, sizeof(inppdescr) / sizeof(struct cnfparamdescr), inppdescr};
|
||||||
|
|
||||||
#include "im-helper.h" /* must be included AFTER the type definitions! */
|
#include "im-helper.h" /* must be included AFTER the type definitions! */
|
||||||
@ -362,6 +365,7 @@ static rsRetVal createInstance(instanceConf_t **pinst) {
|
|||||||
inst->ratelimitInterval = 0;
|
inst->ratelimitInterval = 0;
|
||||||
inst->ratelimitBurst = 10000;
|
inst->ratelimitBurst = 10000;
|
||||||
|
|
||||||
|
inst->pszNetworkNamespace = NULL;
|
||||||
inst->pszStrmDrvrName = NULL;
|
inst->pszStrmDrvrName = NULL;
|
||||||
inst->pszStrmDrvrAuthMode = NULL;
|
inst->pszStrmDrvrAuthMode = NULL;
|
||||||
inst->pszStrmDrvrPermitExpiredCerts = NULL;
|
inst->pszStrmDrvrPermitExpiredCerts = NULL;
|
||||||
@ -413,7 +417,7 @@ finalize_it:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* This function is called when a new listener instace shall be added to
|
/* This function is called when a new listener instance shall be added to
|
||||||
* the current config object via the legacy config system. It just shuffles
|
* the current config object via the legacy config system. It just shuffles
|
||||||
* all parameters to the listener in-memory instance.
|
* all parameters to the listener in-memory instance.
|
||||||
* rgerhards, 2011-05-04
|
* rgerhards, 2011-05-04
|
||||||
@ -473,6 +477,7 @@ finalize_it:
|
|||||||
static rsRetVal addListner(modConfData_t *modConf, instanceConf_t *inst) {
|
static rsRetVal addListner(modConfData_t *modConf, instanceConf_t *inst) {
|
||||||
DEFiRet;
|
DEFiRet;
|
||||||
uchar *psz; /* work variable */
|
uchar *psz; /* work variable */
|
||||||
|
char *ns; /**< network namespace */
|
||||||
permittedPeers_t *peers;
|
permittedPeers_t *peers;
|
||||||
|
|
||||||
tcpsrv_t *pOurTcpsrv;
|
tcpsrv_t *pOurTcpsrv;
|
||||||
@ -542,6 +547,10 @@ static rsRetVal addListner(modConfData_t *modConf, instanceConf_t *inst) {
|
|||||||
/* initialized, now add socket and listener params */
|
/* initialized, now add socket and listener params */
|
||||||
DBGPRINTF("imtcp: trying to add port *:%s\n", inst->cnf_params->pszPort);
|
DBGPRINTF("imtcp: trying to add port *:%s\n", inst->cnf_params->pszPort);
|
||||||
inst->cnf_params->pRuleset = inst->pBindRuleset;
|
inst->cnf_params->pRuleset = inst->pBindRuleset;
|
||||||
|
|
||||||
|
ns = (inst->pszNetworkNamespace == NULL) ? modConf->pszNetworkNamespace : inst->pszNetworkNamespace;
|
||||||
|
CHKiRet(tcpsrv.SetNetworkNamespace(pOurTcpsrv, inst->cnf_params, ns));
|
||||||
|
|
||||||
CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, inst->cnf_params,
|
CHKiRet(tcpsrv.SetInputName(pOurTcpsrv, inst->cnf_params,
|
||||||
inst->pszInputName == NULL ? UCHAR_CONSTANT("imtcp") : inst->pszInputName));
|
inst->pszInputName == NULL ? UCHAR_CONSTANT("imtcp") : inst->pszInputName));
|
||||||
CHKiRet(tcpsrv.SetOrigin(pOurTcpsrv, (uchar *)"imtcp"));
|
CHKiRet(tcpsrv.SetOrigin(pOurTcpsrv, (uchar *)"imtcp"));
|
||||||
@ -596,6 +605,8 @@ BEGINnewInpInst
|
|||||||
if (!pvals[i].bUsed) continue;
|
if (!pvals[i].bUsed) continue;
|
||||||
if (!strcmp(inppblk.descr[i].name, "port")) {
|
if (!strcmp(inppblk.descr[i].name, "port")) {
|
||||||
inst->cnf_params->pszPort = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
|
inst->cnf_params->pszPort = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||||
|
} else if (!strcmp(inppblk.descr[i].name, "networknamespace")) {
|
||||||
|
inst->pszNetworkNamespace = es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||||
} else if (!strcmp(inppblk.descr[i].name, "address")) {
|
} else if (!strcmp(inppblk.descr[i].name, "address")) {
|
||||||
inst->cnf_params->pszAddr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
|
inst->cnf_params->pszAddr = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||||
} else if (!strcmp(inppblk.descr[i].name, "name")) {
|
} else if (!strcmp(inppblk.descr[i].name, "name")) {
|
||||||
@ -729,6 +740,7 @@ BEGINbeginCnfLoad
|
|||||||
loadModConf->bDisableLFDelim = 0;
|
loadModConf->bDisableLFDelim = 0;
|
||||||
loadModConf->discardTruncatedMsg = 0;
|
loadModConf->discardTruncatedMsg = 0;
|
||||||
loadModConf->gnutlsPriorityString = NULL;
|
loadModConf->gnutlsPriorityString = NULL;
|
||||||
|
loadModConf->pszNetworkNamespace = NULL;
|
||||||
loadModConf->pszStrmDrvrName = NULL;
|
loadModConf->pszStrmDrvrName = NULL;
|
||||||
loadModConf->pszStrmDrvrAuthMode = NULL;
|
loadModConf->pszStrmDrvrAuthMode = NULL;
|
||||||
loadModConf->pszStrmDrvrPermitExpiredCerts = NULL;
|
loadModConf->pszStrmDrvrPermitExpiredCerts = NULL;
|
||||||
@ -808,6 +820,8 @@ BEGINsetModCnf
|
|||||||
loadModConf->iKeepAliveIntvl = (int)pvals[i].val.d.n;
|
loadModConf->iKeepAliveIntvl = (int)pvals[i].val.d.n;
|
||||||
} else if (!strcmp(modpblk.descr[i].name, "gnutlsprioritystring")) {
|
} else if (!strcmp(modpblk.descr[i].name, "gnutlsprioritystring")) {
|
||||||
loadModConf->gnutlsPriorityString = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
|
loadModConf->gnutlsPriorityString = (uchar *)es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||||
|
} else if (!strcmp(modpblk.descr[i].name, "networknamespace")) {
|
||||||
|
loadModConf->pszNetworkNamespace = es_str2cstr(pvals[i].val.d.estr, NULL);
|
||||||
} else if (!strcmp(modpblk.descr[i].name, "streamdriver.mode")) {
|
} else if (!strcmp(modpblk.descr[i].name, "streamdriver.mode")) {
|
||||||
loadModConf->iStrmDrvrMode = (int)pvals[i].val.d.n;
|
loadModConf->iStrmDrvrMode = (int)pvals[i].val.d.n;
|
||||||
} else if (!strcmp(modpblk.descr[i].name, "streamdriver.CheckExtendedKeyPurpose")) {
|
} else if (!strcmp(modpblk.descr[i].name, "streamdriver.CheckExtendedKeyPurpose")) {
|
||||||
@ -950,6 +964,7 @@ BEGINfreeCnf
|
|||||||
instanceConf_t *inst, *del;
|
instanceConf_t *inst, *del;
|
||||||
CODESTARTfreeCnf;
|
CODESTARTfreeCnf;
|
||||||
free(pModConf->gnutlsPriorityString);
|
free(pModConf->gnutlsPriorityString);
|
||||||
|
free(pModConf->pszNetworkNamespace);
|
||||||
free(pModConf->pszStrmDrvrName);
|
free(pModConf->pszStrmDrvrName);
|
||||||
free(pModConf->pszStrmDrvrAuthMode);
|
free(pModConf->pszStrmDrvrAuthMode);
|
||||||
free(pModConf->pszStrmDrvrPermitExpiredCerts);
|
free(pModConf->pszStrmDrvrPermitExpiredCerts);
|
||||||
@ -964,6 +979,7 @@ BEGINfreeCnf
|
|||||||
for (inst = pModConf->root; inst != NULL;) {
|
for (inst = pModConf->root; inst != NULL;) {
|
||||||
free((void *)inst->pszBindRuleset);
|
free((void *)inst->pszBindRuleset);
|
||||||
free((void *)inst->pszStrmDrvrAuthMode);
|
free((void *)inst->pszStrmDrvrAuthMode);
|
||||||
|
free((void *)inst->pszNetworkNamespace);
|
||||||
free((void *)inst->pszStrmDrvrName);
|
free((void *)inst->pszStrmDrvrName);
|
||||||
free((void *)inst->pszStrmDrvrPermitExpiredCerts);
|
free((void *)inst->pszStrmDrvrPermitExpiredCerts);
|
||||||
free((void *)inst->pszStrmDrvrCAFile);
|
free((void *)inst->pszStrmDrvrCAFile);
|
||||||
|
|||||||
@ -58,7 +58,7 @@
|
|||||||
|
|
||||||
/* static data */
|
/* static data */
|
||||||
DEFobjStaticHelpers;
|
DEFobjStaticHelpers;
|
||||||
DEFobjCurrIf(netstrms)
|
DEFobjCurrIf(net) DEFobjCurrIf(netstrms)
|
||||||
|
|
||||||
|
|
||||||
/* Standard-Constructor */
|
/* Standard-Constructor */
|
||||||
@ -145,14 +145,31 @@ static rsRetVal ATTR_NONNULL(1, 3, 5) LstnInit(netstrms_t *pNS,
|
|||||||
const int iSessMax,
|
const int iSessMax,
|
||||||
const tcpLstnParams_t *const cnf_params) {
|
const tcpLstnParams_t *const cnf_params) {
|
||||||
DEFiRet;
|
DEFiRet;
|
||||||
|
const char *ns = cnf_params->pszNetworkNamespace;
|
||||||
|
int netns_fd = -1;
|
||||||
|
|
||||||
ISOBJ_TYPE_assert(pNS, netstrms);
|
ISOBJ_TYPE_assert(pNS, netstrms);
|
||||||
assert(fAddLstn != NULL);
|
assert(fAddLstn != NULL);
|
||||||
assert(cnf_params->pszPort != NULL);
|
assert(cnf_params->pszPort != NULL);
|
||||||
|
|
||||||
|
#ifdef HAVE_SETNS
|
||||||
|
if (ns) {
|
||||||
|
CHKiRet(net.netns_save(&netns_fd));
|
||||||
|
CHKiRet(net.netns_switch(ns));
|
||||||
|
}
|
||||||
|
#endif // ndef HAVE_SETNS
|
||||||
|
|
||||||
CHKiRet(pNS->Drvr.LstnInit(pNS, pUsr, fAddLstn, iSessMax, cnf_params));
|
CHKiRet(pNS->Drvr.LstnInit(pNS, pUsr, fAddLstn, iSessMax, cnf_params));
|
||||||
|
|
||||||
finalize_it:
|
finalize_it:
|
||||||
|
#ifdef HAVE_SETNS
|
||||||
|
if (ns) {
|
||||||
|
// netns_restore will log a message on failure
|
||||||
|
// but there's really nothing we can do about it
|
||||||
|
(void)net.netns_restore(&netns_fd);
|
||||||
|
}
|
||||||
|
#endif // ndef HAVE_SETNS
|
||||||
|
|
||||||
RETiRet;
|
RETiRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -493,6 +510,7 @@ BEGINObjClassExit(netstrm, OBJ_IS_LOADABLE_MODULE) /* CHANGE class also in END M
|
|||||||
CODESTARTObjClassExit(netstrm);
|
CODESTARTObjClassExit(netstrm);
|
||||||
/* release objects we no longer need */
|
/* release objects we no longer need */
|
||||||
objRelease(netstrms, DONT_LOAD_LIB);
|
objRelease(netstrms, DONT_LOAD_LIB);
|
||||||
|
objRelease(net, LM_NET_FILENAME);
|
||||||
ENDObjClassExit(netstrm)
|
ENDObjClassExit(netstrm)
|
||||||
|
|
||||||
|
|
||||||
@ -502,6 +520,7 @@ ENDObjClassExit(netstrm)
|
|||||||
*/
|
*/
|
||||||
BEGINAbstractObjClassInit(netstrm, 1, OBJ_IS_CORE_MODULE) /* class, version */
|
BEGINAbstractObjClassInit(netstrm, 1, OBJ_IS_CORE_MODULE) /* class, version */
|
||||||
/* request objects we use */
|
/* request objects we use */
|
||||||
|
CHKiRet(objUse(net, LM_NET_FILENAME));
|
||||||
|
|
||||||
/* set our own handlers */
|
/* set our own handlers */
|
||||||
ENDObjClassInit(netstrm)
|
ENDObjClassInit(netstrm)
|
||||||
|
|||||||
@ -536,6 +536,7 @@ static void ATTR_NONNULL() deinit_tcp_listener(tcpsrv_t *const pThis) {
|
|||||||
free((void *)pEntry->cnf_params->pszPort);
|
free((void *)pEntry->cnf_params->pszPort);
|
||||||
free((void *)pEntry->cnf_params->pszAddr);
|
free((void *)pEntry->cnf_params->pszAddr);
|
||||||
free((void *)pEntry->cnf_params->pszLstnPortFileName);
|
free((void *)pEntry->cnf_params->pszLstnPortFileName);
|
||||||
|
free((void *)pEntry->cnf_params->pszNetworkNamespace);
|
||||||
free((void *)pEntry->cnf_params);
|
free((void *)pEntry->cnf_params);
|
||||||
ratelimitDestruct(pEntry->ratelimiter);
|
ratelimitDestruct(pEntry->ratelimiter);
|
||||||
statsobj.Destruct(&(pEntry->stats));
|
statsobj.Destruct(&(pEntry->stats));
|
||||||
@ -604,12 +605,15 @@ static rsRetVal ATTR_NONNULL() create_tcp_socket(tcpsrv_t *const pThis) {
|
|||||||
while (pEntry != NULL) {
|
while (pEntry != NULL) {
|
||||||
localRet = initTCPListener(pThis, pEntry);
|
localRet = initTCPListener(pThis, pEntry);
|
||||||
if (localRet != RS_RET_OK) {
|
if (localRet != RS_RET_OK) {
|
||||||
|
char *ns = pEntry->cnf_params->pszNetworkNamespace;
|
||||||
|
|
||||||
LogError(
|
LogError(
|
||||||
0, localRet,
|
0, localRet,
|
||||||
"Could not create tcp listener, ignoring port "
|
"Could not create tcp listener, ignoring port "
|
||||||
"%s bind-address %s.",
|
"%s bind-address %s%s%s.",
|
||||||
(pEntry->cnf_params->pszPort == NULL) ? "**UNSPECIFIED**" : (const char *)pEntry->cnf_params->pszPort,
|
(pEntry->cnf_params->pszPort == NULL) ? "**UNSPECIFIED**" : (const char *)pEntry->cnf_params->pszPort,
|
||||||
(pEntry->cnf_params->pszAddr == NULL) ? "**UNSPECIFIED**" : (const char *)pEntry->cnf_params->pszAddr);
|
(pEntry->cnf_params->pszAddr == NULL) ? "**UNSPECIFIED**" : (const char *)pEntry->cnf_params->pszAddr,
|
||||||
|
(ns == NULL) ? "" : " namespace ", (ns == NULL) ? "" : ns);
|
||||||
}
|
}
|
||||||
pEntry = pEntry->pNext;
|
pEntry = pEntry->pNext;
|
||||||
}
|
}
|
||||||
@ -1978,6 +1982,25 @@ finalize_it:
|
|||||||
RETiRet;
|
RETiRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static rsRetVal SetNetworkNamespace(tcpsrv_t *pThis __attribute__((unused)),
|
||||||
|
tcpLstnParams_t *const cnf_params,
|
||||||
|
const char *const networkNamespace) {
|
||||||
|
DEFiRet;
|
||||||
|
ISOBJ_TYPE_assert(pThis, tcpsrv);
|
||||||
|
free(cnf_params->pszNetworkNamespace);
|
||||||
|
if (!networkNamespace || !*networkNamespace) {
|
||||||
|
cnf_params->pszNetworkNamespace = NULL;
|
||||||
|
} else {
|
||||||
|
#ifdef HAVE_SETNS
|
||||||
|
CHKmalloc(cnf_params->pszNetworkNamespace = strdup(networkNamespace));
|
||||||
|
#else // ndef HAVE_SETNS
|
||||||
|
LogError(0, RS_RET_VALUE_NOT_SUPPORTED, "Namespaces are not supported");
|
||||||
|
ABORT_FINALIZE(RS_RET_VALUE_NOT_SUPPORTED);
|
||||||
|
#endif // #else ndef HAVE_SETNS
|
||||||
|
}
|
||||||
|
finalize_it:
|
||||||
|
RETiRet;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set the linux-like ratelimiter settings */
|
/* Set the linux-like ratelimiter settings */
|
||||||
static rsRetVal ATTR_NONNULL(1)
|
static rsRetVal ATTR_NONNULL(1)
|
||||||
@ -2207,6 +2230,7 @@ BEGINobjQueryInterface(tcpsrv)
|
|||||||
pIf->create_tcp_socket = create_tcp_socket;
|
pIf->create_tcp_socket = create_tcp_socket;
|
||||||
pIf->Run = Run;
|
pIf->Run = Run;
|
||||||
|
|
||||||
|
pIf->SetNetworkNamespace = SetNetworkNamespace;
|
||||||
pIf->SetKeepAlive = SetKeepAlive;
|
pIf->SetKeepAlive = SetKeepAlive;
|
||||||
pIf->SetKeepAliveIntvl = SetKeepAliveIntvl;
|
pIf->SetKeepAliveIntvl = SetKeepAliveIntvl;
|
||||||
pIf->SetKeepAliveProbes = SetKeepAliveProbes;
|
pIf->SetKeepAliveProbes = SetKeepAliveProbes;
|
||||||
|
|||||||
@ -47,6 +47,7 @@ struct tcpLstnParams_s {
|
|||||||
sbool bSPFramingFix; /**< support work-around for broken Cisco ASA framing? */
|
sbool bSPFramingFix; /**< support work-around for broken Cisco ASA framing? */
|
||||||
sbool bPreserveCase; /**< preserve case in fromhost */
|
sbool bPreserveCase; /**< preserve case in fromhost */
|
||||||
const uchar *pszLstnPortFileName; /**< File in which the dynamic port is written */
|
const uchar *pszLstnPortFileName; /**< File in which the dynamic port is written */
|
||||||
|
char *pszNetworkNamespace; /**< network namespace to use */
|
||||||
uchar *pszStrmDrvrName; /**< stream driver to use */
|
uchar *pszStrmDrvrName; /**< stream driver to use */
|
||||||
uchar *pszInputName; /**< value to be used as input name */
|
uchar *pszInputName; /**< value to be used as input name */
|
||||||
prop_t *pInputName;
|
prop_t *pInputName;
|
||||||
@ -280,8 +281,27 @@ BEGINinterface(tcpsrv) /* name must also be changed in ENDinterface macro! */
|
|||||||
/* added v28 */
|
/* added v28 */
|
||||||
rsRetVal (*SetNumWrkr)(tcpsrv_t *pThis, int);
|
rsRetVal (*SetNumWrkr)(tcpsrv_t *pThis, int);
|
||||||
rsRetVal (*SetStarvationMaxReads)(tcpsrv_t *pThis, unsigned int);
|
rsRetVal (*SetStarvationMaxReads)(tcpsrv_t *pThis, unsigned int);
|
||||||
|
/* added v29 */
|
||||||
|
/*
|
||||||
|
* @brief Set the Network Namespace into the listener parameters
|
||||||
|
* @param pThis The associated TCP Server instance
|
||||||
|
* @param cnf_params The listener parameters to configure
|
||||||
|
* @param networkNamespace The namespace parameter to set into the
|
||||||
|
* listener configuration parameters
|
||||||
|
* @return RS_RET_OK on success, otherwise a failure code.
|
||||||
|
* @details For platforms that do not support network namespaces,
|
||||||
|
* this function should fail for any non-null and non-empty
|
||||||
|
* namespace passed. Note that the empty string is treated
|
||||||
|
* the same as a NULL, i.e. you are not allowed to actually
|
||||||
|
* use a network namespace with the empty string. So both
|
||||||
|
* a NULL and an empty string "" both mean to use the
|
||||||
|
* original startup network namespace.
|
||||||
|
*/
|
||||||
|
rsRetVal (*SetNetworkNamespace)(tcpsrv_t *pThis, tcpLstnParams_t *const cnf_params,
|
||||||
|
const char *const networkNamespace);
|
||||||
|
|
||||||
ENDinterface(tcpsrv)
|
ENDinterface(tcpsrv)
|
||||||
#define tcpsrvCURR_IF_VERSION 28 /* increment whenever you change the interface structure! */
|
#define tcpsrvCURR_IF_VERSION 29 /* increment whenever you change the interface structure! */
|
||||||
/* change for v4:
|
/* change for v4:
|
||||||
* - SetAddtlFrameDelim() added -- rgerhards, 2008-12-10
|
* - SetAddtlFrameDelim() added -- rgerhards, 2008-12-10
|
||||||
* - SetInputName() added -- rgerhards, 2008-12-10
|
* - SetInputName() added -- rgerhards, 2008-12-10
|
||||||
|
|||||||
@ -650,6 +650,7 @@ TESTS += \
|
|||||||
imtcp-maxFrameSize.sh \
|
imtcp-maxFrameSize.sh \
|
||||||
imtcp-msg-truncation-on-number.sh \
|
imtcp-msg-truncation-on-number.sh \
|
||||||
imtcp-msg-truncation-on-number2.sh \
|
imtcp-msg-truncation-on-number2.sh \
|
||||||
|
imtcp-netns.sh \
|
||||||
imtcp-NUL.sh \
|
imtcp-NUL.sh \
|
||||||
imtcp-NUL-rawmsg.sh \
|
imtcp-NUL-rawmsg.sh \
|
||||||
imtcp_incomplete_frame_at_end.sh \
|
imtcp_incomplete_frame_at_end.sh \
|
||||||
@ -1503,6 +1504,7 @@ TESTS += \
|
|||||||
imptcp-oversize-message-display.sh \
|
imptcp-oversize-message-display.sh \
|
||||||
imptcp-msg-truncation-on-number.sh \
|
imptcp-msg-truncation-on-number.sh \
|
||||||
imptcp-msg-truncation-on-number2.sh \
|
imptcp-msg-truncation-on-number2.sh \
|
||||||
|
imtcp-netns.sh \
|
||||||
imptcp-maxFrameSize-parameter.sh \
|
imptcp-maxFrameSize-parameter.sh \
|
||||||
mmjsonparse_cim.sh \
|
mmjsonparse_cim.sh \
|
||||||
mmjsonparse_cim2.sh \
|
mmjsonparse_cim2.sh \
|
||||||
@ -2549,6 +2551,7 @@ EXTRA_DIST= \
|
|||||||
imptcp-oversize-message-display.sh \
|
imptcp-oversize-message-display.sh \
|
||||||
imptcp-msg-truncation-on-number.sh \
|
imptcp-msg-truncation-on-number.sh \
|
||||||
imptcp-msg-truncation-on-number2.sh \
|
imptcp-msg-truncation-on-number2.sh \
|
||||||
|
imtcp-netns.sh \
|
||||||
imptcp-maxFrameSize-parameter.sh \
|
imptcp-maxFrameSize-parameter.sh \
|
||||||
mmjsonparse_cim.sh \
|
mmjsonparse_cim.sh \
|
||||||
mmjsonparse_cim2.sh \
|
mmjsonparse_cim2.sh \
|
||||||
@ -2638,6 +2641,7 @@ EXTRA_DIST= \
|
|||||||
imtcp-maxFrameSize.sh \
|
imtcp-maxFrameSize.sh \
|
||||||
imtcp-msg-truncation-on-number.sh \
|
imtcp-msg-truncation-on-number.sh \
|
||||||
imtcp-msg-truncation-on-number2.sh \
|
imtcp-msg-truncation-on-number2.sh \
|
||||||
|
imtcp-netns.sh \
|
||||||
imtcp-NUL.sh \
|
imtcp-NUL.sh \
|
||||||
imtcp-NUL-rawmsg.sh \
|
imtcp-NUL-rawmsg.sh \
|
||||||
imtcp-tls-gtls-x509fingerprint-invld.sh \
|
imtcp-tls-gtls-x509fingerprint-invld.sh \
|
||||||
|
|||||||
3
tests/imtcp-netns-vg.sh
Executable file
3
tests/imtcp-netns-vg.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
export USE_VALGRIND="YES"
|
||||||
|
source ${srcdir:-.}/imtcp-netns.sh
|
||||||
140
tests/imtcp-netns.sh
Executable file
140
tests/imtcp-netns.sh
Executable file
@ -0,0 +1,140 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# This test tests listening on ports in another network namespace.
|
||||||
|
echo ===============================================================================
|
||||||
|
echo \[imtcp-netns.sh\]: test for listening in another network namespace
|
||||||
|
echo This test must be run with CAP_SYS_ADMIN capabilities [network namespace creation/change required]
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
exit 77 # Not root, skip this test
|
||||||
|
fi
|
||||||
|
|
||||||
|
. ${srcdir:=.}/diag.sh init
|
||||||
|
generate_conf
|
||||||
|
|
||||||
|
NS_PREFIX=$(basename ${RSYSLOG_DYNNAME})
|
||||||
|
NS_DEFAULT="${NS_PREFIX}.rsyslog_ns_default"
|
||||||
|
NS_FAIL=(
|
||||||
|
"${NS_PREFIX}.rsyslog_ns_a_fail"
|
||||||
|
"${NS_PREFIX}.rsyslog_ns_b_fail"
|
||||||
|
)
|
||||||
|
NS_GOOD=(
|
||||||
|
"${NS_PREFIX}.rsyslog_ns_c"
|
||||||
|
"${NS_PREFIX}.rsyslog_ns_d"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_conf '
|
||||||
|
$MainMsgQueueTimeoutShutdown 10000
|
||||||
|
module(
|
||||||
|
load="../plugins/imtcp/.libs/imtcp"
|
||||||
|
NetworkNamespace="'${NS_DEFAULT}'"
|
||||||
|
)
|
||||||
|
input(
|
||||||
|
Type="imtcp"
|
||||||
|
Port="0"
|
||||||
|
Address="127.0.0.1"
|
||||||
|
ListenPortFileName="'${NS_DEFAULT}'.port"
|
||||||
|
)
|
||||||
|
'
|
||||||
|
|
||||||
|
for ns in "${NS_GOOD[@]}" "${NS_FAIL[@]}"; do
|
||||||
|
add_conf '
|
||||||
|
input(
|
||||||
|
Type="imtcp"
|
||||||
|
Port="0"
|
||||||
|
Address="127.0.0.1"
|
||||||
|
NetworkNamespace="'${ns}'"
|
||||||
|
ListenPortFileName="'${ns}'.port"
|
||||||
|
)
|
||||||
|
'
|
||||||
|
done
|
||||||
|
|
||||||
|
add_conf '
|
||||||
|
input(
|
||||||
|
Type="imtcp"
|
||||||
|
Port="0"
|
||||||
|
Address="127.0.0.1"
|
||||||
|
NetworkNamespace=""
|
||||||
|
ListenPortFileName="'$RSYSLOG_DYNNAME'.port"
|
||||||
|
)
|
||||||
|
|
||||||
|
template(name="outfmt" type="string" string="%msg:%\n")
|
||||||
|
:msg, contains, "imtcp-netns:" action(
|
||||||
|
type="omfile"
|
||||||
|
file="'${RSYSLOG_OUT_LOG}'"
|
||||||
|
template="outfmt"
|
||||||
|
)
|
||||||
|
'
|
||||||
|
#
|
||||||
|
# create network namespace and bring it up
|
||||||
|
NS=(
|
||||||
|
"${NS_DEFAULT}"
|
||||||
|
"${NS_GOOD[@]}"
|
||||||
|
)
|
||||||
|
for ns in "${NS[@]}"; do
|
||||||
|
ip netns add "${ns}"
|
||||||
|
ip netns exec "${ns}" ip link set dev lo up
|
||||||
|
done
|
||||||
|
for ns in "${NS_FAIL[@]}"; do
|
||||||
|
ip netns delete "${ns}" > /dev/null 2>&1
|
||||||
|
done
|
||||||
|
|
||||||
|
# now do the usual run
|
||||||
|
RS_REDIR="> ${RSYSLOG_DYNNAME}.log 2>&1"
|
||||||
|
startup
|
||||||
|
wait_file_exists "${RSYSLOG_DYNNAME}.port"
|
||||||
|
for ns in "${NS[@]}"; do
|
||||||
|
wait_file_exists "${ns}.port"
|
||||||
|
done
|
||||||
|
|
||||||
|
MSGS=()
|
||||||
|
function logmsg() {
|
||||||
|
local ns=$1
|
||||||
|
local msg=$2
|
||||||
|
local logger_cmd=()
|
||||||
|
local port_file=${RSYSLOG_DYNNAME}.port
|
||||||
|
|
||||||
|
if [[ -n "${ns}" ]]; then
|
||||||
|
logger_cmd+=(ip netns exec "${ns}")
|
||||||
|
port_file="${ns}.port"
|
||||||
|
fi
|
||||||
|
logger_cmd+=(
|
||||||
|
logger
|
||||||
|
--tcp
|
||||||
|
--server 127.0.0.1
|
||||||
|
--octet-count
|
||||||
|
--tag "$0"
|
||||||
|
--port "$(cat ${port_file})"
|
||||||
|
--
|
||||||
|
"imtcp-netns: ${msg}"
|
||||||
|
)
|
||||||
|
"${logger_cmd[@]}"
|
||||||
|
MSGS+=("imtcp-netns: ${msg}")
|
||||||
|
}
|
||||||
|
|
||||||
|
# Inject a few messages
|
||||||
|
logmsg "" "start message from local namespace"
|
||||||
|
for ns in "${NS[@]}"; do
|
||||||
|
logmsg "${ns}" "test message from namespace ${ns}"
|
||||||
|
# Try to keep them ordered
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
logmsg "" "end message from local namespace"
|
||||||
|
|
||||||
|
shutdown_when_empty
|
||||||
|
wait_shutdown
|
||||||
|
|
||||||
|
# remove network namespaces
|
||||||
|
for ns in "${NS[@]}"; do
|
||||||
|
ip netns delete "${ns}"
|
||||||
|
done
|
||||||
|
|
||||||
|
EXPECTED=$(printf "%s\n" "${MSGS[@]}")
|
||||||
|
cmp_exact
|
||||||
|
|
||||||
|
# Verify we have error messages for the missing namespaces
|
||||||
|
# We don't redirect with valgrind, so skip this check with valgrind
|
||||||
|
if [[ "${USE_VALGRIND}" != "YES" ]]; then
|
||||||
|
for ns in "${NS_FAIL[@]}"; do
|
||||||
|
content_check "netns_switch: could not open namespace '${ns}':" ${RSYSLOG_DYNNAME}.log
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
exit_test
|
||||||
Loading…
x
Reference in New Issue
Block a user