From: pacien Date: Sun, 9 Apr 2023 20:18:50 +0000 (+0200) Subject: odhcp6c: add -K option to set packet kernel priority X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=bcd283632ac13391aac3ebdd074d1fd832d76fa3;p=project%2Fodhcp6c.git odhcp6c: add -K option to set packet kernel priority This adds a command line option (-K) to set the packet kernel priority. This makes it straightforward to set some VLAN priority for DHCP requests through an egress qos map. (Avoiding the need for firewall matching and marking through iptables, which prevents using flow offloading). (Such priority tag is a hard requirement for some ISPs, such as Orange in France). Signed-off-by: Pacien TRAN-GIRARD --- diff --git a/src/dhcpv6.c b/src/dhcpv6.c index 01bda16..ca5957e 100644 --- a/src/dhcpv6.c +++ b/src/dhcpv6.c @@ -194,7 +194,7 @@ static char *dhcpv6_status_code_to_str(uint16_t code) return "Unknown"; } -int init_dhcpv6(const char *ifname, unsigned int options, int sol_timeout) +int init_dhcpv6(const char *ifname, unsigned int options, int sk_prio, int sol_timeout) { client_options = options; dhcpv6_retx[DHCPV6_MSG_SOLICIT].max_timeo = sol_timeout; @@ -289,6 +289,9 @@ int init_dhcpv6(const char *ifname, unsigned int options, int sol_timeout) if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, ifname, strlen(ifname)) < 0) goto failure; + if (setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &sk_prio, sizeof(sk_prio)) < 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 e713da9..4a6d7bd 100644 --- a/src/odhcp6c.c +++ b/src/odhcp6c.c @@ -178,6 +178,7 @@ int main(_unused int argc, char* const argv[]) bool stateful_only_mode = 0; struct odhcp6c_opt *opt; int ia_pd_iaid_index = 0; + int sk_prio = 0; int sol_timeout = DHCPV6_SOL_MAX_RT; int verbosity = 0; bool help = false, daemonize = false; @@ -187,7 +188,7 @@ int main(_unused int argc, char* const argv[]) unsigned int ra_options = RA_RDNSS_DEFAULT_LIFETIME; unsigned int ra_holdoff_interval = RA_MIN_ADV_INTERVAL; - while ((c = getopt(argc, argv, "S::DN:V:P:FB:c:i:r:Ru:Ux:s:kt:m:Lhedp:fav")) != -1) { + while ((c = getopt(argc, argv, "S::DN:V:P:FB:c:i:r:Ru:Ux:s:kK:t:m:Lhedp:fav")) != -1) { switch (c) { case 'S': allow_slaac_only = (optarg) ? atoi(optarg) : -1; @@ -345,6 +346,10 @@ int main(_unused int argc, char* const argv[]) release = false; break; + case 'K': + sk_prio = atoi(optarg); + break; + case 't': sol_timeout = atoi(optarg); break; @@ -417,7 +422,7 @@ int main(_unused int argc, char* const argv[]) signal(SIGUSR2, sighandler); if ((urandom_fd = open("/dev/urandom", O_CLOEXEC | O_RDONLY)) < 0 || - init_dhcpv6(ifname, client_options, sol_timeout) || + 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)); @@ -627,6 +632,7 @@ static int usage(void) " -a Don't send Accept Reconfigure option\n" " -f Don't send Client FQDN option\n" " -k Don't send a RELEASE when stopping\n" + " -K Set packet kernel priority (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 0831775..5d9d5e3 100644 --- a/src/odhcp6c.h +++ b/src/odhcp6c.h @@ -392,7 +392,7 @@ struct odhcp6c_opt { const char *str; }; -int init_dhcpv6(const char *ifname, unsigned int client_options, int sol_timeout); +int init_dhcpv6(const char *ifname, unsigned int client_options, int sk_prio, int sol_timeout); 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);