@@ -140,6 +140,55 @@ static int link_push_uplink_ntp_to_dhcp_server(Link *link, sd_dhcp_server *s) {
140140 return sd_dhcp_server_set_ntp (s , addresses , n_addresses );
141141}
142142
143+ static int link_push_uplink_pop3_to_dhcp_server (Link * link , sd_dhcp_server * s ) {
144+ _cleanup_free_ struct in_addr * addresses = NULL ;
145+ size_t n_addresses = 0 , n_allocated = 0 ;
146+ char * * a ;
147+
148+ if (!link -> network )
149+ return 0 ;
150+
151+ log_link_debug (link , "Copying POP3 server information from link" );
152+
153+ STRV_FOREACH (a , link -> network -> pop3 ) {
154+ union in_addr_union ia ;
155+
156+ /* Only look for IPv4 addresses */
157+ if (in_addr_from_string (AF_INET , * a , & ia ) <= 0 )
158+ continue ;
159+
160+ /* Never propagate obviously borked data */
161+ if (in4_addr_is_null (& ia .in ) || in4_addr_is_localhost (& ia .in ))
162+ continue ;
163+
164+ if (!GREEDY_REALLOC (addresses , n_allocated , n_addresses + 1 ))
165+ return log_oom ();
166+
167+ addresses [n_addresses ++ ] = ia .in ;
168+ }
169+
170+ if (link -> dhcp_lease ) {
171+ const struct in_addr * da = NULL ;
172+ int j , n ;
173+
174+ n = sd_dhcp_lease_get_pop3_server (link -> dhcp_lease , & da );
175+ if (n > 0 ) {
176+
177+ if (!GREEDY_REALLOC (addresses , n_allocated , n_addresses + n ))
178+ return log_oom ();
179+
180+ for (j = 0 ; j < n ; j ++ )
181+ if (in4_addr_is_non_local (& da [j ]))
182+ addresses [n_addresses ++ ] = da [j ];
183+ }
184+ }
185+
186+ if (n_addresses <= 0 )
187+ return 0 ;
188+
189+ return sd_dhcp_server_set_pop3_server (s , addresses , n_addresses );
190+ }
191+
143192static int link_push_uplink_sip_to_dhcp_server (Link * link , sd_dhcp_server * s ) {
144193 _cleanup_free_ struct in_addr * addresses = NULL ;
145194 size_t n_addresses = 0 , n_allocated = 0 ;
@@ -281,6 +330,22 @@ int dhcp4_server_configure(Link *link) {
281330 log_link_warning_errno (link , r , "Failed to set SIP server for DHCP server, ignoring: %m" );
282331 }
283332
333+ if (link -> network -> n_dhcp_server_pop3 > 0 )
334+ r = sd_dhcp_server_set_pop3_server (link -> dhcp_server , link -> network -> dhcp_server_pop3 , link -> network -> n_dhcp_server_pop3 );
335+ else {
336+ if (!acquired_uplink )
337+ uplink = manager_find_uplink (link -> manager , link );
338+
339+ if (!uplink ) {
340+ log_link_debug (link , "Not emitting POP3 server information on link, couldn't find suitable uplink." );
341+ r = 0 ;
342+ } else
343+ r = link_push_uplink_pop3_to_dhcp_server (uplink , link -> dhcp_server );
344+
345+ }
346+ if (r < 0 )
347+ log_link_warning_errno (link , r , "Failed to set POP3 server for DHCP server, ignoring: %m" );
348+
284349 r = sd_dhcp_server_set_emit_router (link -> dhcp_server , link -> network -> dhcp_server_emit_router );
285350 if (r < 0 )
286351 return log_link_error_errno (link , r , "Failed to set router emission for DHCP server: %m" );
@@ -486,3 +551,55 @@ int config_parse_dhcp_server_sip(
486551 n -> dhcp_server_sip = m ;
487552 }
488553}
554+
555+ int config_parse_dhcp_server_pop3_servers (
556+ const char * unit ,
557+ const char * filename ,
558+ unsigned line ,
559+ const char * section ,
560+ unsigned section_line ,
561+ const char * lvalue ,
562+ int ltype ,
563+ const char * rvalue ,
564+ void * data ,
565+ void * userdata ) {
566+
567+ Network * n = data ;
568+ const char * p = rvalue ;
569+ int r ;
570+
571+ assert (filename );
572+ assert (lvalue );
573+ assert (rvalue );
574+
575+ for (;;) {
576+ _cleanup_free_ char * w = NULL ;
577+ union in_addr_union a ;
578+ struct in_addr * m ;
579+
580+ r = extract_first_word (& p , & w , NULL , 0 );
581+ if (r == - ENOMEM )
582+ return log_oom ();
583+ if (r < 0 ) {
584+ log_syntax (unit , LOG_ERR , filename , line , r ,
585+ "Failed to extract word, ignoring: %s" , rvalue );
586+ return 0 ;
587+ }
588+ if (r == 0 )
589+ return 0 ;
590+
591+ r = in_addr_from_string (AF_INET , w , & a );
592+ if (r < 0 ) {
593+ log_syntax (unit , LOG_ERR , filename , line , r ,
594+ "Failed to parse POP3 server address '%s', ignoring: %m" , w );
595+ continue ;
596+ }
597+
598+ m = reallocarray (n -> dhcp_server_pop3 , n -> n_dhcp_server_pop3 + 1 , sizeof (struct in_addr ));
599+ if (!m )
600+ return log_oom ();
601+
602+ m [n -> n_dhcp_server_pop3 ++ ] = a .in ;
603+ n -> dhcp_server_pop3 = m ;
604+ }
605+ }
0 commit comments