From: Nicolas BESNARD Date: Mon, 30 Sep 2024 09:58:35 +0000 (+0200) Subject: dscp: add option to set dscp value X-Git-Url: http://git.openwrt.org/?a=commitdiff_plain;h=1b5f0c402bbf8ccae87816a3ced9d509c643778a;p=project%2Fodhcp6c.git dscp: add option to set dscp value Problem: odhcp6c doesn't support change of DSCP value. Solution: Adapt odhcp6c to set socket option to change the DSCP value for dhcpv6 packets. Signed-off-by: Nicolas BESNARD Signed-off-by: Paul Donald Link: https://github.com/openwrt/odhcp6c/pull/106 Signed-off-by: Álvaro Fernández Rojas --- diff --git a/src/dhcpv6.c b/src/dhcpv6.c index 50b6f7b..3985927 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -193,7 +193,7 @@ static char *dhcpv6_status_code_to_str(uint16_t code) return "Unknown"; } -int init_dhcpv6(const char *ifname, unsigned int options, int sk_prio, int sol_timeout) +int init_dhcpv6(const char *ifname, unsigned int options, int sk_prio, int sol_timeout, unsigned int dscp) { client_options = options; dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = sol_timeout; @@ -287,6 +287,11 @@ int init_dhcpv6(const char *ifname, unsigned int options, int sk_prio, int sol_t if (setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &sk_prio, sizeof(sk_prio)) < 0) goto failure; + val = dscp << 2; + if (setsockopt(sock, IPPROTO_IPV6, IPV6_TCLASS, &val, sizeof(val)) < 0) { + goto failure; + } + struct sockaddr_in6 client_addr = { .sin6_family = AF_INET6, .sin6_port = htons(DHCPV6_CLIENT_PORT), .sin6_flowinfo = 0 }; diff --git a/src/odhcp6c.c b/src/odhcp6c.c index 8354820..f439901 100644 --- a/src/odhcp6c.c +++ b/src/odhcp6c.c @@ -187,8 +187,9 @@ int main(_unused int argc, char* const argv[]) unsigned int client_options = DHCPV6_CLIENT_FQDN | DHCPV6_ACCEPT_RECONFIGURE; unsigned int ra_options = RA_RDNSS_DEFAULT_LIFETIME; unsigned int ra_holdoff_interval = RA_MIN_ADV_INTERVAL; + unsigned int dscp = 0; - while ((c = getopt(argc, argv, "S::DN:V:P:FB:c:i:r:Ru:Ux:s:kK:t:m:Lhedp:fav")) != -1) { + while ((c = getopt(argc, argv, "S::DN:V:P:FB:c:i:r:Ru:Ux:s:kK:t:C:m:Lhedp:fav")) != -1) { switch (c) { case 'S': allow_slaac_only = (optarg) ? atoi(optarg) : -1; @@ -366,6 +367,14 @@ int main(_unused int argc, char* const argv[]) sol_timeout = atoi(optarg); break; + case 'C': + dscp = atoi(optarg); + if (dscp > 63) { + dscp = 0; + syslog(LOG_ERR, "Invalid DSCP value, using default (0)"); + } + break; + case 'm': ra_holdoff_interval = atoi(optarg); break; @@ -453,13 +462,13 @@ int main(_unused int argc, char* const argv[]) } } - if ((urandom_fd = open("/dev/urandom", O_CLOEXEC | O_RDONLY)) < 0 || - init_dhcpv6(ifname, client_options, sk_prio, sol_timeout) || - ra_init(ifname, &ifid, ra_options, ra_holdoff_interval) || - script_init(script, ifname)) { - syslog(LOG_ERR, "failed to initialize: %s", strerror(errno)); - return 4; - } + if ((urandom_fd = open("/dev/urandom", O_CLOEXEC | O_RDONLY)) < 0 || + init_dhcpv6(ifname, client_options, sk_prio, sol_timeout, dscp) || + ra_init(ifname, &ifid, ra_options, ra_holdoff_interval) || + script_init(script, ifname)) { + syslog(LOG_ERR, "failed to initialize: %s", strerror(errno)); + return 4; + } script_call("started", 0, false); @@ -648,6 +657,7 @@ static int usage(void) " -f Don't send Client FQDN option\n" " -k Don't send a RELEASE when stopping\n" " -K Set packet kernel priority (0)\n" + " -C Set packet DSCP value (0)\n" " -t Maximum timeout for DHCPv6-SOLICIT (120)\n" " -m Minimum time between accepting RA updates (3)\n" " -L Ignore default lifetime for RDNSS records\n" diff --git a/src/odhcp6c.h b/src/odhcp6c.h index 518193e..8bba932 100644 --- a/src/odhcp6c.h +++ b/src/odhcp6c.h @@ -393,7 +393,7 @@ struct odhcp6c_opt { const char *str; }; -int init_dhcpv6(const char *ifname, unsigned int client_options, int sk_prio, int sol_timeout); +int init_dhcpv6(const char *ifname, unsigned int client_options, int sk_prio, int sol_timeout, unsigned int dscp); int dhcpv6_set_ia_mode(enum odhcp6c_ia_mode na, enum odhcp6c_ia_mode pd, bool stateful_only); int dhcpv6_request(enum dhcpv6_msg type); int dhcpv6_poll_reconfigure(void);