Merge pull request #15530 from ssahani/lpr-dhcpv4-option-9

network: add support to DHCPv4 server/client option 9 LPR
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2020-04-23 09:10:14 +02:00 committed by GitHub
commit 73781de41f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 146 additions and 7 deletions

View File

@ -1946,6 +1946,15 @@
<varname>DNS=</varname>.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>LPRServers=</varname></term>
<listitem><para>Similar to the <varname>DNS=</varname> 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
<varname>DNS=</varname>.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>EmitRouter=</varname></term>

View File

@ -67,6 +67,9 @@ struct sd_dhcp_lease {
struct in_addr *smtp_server;
size_t smtp_server_size;
struct in_addr *lpr_server;
size_t lpr_server_size;
struct sd_dhcp_route *static_route;
size_t static_route_size, static_route_allocated;

View File

@ -55,8 +55,8 @@ struct sd_dhcp_server {
char *timezone;
struct in_addr *ntp, *dns, *sip, *pop3_server, *smtp_server;
unsigned n_ntp, n_dns, n_sip, n_pop3_server, n_smtp_server;
struct in_addr *ntp, *dns, *sip, *pop3_server, *smtp_server, *lpr_server;
unsigned n_ntp, n_dns, n_sip, n_pop3_server, n_smtp_server, n_lpr_server;
OrderedHashmap *extra_options;
OrderedHashmap *vendor_options;

View File

@ -140,6 +140,13 @@ int sd_dhcp_lease_get_servers(
*addr = lease->smtp_server;
return (int) lease->smtp_server_size;
case SD_DHCP_LEASE_LPR_SERVERS:
if (lease->lpr_server_size <= 0)
return -ENODATA;
*addr = lease->lpr_server;
return (int) lease->lpr_server_size;
default:
return log_debug_errno(SYNTHETIC_ERRNO(ENXIO),
"Unknown DHCP lease info item %d.", what);
@ -161,6 +168,9 @@ int sd_dhcp_lease_get_pop3_server(sd_dhcp_lease *lease, const struct in_addr **a
int sd_dhcp_lease_get_smtp_server(sd_dhcp_lease *lease, const struct in_addr **addr) {
return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_SMTP_SERVERS, addr);
}
int sd_dhcp_lease_get_lpr_servers(sd_dhcp_lease *lease, const struct in_addr **addr) {
return sd_dhcp_lease_get_servers(lease, SD_DHCP_LEASE_LPR_SERVERS, addr);
}
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname) {
assert_return(lease, -EINVAL);
@ -314,6 +324,7 @@ static sd_dhcp_lease *dhcp_lease_free(sd_dhcp_lease *lease) {
free(lease->sip);
free(lease->pop3_server);
free(lease->smtp_server);
free(lease->lpr_server);
free(lease->static_route);
free(lease->client_id);
free(lease->vendor_specific);
@ -648,6 +659,12 @@ int dhcp_lease_parse_options(uint8_t code, uint8_t len, const void *option, void
log_debug_errno(r, "Failed to parse SMTP server, ignoring: %m");
break;
case SD_DHCP_OPTION_LPR_SERVER:
r = lease_parse_in_addrs(option, len, &lease->lpr_server, &lease->lpr_server_size);
if (r < 0)
log_debug_errno(r, "Failed to parse LPR server, ignoring: %m");
break;
case SD_DHCP_OPTION_STATIC_ROUTE:
r = lease_parse_routes(option, len, &lease->static_route, &lease->static_route_size, &lease->static_route_allocated);
if (r < 0)
@ -1086,6 +1103,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
*sip = NULL,
*pop3_server = NULL,
*smtp_server = NULL,
*lpr_server = NULL,
*mtu = NULL,
*routes = NULL,
*domains = NULL,
@ -1117,6 +1135,7 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
"SIP", &sip,
"POP3_SERVERS", &pop3_server,
"SMTP_SERVERS", &smtp_server,
"LPR_SERVERS", &lpr_server,
"MTU", &mtu,
"DOMAINNAME", &lease->domainname,
"HOSTNAME", &lease->hostname,
@ -1245,6 +1264,15 @@ int dhcp_lease_load(sd_dhcp_lease **ret, const char *lease_file) {
lease->smtp_server_size = r;
}
if (lpr_server) {
r = deserialize_in_addrs(&lease->lpr_server, lpr_server);
if (r < 0)
log_debug_errno(r, "Failed to deserialize LPR server %s, ignoring: %m", lpr_server);
else
lease->lpr_server_size = r;
}
if (mtu) {
r = safe_atou16(mtu, &lease->mtu);
if (r < 0)

View File

@ -142,6 +142,7 @@ static sd_dhcp_server *dhcp_server_free(sd_dhcp_server *server) {
free(server->sip);
free(server->pop3_server);
free(server->smtp_server);
free(server->lpr_server);
hashmap_free(server->leases_by_client_id);
@ -533,6 +534,15 @@ static int server_send_ack(sd_dhcp_server *server, DHCPRequest *req,
return r;
}
if (server->n_lpr_server > 0) {
r = dhcp_option_append(
&packet->dhcp, req->max_optlen, &offset, 0,
SD_DHCP_OPTION_LPR_SERVER,
sizeof(struct in_addr) * server->n_lpr_server, server->lpr_server);
if (r < 0)
return r;
}
if (server->timezone) {
r = dhcp_option_append(
&packet->dhcp, req->max_optlen, &offset, 0,
@ -1161,6 +1171,11 @@ int sd_dhcp_server_set_servers(
n_a = &server->n_smtp_server;
break;
case SD_DHCP_LEASE_LPR_SERVERS:
a = &server->lpr_server;
n_a = &server->n_lpr_server;
break;
default:
return log_debug_errno(SYNTHETIC_ERRNO(ENXIO),
"Unknown DHCP lease info item %d.", what);
@ -1199,6 +1214,9 @@ int sd_dhcp_server_set_pop3_server(sd_dhcp_server *server, const struct in_addr
int sd_dhcp_server_set_smtp_server(sd_dhcp_server *server, const struct in_addr smtp[], unsigned n) {
return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_SMTP_SERVERS, smtp, n);
}
int sd_dhcp_server_set_lpr(sd_dhcp_server *server, const struct in_addr lpr[], unsigned n) {
return sd_dhcp_server_set_servers(server, SD_DHCP_LEASE_LPR_SERVERS, lpr, n);
}
int sd_dhcp_server_set_emit_router(sd_dhcp_server *server, int enabled) {
assert_return(server, -EINVAL);

View File

@ -264,6 +264,10 @@ _public_ int sd_network_link_get_smtp_servers(int ifindex, char ***ret) {
return network_link_get_strv(ifindex, "SMTP_SERVERS", ret);
}
_public_ int sd_network_link_get_lpr_servers(int ifindex, char ***ret) {
return network_link_get_strv(ifindex, "LPR_SERVERS", ret);
}
_public_ int sd_network_link_get_dns_default_route(int ifindex) {
char path[STRLEN("/run/systemd/netif/links/") + DECIMAL_STR_MAX(ifindex) + 1];
_cleanup_free_ char *s = NULL;

View File

@ -1241,7 +1241,7 @@ static int link_status_one(
const LinkInfo *info) {
_cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **sip = NULL, **search_domains = NULL, **route_domains = NULL,
**pop3_server = NULL, **smtp_server = NULL;
**pop3_server = NULL, **smtp_server = NULL, **lpr_server = NULL;
_cleanup_free_ char *setup_state = NULL, *operational_state = NULL, *tz = NULL;
_cleanup_free_ char *t = NULL, *network = NULL;
const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL;
@ -1270,6 +1270,7 @@ static int link_status_one(
(void) sd_network_link_get_sip(info->ifindex, &sip);
(void) sd_network_link_get_pop3_servers(info->ifindex, &pop3_server);
(void) sd_network_link_get_smtp_servers(info->ifindex, &smtp_server);
(void) sd_network_link_get_lpr_servers(info->ifindex, &lpr_server);
if (info->sd_device) {
(void) sd_device_get_property_value(info->sd_device, "ID_NET_LINK_FILE", &link);
@ -1844,6 +1845,9 @@ static int link_status_one(
if (r < 0)
return r;
r = dump_list(table, "SMTP servers:", smtp_server);
if (r < 0)
return r;
r = dump_list(table, "LPR servers:", lpr_server);
if (r < 0)
return r;
r = dump_ifindexes(table, "Carrier Bound To:", carrier_bound_to);

View File

@ -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("Unknown 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);
}

View File

@ -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);

View File

@ -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;

View File

@ -1495,7 +1495,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;
@ -1529,8 +1529,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)
@ -1623,6 +1627,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;
@ -1676,6 +1688,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);

View File

@ -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)

View File

@ -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;
};

View File

@ -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);

View File

@ -48,6 +48,7 @@ enum {
SD_DHCP_OPTION_TIME_OFFSET = 2,
SD_DHCP_OPTION_ROUTER = 3,
SD_DHCP_OPTION_DOMAIN_NAME_SERVER = 6,
SD_DHCP_OPTION_LPR_SERVER = 9,
SD_DHCP_OPTION_HOST_NAME = 12,
SD_DHCP_OPTION_BOOT_FILE_SIZE = 13,
SD_DHCP_OPTION_DOMAIN_NAME = 15,

View File

@ -39,6 +39,7 @@ typedef enum sd_dhcp_lease_info {
SD_DHCP_LEASE_SIP_SERVERS,
SD_DHCP_LEASE_POP3_SERVERS,
SD_DHCP_LEASE_SMTP_SERVERS,
SD_DHCP_LEASE_LPR_SERVERS,
_SD_DHCP_LEASE_INFO_MAX,
} sd_dhcp_lease_info;
@ -57,6 +58,7 @@ int sd_dhcp_lease_get_ntp(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_sip(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_pop3_server(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_smtp_server(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_lpr_servers(sd_dhcp_lease *lease, const struct in_addr **addr);
int sd_dhcp_lease_get_mtu(sd_dhcp_lease *lease, uint16_t *mtu);
int sd_dhcp_lease_get_domainname(sd_dhcp_lease *lease, const char **domainname);
int sd_dhcp_lease_get_search_domains(sd_dhcp_lease *lease, char ***domains);

View File

@ -56,6 +56,7 @@ int sd_dhcp_server_set_servers(
const struct in_addr addresses[],
unsigned n_addresses);
int sd_dhcp_server_set_lpr(sd_dhcp_server *server, const struct in_addr lpr[], unsigned n);
int sd_dhcp_server_set_dns(sd_dhcp_server *server, const struct in_addr dns[], unsigned n);
int sd_dhcp_server_set_ntp(sd_dhcp_server *server, const struct in_addr ntp[], unsigned n);
int sd_dhcp_server_set_sip(sd_dhcp_server *server, const struct in_addr sip[], unsigned n);

View File

@ -173,6 +173,9 @@ int sd_network_link_get_pop3_servers(int ifindex, char ***pop3);
/* Get the SMTP servers for a given link. */
int sd_network_link_get_smtp_servers(int ifindex, char ***smtp);
/* Get the LPR servers for a given link. */
int sd_network_link_get_lpr_servers(int ifindex, char ***lpr);
/* Get whether this link shall be used as 'default route' for DNS queries */
int sd_network_link_get_dns_default_route(int ifindex);

View File

@ -278,6 +278,7 @@ EmitSIP=
SIP=
POP3Servers=
SMTPServers=
LPRServers=
EmitRouter=
MaxLeaseTimeSec=
DefaultLeaseTimeSec=