Now teamd uses dot symbol to split path string into different nodes
in __teamd_json_path_lite_va() when dumping teamd state. But team
port ifname is a part of path string, if ifname has dot character
inside, it would be parsed as two nodes incorrectly.
Like, if users uses eth1.1 as a port ifname
teamdctl team0 state dump would be:
"ports": {
"eth1": {
"1": {
"ifinfo": {
...
and teamdctl team0 state view even crashs as:
...
ports:
Failed to parse JSON port dump.
command call failed (Invalid argument)
Actually it's common for users to use dot in ifname, especially for
vlan device.
This patch is to escape dot inside ifname by quoting ifname with double
quotation marks, which can also escape any other characters, like '['
and '\"' in ifname.
Note that this patch can also fix the issue that users set/get state
like team0 has two ports eth1.1 and eth2\" :
teamdctl team0 state item get 'ports."eth1.1".link_watches.up'
teamdctl team0 state item get 'ports."eth2"".link_watches.up'
No matter what character is inside ifname, users just need to quoting
it with double quotation marks if necessary.
Signed-off-by: Xin Long <lucien.xin(a)gmail.com>
---
man/teamdctl.8 | 2 ++
teamd/teamd_json.c | 11 ++++++++++-
teamd/teamd_state.c | 24 ++++++++++++++++++------
3 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/man/teamdctl.8 b/man/teamdctl.8
index 55262e6..fb2876d 100644
--- a/man/teamdctl.8
+++ b/man/teamdctl.8
@@ -50,6 +50,8 @@ Prints out state of teamd parsed from JSON state document.
.TP
.BI "state item get " state_item_path
Finds state item in JSON state document and returns its value.
+
+If PORTIFNAME in state_item_path has any sensitive character, use double quotation marks
to escape it, like: ports."eth1.1".link_watches.up. To process state_item_path
of 'state item set' is the same as here.
.TP
.BI "state item set " "state_item_path value"
Finds state item in JSON state document and sets its value by value parameter. This is
available only for a limited number of paths:
diff --git a/teamd/teamd_json.c b/teamd/teamd_json.c
index 5fd5e8e..b5e5464 100644
--- a/teamd/teamd_json.c
+++ b/teamd/teamd_json.c
@@ -76,7 +76,16 @@ static int __teamd_json_path_lite_va(json_t **p_json_obj, json_t
*json_root,
char tmp = 0; /* gcc needs this initialized */
ptr++;
- end = __strchrs(ptr, ".[");
+ if (*ptr == '\"') {
+ ptr++;
+ end = strrchr(ptr, '\"');
+ if (end) {
+ *end = '\0';
+ end++;
+ }
+ } else {
+ end = __strchrs(ptr, ".[");
+ }
if (end) {
tmp = *end;
*end = '\0';
diff --git a/teamd/teamd_state.c b/teamd/teamd_state.c
index 51fac8d..ab64db9 100644
--- a/teamd/teamd_state.c
+++ b/teamd/teamd_state.c
@@ -195,7 +195,7 @@ static int teamd_state_build_val_json_subpath(json_t **p_vg_json_obj,
char *dot;
if (tdport)
- ret = asprintf(&path, "$." TEAMD_STATE_PER_PORT_PREFIX "%s%s",
+ ret = asprintf(&path, "$." TEAMD_STATE_PER_PORT_PREFIX
"\"%s\"%s",
tdport->ifname, subpath);
else
ret = asprintf(&path, "$%s", subpath);
@@ -296,13 +296,25 @@ static int __find_by_item_path(struct teamd_state_val_item
**p_item,
if (!strncmp(item_path, TEAMD_STATE_PER_PORT_PREFIX,
strlen(TEAMD_STATE_PER_PORT_PREFIX))) {
+ char *ifname_start, *ifname_end;
struct teamd_port *cur_tdport;
- char *ifname_start = strchr(item_path, '.') + 1;
- char *ifname_end = strchr(ifname_start, '.');
- size_t ifname_len = ifname_end - ifname_start;
+ size_t ifname_len;
+
+ ifname_start = strchr(item_path, '.') + 1;
+ if (*ifname_start == '\"') {
+ ifname_start++;
+ ifname_end = strrchr(ifname_start, '\"');
+ if (!ifname_end)
+ return -EINVAL;
+ ifname_len = ifname_end - ifname_start;
+ ifname_end++;
+ } else {
+ ifname_end = strchr(ifname_start, '.');
+ if (!ifname_end)
+ return -EINVAL;
+ ifname_len = ifname_end - ifname_start;
+ }
- if (!ifname_end)
- return -EINVAL;
subpath = ifname_end + 1;
teamd_for_each_tdport(cur_tdport, ctx) {
--
2.1.0
Show replies by date
Wed, Dec 21, 2016 at 05:16:54AM CET, lucien.xin(a)gmail.com wrote:
Now teamd uses dot symbol to split path string into different nodes
in __teamd_json_path_lite_va() when dumping teamd state. But team
port ifname is a part of path string, if ifname has dot character
inside, it would be parsed as two nodes incorrectly.
Like, if users uses eth1.1 as a port ifname
teamdctl team0 state dump would be:
"ports": {
"eth1": {
"1": {
"ifinfo": {
...
and teamdctl team0 state view even crashs as:
...
ports:
Failed to parse JSON port dump.
command call failed (Invalid argument)
Actually it's common for users to use dot in ifname, especially for
vlan device.
This patch is to escape dot inside ifname by quoting ifname with double
quotation marks, which can also escape any other characters, like '['
and '\"' in ifname.
Note that this patch can also fix the issue that users set/get state
like team0 has two ports eth1.1 and eth2\" :
teamdctl team0 state item get 'ports."eth1.1".link_watches.up'
teamdctl team0 state item get 'ports."eth2"".link_watches.up'
No matter what character is inside ifname, users just need to quoting
it with double quotation marks if necessary.
Signed-off-by: Xin Long <lucien.xin(a)gmail.com>
applied, thank you for taking care of this!