diff options
-rw-r--r-- | Documentation/filesystems/nfs/nfsroot.txt | 35 | ||||
-rw-r--r-- | net/ipv4/ipconfig.c | 118 |
2 files changed, 136 insertions, 17 deletions
diff --git a/Documentation/filesystems/nfs/nfsroot.txt b/Documentation/filesystems/nfs/nfsroot.txt index a1030bea60d3..d2963123eb1c 100644 --- a/Documentation/filesystems/nfs/nfsroot.txt +++ b/Documentation/filesystems/nfs/nfsroot.txt | |||
@@ -5,6 +5,7 @@ Written 1996 by Gero Kuhlmann <gero@gkminix.han.de> | |||
5 | Updated 1997 by Martin Mares <mj@atrey.karlin.mff.cuni.cz> | 5 | Updated 1997 by Martin Mares <mj@atrey.karlin.mff.cuni.cz> |
6 | Updated 2006 by Nico Schottelius <nico-kernel-nfsroot@schottelius.org> | 6 | Updated 2006 by Nico Schottelius <nico-kernel-nfsroot@schottelius.org> |
7 | Updated 2006 by Horms <horms@verge.net.au> | 7 | Updated 2006 by Horms <horms@verge.net.au> |
8 | Updated 2018 by Chris Novakovic <chris@chrisn.me.uk> | ||
8 | 9 | ||
9 | 10 | ||
10 | 11 | ||
@@ -79,7 +80,7 @@ nfsroot=[<server-ip>:]<root-dir>[,<nfs-options>] | |||
79 | 80 | ||
80 | 81 | ||
81 | ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>: | 82 | ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>: |
82 | <dns0-ip>:<dns1-ip> | 83 | <dns0-ip>:<dns1-ip>:<ntp0-ip> |
83 | 84 | ||
84 | This parameter tells the kernel how to configure IP addresses of devices | 85 | This parameter tells the kernel how to configure IP addresses of devices |
85 | and also how to set up the IP routing table. It was originally called | 86 | and also how to set up the IP routing table. It was originally called |
@@ -178,9 +179,18 @@ ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>: | |||
178 | <dns1-ip> IP address of secondary nameserver. | 179 | <dns1-ip> IP address of secondary nameserver. |
179 | See <dns0-ip>. | 180 | See <dns0-ip>. |
180 | 181 | ||
181 | After configuration (whether manual or automatic) is complete, a file is | 182 | <ntp0-ip> IP address of a Network Time Protocol (NTP) server. |
182 | created at /proc/net/pnp in the following format; lines are omitted if | 183 | Value is exported to /proc/net/ipconfig/ntp_servers, but is |
183 | their respective value is empty following configuration. | 184 | otherwise unused (see below). |
185 | |||
186 | Default: None if not using autoconfiguration; determined | ||
187 | automatically if using autoconfiguration. | ||
188 | |||
189 | After configuration (whether manual or automatic) is complete, two files | ||
190 | are created in the following format; lines are omitted if their respective | ||
191 | value is empty following configuration: | ||
192 | |||
193 | - /proc/net/pnp: | ||
184 | 194 | ||
185 | #PROTO: <DHCP|BOOTP|RARP|MANUAL> (depending on configuration method) | 195 | #PROTO: <DHCP|BOOTP|RARP|MANUAL> (depending on configuration method) |
186 | domain <dns-domain> (if autoconfigured, the DNS domain) | 196 | domain <dns-domain> (if autoconfigured, the DNS domain) |
@@ -189,13 +199,26 @@ ip=<client-ip>:<server-ip>:<gw-ip>:<netmask>:<hostname>:<device>:<autoconf>: | |||
189 | nameserver <dns2-ip> (tertiary name server IP) | 199 | nameserver <dns2-ip> (tertiary name server IP) |
190 | bootserver <server-ip> (NFS server IP) | 200 | bootserver <server-ip> (NFS server IP) |
191 | 201 | ||
192 | <dns-domain> and <dns2-ip> are requested during autoconfiguration; they | 202 | - /proc/net/ipconfig/ntp_servers: |
193 | cannot be specified as part of the "ip=" kernel command line parameter. | 203 | |
204 | <ntp0-ip> (NTP server IP) | ||
205 | <ntp1-ip> (NTP server IP) | ||
206 | <ntp2-ip> (NTP server IP) | ||
207 | |||
208 | <dns-domain> and <dns2-ip> (in /proc/net/pnp) and <ntp1-ip> and <ntp2-ip> | ||
209 | (in /proc/net/ipconfig/ntp_servers) are requested during autoconfiguration; | ||
210 | they cannot be specified as part of the "ip=" kernel command line parameter. | ||
194 | 211 | ||
195 | Because the "domain" and "nameserver" options are recognised by DNS | 212 | Because the "domain" and "nameserver" options are recognised by DNS |
196 | resolvers, /etc/resolv.conf is often linked to /proc/net/pnp on systems | 213 | resolvers, /etc/resolv.conf is often linked to /proc/net/pnp on systems |
197 | that use an NFS root filesystem. | 214 | that use an NFS root filesystem. |
198 | 215 | ||
216 | Note that the kernel will not synchronise the system time with any NTP | ||
217 | servers it discovers; this is the responsibility of a user space process | ||
218 | (e.g. an initrd/initramfs script that passes the IP addresses listed in | ||
219 | /proc/net/ipconfig/ntp_servers to an NTP client before mounting the real | ||
220 | root filesystem if it is on NFS). | ||
221 | |||
199 | 222 | ||
200 | nfsrootdebug | 223 | nfsrootdebug |
201 | 224 | ||
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 9abf833f3a99..d839d74853fc 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c | |||
@@ -28,6 +28,9 @@ | |||
28 | * | 28 | * |
29 | * Multiple Nameservers in /proc/net/pnp | 29 | * Multiple Nameservers in /proc/net/pnp |
30 | * -- Josef Siemes <jsiemes@web.de>, Aug 2002 | 30 | * -- Josef Siemes <jsiemes@web.de>, Aug 2002 |
31 | * | ||
32 | * NTP servers in /proc/net/ipconfig/ntp_servers | ||
33 | * -- Chris Novakovic <chris@chrisn.me.uk>, April 2018 | ||
31 | */ | 34 | */ |
32 | 35 | ||
33 | #include <linux/types.h> | 36 | #include <linux/types.h> |
@@ -93,6 +96,7 @@ | |||
93 | #define CONF_TIMEOUT_MAX (HZ*30) /* Maximum allowed timeout */ | 96 | #define CONF_TIMEOUT_MAX (HZ*30) /* Maximum allowed timeout */ |
94 | #define CONF_NAMESERVERS_MAX 3 /* Maximum number of nameservers | 97 | #define CONF_NAMESERVERS_MAX 3 /* Maximum number of nameservers |
95 | - '3' from resolv.h */ | 98 | - '3' from resolv.h */ |
99 | #define CONF_NTP_SERVERS_MAX 3 /* Maximum number of NTP servers */ | ||
96 | 100 | ||
97 | #define NONE cpu_to_be32(INADDR_NONE) | 101 | #define NONE cpu_to_be32(INADDR_NONE) |
98 | #define ANY cpu_to_be32(INADDR_ANY) | 102 | #define ANY cpu_to_be32(INADDR_ANY) |
@@ -152,6 +156,7 @@ static int ic_proto_used; /* Protocol used, if any */ | |||
152 | #define ic_proto_used 0 | 156 | #define ic_proto_used 0 |
153 | #endif | 157 | #endif |
154 | static __be32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */ | 158 | static __be32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */ |
159 | static __be32 ic_ntp_servers[CONF_NTP_SERVERS_MAX]; /* NTP server IP addresses */ | ||
155 | static u8 ic_domain[64]; /* DNS (not NIS) domain name */ | 160 | static u8 ic_domain[64]; /* DNS (not NIS) domain name */ |
156 | 161 | ||
157 | /* | 162 | /* |
@@ -579,6 +584,15 @@ static inline void __init ic_nameservers_predef(void) | |||
579 | ic_nameservers[i] = NONE; | 584 | ic_nameservers[i] = NONE; |
580 | } | 585 | } |
581 | 586 | ||
587 | /* Predefine NTP servers */ | ||
588 | static inline void __init ic_ntp_servers_predef(void) | ||
589 | { | ||
590 | int i; | ||
591 | |||
592 | for (i = 0; i < CONF_NTP_SERVERS_MAX; i++) | ||
593 | ic_ntp_servers[i] = NONE; | ||
594 | } | ||
595 | |||
582 | /* | 596 | /* |
583 | * DHCP/BOOTP support. | 597 | * DHCP/BOOTP support. |
584 | */ | 598 | */ |
@@ -674,6 +688,7 @@ ic_dhcp_init_options(u8 *options, struct ic_device *d) | |||
674 | 17, /* Boot path */ | 688 | 17, /* Boot path */ |
675 | 26, /* MTU */ | 689 | 26, /* MTU */ |
676 | 40, /* NIS domain name */ | 690 | 40, /* NIS domain name */ |
691 | 42, /* NTP servers */ | ||
677 | }; | 692 | }; |
678 | 693 | ||
679 | *e++ = 55; /* Parameter request list */ | 694 | *e++ = 55; /* Parameter request list */ |
@@ -753,12 +768,13 @@ static void __init ic_bootp_init_ext(u8 *e) | |||
753 | */ | 768 | */ |
754 | static inline void __init ic_bootp_init(void) | 769 | static inline void __init ic_bootp_init(void) |
755 | { | 770 | { |
756 | /* Re-initialise all name servers to NONE, in case any were set via the | 771 | /* Re-initialise all name servers and NTP servers to NONE, in case any |
757 | * "ip=" or "nfsaddrs=" kernel command line parameters: any IP addresses | 772 | * were set via the "ip=" or "nfsaddrs=" kernel command line parameters: |
758 | * specified there will already have been decoded but are no longer | 773 | * any IP addresses specified there will already have been decoded but |
759 | * needed | 774 | * are no longer needed |
760 | */ | 775 | */ |
761 | ic_nameservers_predef(); | 776 | ic_nameservers_predef(); |
777 | ic_ntp_servers_predef(); | ||
762 | 778 | ||
763 | dev_add_pack(&bootp_packet_type); | 779 | dev_add_pack(&bootp_packet_type); |
764 | } | 780 | } |
@@ -922,6 +938,15 @@ static void __init ic_do_bootp_ext(u8 *ext) | |||
922 | ic_bootp_string(utsname()->domainname, ext+1, *ext, | 938 | ic_bootp_string(utsname()->domainname, ext+1, *ext, |
923 | __NEW_UTS_LEN); | 939 | __NEW_UTS_LEN); |
924 | break; | 940 | break; |
941 | case 42: /* NTP servers */ | ||
942 | servers = *ext / 4; | ||
943 | if (servers > CONF_NTP_SERVERS_MAX) | ||
944 | servers = CONF_NTP_SERVERS_MAX; | ||
945 | for (i = 0; i < servers; i++) { | ||
946 | if (ic_ntp_servers[i] == NONE) | ||
947 | memcpy(&ic_ntp_servers[i], ext+1+4*i, 4); | ||
948 | } | ||
949 | break; | ||
925 | } | 950 | } |
926 | } | 951 | } |
927 | 952 | ||
@@ -1268,6 +1293,7 @@ static int __init ic_dynamic(void) | |||
1268 | 1293 | ||
1269 | #ifdef CONFIG_PROC_FS | 1294 | #ifdef CONFIG_PROC_FS |
1270 | 1295 | ||
1296 | /* Name servers: */ | ||
1271 | static int pnp_seq_show(struct seq_file *seq, void *v) | 1297 | static int pnp_seq_show(struct seq_file *seq, void *v) |
1272 | { | 1298 | { |
1273 | int i; | 1299 | int i; |
@@ -1306,7 +1332,7 @@ static const struct file_operations pnp_seq_fops = { | |||
1306 | }; | 1332 | }; |
1307 | 1333 | ||
1308 | /* Create the /proc/net/ipconfig directory */ | 1334 | /* Create the /proc/net/ipconfig directory */ |
1309 | static int ipconfig_proc_net_init(void) | 1335 | static int __init ipconfig_proc_net_init(void) |
1310 | { | 1336 | { |
1311 | ipconfig_dir = proc_net_mkdir(&init_net, "ipconfig", init_net.proc_net); | 1337 | ipconfig_dir = proc_net_mkdir(&init_net, "ipconfig", init_net.proc_net); |
1312 | if (!ipconfig_dir) | 1338 | if (!ipconfig_dir) |
@@ -1314,6 +1340,52 @@ static int ipconfig_proc_net_init(void) | |||
1314 | 1340 | ||
1315 | return 0; | 1341 | return 0; |
1316 | } | 1342 | } |
1343 | |||
1344 | /* Create a new file under /proc/net/ipconfig */ | ||
1345 | static int ipconfig_proc_net_create(const char *name, | ||
1346 | const struct file_operations *fops) | ||
1347 | { | ||
1348 | char *pname; | ||
1349 | struct proc_dir_entry *p; | ||
1350 | |||
1351 | if (!ipconfig_dir) | ||
1352 | return -ENOMEM; | ||
1353 | |||
1354 | pname = kasprintf(GFP_KERNEL, "%s%s", "ipconfig/", name); | ||
1355 | if (!pname) | ||
1356 | return -ENOMEM; | ||
1357 | |||
1358 | p = proc_create(pname, 0444, init_net.proc_net, fops); | ||
1359 | kfree(pname); | ||
1360 | if (!p) | ||
1361 | return -ENOMEM; | ||
1362 | |||
1363 | return 0; | ||
1364 | } | ||
1365 | |||
1366 | /* Write NTP server IP addresses to /proc/net/ipconfig/ntp_servers */ | ||
1367 | static int ntp_servers_seq_show(struct seq_file *seq, void *v) | ||
1368 | { | ||
1369 | int i; | ||
1370 | |||
1371 | for (i = 0; i < CONF_NTP_SERVERS_MAX; i++) { | ||
1372 | if (ic_ntp_servers[i] != NONE) | ||
1373 | seq_printf(seq, "%pI4\n", &ic_ntp_servers[i]); | ||
1374 | } | ||
1375 | return 0; | ||
1376 | } | ||
1377 | |||
1378 | static int ntp_servers_seq_open(struct inode *inode, struct file *file) | ||
1379 | { | ||
1380 | return single_open(file, ntp_servers_seq_show, NULL); | ||
1381 | } | ||
1382 | |||
1383 | static const struct file_operations ntp_servers_seq_fops = { | ||
1384 | .open = ntp_servers_seq_open, | ||
1385 | .read = seq_read, | ||
1386 | .llseek = seq_lseek, | ||
1387 | .release = single_release, | ||
1388 | }; | ||
1317 | #endif /* CONFIG_PROC_FS */ | 1389 | #endif /* CONFIG_PROC_FS */ |
1318 | 1390 | ||
1319 | /* | 1391 | /* |
@@ -1388,17 +1460,20 @@ static int __init ip_auto_config(void) | |||
1388 | int err; | 1460 | int err; |
1389 | unsigned int i; | 1461 | unsigned int i; |
1390 | 1462 | ||
1391 | /* Initialise all name servers to NONE (but only if the "ip=" or | 1463 | /* Initialise all name servers and NTP servers to NONE (but only if the |
1392 | * "nfsaddrs=" kernel command line parameters weren't decoded, otherwise | 1464 | * "ip=" or "nfsaddrs=" kernel command line parameters weren't decoded, |
1393 | * we'll overwrite the IP addresses specified there) | 1465 | * otherwise we'll overwrite the IP addresses specified there) |
1394 | */ | 1466 | */ |
1395 | if (ic_set_manually == 0) | 1467 | if (ic_set_manually == 0) { |
1396 | ic_nameservers_predef(); | 1468 | ic_nameservers_predef(); |
1469 | ic_ntp_servers_predef(); | ||
1470 | } | ||
1397 | 1471 | ||
1398 | #ifdef CONFIG_PROC_FS | 1472 | #ifdef CONFIG_PROC_FS |
1399 | proc_create("pnp", 0444, init_net.proc_net, &pnp_seq_fops); | 1473 | proc_create("pnp", 0444, init_net.proc_net, &pnp_seq_fops); |
1400 | 1474 | ||
1401 | ipconfig_proc_net_init(); | 1475 | if (ipconfig_proc_net_init() == 0) |
1476 | ipconfig_proc_net_create("ntp_servers", &ntp_servers_seq_fops); | ||
1402 | #endif /* CONFIG_PROC_FS */ | 1477 | #endif /* CONFIG_PROC_FS */ |
1403 | 1478 | ||
1404 | if (!ic_enable) | 1479 | if (!ic_enable) |
@@ -1523,6 +1598,19 @@ static int __init ip_auto_config(void) | |||
1523 | if (i + 1 == CONF_NAMESERVERS_MAX) | 1598 | if (i + 1 == CONF_NAMESERVERS_MAX) |
1524 | pr_cont("\n"); | 1599 | pr_cont("\n"); |
1525 | } | 1600 | } |
1601 | /* NTP servers (if any): */ | ||
1602 | for (i = 0; i < CONF_NTP_SERVERS_MAX; i++) { | ||
1603 | if (ic_ntp_servers[i] != NONE) { | ||
1604 | if (i == 0) | ||
1605 | pr_info(" ntpserver%u=%pI4", | ||
1606 | i, &ic_ntp_servers[i]); | ||
1607 | else | ||
1608 | pr_cont(", ntpserver%u=%pI4", | ||
1609 | i, &ic_ntp_servers[i]); | ||
1610 | } | ||
1611 | if (i + 1 == CONF_NTP_SERVERS_MAX) | ||
1612 | pr_cont("\n"); | ||
1613 | } | ||
1526 | #endif /* !SILENT */ | 1614 | #endif /* !SILENT */ |
1527 | 1615 | ||
1528 | /* | 1616 | /* |
@@ -1620,8 +1708,9 @@ static int __init ip_auto_config_setup(char *addrs) | |||
1620 | return 1; | 1708 | return 1; |
1621 | } | 1709 | } |
1622 | 1710 | ||
1623 | /* Initialise all name servers to NONE */ | 1711 | /* Initialise all name servers and NTP servers to NONE */ |
1624 | ic_nameservers_predef(); | 1712 | ic_nameservers_predef(); |
1713 | ic_ntp_servers_predef(); | ||
1625 | 1714 | ||
1626 | /* Parse string for static IP assignment. */ | 1715 | /* Parse string for static IP assignment. */ |
1627 | ip = addrs; | 1716 | ip = addrs; |
@@ -1680,6 +1769,13 @@ static int __init ip_auto_config_setup(char *addrs) | |||
1680 | ic_nameservers[1] = NONE; | 1769 | ic_nameservers[1] = NONE; |
1681 | } | 1770 | } |
1682 | break; | 1771 | break; |
1772 | case 9: | ||
1773 | if (CONF_NTP_SERVERS_MAX >= 1) { | ||
1774 | ic_ntp_servers[0] = in_aton(ip); | ||
1775 | if (ic_ntp_servers[0] == ANY) | ||
1776 | ic_ntp_servers[0] = NONE; | ||
1777 | } | ||
1778 | break; | ||
1683 | } | 1779 | } |
1684 | } | 1780 | } |
1685 | ip = cp; | 1781 | ip = cp; |