OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [nfs/] [nfsroot.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1628 jcastillo
/*
2
 *  linux/fs/nfs/nfsroot.c -- version 2.3
3
 *
4
 *  Copyright (C) 1995, 1996  Gero Kuhlmann <gero@gkminix.han.de>
5
 *
6
 *  For parts of this file:
7
 *  Copyright (C) 1996  Martin Mares <mj@k332.feld.cvut.cz>
8
 *
9
 *  Allow an NFS filesystem to be mounted as root. The way this works is:
10
 *     (1) Determine the local IP address via RARP or BOOTP or from the
11
 *         kernel command line.
12
 *     (2) Handle RPC negotiation with the system which replied to RARP or
13
 *         was reported as a boot server by BOOTP or manually.
14
 *     (3) The actual mounting is done later, when init() is running.
15
 *
16
 *
17
 *      Changes:
18
 *
19
 *      R. Drahtmueller :       Set IFF_MULTICAST in dev->flags if applicable.
20
 *      Alan Cox        :       Removed get_address name clash with FPU.
21
 *      Alan Cox        :       Reformatted a bit.
22
 *      Gero Kuhlmann   :       Code cleanup
23
 *      Michael Rausch  :       Fixed recognition of an incoming RARP answer.
24
 *      Martin Mares    : (2.0) Auto-configuration via BOOTP supported.
25
 *      Martin Mares    :       Manual selection of interface & BOOTP/RARP.
26
 *      Martin Mares    :       Using network routes instead of host routes,
27
 *                              allowing the default configuration to be used
28
 *                              for normal operation of the host.
29
 *      Martin Mares    :       Randomized timer with exponential backoff
30
 *                              installed to minimize network congestion.
31
 *      Martin Mares    :       Code cleanup.
32
 *      Martin Mares    : (2.1) BOOTP and RARP made configuration options.
33
 *      Martin Mares    :       Server hostname generation fixed.
34
 *      Gerd Knorr      :       Fixed wired inode handling
35
 *      Martin Mares    : (2.2) "0.0.0.0" addresses from command line ignored.
36
 *      Martin Mares    :       RARP replies not tested for server address.
37
 *      Gero Kuhlmann   : (2.3) Some bug fixes and code cleanup again (please
38
 *                              send me your new patches _before_ bothering
39
 *                              Linus so that I don' always have to cleanup
40
 *                              _afterwards_ - thanks)
41
 *      Gero Kuhlmann   :       Last changes of Martin Mares undone.
42
 *      Gero Kuhlmann   :       RARP replies are tested for specified server
43
 *                              again. However, it's now possible to have
44
 *                              different RARP and NFS servers.
45
 *      Gero Kuhlmann   :       "0.0.0.0" addresses from command line are
46
 *                              now mapped to INADDR_NONE.
47
 *      Gero Kuhlmann   :       Fixed a bug which prevented BOOTP path name
48
 *                              from being used (thanks to Leo Spiekman)
49
 *      Andy Walker     :       Allow to specify the NFS server in nfs_root
50
 *                              without giving a path name
51
 *      Swen Th=FCmmler :       Allow to specify the NFS options in nfs_root
52
 *                              without giving a path name. Fix BOOTP request
53
 *                              for domainname (domainname is NIS domain, not
54
 *                              DNS domain!). Skip dummy devices for BOOTP.
55
 *      Jacek Zapala    :       Fixed a bug which prevented server-ip address
56
 *                              from nfsroot parameter from being used.
57
 *
58
 */
59
 
60
 
61
/* Define this to allow debugging output */
62
#undef NFSROOT_DEBUG
63
#undef NFSROOT_BOOTP_DEBUG
64
 
65
 
66
#include <linux/config.h>
67
#include <linux/types.h>
68
#include <linux/string.h>
69
#include <linux/kernel.h>
70
#include <linux/sched.h>
71
#include <linux/fs.h>
72
#include <linux/random.h>
73
#include <linux/fcntl.h>
74
 
75
#include <asm/param.h>
76
#include <linux/utsname.h>
77
#include <linux/in.h>
78
#include <linux/if.h>
79
#include <linux/inet.h>
80
#include <linux/net.h>
81
#include <linux/netdevice.h>
82
#include <linux/if_arp.h>
83
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
84
#include <net/ax25.h>   /* For AX25_P_IP */
85
#endif
86
#include <linux/skbuff.h>
87
#include <linux/socket.h>
88
#include <linux/route.h>
89
#include <linux/nfs.h>
90
#include <linux/nfs_fs.h>
91
#include <linux/nfs_mount.h>
92
#include <linux/in.h>
93
#include <net/route.h>
94
#include <net/sock.h>
95
 
96
#include <asm/segment.h>
97
 
98
/* Range of privileged ports */
99
#define STARTPORT       600
100
#define ENDPORT         1023
101
#define NPORTS          (ENDPORT - STARTPORT + 1)
102
 
103
 
104
/* Define the timeout for waiting for a RARP/BOOTP reply */
105
#define CONF_BASE_TIMEOUT       (HZ*5)  /* Initial timeout: 5 seconds */
106
#define CONF_RETRIES            10      /* 10 retries */
107
#define CONF_TIMEOUT_RANDOM     (HZ)    /* Maximum amount of randomization */
108
#define CONF_TIMEOUT_MULT       *5/4    /* Speed of timeout growth */
109
#define CONF_TIMEOUT_MAX        (HZ*30) /* Maximum allowed timeout */
110
 
111
 
112
/* List of open devices */
113
struct open_dev {
114
        struct device *dev;
115
        unsigned short old_flags;
116
        struct open_dev *next;
117
};
118
 
119
static struct open_dev *open_base = NULL;
120
 
121
 
122
/* IP configuration */
123
static struct device *root_dev = NULL;  /* Device selected for booting */
124
static char user_dev_name[IFNAMSIZ];    /* Name of user-selected boot device */
125
static struct sockaddr_in myaddr;       /* My IP address */
126
static struct sockaddr_in server;       /* Server IP address */
127
static struct sockaddr_in gateway;      /* Gateway IP address */
128
static struct sockaddr_in netmask;      /* Netmask for local subnet */
129
 
130
 
131
/* BOOTP/RARP variables */
132
static int bootp_flag;                  /* User said: Use BOOTP! */
133
static int rarp_flag;                   /* User said: Use RARP! */
134
static int bootp_dev_count = 0;          /* Number of devices allowing BOOTP */
135
static int rarp_dev_count = 0;           /* Number of devices allowing RARP */
136
static struct sockaddr_in rarp_serv;    /* IP address of RARP server */
137
 
138
#if defined(CONFIG_RNFS_BOOTP) || defined(CONFIG_RNFS_RARP)
139
#define CONFIG_RNFS_DYNAMIC             /* Enable dynamic IP config */
140
static volatile int pkt_arrived;        /* BOOTP/RARP packet detected */
141
 
142
#define ARRIVED_BOOTP   1
143
#define ARRIVED_RARP    2
144
#endif
145
 
146
 
147
/* NFS-related data */
148
static struct nfs_mount_data nfs_data;          /* NFS mount info */
149
static char nfs_path[NFS_MAXPATHLEN] = "";      /* Name of directory to mount */
150
static int nfs_port;                            /* Port to connect to for NFS */
151
 
152
 
153
/* Yes, we use sys_socket, but there's no include file for it */
154
extern asmlinkage int sys_socket(int family, int type, int protocol);
155
 
156
 
157
 
158
/***************************************************************************
159
 
160
                        Device Handling Subroutines
161
 
162
 ***************************************************************************/
163
 
164
/*
165
 * Setup and initialize all network devices. If there is a user-preferred
166
 * interface, ignore all other interfaces.
167
 */
168
static int root_dev_open(void)
169
{
170
        struct open_dev *openp, **last;
171
        struct device *dev;
172
        unsigned short old_flags;
173
 
174
        last = &open_base;
175
        for (dev = dev_base; dev != NULL; dev = dev->next) {
176
                if (dev->type < ARPHRD_SLIP &&
177
                    dev->family == AF_INET &&
178
                    !(dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) &&
179
                    (0 != strncmp(dev->name, "dummy", 5)) &&
180
                    (!user_dev_name[0] || !strcmp(dev->name, user_dev_name))) {
181
                        /* First up the interface */
182
                        old_flags = dev->flags;
183
#ifdef CONFIG_IP_MULTICAST
184
                        dev->flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING | IFF_MULTICAST;
185
#else
186
                        dev->flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING;
187
#endif
188
                        if (!(old_flags & IFF_UP) && dev_open(dev)) {
189
                                dev->flags = old_flags;
190
                                continue;
191
                        }
192
                        openp = (struct open_dev *) kmalloc(sizeof(struct open_dev),
193
                                                GFP_ATOMIC);
194
                        if (openp == NULL)
195
                                continue;
196
                        openp->dev = dev;
197
                        openp->old_flags = old_flags;
198
                        *last = openp;
199
                        last = &openp->next;
200
                        bootp_dev_count++;
201
                        if (!(dev->flags & IFF_NOARP))
202
                                rarp_dev_count++;
203
#ifdef NFSROOT_DEBUG
204
                        printk(KERN_NOTICE "Root-NFS: Opened %s\n", dev->name);
205
#endif
206
                }
207
        }
208
        *last = NULL;
209
 
210
        if (!bootp_dev_count && !rarp_dev_count) {
211
                printk(KERN_ERR "Root-NFS: Unable to open at least one network device\n");
212
                return -1;
213
        }
214
        return 0;
215
}
216
 
217
 
218
/*
219
 *  Restore the state of all devices. However, keep the root device open
220
 *  for the upcoming mount.
221
 */
222
static void root_dev_close(void)
223
{
224
        struct open_dev *openp;
225
        struct open_dev *nextp;
226
 
227
        openp = open_base;
228
        while (openp != NULL) {
229
                nextp = openp->next;
230
                openp->next = NULL;
231
                if (openp->dev != root_dev) {
232
                        if (!(openp->old_flags & IFF_UP))
233
                                dev_close(openp->dev);
234
                        openp->dev->flags = openp->old_flags;
235
                }
236
                kfree_s(openp, sizeof(struct open_dev));
237
                openp = nextp;
238
        }
239
}
240
 
241
 
242
 
243
/***************************************************************************
244
 
245
                              RARP Subroutines
246
 
247
 ***************************************************************************/
248
 
249
#ifdef CONFIG_RNFS_RARP
250
 
251
extern void arp_send(int type, int ptype, unsigned long target_ip,
252
                     struct device *dev, unsigned long src_ip,
253
                     unsigned char *dest_hw, unsigned char *src_hw,
254
                     unsigned char *target_hw);
255
 
256
static int root_rarp_recv(struct sk_buff *skb, struct device *dev,
257
                          struct packet_type *pt);
258
 
259
 
260
static struct packet_type rarp_packet_type = {
261
        0,                       /* Should be: __constant_htons(ETH_P_RARP)
262
                                 * - but this _doesn't_ come out constant! */
263
        NULL,                   /* Listen to all devices */
264
        root_rarp_recv,
265
        NULL,
266
        NULL
267
};
268
 
269
 
270
/*
271
 *  Register the packet type for RARP
272
 */
273
static void root_rarp_open(void)
274
{
275
        rarp_packet_type.type = htons(ETH_P_RARP);
276
        dev_add_pack(&rarp_packet_type);
277
}
278
 
279
 
280
/*
281
 *  Deregister the RARP packet type
282
 */
283
static void root_rarp_close(void)
284
{
285
        rarp_packet_type.type = htons(ETH_P_RARP);
286
        dev_remove_pack(&rarp_packet_type);
287
}
288
 
289
 
290
/*
291
 *  Receive RARP packets.
292
 */
293
static int root_rarp_recv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
294
{
295
        struct arphdr *rarp = (struct arphdr *)skb->h.raw;
296
        unsigned char *rarp_ptr = (unsigned char *) (rarp + 1);
297
        unsigned long sip, tip;
298
        unsigned char *sha, *tha;               /* s for "source", t for "target" */
299
 
300
        /* If this test doesn't pass, it's not IP, or we should ignore it anyway */
301
        if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd)) {
302
                kfree_skb(skb, FREE_READ);
303
                return 0;
304
        }
305
 
306
        /* If it's not a RARP reply, delete it. */
307
        if (rarp->ar_op != htons(ARPOP_RREPLY)) {
308
                kfree_skb(skb, FREE_READ);
309
                return 0;
310
        }
311
 
312
        /* If it's not ethernet or AX25, delete it. */
313
        if ((rarp->ar_pro != htons(ETH_P_IP) && dev->type != ARPHRD_AX25) ||
314
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
315
           (rarp->ar_pro != htons(AX25_P_IP) && dev->type == ARPHRD_AX25) ||
316
#endif
317
            rarp->ar_pln != 4) {
318
                kfree_skb(skb, FREE_READ);
319
                return 0;
320
        }
321
 
322
        /* Extract variable width fields */
323
        sha = rarp_ptr;
324
        rarp_ptr += dev->addr_len;
325
        memcpy(&sip, rarp_ptr, 4);
326
        rarp_ptr += 4;
327
        tha = rarp_ptr;
328
        rarp_ptr += dev->addr_len;
329
        memcpy(&tip, rarp_ptr, 4);
330
 
331
        /* Discard packets which are not meant for us. */
332
        if (memcmp(tha, dev->dev_addr, dev->addr_len)) {
333
                kfree_skb(skb, FREE_READ);
334
                return 0;
335
        }
336
        /* Discard packets which are not from specified server. */
337
        if (rarp_flag && !bootp_flag &&
338
            rarp_serv.sin_addr.s_addr != INADDR_NONE &&
339
            rarp_serv.sin_addr.s_addr != sip) {
340
                kfree_skb(skb, FREE_READ);
341
                return 0;
342
        }
343
 
344
        /*
345
         * The packet is what we were looking for. Setup the global
346
         * variables.
347
         */
348
        cli();
349
        if (pkt_arrived) {
350
                sti();
351
                kfree_skb(skb, FREE_READ);
352
                return 0;
353
        }
354
        pkt_arrived = ARRIVED_RARP;
355
        sti();
356
        root_dev = dev;
357
 
358
        if (myaddr.sin_addr.s_addr == INADDR_NONE) {
359
                myaddr.sin_family = dev->family;
360
                myaddr.sin_addr.s_addr = tip;
361
        }
362
        if (server.sin_addr.s_addr == INADDR_NONE) {
363
                server.sin_family = dev->family;
364
                server.sin_addr.s_addr = sip;
365
        }
366
        kfree_skb(skb, FREE_READ);
367
        return 0;
368
}
369
 
370
 
371
/*
372
 *  Send RARP request packet over all devices which allow RARP.
373
 */
374
static void root_rarp_send(void)
375
{
376
        struct open_dev *openp;
377
        struct device *dev;
378
        int num = 0;
379
 
380
        for (openp = open_base; openp != NULL; openp = openp->next) {
381
                dev = openp->dev;
382
                if (!(dev->flags & IFF_NOARP)) {
383
                        arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,
384
                                 dev->dev_addr, dev->dev_addr);
385
                        num++;
386
                }
387
        }
388
}
389
#endif
390
 
391
 
392
 
393
/***************************************************************************
394
 
395
                             BOOTP Subroutines
396
 
397
 ***************************************************************************/
398
 
399
#ifdef CONFIG_RNFS_BOOTP
400
 
401
static struct device *bootp_dev = NULL; /* Device selected as best BOOTP target */
402
 
403
static int bootp_xmit_fd = -1;          /* Socket descriptor for transmit */
404
static struct socket *bootp_xmit_sock;  /* The socket itself */
405
static int bootp_recv_fd = -1;          /* Socket descriptor for receive */
406
static struct socket *bootp_recv_sock;  /* The socket itself */
407
 
408
struct bootp_pkt {              /* BOOTP packet format */
409
        u8 op;                  /* 1=request, 2=reply */
410
        u8 htype;               /* HW address type */
411
        u8 hlen;                /* HW address length */
412
        u8 hops;                /* Used only by gateways */
413
        u32 xid;                /* Transaction ID */
414
        u16 secs;               /* Seconds since we started */
415
        u16 flags;              /* Just what is says */
416
        u32 client_ip;          /* Client's IP address if known */
417
        u32 your_ip;            /* Assigned IP address */
418
        u32 server_ip;          /* Server's IP address */
419
        u32 relay_ip;           /* IP address of BOOTP relay */
420
        u8 hw_addr[16];         /* Client's HW address */
421
        u8 serv_name[64];       /* Server host name */
422
        u8 boot_file[128];      /* Name of boot file */
423
        u8 vendor_area[128];    /* Area for extensions */
424
};
425
 
426
#define BOOTP_REQUEST 1
427
#define BOOTP_REPLY 2
428
 
429
static struct bootp_pkt *xmit_bootp;    /* Packet being transmitted */
430
static struct bootp_pkt *recv_bootp;    /* Packet being received */
431
 
432
static int bootp_have_route = 0; /* BOOTP route installed */
433
 
434
 
435
/*
436
 *  Free BOOTP packet buffers
437
 */
438
static void root_free_bootp(void)
439
{
440
        if (xmit_bootp) {
441
                kfree_s(xmit_bootp, sizeof(struct bootp_pkt));
442
                xmit_bootp = NULL;
443
        }
444
        if (recv_bootp) {
445
                kfree_s(recv_bootp, sizeof(struct bootp_pkt));
446
                recv_bootp = NULL;
447
        }
448
}
449
 
450
 
451
/*
452
 *  Allocate memory for BOOTP packet buffers
453
 */
454
static inline int root_alloc_bootp(void)
455
{
456
        if (!(xmit_bootp = kmalloc(sizeof(struct bootp_pkt), GFP_KERNEL)) ||
457
            !(recv_bootp = kmalloc(sizeof(struct bootp_pkt), GFP_KERNEL))) {
458
                printk("BOOTP: Out of memory!");
459
                return -1;
460
        }
461
        return 0;
462
}
463
 
464
 
465
/*
466
 *  Create default route for BOOTP sending
467
 */
468
static int root_add_bootp_route(void)
469
{
470
        struct rtentry route;
471
 
472
        memset(&route, 0, sizeof(route));
473
        route.rt_dev = bootp_dev->name;
474
        route.rt_mss = bootp_dev->mtu;
475
        route.rt_flags = RTF_UP;
476
        ((struct sockaddr_in *) &(route.rt_dst)) -> sin_addr.s_addr = 0;
477
        ((struct sockaddr_in *) &(route.rt_dst)) -> sin_family = AF_INET;
478
        ((struct sockaddr_in *) &(route.rt_genmask)) -> sin_addr.s_addr = 0;
479
        ((struct sockaddr_in *) &(route.rt_genmask)) -> sin_family = AF_INET;
480
        if (ip_rt_new(&route)) {
481
                printk(KERN_ERR "BOOTP: Adding of route failed!\n");
482
                return -1;
483
        }
484
        bootp_have_route = 1;
485
        return 0;
486
}
487
 
488
 
489
/*
490
 *  Delete default route for BOOTP sending
491
 */
492
static int root_del_bootp_route(void)
493
{
494
        struct rtentry route;
495
 
496
        if (!bootp_have_route)
497
                return 0;
498
        memset(&route, 0, sizeof(route));
499
        ((struct sockaddr_in *) &(route.rt_dst)) -> sin_addr.s_addr = 0;
500
        ((struct sockaddr_in *) &(route.rt_genmask)) -> sin_addr.s_addr = 0;
501
        if (ip_rt_kill(&route)) {
502
                printk(KERN_ERR "BOOTP: Deleting of route failed!\n");
503
                return -1;
504
        }
505
        bootp_have_route = 0;
506
        return 0;
507
}
508
 
509
 
510
/*
511
 *  Open UDP socket.
512
 */
513
static int root_open_udp_sock(int *fd, struct socket **sock)
514
{
515
        struct file *file;
516
        struct inode *inode;
517
 
518
        *fd = sys_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
519
        if (*fd >= 0) {
520
                file = current->files->fd[*fd];
521
                inode = file->f_inode;
522
                *sock = &inode->u.socket_i;
523
                return 0;
524
        }
525
 
526
        printk(KERN_ERR "BOOTP: Cannot open UDP socket!\n");
527
        return -1;
528
}
529
 
530
 
531
/*
532
 *  Connect UDP socket.
533
 */
534
static int root_connect_udp_sock(struct socket *sock, u32 addr, u16 port)
535
{
536
        struct sockaddr_in sa;
537
        int result;
538
 
539
        sa.sin_family = AF_INET;
540
        sa.sin_addr.s_addr = htonl(addr);
541
        sa.sin_port = htons(port);
542
        result = sock->ops->connect(sock, (struct sockaddr *) &sa, sizeof(sa), 0);
543
        if (result < 0) {
544
                printk(KERN_ERR "BOOTP: connect() failed\n");
545
                return -1;
546
        }
547
        return 0;
548
}
549
 
550
 
551
/*
552
 *  Bind UDP socket.
553
 */
554
static int root_bind_udp_sock(struct socket *sock, u32 addr, u16 port)
555
{
556
        struct sockaddr_in sa;
557
        int result;
558
 
559
        sa.sin_family = AF_INET;
560
        sa.sin_addr.s_addr = htonl(addr);
561
        sa.sin_port = htons(port);
562
        result = sock->ops->bind(sock, (struct sockaddr *) &sa, sizeof(sa));
563
        if (result < 0) {
564
                printk(KERN_ERR "BOOTP: bind() failed\n");
565
                return -1;
566
        }
567
        return 0;
568
}
569
 
570
 
571
/*
572
 *  Send UDP packet.
573
 */
574
static inline int root_send_udp(struct socket *sock, void *buf, int size)
575
{
576
        u32 oldfs;
577
        int result;
578
        struct msghdr msg;
579
        struct iovec iov;
580
 
581
        oldfs = get_fs();
582
        set_fs(get_ds());
583
        iov.iov_base = buf;
584
        iov.iov_len = size;
585
        msg.msg_name = NULL;
586
        msg.msg_iov = &iov;
587
        msg.msg_iovlen = 1;
588
        msg.msg_control = NULL;
589
        result = sock->ops->sendmsg(sock, &msg, size, 0, 0);
590
        set_fs(oldfs);
591
        return (result != size);
592
}
593
 
594
 
595
/*
596
 *  Try to receive UDP packet.
597
 */
598
static inline int root_recv_udp(struct socket *sock, void *buf, int size)
599
{
600
        u32 oldfs;
601
        int result;
602
        struct msghdr msg;
603
        struct iovec iov;
604
 
605
        oldfs = get_fs();
606
        set_fs(get_ds());
607
        iov.iov_base = buf;
608
        iov.iov_len = size;
609
        msg.msg_name = NULL;
610
        msg.msg_iov = &iov;
611
        msg.msg_iovlen = 1;
612
        msg.msg_control = NULL;
613
        msg.msg_namelen = 0;
614
        result = sock->ops->recvmsg(sock, &msg, size, O_NONBLOCK, 0, &msg.msg_namelen);
615
        set_fs(oldfs);
616
        return result;
617
}
618
 
619
 
620
/*
621
 *  Initialize BOOTP extension fields in the request.
622
 */
623
static void root_bootp_init_ext(u8 *e)
624
{
625
        *e++ = 99;              /* RFC1048 Magic Cookie */
626
        *e++ = 130;
627
        *e++ = 83;
628
        *e++ = 99;
629
        *e++ = 1;               /* Subnet mask request */
630
        *e++ = 4;
631
        e += 4;
632
        *e++ = 3;               /* Default gateway request */
633
        *e++ = 4;
634
        e += 4;
635
        *e++ = 12;              /* Host name request */
636
        *e++ = 32;
637
        e += 32;
638
        *e++ = 40;              /* NIS Domain name request */
639
        *e++ = 32;
640
        e += 32;
641
        *e++ = 17;              /* Boot path */
642
        *e++ = 32;
643
        e += 32;
644
        *e = 255;               /* End of the list */
645
}
646
 
647
 
648
/*
649
 *  Deinitialize the BOOTP mechanism.
650
 */
651
static void root_bootp_close(void)
652
{
653
        if (bootp_xmit_fd != -1)
654
                sys_close(bootp_xmit_fd);
655
        if (bootp_recv_fd != -1)
656
                sys_close(bootp_recv_fd);
657
        root_del_bootp_route();
658
        root_free_bootp();
659
}
660
 
661
 
662
/*
663
 *  Initialize the BOOTP mechanism.
664
 */
665
static int root_bootp_open(void)
666
{
667
        struct open_dev *openp;
668
        struct device *dev, *best_dev;
669
 
670
        /*
671
         * Select the best interface for BOOTP. We try to select a first
672
         * Ethernet-like interface. It's shame I know no simple way how to send
673
         * BOOTP's to all interfaces, but it doesn't apply to usual diskless
674
         * stations as they don't have multiple interfaces.
675
         */
676
 
677
        best_dev = NULL;
678
        for (openp = open_base; openp != NULL; openp = openp->next) {
679
                dev = openp->dev;
680
                if (dev->flags & IFF_BROADCAST) {
681
                        if (!best_dev ||
682
                           ((best_dev->flags & IFF_NOARP) && !(dev->flags & IFF_NOARP)))
683
                                best_dev = dev;
684
                        }
685
                }
686
 
687
        if (!best_dev) {
688
                printk(KERN_ERR "BOOTP: This cannot happen!\n");
689
                return -1;
690
        }
691
        bootp_dev = best_dev;
692
 
693
        /* Allocate memory for BOOTP packets */
694
        if (root_alloc_bootp())
695
                return -1;
696
 
697
        /* Construct BOOTP request */
698
        memset(xmit_bootp, 0, sizeof(struct bootp_pkt));
699
        xmit_bootp->op = BOOTP_REQUEST;
700
        get_random_bytes(&xmit_bootp->xid, sizeof(xmit_bootp->xid));
701
        xmit_bootp->htype = best_dev->type;
702
        xmit_bootp->hlen = best_dev->addr_len;
703
        memcpy(xmit_bootp->hw_addr, best_dev->dev_addr, best_dev->addr_len);
704
        root_bootp_init_ext(xmit_bootp->vendor_area);
705
#ifdef NFSROOT_BOOTP_DEBUG
706
        {
707
                int x;
708
                printk(KERN_NOTICE "BOOTP: XID=%08x, DE=%s, HT=%02x, HL=%02x, HA=",
709
                        xmit_bootp->xid,
710
                        best_dev->name,
711
                        xmit_bootp->htype,
712
                        xmit_bootp->hlen);
713
                for(x=0; x<xmit_bootp->hlen; x++)
714
                        printk("%02x", xmit_bootp->hw_addr[x]);
715
                printk("\n");
716
        }
717
#endif
718
 
719
        /* Create default route to that interface */
720
        if (root_add_bootp_route())
721
                return -1;
722
 
723
        /* Open the sockets */
724
        if (root_open_udp_sock(&bootp_xmit_fd, &bootp_xmit_sock) ||
725
            root_open_udp_sock(&bootp_recv_fd, &bootp_recv_sock))
726
                return -1;
727
 
728
        /* Bind/connect the sockets */
729
        ((struct sock *) bootp_xmit_sock->data) -> broadcast = 1;
730
        ((struct sock *) bootp_xmit_sock->data) -> reuse = 1;
731
        ((struct sock *) bootp_recv_sock->data) -> reuse = 1;
732
        if (root_bind_udp_sock(bootp_recv_sock, INADDR_ANY, 68) ||
733
            root_bind_udp_sock(bootp_xmit_sock, INADDR_ANY, 68) ||
734
            root_connect_udp_sock(bootp_xmit_sock, INADDR_BROADCAST, 67))
735
                return -1;
736
 
737
        return 0;
738
}
739
 
740
 
741
/*
742
 *  Send BOOTP request.
743
 */
744
static int root_bootp_send(u32 jiffies)
745
{
746
        xmit_bootp->secs = htons(jiffies / HZ);
747
        return root_send_udp(bootp_xmit_sock, xmit_bootp, sizeof(struct bootp_pkt));
748
}
749
 
750
 
751
/*
752
 *  Copy BOOTP-supplied string if not already set.
753
 */
754
static int root_bootp_string(char *dest, char *src, int len, int max)
755
{
756
        if (*dest || !len)
757
                return 0;
758
        if (len > max-1)
759
                len = max-1;
760
        strncpy(dest, src, len);
761
        dest[len] = '\0';
762
        return 1;
763
}
764
 
765
 
766
/*
767
 *  Process BOOTP extension.
768
 */
769
static void root_do_bootp_ext(u8 *ext)
770
{
771
#ifdef NFSROOT_BOOTP_DEBUG
772
        u8 *c;
773
 
774
        printk("BOOTP: Got extension %02x",*ext);
775
        for(c=ext+2; c<ext+2+ext[1]; c++)
776
                printk(" %02x", *c);
777
        printk("\n");
778
#endif
779
 
780
        switch (*ext++) {
781
                case 1:         /* Subnet mask */
782
                        if (netmask.sin_addr.s_addr == INADDR_NONE)
783
                                memcpy(&netmask.sin_addr.s_addr, ext+1, 4);
784
                        break;
785
                case 3:         /* Default gateway */
786
                        if (gateway.sin_addr.s_addr == INADDR_NONE)
787
                                memcpy(&gateway.sin_addr.s_addr, ext+1, 4);
788
                        break;
789
                case 12:        /* Host name */
790
                        root_bootp_string(system_utsname.nodename, ext+1, *ext, __NEW_UTS_LEN);
791
                        break;
792
                case 40:        /* NIS Domain name */
793
                        root_bootp_string(system_utsname.domainname, ext+1, *ext, __NEW_UTS_LEN);
794
                        break;
795
                case 17:        /* Root path */
796
                        root_bootp_string(nfs_path, ext+1, *ext, NFS_MAXPATHLEN);
797
                        break;
798
        }
799
}
800
 
801
 
802
/*
803
 *  Receive BOOTP request.
804
 */
805
static void root_bootp_recv(void)
806
{
807
        int len;
808
        u8 *ext, *end, *opt;
809
 
810
        len = root_recv_udp(bootp_recv_sock, recv_bootp, sizeof(struct bootp_pkt));
811
        if (len < 0)
812
                return;
813
 
814
        /* Check consistency of incoming packet */
815
        if (len < 300 ||                        /* See RFC 1542:2.1 */
816
            recv_bootp->op != BOOTP_REPLY ||
817
            recv_bootp->htype != xmit_bootp->htype ||
818
            recv_bootp->hlen != xmit_bootp->hlen ||
819
            recv_bootp->xid != xmit_bootp->xid) {
820
#ifdef NFSROOT_BOOTP_DEBUG
821
                printk("?");
822
#endif
823
                return;
824
                }
825
 
826
        /* Record BOOTP packet arrival in the global variables */
827
        cli();
828
        if (pkt_arrived) {
829
                sti();
830
                return;
831
        }
832
        pkt_arrived = ARRIVED_BOOTP;
833
        sti();
834
        root_dev = bootp_dev;
835
 
836
        /* Extract basic fields */
837
        myaddr.sin_addr.s_addr = recv_bootp->your_ip;
838
        if (server.sin_addr.s_addr==INADDR_NONE)
839
                server.sin_addr.s_addr = recv_bootp->server_ip;
840
 
841
        /* Parse extensions */
842
        if (recv_bootp->vendor_area[0] == 99 &&  /* Check magic cookie */
843
            recv_bootp->vendor_area[1] == 130 &&
844
            recv_bootp->vendor_area[2] == 83 &&
845
            recv_bootp->vendor_area[3] == 99) {
846
                ext = &recv_bootp->vendor_area[4];
847
                end = (u8 *) recv_bootp + len;
848
                while (ext < end && *ext != 255) {
849
                        if (*ext == 0)           /* Padding */
850
                                ext++;
851
                        else {
852
                                opt = ext;
853
                                ext += ext[1] + 2;
854
                                if (ext <= end)
855
                                        root_do_bootp_ext(opt);
856
                        }
857
                }
858
        }
859
}
860
#endif
861
 
862
 
863
 
864
/***************************************************************************
865
 
866
                        Dynamic configuration of IP.
867
 
868
 ***************************************************************************/
869
 
870
#ifdef CONFIG_RNFS_DYNAMIC
871
 
872
/*
873
 *  Determine client and server IP numbers and appropriate device by using
874
 *  the RARP and BOOTP protocols.
875
 */
876
static int root_auto_config(void)
877
{
878
        int retries;
879
        unsigned long timeout, jiff;
880
        unsigned long start_jiffies;
881
 
882
        /*
883
         * If neither BOOTP nor RARP was selected, return with an error. This
884
         * routine gets only called when some pieces of information are mis-
885
         * sing, and without BOOTP and RARP we are not able to get that in-
886
         * formation.
887
         */
888
        if (!bootp_flag && !rarp_flag) {
889
                printk(KERN_ERR "Root-NFS: Neither RARP nor BOOTP selected.\n");
890
                return -1;
891
        }
892
 
893
#ifdef CONFIG_RNFS_BOOTP
894
        if (bootp_flag && !bootp_dev_count) {
895
                printk(KERN_ERR "Root-NFS: No suitable device for BOOTP found.\n");
896
                bootp_flag = 0;
897
        }
898
#else
899
        bootp_flag = 0;
900
#endif
901
 
902
#ifdef CONFIG_RNFS_RARP
903
        if (rarp_flag && !rarp_dev_count) {
904
                printk(KERN_ERR "Root-NFS: No suitable device for RARP found.\n");
905
                rarp_flag = 0;
906
        }
907
#else
908
        rarp_flag = 0;
909
#endif
910
 
911
        if (!bootp_flag && !rarp_flag)
912
                /* Error message already printed */
913
                return -1;
914
 
915
        /*
916
         * Setup RARP and BOOTP protocols
917
         */
918
#ifdef CONFIG_RNFS_RARP
919
        if (rarp_flag)
920
                root_rarp_open();
921
#endif
922
#ifdef CONFIG_RNFS_BOOTP
923
        if (bootp_flag && root_bootp_open() < 0) {
924
                root_bootp_close();
925
                return -1;
926
        }
927
#endif
928
 
929
        /*
930
         * Send requests and wait, until we get an answer. This loop
931
         * seems to be a terrible waste of CPU time, but actually there is
932
         * only one process running at all, so we don't need to use any
933
         * scheduler functions.
934
         * [Actually we could now, but the nothing else running note still
935
         *  applies.. - AC]
936
         */
937
        printk(KERN_NOTICE "Sending %s%s%s requests...",
938
                bootp_flag ? "BOOTP" : "",
939
                bootp_flag && rarp_flag ? " and " : "",
940
                rarp_flag ? "RARP" : "");
941
        start_jiffies = jiffies;
942
        retries = CONF_RETRIES;
943
        get_random_bytes(&timeout, sizeof(timeout));
944
        timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM);
945
        for(;;) {
946
#ifdef CONFIG_RNFS_BOOTP
947
                if (bootp_flag && root_bootp_send(jiffies - start_jiffies) < 0) {
948
                        printk(" BOOTP failed!\n");
949
                        root_bootp_close();
950
                        bootp_flag = 0;
951
                        if (!rarp_flag)
952
                                break;
953
                }
954
#endif
955
#ifdef CONFIG_RNFS_RARP
956
                if (rarp_flag)
957
                        root_rarp_send();
958
#endif
959
                printk(".");
960
                jiff = jiffies + timeout;
961
                while (jiffies < jiff && !pkt_arrived)
962
#ifdef CONFIG_RNFS_BOOTP
963
                        root_bootp_recv();
964
#else
965
                        ;
966
#endif
967
                if (pkt_arrived)
968
                        break;
969
                if (! --retries) {
970
                        printk(" timed out!\n");
971
                        break;
972
                }
973
                timeout = timeout CONF_TIMEOUT_MULT;
974
                if (timeout > CONF_TIMEOUT_MAX)
975
                        timeout = CONF_TIMEOUT_MAX;
976
        }
977
 
978
#ifdef CONFIG_RNFS_RARP
979
        if (rarp_flag)
980
                root_rarp_close();
981
#endif
982
#ifdef CONFIG_RNFS_BOOTP
983
        if (bootp_flag)
984
                root_bootp_close();
985
#endif
986
 
987
        if (!pkt_arrived)
988
                return -1;
989
 
990
        printk(" OK\n");
991
        printk(KERN_NOTICE "Root-NFS: Got %s answer from %s, ",
992
                (pkt_arrived == ARRIVED_BOOTP) ? "BOOTP" : "RARP",
993
                in_ntoa(server.sin_addr.s_addr));
994
        printk("my address is %s\n", in_ntoa(myaddr.sin_addr.s_addr));
995
 
996
        return 0;
997
}
998
#endif
999
 
1000
 
1001
 
1002
/***************************************************************************
1003
 
1004
                             Parsing of options
1005
 
1006
 ***************************************************************************/
1007
 
1008
 
1009
/*
1010
 *  The following integer options are recognized
1011
 */
1012
static struct nfs_int_opts {
1013
        char *name;
1014
        int  *val;
1015
} root_int_opts[] = {
1016
        { "port",       &nfs_port },
1017
        { "rsize",      &nfs_data.rsize },
1018
        { "wsize",      &nfs_data.wsize },
1019
        { "timeo",      &nfs_data.timeo },
1020
        { "retrans",    &nfs_data.retrans },
1021
        { "acregmin",   &nfs_data.acregmin },
1022
        { "acregmax",   &nfs_data.acregmax },
1023
        { "acdirmin",   &nfs_data.acdirmin },
1024
        { "acdirmax",   &nfs_data.acdirmax },
1025
        { NULL,         NULL }
1026
};
1027
 
1028
 
1029
/*
1030
 *  And now the flag options
1031
 */
1032
static struct nfs_bool_opts {
1033
        char *name;
1034
        int  and_mask;
1035
        int  or_mask;
1036
} root_bool_opts[] = {
1037
        { "soft",       ~NFS_MOUNT_SOFT,        NFS_MOUNT_SOFT },
1038
        { "hard",       ~NFS_MOUNT_SOFT,        0 },
1039
        { "intr",       ~NFS_MOUNT_INTR,        NFS_MOUNT_INTR },
1040
        { "nointr",     ~NFS_MOUNT_INTR,        0 },
1041
        { "posix",      ~NFS_MOUNT_POSIX,       NFS_MOUNT_POSIX },
1042
        { "noposix",    ~NFS_MOUNT_POSIX,       0 },
1043
        { "cto",        ~NFS_MOUNT_NOCTO,       0 },
1044
        { "nocto",      ~NFS_MOUNT_NOCTO,       NFS_MOUNT_NOCTO },
1045
        { "ac",         ~NFS_MOUNT_NOAC,        0 },
1046
        { "noac",       ~NFS_MOUNT_NOAC,        NFS_MOUNT_NOAC },
1047
        { NULL,         0,                       0 }
1048
};
1049
 
1050
 
1051
/*
1052
 *  Prepare the NFS data structure and parse any options. This tries to
1053
 *  set as many values in the nfs_data structure as known right now.
1054
 */
1055
static int root_nfs_name(char *name)
1056
{
1057
        char buf[NFS_MAXPATHLEN];
1058
        char *cp, *cq, *options, *val;
1059
        int octets = 0;
1060
 
1061
        /* It is possible to override the server IP number here */
1062
        cp = cq = name;
1063
        while (octets < 4) {
1064
                while (*cp >= '0' && *cp <= '9')
1065
                        cp++;
1066
                if (cp == cq || cp - cq > 3)
1067
                        break;
1068
                if (*cp == '.' || octets == 3)
1069
                        octets++;
1070
                if (octets < 4)
1071
                        cp++;
1072
                cq = cp;
1073
        }
1074
        if (octets == 4 && (*cp == ':' || *cp == '\0')) {
1075
                if (*cp == ':')
1076
                        *cp++ = '\0';
1077
                server.sin_addr.s_addr = in_aton(name);
1078
                name = cp;
1079
        }
1080
 
1081
        /* Clear the nfs_data structure and setup the server hostname */
1082
        memset(&nfs_data, 0, sizeof(nfs_data));
1083
        strncpy(nfs_data.hostname, in_ntoa(server.sin_addr.s_addr),
1084
                                                sizeof(nfs_data.hostname)-1);
1085
 
1086
        /* Set the name of the directory to mount */
1087
        if (nfs_path[0] == '\0' || strncmp(name, "default", 7))
1088
                strncpy(buf, name, NFS_MAXPATHLEN);
1089
        else
1090
                strncpy(buf, nfs_path, NFS_MAXPATHLEN);
1091
        if ((options = strchr(buf, ',')))
1092
                *options++ = '\0';
1093
        if (!strcmp(buf, "default"))
1094
                strcpy(buf, NFS_ROOT);
1095
        cp = in_ntoa(myaddr.sin_addr.s_addr);
1096
        if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) {
1097
                printk(KERN_ERR "Root-NFS: Pathname for remote directory too long.\n");
1098
                return -1;
1099
        }
1100
        /* update nfs_path with path from nfsroot=... command line parameter */
1101
        if (*buf)
1102
                sprintf(nfs_path, buf, cp);
1103
 
1104
        /* Set some default values */
1105
        nfs_port          = -1;
1106
        nfs_data.version  = NFS_MOUNT_VERSION;
1107
        nfs_data.flags    = 0;
1108
        nfs_data.rsize    = NFS_DEF_FILE_IO_BUFFER_SIZE;
1109
        nfs_data.wsize    = NFS_DEF_FILE_IO_BUFFER_SIZE;
1110
        nfs_data.timeo    = 7;
1111
        nfs_data.retrans  = 3;
1112
        nfs_data.acregmin = 3;
1113
        nfs_data.acregmax = 60;
1114
        nfs_data.acdirmin = 30;
1115
        nfs_data.acdirmax = 60;
1116
 
1117
        /* Process any options */
1118
        if (options) {
1119
                cp = strtok(options, ",");
1120
                while (cp) {
1121
                        if ((val = strchr(cp, '='))) {
1122
                                struct nfs_int_opts *opts = root_int_opts;
1123
                                *val++ = '\0';
1124
                                while (opts->name && strcmp(opts->name, cp))
1125
                                        opts++;
1126
                                if (opts->name)
1127
                                        *(opts->val) = (int) simple_strtoul(val, NULL, 10);
1128
                        } else {
1129
                                struct nfs_bool_opts *opts = root_bool_opts;
1130
                                while (opts->name && strcmp(opts->name, cp))
1131
                                        opts++;
1132
                                if (opts->name) {
1133
                                        nfs_data.flags &= opts->and_mask;
1134
                                        nfs_data.flags |= opts->or_mask;
1135
                                }
1136
                        }
1137
                        cp = strtok(NULL, ",");
1138
                }
1139
        }
1140
        return 0;
1141
}
1142
 
1143
 
1144
/*
1145
 *  Tell the user what's going on.
1146
 */
1147
#ifdef NFSROOT_DEBUG
1148
static void root_nfs_print(void)
1149
{
1150
#define IN_NTOA(x) (((x) == INADDR_NONE) ? "none" : in_ntoa(x))
1151
 
1152
        printk(KERN_NOTICE "Root-NFS: IP config: dev=%s, ",
1153
                root_dev ? root_dev->name : "none");
1154
        printk("local=%s, ", IN_NTOA(myaddr.sin_addr.s_addr));
1155
        printk("server=%s, ", IN_NTOA(server.sin_addr.s_addr));
1156
        printk("gw=%s, ", IN_NTOA(gateway.sin_addr.s_addr));
1157
        printk("mask=%s, ", IN_NTOA(netmask.sin_addr.s_addr));
1158
        printk("host=%s, domain=%s\n",
1159
                system_utsname.nodename[0] ? system_utsname.nodename : "none",
1160
                system_utsname.domainname[0] ? system_utsname.domainname : "none");
1161
        printk(KERN_NOTICE "Root-NFS: Mounting %s on server %s as root\n",
1162
                nfs_path, nfs_data.hostname);
1163
        printk(KERN_NOTICE "Root-NFS:     rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
1164
                nfs_data.rsize, nfs_data.wsize, nfs_data.timeo, nfs_data.retrans);
1165
        printk(KERN_NOTICE "Root-NFS:     acreg (min,max) = (%d,%d), acdir (min,max) = (%d,%d)\n",
1166
                nfs_data.acregmin, nfs_data.acregmax,
1167
                nfs_data.acdirmin, nfs_data.acdirmax);
1168
        printk(KERN_NOTICE "Root-NFS:     port = %d, flags = %08x\n",
1169
                nfs_port, nfs_data.flags);
1170
 
1171
#undef IN_NTOA
1172
}
1173
#endif
1174
 
1175
 
1176
/*
1177
 *  Decode any IP configuration options in the "nfsaddrs" kernel command
1178
 *  line parameter. It consists of option fields separated by colons in
1179
 *  the following order:
1180
 *
1181
 *  <client-ip>:<server-ip>:<gw-ip>:<netmask>:<host name>:<device>:<bootp|rarp>
1182
 *
1183
 *  Any of the fields can be empty which means to use a default value:
1184
 *      <client-ip>     - address given by BOOTP or RARP
1185
 *      <server-ip>     - address of host returning BOOTP or RARP packet
1186
 *      <gw-ip>         - none, or the address returned by BOOTP
1187
 *      <netmask>       - automatically determined from <client-ip>, or the
1188
 *                        one returned by BOOTP
1189
 *      <host name>     - <client-ip> in ASCII notation, or the name returned
1190
 *                        by BOOTP
1191
 *      <device>        - use all available devices for RARP and the first
1192
 *                        one for BOOTP
1193
 *      <bootp|rarp>    - use both protocols to determine my own address
1194
 */
1195
static void root_nfs_addrs(char *addrs)
1196
{
1197
        char *cp, *ip, *dp;
1198
        int num = 0;
1199
 
1200
        /* Clear all addresses and strings */
1201
        myaddr.sin_family = server.sin_family = rarp_serv.sin_family =
1202
            gateway.sin_family = netmask.sin_family = AF_INET;
1203
        myaddr.sin_addr.s_addr = server.sin_addr.s_addr = rarp_serv.sin_addr.s_addr =
1204
            gateway.sin_addr.s_addr = netmask.sin_addr.s_addr = INADDR_NONE;
1205
        system_utsname.nodename[0] = '\0';
1206
        system_utsname.domainname[0] = '\0';
1207
        user_dev_name[0] = '\0';
1208
        bootp_flag = rarp_flag = 1;
1209
 
1210
        /* The following is just a shortcut for automatic IP configuration */
1211
        if (!strcmp(addrs, "bootp")) {
1212
                rarp_flag = 0;
1213
                return;
1214
        } else if (!strcmp(addrs, "rarp")) {
1215
                bootp_flag = 0;
1216
                return;
1217
        } else if (!strcmp(addrs, "both")) {
1218
                return;
1219
        }
1220
 
1221
        /* Parse the whole string */
1222
        ip = addrs;
1223
        while (ip && *ip) {
1224
                if ((cp = strchr(ip, ':')))
1225
                        *cp++ = '\0';
1226
                if (strlen(ip) > 0) {
1227
#ifdef NFSROOT_DEBUG
1228
                        printk(KERN_NOTICE "Root-NFS: Config string num %d is \"%s\"\n",
1229
                                                                num, ip);
1230
#endif
1231
                        switch (num) {
1232
                        case 0:
1233
                                if ((myaddr.sin_addr.s_addr = in_aton(ip)) == INADDR_ANY)
1234
                                        myaddr.sin_addr.s_addr = INADDR_NONE;
1235
                                break;
1236
                        case 1:
1237
                                if ((server.sin_addr.s_addr = in_aton(ip)) == INADDR_ANY)
1238
                                        server.sin_addr.s_addr = INADDR_NONE;
1239
                                break;
1240
                        case 2:
1241
                                if ((gateway.sin_addr.s_addr = in_aton(ip)) == INADDR_ANY)
1242
                                        gateway.sin_addr.s_addr = INADDR_NONE;
1243
                                break;
1244
                        case 3:
1245
                                if ((netmask.sin_addr.s_addr = in_aton(ip)) == INADDR_ANY)
1246
                                        netmask.sin_addr.s_addr = INADDR_NONE;
1247
                                break;
1248
                        case 4:
1249
                                if ((dp = strchr(ip, '.'))) {
1250
                                        *dp++ = '\0';
1251
                                        strncpy(system_utsname.domainname, dp, __NEW_UTS_LEN);
1252
                                        system_utsname.domainname[__NEW_UTS_LEN] = '\0';
1253
                                }
1254
                                strncpy(system_utsname.nodename, ip, __NEW_UTS_LEN);
1255
                                system_utsname.nodename[__NEW_UTS_LEN] = '\0';
1256
                                break;
1257
                        case 5:
1258
                                strncpy(user_dev_name, ip, IFNAMSIZ);
1259
                                user_dev_name[IFNAMSIZ-1] = '\0';
1260
                                break;
1261
                        case 6:
1262
                                if (!strcmp(ip, "rarp"))
1263
                                        bootp_flag = 0;
1264
                                else if (!strcmp(ip, "bootp"))
1265
                                        rarp_flag = 0;
1266
                                else if (strcmp(ip, "both"))
1267
                                        bootp_flag = rarp_flag = 0;
1268
                                break;
1269
                        default:
1270
                                break;
1271
                        }
1272
                }
1273
                ip = cp;
1274
                num++;
1275
        }
1276
        rarp_serv = server;
1277
}
1278
 
1279
 
1280
/*
1281
 *  Set the interface address and configure a route to the server.
1282
 */
1283
static int root_nfs_setup(void)
1284
{
1285
        struct rtentry route;
1286
 
1287
        /* Set the default system name in case none was previously found */
1288
        if (!system_utsname.nodename[0]) {
1289
                strncpy(system_utsname.nodename, in_ntoa(myaddr.sin_addr.s_addr), __NEW_UTS_LEN);
1290
                system_utsname.nodename[__NEW_UTS_LEN] = '\0';
1291
        }
1292
 
1293
        /* Set the correct netmask */
1294
        if (netmask.sin_addr.s_addr == INADDR_NONE)
1295
                netmask.sin_addr.s_addr = ip_get_mask(myaddr.sin_addr.s_addr);
1296
 
1297
        /* Setup the device correctly */
1298
        root_dev->family     = myaddr.sin_family;
1299
        root_dev->pa_addr    = myaddr.sin_addr.s_addr;
1300
        root_dev->pa_mask    = netmask.sin_addr.s_addr;
1301
        root_dev->pa_brdaddr = root_dev->pa_addr | ~root_dev->pa_mask;
1302
        root_dev->pa_dstaddr = 0;
1303
 
1304
        /*
1305
         * Now add a route to the server. If there is no gateway given,
1306
         * the server is on the same subnet, so we establish only a route to
1307
         * the local network. Otherwise we create a route to the gateway (the
1308
         * same local network router as in the former case) and then setup a
1309
         * gatewayed default route. Note that this gives sufficient network
1310
         * setup even for full system operation in all common cases.
1311
         */
1312
        memset(&route, 0, sizeof(route));        /* Local subnet route */
1313
        route.rt_dev = root_dev->name;
1314
        route.rt_mss = root_dev->mtu;
1315
        route.rt_flags = RTF_UP;
1316
        *((struct sockaddr_in *) &(route.rt_dst)) = myaddr;
1317
        (((struct sockaddr_in *) &(route.rt_dst)))->sin_addr.s_addr &= netmask.sin_addr.s_addr;
1318
        *((struct sockaddr_in *) &(route.rt_genmask)) = netmask;
1319
        if (ip_rt_new(&route)) {
1320
                printk(KERN_ERR "Root-NFS: Adding of local route failed!\n");
1321
                return -1;
1322
        }
1323
 
1324
        if (gateway.sin_addr.s_addr != INADDR_NONE) {   /* Default route */
1325
                (((struct sockaddr_in *) &(route.rt_dst)))->sin_addr.s_addr = INADDR_ANY;
1326
                (((struct sockaddr_in *) &(route.rt_genmask)))->sin_addr.s_addr = INADDR_ANY;
1327
                *((struct sockaddr_in *) &(route.rt_gateway)) = gateway;
1328
                route.rt_flags |= RTF_GATEWAY;
1329
                if ((gateway.sin_addr.s_addr ^ myaddr.sin_addr.s_addr) & netmask.sin_addr.s_addr) {
1330
                        printk(KERN_ERR "Root-NFS: Gateway not on local network!\n");
1331
                        return -1;
1332
                }
1333
                if (ip_rt_new(&route)) {
1334
                        printk(KERN_ERR "Root-NFS: Adding of default route failed!\n");
1335
                        return -1;
1336
                }
1337
        } else if ((server.sin_addr.s_addr ^ myaddr.sin_addr.s_addr) & netmask.sin_addr.s_addr) {
1338
                printk(KERN_ERR "Root-NFS: Boot server not on local network and no default gateway configured!\n");
1339
                return -1;
1340
        }
1341
 
1342
        return 0;
1343
}
1344
 
1345
 
1346
/*
1347
 *  Get the necessary IP addresses and prepare for mounting the required
1348
 *  NFS filesystem.
1349
 */
1350
int nfs_root_init(char *nfsname, char *nfsaddrs)
1351
{
1352
        /*
1353
         * Decode IP addresses and other configuration info contained
1354
         * in the nfsaddrs string (which came from the kernel command
1355
         * line).
1356
         */
1357
        root_nfs_addrs(nfsaddrs);
1358
 
1359
        /*
1360
         * Setup all network devices
1361
         */
1362
        if (root_dev_open() < 0)
1363
                return -1;
1364
 
1365
        /*
1366
         * If the config information is insufficient (e.g., our IP address or
1367
         * IP address of the boot server is missing or we have multiple network
1368
         * interfaces and no default was set), use BOOTP or RARP to get the
1369
         * missing values.
1370
         *
1371
         * Note that we don't try to set up correct routes for multiple
1372
         * interfaces (could be solved by trying icmp echo requests), because
1373
         * it's only necessary in the rare case of multiple ethernet devices
1374
         * in the (diskless) system and if the server is on another subnet.
1375
         * If only one interface is installed, the routing is obvious.
1376
         */
1377
        if ((myaddr.sin_addr.s_addr == INADDR_NONE ||
1378
             server.sin_addr.s_addr == INADDR_NONE ||
1379
             (open_base != NULL && open_base->next != NULL))
1380
#ifdef CONFIG_RNFS_DYNAMIC
1381
                && root_auto_config() < 0
1382
#endif
1383
           ) {
1384
                root_dev_close();
1385
                return -1;
1386
        }
1387
        if (root_dev == NULL) {
1388
                if (open_base != NULL && open_base->next == NULL) {
1389
                        root_dev = open_base->dev;
1390
                } else {
1391
                        printk(KERN_ERR "Root-NFS: Multiple devices and no server\n");
1392
                        root_dev_close();
1393
                        return -1;
1394
                }
1395
        }
1396
 
1397
        /*
1398
         * Close all network devices except the device which connects to
1399
         * server
1400
         */
1401
        root_dev_close();
1402
 
1403
        /*
1404
         * Decode the root directory path name and NFS options from
1405
         * the kernel command line. This has to go here in order to
1406
         * be able to use the client IP address for the remote root
1407
         * directory (necessary for pure RARP booting).
1408
         */
1409
        if (root_nfs_name(nfsname) < 0)
1410
                return -1;
1411
 
1412
        /*
1413
         * Setup devices and routes. The server directory is actually
1414
         * mounted after init() has been started.
1415
         */
1416
        if (root_nfs_setup() < 0)
1417
                return -1;
1418
 
1419
#ifdef NFSROOT_DEBUG
1420
        root_nfs_print();
1421
#endif
1422
 
1423
        return 0;
1424
}
1425
 
1426
 
1427
/***************************************************************************
1428
 
1429
               Routines to actually mount the root directory
1430
 
1431
 ***************************************************************************/
1432
 
1433
static struct file  *nfs_file;          /* File descriptor pointing to inode */
1434
static struct inode *nfs_sock_inode;    /* Inode containing socket */
1435
static int *rpc_packet = NULL;          /* RPC packet */
1436
 
1437
 
1438
/*
1439
 *  Open a UDP socket.
1440
 */
1441
static int root_nfs_open(void)
1442
{
1443
        /* Open the socket */
1444
        if ((nfs_data.fd = sys_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
1445
                printk(KERN_ERR "Root-NFS: Cannot open UDP socket for NFS!\n");
1446
                return -1;
1447
        }
1448
        nfs_file = current->files->fd[nfs_data.fd];
1449
        nfs_sock_inode = nfs_file->f_inode;
1450
        return 0;
1451
}
1452
 
1453
 
1454
/*
1455
 *  Close the UDP file descriptor. If nfs_read_super is successful, it
1456
 *  increases the reference count, so we can simply close the file, and
1457
 *  the socket keeps open.
1458
 */
1459
static void root_nfs_close(void)
1460
{
1461
        /*
1462
         * The following close doesn't touch the server structure, which
1463
         * now contains a file pointer pointing into nowhere. The system
1464
         * _should_ crash as soon as someone tries to select on the root
1465
         * filesystem. Haven't tried it yet - we can still change it back
1466
         * to the old way of keeping a static copy of all important data
1467
         * structures, including their pointers. At least this should be
1468
         * checked out _carefully_ before going into a public release
1469
         * kernel.  -  GK
1470
         */
1471
        sys_close(nfs_data.fd);
1472
}
1473
 
1474
 
1475
/*
1476
 *  Find a suitable listening port and bind to it
1477
 */
1478
static int root_nfs_bind(void)
1479
{
1480
        int res = -1;
1481
        short port = STARTPORT;
1482
        struct sockaddr_in *sin = &myaddr;
1483
        int i;
1484
 
1485
        if (nfs_sock_inode->u.socket_i.ops->bind) {
1486
                for (i = 0; i < NPORTS && res < 0; i++) {
1487
                        sin->sin_port = htons(port++);
1488
                        if (port > ENDPORT) {
1489
                                port = STARTPORT;
1490
                        }
1491
                        res = nfs_sock_inode->u.socket_i.ops->bind(&nfs_sock_inode->u.socket_i,
1492
                                                (struct sockaddr *)sin,
1493
                                                sizeof(struct sockaddr_in));
1494
                }
1495
        }
1496
        if (res < 0) {
1497
                printk(KERN_ERR "Root-NFS: Cannot find a suitable listening port\n");
1498
                root_nfs_close();
1499
                return -1;
1500
        }
1501
#ifdef NFSROOT_DEBUG
1502
        printk(KERN_NOTICE "Root-NFS: Binding to listening port %d\n", port);
1503
#endif
1504
        return 0;
1505
}
1506
 
1507
 
1508
/*
1509
 *  Send an RPC request and wait for the answer
1510
 */
1511
static int *root_nfs_call(int *end)
1512
{
1513
        struct socket *sock;
1514
        int dummylen;
1515
        static struct nfs_server s = {
1516
                0,                       /* struct file *         */
1517
                0,                       /* struct rsock *        */
1518
                {
1519
                    0, "",
1520
                },                      /* toaddr                */
1521
                0,                       /* lock                  */
1522
                NULL,                   /* wait queue            */
1523
                NFS_MOUNT_SOFT,         /* flags                 */
1524
                0, 0,                     /* rsize, wsize          */
1525
                0,                       /* timeo                 */
1526
                0,                       /* retrans               */
1527
                3 * HZ, 60 * HZ, 30 * HZ, 60 * HZ, "\0"
1528
        };
1529
 
1530
        s.file = nfs_file;
1531
        sock = &((nfs_file->f_inode)->u.socket_i);
1532
 
1533
        /* Extract the other end of the socket into s->toaddr */
1534
        sock->ops->getname(sock, &(s.toaddr), &dummylen, 1);
1535
        ((struct sockaddr_in *) &s.toaddr)->sin_port   = server.sin_port;
1536
        ((struct sockaddr_in *) &s.toaddr)->sin_family = server.sin_family;
1537
        ((struct sockaddr_in *) &s.toaddr)->sin_addr.s_addr = server.sin_addr.s_addr;
1538
 
1539
        s.rsock = rpc_makesock(nfs_file);
1540
        s.flags = nfs_data.flags;
1541
        s.rsize = nfs_data.rsize;
1542
        s.wsize = nfs_data.wsize;
1543
        s.timeo = nfs_data.timeo * HZ / 10;
1544
        s.retrans = nfs_data.retrans;
1545
        strcpy(s.hostname, nfs_data.hostname);
1546
 
1547
        /*
1548
         * First connect the UDP socket to a server port, then send the
1549
         * packet out, and finally check whether the answer is OK.
1550
         */
1551
        if (nfs_sock_inode->u.socket_i.ops->connect &&
1552
            nfs_sock_inode->u.socket_i.ops->connect(&nfs_sock_inode->u.socket_i,
1553
                                                (struct sockaddr *) &server,
1554
                                                sizeof(struct sockaddr_in),
1555
                                                nfs_file->f_flags) < 0)
1556
                return NULL;
1557
        if (nfs_rpc_call(&s, rpc_packet, end, nfs_data.wsize) < 0)
1558
                return NULL;
1559
        return rpc_verify(rpc_packet);
1560
}
1561
 
1562
 
1563
/*
1564
 *  Create an RPC packet header
1565
 */
1566
static int *root_nfs_header(int proc, int program, int version)
1567
{
1568
        int groups[] = { 0, NOGROUP };
1569
 
1570
        if (rpc_packet == NULL) {
1571
                if (!(rpc_packet = kmalloc(nfs_data.wsize + 1024, GFP_NFS))) {
1572
                        printk(KERN_ERR "Root-NFS: Cannot allocate UDP buffer\n");
1573
                        return NULL;
1574
                }
1575
        }
1576
        return rpc_header(rpc_packet, proc, program, version, 0, 0, groups);
1577
}
1578
 
1579
 
1580
/*
1581
 *  Query server portmapper for the port of a daemon program
1582
 */
1583
static int root_nfs_get_port(int program, int version)
1584
{
1585
        int *p;
1586
 
1587
        /* Prepare header for portmap request */
1588
        server.sin_port = htons(NFS_PMAP_PORT);
1589
        p = root_nfs_header(NFS_PMAP_PROC, NFS_PMAP_PROGRAM, NFS_PMAP_VERSION);
1590
        if (!p)
1591
                return -1;
1592
 
1593
        /* Set arguments for portmapper */
1594
        *p++ = htonl(program);
1595
        *p++ = htonl(version);
1596
        *p++ = htonl(IPPROTO_UDP);
1597
        *p++ = 0;
1598
 
1599
        /* Send request to server portmapper */
1600
        if ((p = root_nfs_call(p)) == NULL)
1601
                return -1;
1602
 
1603
        return ntohl(*p);
1604
}
1605
 
1606
 
1607
/*
1608
 *  Get portnumbers for mountd and nfsd from server
1609
 */
1610
static int root_nfs_ports(void)
1611
{
1612
        int port;
1613
 
1614
        if (nfs_port < 0) {
1615
                if ((port = root_nfs_get_port(NFS_NFS_PROGRAM, NFS_NFS_VERSION)) < 0) {
1616
                        printk(KERN_ERR "Root-NFS: Unable to get nfsd port number from server, using default\n");
1617
                        port = NFS_NFS_PORT;
1618
                }
1619
                nfs_port = port;
1620
#ifdef NFSROOT_DEBUG
1621
                printk(KERN_NOTICE "Root-NFS: Portmapper on server returned %d as nfsd port\n", port);
1622
#endif
1623
        }
1624
        if ((port = root_nfs_get_port(NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION)) < 0) {
1625
                printk(KERN_ERR "Root-NFS: Unable to get mountd port number from server, using default\n");
1626
                port = NFS_MOUNT_PORT;
1627
        }
1628
        server.sin_port = htons(port);
1629
#ifdef NFSROOT_DEBUG
1630
        printk(KERN_NOTICE "Root-NFS: Portmapper on server returned %d as mountd port\n", port);
1631
#endif
1632
 
1633
        return 0;
1634
}
1635
 
1636
 
1637
/*
1638
 *  Get a file handle from the server for the directory which is to be
1639
 *  mounted
1640
 */
1641
static int root_nfs_get_handle(void)
1642
{
1643
        int len, status, *p;
1644
 
1645
        /* Prepare header for mountd request */
1646
        p = root_nfs_header(NFS_MOUNT_PROC, NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION);
1647
        if (!p) {
1648
                root_nfs_close();
1649
                return -1;
1650
        }
1651
 
1652
        /* Set arguments for mountd */
1653
        len = strlen(nfs_path);
1654
        *p++ = htonl(len);
1655
        memcpy(p, nfs_path, len);
1656
        len = (len + 3) >> 2;
1657
        p[len] = 0;
1658
        p += len;
1659
 
1660
        /* Send request to server mountd */
1661
        if ((p = root_nfs_call(p)) == NULL) {
1662
                root_nfs_close();
1663
                return -1;
1664
        }
1665
        status = ntohl(*p++);
1666
        if (status == 0) {
1667
                nfs_data.root = *((struct nfs_fh *) p);
1668
                printk(KERN_NOTICE "Root-NFS: Got file handle for %s via RPC\n", nfs_path);
1669
        } else {
1670
                printk(KERN_ERR "Root-NFS: Server returned error %d while mounting %s\n",
1671
                        status, nfs_path);
1672
                root_nfs_close();
1673
                return -1;
1674
        }
1675
 
1676
        return 0;
1677
}
1678
 
1679
 
1680
/*
1681
 *  Now actually mount the given directory
1682
 */
1683
static int root_nfs_do_mount(struct super_block *sb)
1684
{
1685
        /* First connect to the nfsd port on the server */
1686
        server.sin_port = htons(nfs_port);
1687
        nfs_data.addr = server;
1688
        if (nfs_sock_inode->u.socket_i.ops->connect &&
1689
            nfs_sock_inode->u.socket_i.ops->connect(&nfs_sock_inode->u.socket_i,
1690
                                                (struct sockaddr *) &server,
1691
                                                sizeof(struct sockaddr_in),
1692
                                                nfs_file->f_flags) < 0) {
1693
                root_nfs_close();
1694
                return -1;
1695
        }
1696
 
1697
        /* Now (finally ;-)) read the super block for mounting */
1698
        if (nfs_read_super(sb, &nfs_data, 1) == NULL) {
1699
                root_nfs_close();
1700
                return -1;
1701
        }
1702
        return 0;
1703
}
1704
 
1705
 
1706
/*
1707
 *  Get the NFS port numbers and file handle, and then read the super-
1708
 *  block for mounting.
1709
 */
1710
int nfs_root_mount(struct super_block *sb)
1711
{
1712
        if (root_nfs_open() < 0)
1713
                return -1;
1714
        if (root_nfs_bind() < 0)
1715
                return -1;
1716
        if (root_nfs_ports() < 0)
1717
                return -1;
1718
        if (root_nfs_get_handle() < 0)
1719
                return -1;
1720
        if (root_nfs_do_mount(sb) < 0)
1721
                return -1;
1722
        root_nfs_close();
1723
        return 0;
1724
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.