mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-31 06:25:31 +00:00
[master] add DSCP support
3535. [func] Add support for setting Differentiated Services Code Point (DSCP) values in named. Most configuration options which take a "port" option (e.g., listen-on, forwarders, also-notify, masters, notify-source, etc) can now also take a "dscp" option specifying a code point for use with outgoing traffic, if supported by the underlying OS. [RT #27596]
This commit is contained in:
@@ -1860,6 +1860,28 @@ cfg_print_rawaddr(cfg_printer_t *pctx, const isc_netaddr_t *na) {
|
||||
cfg_print_chars(pctx, isc_buffer_base(&buf), isc_buffer_usedlength(&buf));
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
cfg_parse_dscp(cfg_parser_t *pctx, isc_dscp_t *dscp) {
|
||||
isc_result_t result;
|
||||
|
||||
CHECK(cfg_gettoken(pctx, ISC_LEXOPT_NUMBER));
|
||||
|
||||
if (pctx->token.type != isc_tokentype_number) {
|
||||
cfg_parser_error(pctx, CFG_LOG_NEAR,
|
||||
"expected number");
|
||||
return (ISC_R_UNEXPECTEDTOKEN);
|
||||
}
|
||||
if (pctx->token.value.as_ulong > 63) {
|
||||
cfg_parser_error(pctx, CFG_LOG_NEAR,
|
||||
"dscp out of range");
|
||||
return (ISC_R_RANGE);
|
||||
}
|
||||
*dscp = (isc_dscp_t)(pctx->token.value.as_ulong);
|
||||
return (ISC_R_SUCCESS);
|
||||
cleanup:
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* netaddr */
|
||||
|
||||
static unsigned int netaddr_flags = CFG_ADDR_V4OK | CFG_ADDR_V6OK;
|
||||
@@ -2030,17 +2052,43 @@ parse_sockaddrsub(cfg_parser_t *pctx, const cfg_type_t *type,
|
||||
isc_result_t result;
|
||||
isc_netaddr_t netaddr;
|
||||
in_port_t port = 0;
|
||||
isc_dscp_t dscp = -1;
|
||||
cfg_obj_t *obj = NULL;
|
||||
int have_port = 0, have_dscp = 0;
|
||||
|
||||
CHECK(cfg_create_obj(pctx, type, &obj));
|
||||
CHECK(cfg_parse_rawaddr(pctx, flags, &netaddr));
|
||||
CHECK(cfg_peektoken(pctx, 0));
|
||||
if (pctx->token.type == isc_tokentype_string &&
|
||||
strcasecmp(TOKEN_STRING(pctx), "port") == 0) {
|
||||
CHECK(cfg_gettoken(pctx, 0)); /* read "port" */
|
||||
CHECK(cfg_parse_rawport(pctx, flags, &port));
|
||||
for (;;) {
|
||||
CHECK(cfg_peektoken(pctx, 0));
|
||||
if (pctx->token.type == isc_tokentype_string) {
|
||||
if (strcasecmp(TOKEN_STRING(pctx), "port") == 0) {
|
||||
CHECK(cfg_gettoken(pctx, 0)); /* read "port" */
|
||||
CHECK(cfg_parse_rawport(pctx, flags, &port));
|
||||
++have_port;
|
||||
} else if ((flags & CFG_ADDR_DSCPOK) != 0 &&
|
||||
strcasecmp(TOKEN_STRING(pctx), "dscp") == 0)
|
||||
{
|
||||
CHECK(cfg_gettoken(pctx, 0)); /* read "dscp" */
|
||||
CHECK(cfg_parse_dscp(pctx, &dscp));
|
||||
++have_dscp;
|
||||
} else
|
||||
break;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
if (have_port > 1) {
|
||||
cfg_parser_error(pctx, 0, "expected at most one port");
|
||||
result = ISC_R_UNEXPECTEDTOKEN;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (have_dscp > 1) {
|
||||
cfg_parser_error(pctx, 0, "expected at most one dscp");
|
||||
result = ISC_R_UNEXPECTEDTOKEN;
|
||||
goto cleanup;
|
||||
}
|
||||
isc_sockaddr_fromnetaddr(&obj->value.sockaddr, &netaddr, port);
|
||||
obj->value.sockaddrdscp.dscp = dscp;
|
||||
*ret = obj;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
@@ -2055,6 +2103,13 @@ cfg_type_t cfg_type_sockaddr = {
|
||||
&cfg_rep_sockaddr, &sockaddr_flags
|
||||
};
|
||||
|
||||
static unsigned int sockaddrdscp_flags = CFG_ADDR_V4OK | CFG_ADDR_V6OK |
|
||||
CFG_ADDR_DSCPOK;
|
||||
cfg_type_t cfg_type_sockaddrdscp = {
|
||||
"sockaddr", cfg_parse_sockaddr, cfg_print_sockaddr, cfg_doc_sockaddr,
|
||||
&cfg_rep_sockaddr, &sockaddrdscp_flags
|
||||
};
|
||||
|
||||
isc_result_t
|
||||
cfg_parse_sockaddr(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
|
||||
const unsigned int *flagp = type->of;
|
||||
@@ -2075,6 +2130,10 @@ cfg_print_sockaddr(cfg_printer_t *pctx, const cfg_obj_t *obj) {
|
||||
cfg_print_chars(pctx, " port ", 6);
|
||||
cfg_print_rawuint(pctx, port);
|
||||
}
|
||||
if (obj->value.sockaddrdscp.dscp != -1) {
|
||||
cfg_print_chars(pctx, " dscp ", 6);
|
||||
cfg_print_rawuint(pctx, obj->value.sockaddrdscp.dscp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -2105,6 +2164,9 @@ cfg_doc_sockaddr(cfg_printer_t *pctx, const cfg_type_t *type) {
|
||||
} else {
|
||||
cfg_print_cstr(pctx, "[ port <integer> ]");
|
||||
}
|
||||
if ((*flagp & CFG_ADDR_DSCPOK) != 0) {
|
||||
cfg_print_cstr(pctx, " [ dscp <integer> ]");
|
||||
}
|
||||
}
|
||||
|
||||
isc_boolean_t
|
||||
@@ -2119,6 +2181,12 @@ cfg_obj_assockaddr(const cfg_obj_t *obj) {
|
||||
return (&obj->value.sockaddr);
|
||||
}
|
||||
|
||||
isc_dscp_t
|
||||
cfg_obj_getdscp(const cfg_obj_t *obj) {
|
||||
REQUIRE(obj != NULL && obj->type->rep == &cfg_rep_sockaddr);
|
||||
return (obj->value.sockaddrdscp.dscp);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
cfg_gettoken(cfg_parser_t *pctx, int options) {
|
||||
isc_result_t result;
|
||||
|
Reference in New Issue
Block a user