diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 75a581816d..9dc9a4673d 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1945,6 +1945,15 @@ DNS=. + + LPRServers= + + Similar to the DNS= setting described above, this + setting configures whether and what LPR (line printer) server information shall be emitted + as part of the DHCP lease. The same syntax, propagation semantics and defaults apply as for + DNS=. + + EmitRouter= diff --git a/src/network/networkd-dhcp-server.c b/src/network/networkd-dhcp-server.c index ce2244a8fe..be723ddbbc 100644 --- a/src/network/networkd-dhcp-server.c +++ b/src/network/networkd-dhcp-server.c @@ -127,6 +127,11 @@ static int link_push_uplink_to_dhcp_server( lease_condition = link->network->dhcp_use_sip; break; + case SD_DHCP_LEASE_LPR_SERVERS: + servers = link->network->lpr; + lease_condition = true; + break; + default: assert_not_reached("Uknown DHCP lease info item"); } @@ -238,6 +243,11 @@ int dhcp4_server_configure(Link *link) { link->network->dhcp_server_smtp, link->network->n_dhcp_server_smtp, }, + [SD_DHCP_LEASE_LPR_SERVERS] = { + true, + link->network->dhcp_server_lpr, + link->network->n_dhcp_server_lpr, + }, }; assert_cc(ELEMENTSOF(configs) == _SD_DHCP_LEASE_INFO_MAX); @@ -454,3 +464,23 @@ int config_parse_dhcp_server_smtp_servers( &n->dhcp_server_smtp, &n->n_dhcp_server_smtp); } + +int config_parse_dhcp_server_lpr_servers( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Network *n = data; + + return config_parse_dhcp_lease_server_list(unit, filename, line, + lvalue, rvalue, + &n->dhcp_server_lpr, &n->n_dhcp_server_lpr); + +} diff --git a/src/network/networkd-dhcp-server.h b/src/network/networkd-dhcp-server.h index 9da475dd3f..898e9acd52 100644 --- a/src/network/networkd-dhcp-server.h +++ b/src/network/networkd-dhcp-server.h @@ -14,3 +14,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_ntp); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_sip); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_pop3_servers); CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_smtp_servers); +CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_server_lpr_servers); diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 7672b33128..e261473f6f 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -3951,9 +3951,9 @@ static void link_save_dns(FILE *f, struct in_addr_data *dns, unsigned n_dns, boo } int link_save(Link *link) { + const char *admin_state, *oper_state, *carrier_state, *address_state; _cleanup_free_ char *temp_path = NULL; _cleanup_fclose_ FILE *f = NULL; - const char *admin_state, *oper_state, *carrier_state, *address_state; Address *a; Route *route; Iterator i; @@ -4112,6 +4112,12 @@ int link_save(Link *link) { space = false; fputstrv(f, link->network->smtp, NULL, &space); + fputc('\n', f); + + fputs("LPR_SERVERS=", f); + space = false; + fputstrv(f, link->network->lpr, NULL, &space); + if (link->dhcp_lease) { const struct in_addr *addresses; @@ -4130,6 +4136,15 @@ int link_save(Link *link) { space = true; } + if (link->dhcp_lease) { + const struct in_addr *addresses; + + r = sd_dhcp_lease_get_lpr_servers(link->dhcp_lease, &addresses); + if (r > 0) + if (serialize_in_addrs(f, addresses, r, space, in4_addr_is_non_local) > 0) + space = true; + } + if (link->network->dhcp6_use_ntp && dhcp6_lease) { struct in6_addr *in6_addrs; char **hosts; diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 1348fcb9b3..2161f70ae1 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -1490,7 +1490,7 @@ static int ordered_set_put_in4_addrv(OrderedSet *s, static int manager_save(Manager *m) { _cleanup_ordered_set_free_free_ OrderedSet *dns = NULL, *ntp = NULL, *sip = NULL, *pop3 = NULL, - *smtp = NULL, *search_domains = NULL, *route_domains = NULL; + *smtp = NULL, *lpr = NULL, *search_domains = NULL, *route_domains = NULL; const char *operstate_str, *carrier_state_str, *address_state_str; LinkOperationalState operstate = LINK_OPERSTATE_OFF; LinkCarrierState carrier_state = LINK_CARRIER_STATE_OFF; @@ -1524,8 +1524,12 @@ static int manager_save(Manager *m) { return -ENOMEM; smtp = ordered_set_new(&string_hash_ops); - if (!smtp) - return -ENOMEM; + if (!smtp) + return -ENOMEM; + + lpr = ordered_set_new(&string_hash_ops); + if (!lpr) + return -ENOMEM; search_domains = ordered_set_new(&dns_name_hash_ops); if (!search_domains) @@ -1618,6 +1622,14 @@ static int manager_save(Manager *m) { } else if (r < 0 && r != -ENODATA) return r; + r = sd_dhcp_lease_get_lpr_servers(link->dhcp_lease, &addresses); + if (r > 0) { + r = ordered_set_put_in4_addrv(lpr, addresses, r, in4_addr_is_non_local); + if (r < 0) + return r; + } else if (r < 0 && r != -ENODATA) + return r; + if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) { const char *domainname; char **domains = NULL; @@ -1671,6 +1683,7 @@ static int manager_save(Manager *m) { ordered_set_print(f, "SIP=", sip); ordered_set_print(f, "POP3_SERVERS=", pop3); ordered_set_print(f, "SMTP_SERVERS=", smtp); + ordered_set_print(f, "LPR_SERVERS=", lpr); ordered_set_print(f, "DOMAINS=", search_domains); ordered_set_print(f, "ROUTE_DOMAINS=", route_domains); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 9597176b1c..c246dc5cc1 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -212,6 +212,7 @@ DHCPServer.EmitSIP, config_parse_bool, DHCPServer.SIP, config_parse_dhcp_server_sip, 0, 0 DHCPServer.POP3Servers, config_parse_dhcp_server_pop3_servers, 0, 0 DHCPServer.SMTPServers, config_parse_dhcp_server_smtp_servers, 0, 0 +DHCPServer.LPRServers, config_parse_dhcp_server_lpr_servers, 0, 0 DHCPServer.EmitRouter, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_router) DHCPServer.EmitTimezone, config_parse_bool, 0, offsetof(Network, dhcp_server_emit_timezone) DHCPServer.Timezone, config_parse_timezone, 0, offsetof(Network, dhcp_server_timezone) diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 240f6689dd..a99f679318 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -155,6 +155,9 @@ struct Network { struct in_addr *dhcp_server_smtp; unsigned n_dhcp_server_smtp; + struct in_addr *dhcp_server_lpr; + unsigned n_dhcp_server_lpr; + bool dhcp_server_emit_router; bool dhcp_server_emit_timezone; char *dhcp_server_timezone; @@ -312,6 +315,7 @@ struct Network { char **sip; char **pop3; char **smtp; + char **lpr; char **bind_carrier; }; diff --git a/src/network/networkd-util.c b/src/network/networkd-util.c index 3d1d3bd684..5471e74592 100644 --- a/src/network/networkd-util.c +++ b/src/network/networkd-util.c @@ -43,6 +43,7 @@ static const char* const dhcp_lease_info_table[_SD_DHCP_LEASE_INFO_MAX] = { [SD_DHCP_LEASE_SIP_SERVERS] = "SIP servers", [SD_DHCP_LEASE_POP3_SERVERS] = "POP3 servers", [SD_DHCP_LEASE_SMTP_SERVERS] = "SMTP servers", + [SD_DHCP_LEASE_LPR_SERVERS] = "LPR servers", }; DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(address_family, AddressFamily, ADDRESS_FAMILY_YES); diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network index 147ea1b639..1cd18202f4 100644 --- a/test/fuzz/fuzz-network-parser/directives.network +++ b/test/fuzz/fuzz-network-parser/directives.network @@ -278,6 +278,7 @@ EmitSIP= SIP= POP3Servers= SMTPServers= +LPRServers= EmitRouter= MaxLeaseTimeSec= DefaultLeaseTimeSec=