bgpd: Flowspec display handlers uses snprintf

snprintf routine is used widely, when the handler routine in charge of
displaying the output is called.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
Philippe Guibert 2018-03-28 14:35:56 +02:00
parent a83da8e19c
commit 362a06e37d
2 changed files with 147 additions and 53 deletions

View file

@ -107,6 +107,8 @@ int bgp_flowspec_ip_address(enum bgp_flowspec_util_nlri_t type,
* return number of bytes analysed * return number of bytes analysed
* if there is an error, the passed error param is used to give error: * if there is an error, the passed error param is used to give error:
* -1 if decoding error, * -1 if decoding error,
* if result is a string, its assumed length
* is BGP_FLOWSPEC_STRING_DISPLAY_MAX
*/ */
int bgp_flowspec_op_decode(enum bgp_flowspec_util_nlri_t type, int bgp_flowspec_op_decode(enum bgp_flowspec_util_nlri_t type,
uint8_t *nlri_ptr, uint8_t *nlri_ptr,
@ -118,6 +120,8 @@ int bgp_flowspec_op_decode(enum bgp_flowspec_util_nlri_t type,
int loop = 0; int loop = 0;
char *ptr = (char *)result; /* for return_string */ char *ptr = (char *)result; /* for return_string */
uint32_t offset = 0; uint32_t offset = 0;
int len_string = BGP_FLOWSPEC_STRING_DISPLAY_MAX;
int len_written;
*error = 0; *error = 0;
do { do {
@ -134,15 +138,34 @@ int bgp_flowspec_op_decode(enum bgp_flowspec_util_nlri_t type,
*error = -1; *error = -1;
switch (type) { switch (type) {
case BGP_FLOWSPEC_RETURN_STRING: case BGP_FLOWSPEC_RETURN_STRING:
if (loop) if (loop) {
ptr += sprintf(ptr, ", "); len_written = snprintf(ptr, len_string,
if (op[5] == 1) ", ");
ptr += sprintf(ptr, "<"); len_string -= len_written;
if (op[6] == 1) ptr += len_written;
ptr += sprintf(ptr, ">"); }
if (op[7] == 1) if (op[5] == 1) {
ptr += sprintf(ptr, "="); len_written = snprintf(ptr, len_string,
ptr += sprintf(ptr, " %d ", value); "<");
len_string -= len_written;
ptr += len_written;
}
if (op[6] == 1) {
len_written = snprintf(ptr, len_string,
">");
len_string -= len_written;
ptr += len_written;
}
if (op[7] == 1) {
len_written = snprintf(ptr, len_string,
"=");
len_string -= len_written;
ptr += len_written;
}
len_written = snprintf(ptr, len_string,
" %d ", value);
len_string -= len_written;
ptr += len_written;
break; break;
case BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE: case BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE:
/* TODO : FS OPAQUE */ /* TODO : FS OPAQUE */
@ -169,6 +192,8 @@ int bgp_flowspec_op_decode(enum bgp_flowspec_util_nlri_t type,
* return number of bytes analysed * return number of bytes analysed
* if there is an error, the passed error param is used to give error: * if there is an error, the passed error param is used to give error:
* -1 if decoding error, * -1 if decoding error,
* if result is a string, its assumed length
* is BGP_FLOWSPEC_STRING_DISPLAY_MAX
*/ */
int bgp_flowspec_tcpflags_decode(enum bgp_flowspec_util_nlri_t type, int bgp_flowspec_tcpflags_decode(enum bgp_flowspec_util_nlri_t type,
uint8_t *nlri_ptr, uint8_t *nlri_ptr,
@ -179,6 +204,8 @@ int bgp_flowspec_tcpflags_decode(enum bgp_flowspec_util_nlri_t type,
int len, value_size, loop = 0, value; int len, value_size, loop = 0, value;
char *ptr = (char *)result; /* for return_string */ char *ptr = (char *)result; /* for return_string */
uint32_t offset = 0; uint32_t offset = 0;
int len_string = BGP_FLOWSPEC_STRING_DISPLAY_MAX;
int len_written;
*error = 0; *error = 0;
do { do {
@ -192,16 +219,37 @@ int bgp_flowspec_tcpflags_decode(enum bgp_flowspec_util_nlri_t type,
value = hexstr2num(&nlri_ptr[offset], value_size); value = hexstr2num(&nlri_ptr[offset], value_size);
switch (type) { switch (type) {
case BGP_FLOWSPEC_RETURN_STRING: case BGP_FLOWSPEC_RETURN_STRING:
if (op[1] == 1 && loop != 0) if (op[1] == 1 && loop != 0) {
ptr += sprintf(ptr, ", and "); len_written = snprintf(ptr, len_string,
else if (op[1] == 0 && loop != 0) ", and ");
ptr += sprintf(ptr, ", or "); len_string -= len_written;
ptr += sprintf(ptr, "tcp flags is "); ptr += len_written;
if (op[6] == 1) } else if (op[1] == 0 && loop != 0) {
ptr += sprintf(ptr, "not "); len_written = snprintf(ptr, len_string,
if (op[7] == 1) ", or ");
ptr += sprintf(ptr, "exactly match "); len_string -= len_written;
ptr += sprintf(ptr, "%d", value); ptr += len_written;
}
len_written = snprintf(ptr, len_string,
"tcp flags is ");
len_string -= len_written;
ptr += len_written;
if (op[6] == 1) {
ptr += snprintf(ptr, len_string,
"not ");
len_string -= len_written;
ptr += len_written;
}
if (op[7] == 1) {
ptr += snprintf(ptr, len_string,
"exactly match ");
len_string -= len_written;
ptr += len_written;
}
ptr += snprintf(ptr, len_string,
"%d", value);
len_string -= len_written;
ptr += len_written;
break; break;
case BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE: case BGP_FLOWSPEC_CONVERT_TO_NON_OPAQUE:
/* TODO : FS OPAQUE */ /* TODO : FS OPAQUE */
@ -237,6 +285,8 @@ int bgp_flowspec_fragment_type_decode(enum bgp_flowspec_util_nlri_t type,
int len, value, value_size, loop = 0; int len, value, value_size, loop = 0;
char *ptr = (char *)result; /* for return_string */ char *ptr = (char *)result; /* for return_string */
uint32_t offset = 0; uint32_t offset = 0;
int len_string = BGP_FLOWSPEC_STRING_DISPLAY_MAX;
int len_written;
*error = 0; *error = 0;
do { do {
@ -262,16 +312,28 @@ int bgp_flowspec_fragment_type_decode(enum bgp_flowspec_util_nlri_t type,
case BGP_FLOWSPEC_RETURN_STRING: case BGP_FLOWSPEC_RETURN_STRING:
switch (value) { switch (value) {
case 1: case 1:
ptr += sprintf(ptr, "dont-fragment"); len_written = snprintf(ptr, len_string,
"dont-fragment");
len_string -= len_written;
ptr += len_written;
break; break;
case 2: case 2:
ptr += sprintf(ptr, "is-fragment"); len_written = snprintf(ptr, len_string,
"is-fragment");
len_string -= len_written;
ptr += len_written;
break; break;
case 4: case 4:
ptr += sprintf(ptr, "first-fragment"); len_written = snprintf(ptr, len_string,
"first-fragment");
len_string -= len_written;
ptr += len_written;
break; break;
case 8: case 8:
ptr += sprintf(ptr, "last-fragment"); len_written = snprintf(ptr, len_string,
"last-fragment");
len_string -= len_written;
ptr += len_written;
break; break;
default: default:
{} {}

View file

@ -68,16 +68,28 @@ static const struct message bgp_flowspec_display_min[] = {
{0} {0}
}; };
#define FS_STRING_UPDATE(count, ptr, format) do { \ #define FS_STRING_UPDATE(count, ptr, format, remaining_len) do { \
if (((format) == NLRI_STRING_FORMAT_DEBUG) && (count)) { \ int _len_written; \
(ptr) += sprintf((ptr), ", "); \ \
} else if (((format) == NLRI_STRING_FORMAT_MIN) && (count)) { \ if (((format) == NLRI_STRING_FORMAT_DEBUG) && (count)) {\
(ptr) += sprintf((ptr), " "); \ _len_written = snprintf((ptr), (remaining_len), \
} \ ", "); \
count++; \ (remaining_len) -= _len_written; \
(ptr) += _len_written; \
} else if (((format) == NLRI_STRING_FORMAT_MIN) \
&& (count)) { \
_len_written = snprintf((ptr), (remaining_len), \
" "); \
(remaining_len) -= _len_written; \
(ptr) += _len_written; \
} \
count++; \
} while (0) } while (0)
/* Parse FLOWSPEC NLRI*/ /* Parse FLOWSPEC NLRI
* passed return_string string has assumed length
* BGP_FLOWSPEC_STRING_DISPLAY_MAX
*/
void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len, void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len,
char *return_string, int format, char *return_string, int format,
json_object *json_path) json_object *json_path)
@ -92,6 +104,8 @@ void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len,
char pre_extra[2] = ""; char pre_extra[2] = "";
const struct message *bgp_flowspec_display; const struct message *bgp_flowspec_display;
enum bgp_flowspec_util_nlri_t type_util; enum bgp_flowspec_util_nlri_t type_util;
int len_string = BGP_FLOWSPEC_STRING_DISPLAY_MAX;
int len_written;
if (format == NLRI_STRING_FORMAT_LARGE) { if (format == NLRI_STRING_FORMAT_LARGE) {
snprintf(pre_extra, sizeof(pre_extra), "\t"); snprintf(pre_extra, sizeof(pre_extra), "\t");
@ -121,10 +135,14 @@ void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len,
local_string); local_string);
break; break;
} }
FS_STRING_UPDATE(count, ptr, format); FS_STRING_UPDATE(count, ptr, format, len_string);
ptr += sprintf(ptr, "%s%s %s%s", pre_extra, len_written = snprintf(ptr, len_string, "%s%s %s%s",
lookup_msg(bgp_flowspec_display, type, ""), pre_extra,
local_string, extra); lookup_msg(bgp_flowspec_display,
type, ""),
local_string, extra);
len_string -= len_written;
ptr += len_written;
break; break;
case FLOWSPEC_IP_PROTOCOL: case FLOWSPEC_IP_PROTOCOL:
case FLOWSPEC_PORT: case FLOWSPEC_PORT:
@ -144,11 +162,14 @@ void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len,
local_string); local_string);
break; break;
} }
FS_STRING_UPDATE(count, ptr, format); FS_STRING_UPDATE(count, ptr, format, len_string);
ptr += sprintf(ptr, "%s%s %s%s", pre_extra, len_written = snprintf(ptr, len_string, "%s%s %s%s",
lookup_msg(bgp_flowspec_display, pre_extra,
type, ""), lookup_msg(bgp_flowspec_display,
type, ""),
local_string, extra); local_string, extra);
len_string -= len_written;
ptr += len_written;
break; break;
case FLOWSPEC_TCP_FLAGS: case FLOWSPEC_TCP_FLAGS:
ret = bgp_flowspec_tcpflags_decode( ret = bgp_flowspec_tcpflags_decode(
@ -160,14 +181,19 @@ void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len,
break; break;
if (json_path) { if (json_path) {
json_object_string_add(json_path, json_object_string_add(json_path,
lookup_msg(bgp_flowspec_display, type, ""), lookup_msg(bgp_flowspec_display,
type, ""),
local_string); local_string);
break; break;
} }
FS_STRING_UPDATE(count, ptr, format); FS_STRING_UPDATE(count, ptr, format, len_string);
ptr += sprintf(ptr, "%s%s %s%s", pre_extra, len_written = snprintf(ptr, len_string, "%s%s %s%s",
lookup_msg(bgp_flowspec_display, type, ""), pre_extra,
local_string, extra); lookup_msg(bgp_flowspec_display,
type, ""),
local_string, extra);
len_string -= len_written;
ptr += len_written;
break; break;
case FLOWSPEC_PKT_LEN: case FLOWSPEC_PKT_LEN:
case FLOWSPEC_DSCP: case FLOWSPEC_DSCP:
@ -184,11 +210,14 @@ void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len,
local_string); local_string);
break; break;
} }
FS_STRING_UPDATE(count, ptr, format); FS_STRING_UPDATE(count, ptr, format, len_string);
ptr += sprintf(ptr, "%s%s %s%s", pre_extra, len_written = snprintf(ptr, len_string, "%s%s %s%s",
lookup_msg(bgp_flowspec_display, pre_extra,
type, ""), lookup_msg(bgp_flowspec_display,
type, ""),
local_string, extra); local_string, extra);
len_string -= len_written;
ptr += len_written;
break; break;
case FLOWSPEC_FRAGMENT: case FLOWSPEC_FRAGMENT:
ret = bgp_flowspec_fragment_type_decode( ret = bgp_flowspec_fragment_type_decode(
@ -205,11 +234,14 @@ void bgp_fs_nlri_get_string(unsigned char *nlri_content, size_t len,
local_string); local_string);
break; break;
} }
FS_STRING_UPDATE(count, ptr, format); FS_STRING_UPDATE(count, ptr, format, len_string);
ptr += sprintf(ptr, "%s%s %s%s", pre_extra, len_written = snprintf(ptr, len_string, "%s%s %s%s",
lookup_msg(bgp_flowspec_display, pre_extra,
type, ""), lookup_msg(bgp_flowspec_display,
local_string, extra); type, ""),
local_string, extra);
len_string -= len_written;
ptr += len_written;
break; break;
default: default:
error = -1; error = -1;