Codebase list netplan.io / d96a6a0
networkd: force bringing up devices with no IP addresses Signed-off-by: Mathieu Trudel-Lapierre <mathieu.trudel-lapierre@canonical.com> Mathieu Trudel-Lapierre 5 years ago
4 changed file(s) with 119 addition(s) and 221 deletion(s). Raw diff Collapse all Expand all
420420 static void
421421 write_network_file(net_definition* def, const char* rootdir, const char* path)
422422 {
423 GString* network = NULL;
424 GString* link = NULL;
423425 GString* s = NULL;
424426 mode_t orig_umask;
425427
426 /* do we need to write a .network file? */
427 if (!def->dhcp4 && !def->dhcp6 && !def->bridge && !def->bond &&
428 !def->ip4_addresses && !def->ip6_addresses && !def->gateway4 && !def->gateway6 &&
429 !def->ip4_nameservers && !def->ip6_nameservers && !def->has_vlans &&
430 def->type < ND_VIRTUAL)
431 return;
432
433 /* build file contents */
434 s = g_string_sized_new(200);
435 append_match_section(def, s, TRUE);
428 /* Prepare the [Link] section of the .network file. */
429 link = g_string_sized_new(200);
430
431 /* Prepare the [Network] section */
432 network = g_string_sized_new(200);
436433
437434 if (def->optional || def->optional_addresses) {
438 g_string_append(s, "\n[Link]\n");
439435 if (def->optional) {
440 g_string_append(s, "RequiredForOnline=no\n");
436 g_string_append(link, "RequiredForOnline=no\n");
441437 }
442438 for (unsigned i = 0; optional_address_options[i].name != NULL; ++i) {
443439 if (def->optional_addresses & optional_address_options[i].flag) {
444 g_string_append_printf(s, "OptionalAddresses=%s\n", optional_address_options[i].name);
440 g_string_append_printf(link, "OptionalAddresses=%s\n", optional_address_options[i].name);
445441 }
446442 }
447443 }
448444
449 g_string_append(s, "\n[Network]\n");
445
450446 if (def->dhcp4 && def->dhcp6)
451 g_string_append(s, "DHCP=yes\n");
447 g_string_append(network, "DHCP=yes\n");
452448 else if (def->dhcp4)
453 g_string_append(s, "DHCP=ipv4\n");
449 g_string_append(network, "DHCP=ipv4\n");
454450 else if (def->dhcp6)
455 g_string_append(s, "DHCP=ipv6\n");
451 g_string_append(network, "DHCP=ipv6\n");
456452
457453 /* Set link local addressing -- this does not apply to bond and bridge
458454 * member interfaces, which always get it disabled.
459455 */
460456 if (!def->bond && !def->bridge && (def->linklocal.ipv4 || def->linklocal.ipv6)) {
461457 if (def->linklocal.ipv4 && def->linklocal.ipv6)
462 g_string_append(s, "LinkLocalAddressing=yes\n");
458 g_string_append(network, "LinkLocalAddressing=yes\n");
463459 else if (def->linklocal.ipv4)
464 g_string_append(s, "LinkLocalAddressing=ipv4\n");
460 g_string_append(network, "LinkLocalAddressing=ipv4\n");
465461 else if (def->linklocal.ipv6)
466 g_string_append(s, "LinkLocalAddressing=ipv6\n");
462 g_string_append(network, "LinkLocalAddressing=ipv6\n");
467463 } else {
468 g_string_append(s, "LinkLocalAddressing=no\n");
464 g_string_append(network, "LinkLocalAddressing=no\n");
469465 }
470466
471467 if (def->ip4_addresses)
472468 for (unsigned i = 0; i < def->ip4_addresses->len; ++i)
473 g_string_append_printf(s, "Address=%s\n", g_array_index(def->ip4_addresses, char*, i));
469 g_string_append_printf(network, "Address=%s\n", g_array_index(def->ip4_addresses, char*, i));
474470 if (def->ip6_addresses)
475471 for (unsigned i = 0; i < def->ip6_addresses->len; ++i)
476 g_string_append_printf(s, "Address=%s\n", g_array_index(def->ip6_addresses, char*, i));
472 g_string_append_printf(network, "Address=%s\n", g_array_index(def->ip6_addresses, char*, i));
477473 if (def->accept_ra == ACCEPT_RA_ENABLED)
478 g_string_append_printf(s, "IPv6AcceptRA=yes\n");
474 g_string_append_printf(network, "IPv6AcceptRA=yes\n");
479475 else if (def->accept_ra == ACCEPT_RA_DISABLED)
480 g_string_append_printf(s, "IPv6AcceptRA=no\n");
476 g_string_append_printf(network, "IPv6AcceptRA=no\n");
481477 if (def->ip6_privacy)
482 g_string_append(s, "IPv6PrivacyExtensions=yes\n");
478 g_string_append(network, "IPv6PrivacyExtensions=yes\n");
483479 if (def->gateway4)
484 g_string_append_printf(s, "Gateway=%s\n", def->gateway4);
480 g_string_append_printf(network, "Gateway=%s\n", def->gateway4);
485481 if (def->gateway6)
486 g_string_append_printf(s, "Gateway=%s\n", def->gateway6);
482 g_string_append_printf(network, "Gateway=%s\n", def->gateway6);
487483 if (def->ip4_nameservers)
488484 for (unsigned i = 0; i < def->ip4_nameservers->len; ++i)
489 g_string_append_printf(s, "DNS=%s\n", g_array_index(def->ip4_nameservers, char*, i));
485 g_string_append_printf(network, "DNS=%s\n", g_array_index(def->ip4_nameservers, char*, i));
490486 if (def->ip6_nameservers)
491487 for (unsigned i = 0; i < def->ip6_nameservers->len; ++i)
492 g_string_append_printf(s, "DNS=%s\n", g_array_index(def->ip6_nameservers, char*, i));
488 g_string_append_printf(network, "DNS=%s\n", g_array_index(def->ip6_nameservers, char*, i));
493489 if (def->search_domains) {
494 g_string_append_printf(s, "Domains=%s", g_array_index(def->search_domains, char*, 0));
490 g_string_append_printf(network, "Domains=%s", g_array_index(def->search_domains, char*, 0));
495491 for (unsigned i = 1; i < def->search_domains->len; ++i)
496 g_string_append_printf(s, " %s", g_array_index(def->search_domains, char*, i));
497 g_string_append(s, "\n");
492 g_string_append_printf(network, " %s", g_array_index(def->search_domains, char*, i));
493 g_string_append(network, "\n");
498494 }
499495
500496 if (def->type >= ND_VIRTUAL)
501 g_string_append(s, "ConfigureWithoutCarrier=yes\n");
497 g_string_append(network, "ConfigureWithoutCarrier=yes\n");
502498
503499 if (def->bridge) {
504 g_string_append_printf(s, "Bridge=%s\n", def->bridge);
500 g_string_append_printf(network, "Bridge=%s\n", def->bridge);
505501
506502 if (def->bridge_params.path_cost || def->bridge_params.port_priority)
507 g_string_append_printf(s, "\n[Bridge]\n");
503 g_string_append_printf(network, "\n[Bridge]\n");
508504 if (def->bridge_params.path_cost)
509 g_string_append_printf(s, "Cost=%u\n", def->bridge_params.path_cost);
505 g_string_append_printf(network, "Cost=%u\n", def->bridge_params.path_cost);
510506 if (def->bridge_params.port_priority)
511 g_string_append_printf(s, "Priority=%u\n", def->bridge_params.port_priority);
507 g_string_append_printf(network, "Priority=%u\n", def->bridge_params.port_priority);
512508 }
513509 if (def->bond) {
514 g_string_append_printf(s, "Bond=%s\n", def->bond);
510 g_string_append_printf(network, "Bond=%s\n", def->bond);
515511
516512 if (def->bond_params.primary_slave)
517 g_string_append_printf(s, "PrimarySlave=true\n");
513 g_string_append_printf(network, "PrimarySlave=true\n");
518514 }
519515
520516 if (def->has_vlans) {
524520 g_hash_table_iter_init(&i, netdefs);
525521 while (g_hash_table_iter_next (&i, NULL, (gpointer*) &nd))
526522 if (nd->vlan_link == def)
527 g_string_append_printf(s, "VLAN=%s\n", nd->id);
523 g_string_append_printf(network, "VLAN=%s\n", nd->id);
528524 }
529525
530526 if (def->routes != NULL) {
531527 for (unsigned i = 0; i < def->routes->len; ++i) {
532528 ip_route* cur_route = g_array_index (def->routes, ip_route*, i);
533 write_route(cur_route, s);
529 write_route(cur_route, network);
534530 }
535531 }
536532 if (def->ip_rules != NULL) {
537533 for (unsigned i = 0; i < def->ip_rules->len; ++i) {
538534 ip_rule* cur_rule = g_array_index (def->ip_rules, ip_rule*, i);
539 write_ip_rule(cur_rule, s);
535 write_ip_rule(cur_rule, network);
540536 }
541537 }
542538
543539 if (def->dhcp4 || def->dhcp6) {
544540 /* NetworkManager compatible route metrics */
545 g_string_append(s, "\n[DHCP]\n");
541 g_string_append(network, "\n[DHCP]\n");
542
546543 if (g_strcmp0(def->dhcp_identifier, "duid") != 0)
547 g_string_append_printf(s, "ClientIdentifier=%s\n", def->dhcp_identifier);
544 g_string_append_printf(network, "ClientIdentifier=%s\n", def->dhcp_identifier);
548545 if (def->critical)
549 g_string_append_printf(s, "CriticalConnection=true\n");
546 g_string_append_printf(network, "CriticalConnection=true\n");
550547
551548 dhcp_overrides combined_dhcp_overrides;
552549 combine_dhcp_overrides(def, &combined_dhcp_overrides);
553550
554551 if (combined_dhcp_overrides.metric == METRIC_UNSPEC) {
555 g_string_append_printf(s, "RouteMetric=%i\n", (def->type == ND_WIFI ? 600 : 100));
552 g_string_append_printf(network, "RouteMetric=%i\n", (def->type == ND_WIFI ? 600 : 100));
556553 } else {
557 g_string_append_printf(s, "RouteMetric=%u\n",
554 g_string_append_printf(network, "RouteMetric=%u\n",
558555 combined_dhcp_overrides.metric);
559556 }
560557
562559 if (!combined_dhcp_overrides.use_mtu) {
563560 /* isc-dhcp dhclient compatible UseMTU, networkd default is to
564561 * not accept MTU, which breaks clouds */
565 g_string_append_printf(s, "UseMTU=false\n");
562 g_string_append_printf(network, "UseMTU=false\n");
566563 } else {
567 g_string_append_printf(s, "UseMTU=true\n");
564 g_string_append_printf(network, "UseMTU=true\n");
568565 }
569566
570567 /* Only write DHCP options that differ from the networkd default. */
571568 if (!combined_dhcp_overrides.use_routes)
572 g_string_append_printf(s, "UseRoutes=false\n");
569 g_string_append_printf(network, "UseRoutes=false\n");
573570 if (!combined_dhcp_overrides.use_dns)
574 g_string_append_printf(s, "UseDNS=false\n");
571 g_string_append_printf(network, "UseDNS=false\n");
575572 if (!combined_dhcp_overrides.use_ntp)
576 g_string_append_printf(s, "UseNTP=false\n");
573 g_string_append_printf(network, "UseNTP=false\n");
577574 if (!combined_dhcp_overrides.send_hostname)
578 g_string_append_printf(s, "SendHostname=false\n");
575 g_string_append_printf(network, "SendHostname=false\n");
579576 if (!combined_dhcp_overrides.use_hostname)
580 g_string_append_printf(s, "UseHostname=false\n");
577 g_string_append_printf(network, "UseHostname=false\n");
581578 if (combined_dhcp_overrides.hostname)
582 g_string_append_printf(s, "Hostname=%s\n", combined_dhcp_overrides.hostname);
583 }
584
585 /* these do not contain secrets and need to be readable by
586 * systemd-networkd - LP: #1736965 */
587 orig_umask = umask(022);
588 g_string_free_to_file(s, rootdir, path, ".network");
589 umask(orig_umask);
579 g_string_append_printf(network, "Hostname=%s\n", combined_dhcp_overrides.hostname);
580 }
581
582 if (network->len > 0 || link->len > 0) {
583 s = g_string_sized_new(200);
584 append_match_section(def, s, TRUE);
585
586 if (link->len > 0)
587 g_string_append_printf(s, "\n[Link]\n%s", link->str);
588 if (network->len > 0)
589 g_string_append_printf(s, "\n[Network]\n%s", network->str);
590
591 g_string_free(link, TRUE);
592 g_string_free(network, TRUE);
593
594 /* these do not contain secrets and need to be readable by
595 * systemd-networkd - LP: #1736965 */
596 orig_umask = umask(022);
597 g_string_free_to_file(s, rootdir, path, ".network");
598 umask(orig_umask);
599 }
590600 }
591601
592602 static void
12421242
12431243 self.assert_networkd({'engreen.network': ND_DHCP4 % 'engreen',
12441244 'enred.link': '[Match]\nOriginalName=enred\n\n[Link]\nWakeOnLan=magic\n',
1245 'enred.network': '''[Match]
1246 Name=enred
1247
1248 [Network]
1249 LinkLocalAddressing=ipv6
1250 ''',
12451251 'enyellow.network': ND_DHCP4 % 'enyellow',
12461252 'enblue.network': ND_DHCP4 % 'enblue'})
12471253
3131 wakeonlan: true
3232 dhcp4: n''')
3333
34 self.assert_networkd({'eth0.link': '[Match]\nOriginalName=eth0\n\n[Link]\nWakeOnLan=magic\n'})
34 self.assert_networkd({'eth0.link': '[Match]\nOriginalName=eth0\n\n[Link]\nWakeOnLan=magic\n',
35 'eth0.network': '''[Match]
36 Name=eth0
37
38 [Network]
39 LinkLocalAddressing=ipv6
40 '''})
3541 self.assert_networkd_udev(None)
3642 self.assert_nm(None, '''[keyfile]
3743 # devices managed by networkd
4854 mtu: 1280
4955 dhcp4: n''')
5056
51 self.assert_networkd({'eth1.link': '[Match]\nOriginalName=eth1\n\n[Link]\nWakeOnLan=off\nMTUBytes=1280\n'})
57 self.assert_networkd({'eth1.link': '[Match]\nOriginalName=eth1\n\n[Link]\nWakeOnLan=off\nMTUBytes=1280\n',
58 'eth1.network': '''[Match]
59 Name=eth1
60
61 [Network]
62 LinkLocalAddressing=ipv6
63 '''})
5264 self.assert_networkd_udev(None)
5365
5466 def test_eth_match_by_driver_rename(self):
6072 driver: ixgbe
6173 set-name: lom1''')
6274
63 self.assert_networkd({'def1.link': '[Match]\nDriver=ixgbe\n\n[Link]\nName=lom1\nWakeOnLan=off\n'})
75 self.assert_networkd({'def1.link': '[Match]\nDriver=ixgbe\n\n[Link]\nName=lom1\nWakeOnLan=off\n',
76 'def1.network': '''[Match]
77 Driver=ixgbe
78 Name=lom1
79
80 [Network]
81 LinkLocalAddressing=ipv6
82 '''})
6483 self.assert_networkd_udev({'def1.rules': (UDEV_NO_MAC_RULE % ('ixgbe', 'lom1'))})
6584 # NM cannot match by driver, so blacklisting needs to happen via udev
6685 self.assert_nm(None, None)
7594 macaddress: 11:22:33:44:55:66
7695 set-name: lom1''')
7796
78 self.assert_networkd({'def1.link': '[Match]\nMACAddress=11:22:33:44:55:66\n\n[Link]\nName=lom1\nWakeOnLan=off\n'})
97 self.assert_networkd({'def1.link': '[Match]\nMACAddress=11:22:33:44:55:66\n\n[Link]\nName=lom1\nWakeOnLan=off\n',
98 'def1.network': '''[Match]
99 MACAddress=11:22:33:44:55:66
100 Name=lom1
101
102 [Network]
103 LinkLocalAddressing=ipv6
104 '''})
79105 self.assert_networkd_udev({'def1.rules': (UDEV_MAC_RULE % ('?*', '11:22:33:44:55:66', 'lom1'))})
80106 self.assert_nm(None, '''[keyfile]
81107 # devices managed by networkd
2525 version: 2
2626 renderer: {}
2727 """.format(renderer)
28 config += '''
29 ethernets:
30 en1: {}
31 '''
3228
3329 if mode == "ip6gre" \
3430 or mode == "ip6ip6" \
427423 """[NetworkManager] Validate ISATAP tunnel generation"""
428424 config = prepare_config_for_mode('NetworkManager', 'isatap')
429425 self.generate(config)
430 self.assert_nm({'en1': '''[connection]
431 id=netplan-en1
432 type=ethernet
433 interface-name=en1
434
435 [ethernet]
436 wake-on-lan=0
437
438 [ipv4]
439 method=link-local
440
441 [ipv6]
442 method=ignore
443 ''',
444 'tun0': '''[connection]
426 self.assert_nm({'tun0': '''[connection]
445427 id=netplan-tun0
446428 type=ip-tunnel
447429 interface-name=tun0
464446 """[NetworkManager] Validate generation of SIT tunnels"""
465447 config = prepare_config_for_mode('NetworkManager', 'sit')
466448 self.generate(config)
467 self.assert_nm({'en1': '''[connection]
468 id=netplan-en1
469 type=ethernet
470 interface-name=en1
471
472 [ethernet]
473 wake-on-lan=0
474
475 [ipv4]
476 method=link-local
477
478 [ipv6]
479 method=ignore
480 ''',
481 'tun0': '''[connection]
449 self.assert_nm({'tun0': '''[connection]
482450 id=netplan-tun0
483451 type=ip-tunnel
484452 interface-name=tun0
560528 """[NetworkManager] Validate generation of VTI tunnels"""
561529 config = prepare_config_for_mode('NetworkManager', 'vti')
562530 self.generate(config)
563 self.assert_nm({'en1': '''[connection]
564 id=netplan-en1
565 type=ethernet
566 interface-name=en1
567
568 [ethernet]
569 wake-on-lan=0
570
571 [ipv4]
572 method=link-local
573
574 [ipv6]
575 method=ignore
576 ''',
577 'tun0': '''[connection]
531 self.assert_nm({'tun0': '''[connection]
578532 id=netplan-tun0
579533 type=ip-tunnel
580534 interface-name=tun0
597551 """[NetworkManager] Validate generation of VTI6 tunnels"""
598552 config = prepare_config_for_mode('NetworkManager', 'vti6')
599553 self.generate(config)
600 self.assert_nm({'en1': '''[connection]
601 id=netplan-en1
602 type=ethernet
603 interface-name=en1
604
605 [ethernet]
606 wake-on-lan=0
607
608 [ipv4]
609 method=link-local
610
611 [ipv6]
612 method=ignore
613 ''',
614 'tun0': '''[connection]
554 self.assert_nm({'tun0': '''[connection]
615555 id=netplan-tun0
616556 type=ip-tunnel
617557 interface-name=tun0
634574 """[NetworkManager] Validate generation of IP6IP6 tunnels"""
635575 config = prepare_config_for_mode('NetworkManager', 'ip6ip6')
636576 self.generate(config)
637 self.assert_nm({'en1': '''[connection]
638 id=netplan-en1
639 type=ethernet
640 interface-name=en1
641
642 [ethernet]
643 wake-on-lan=0
644
645 [ipv4]
646 method=link-local
647
648 [ipv6]
649 method=ignore
650 ''',
651 'tun0': '''[connection]
577 self.assert_nm({'tun0': '''[connection]
652578 id=netplan-tun0
653579 type=ip-tunnel
654580 interface-name=tun0
671597 """[NetworkManager] Validate generation of IPIP tunnels"""
672598 config = prepare_config_for_mode('NetworkManager', 'ipip')
673599 self.generate(config)
674 self.assert_nm({'en1': '''[connection]
675 id=netplan-en1
676 type=ethernet
677 interface-name=en1
678
679 [ethernet]
680 wake-on-lan=0
681
682 [ipv4]
683 method=link-local
684
685 [ipv6]
686 method=ignore
687 ''',
688 'tun0': '''[connection]
600 self.assert_nm({'tun0': '''[connection]
689601 id=netplan-tun0
690602 type=ip-tunnel
691603 interface-name=tun0
708620 """[NetworkManager] Validate generation of GRE tunnels"""
709621 config = prepare_config_for_mode('NetworkManager', 'gre')
710622 self.generate(config)
711 self.assert_nm({'en1': '''[connection]
712 id=netplan-en1
713 type=ethernet
714 interface-name=en1
715
716 [ethernet]
717 wake-on-lan=0
718
719 [ipv4]
720 method=link-local
721
722 [ipv6]
723 method=ignore
724 ''',
725 'tun0': '''[connection]
623 self.assert_nm({'tun0': '''[connection]
726624 id=netplan-tun0
727625 type=ip-tunnel
728626 interface-name=tun0
745643 """[NetworkManager] Validate generation of GRE tunnels with keys"""
746644 config = prepare_config_for_mode('NetworkManager', 'gre', key={'input': 1111, 'output': 5555})
747645 self.generate(config)
748 self.assert_nm({'en1': '''[connection]
749 id=netplan-en1
750 type=ethernet
751 interface-name=en1
752
753 [ethernet]
754 wake-on-lan=0
755
756 [ipv4]
757 method=link-local
758
759 [ipv6]
760 method=ignore
761 ''',
762 'tun0': '''[connection]
646 self.assert_nm({'tun0': '''[connection]
763647 id=netplan-tun0
764648 type=ip-tunnel
765649 interface-name=tun0
784668 """[NetworkManager] Validate generation of IP6GRE tunnels"""
785669 config = prepare_config_for_mode('NetworkManager', 'ip6gre')
786670 self.generate(config)
787 self.assert_nm({'en1': '''[connection]
788 id=netplan-en1
789 type=ethernet
790 interface-name=en1
791
792 [ethernet]
793 wake-on-lan=0
794
795 [ipv4]
796 method=link-local
797
798 [ipv6]
799 method=ignore
800 ''',
801 'tun0': '''[connection]
671 self.assert_nm({'tun0': '''[connection]
802672 id=netplan-tun0
803673 type=ip-tunnel
804674 interface-name=tun0
821691 """[NetworkManager] Validate generation of IP6GRE tunnels with key"""
822692 config = prepare_config_for_mode('NetworkManager', 'ip6gre', key='9999')
823693 self.generate(config)
824 self.assert_nm({'en1': '''[connection]
825 id=netplan-en1
826 type=ethernet
827 interface-name=en1
828
829 [ethernet]
830 wake-on-lan=0
831
832 [ipv4]
833 method=link-local
834
835 [ipv6]
836 method=ignore
837 ''',
838 'tun0': '''[connection]
694 self.assert_nm({'tun0': '''[connection]
839695 id=netplan-tun0
840696 type=ip-tunnel
841697 interface-name=tun0