root/fs/nfs/nfsroot.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. root_dev_open
  2. root_dev_close
  3. root_rarp_open
  4. root_rarp_close
  5. root_rarp_recv
  6. root_rarp_send
  7. root_free_bootp
  8. root_alloc_bootp
  9. root_add_bootp_route
  10. root_del_bootp_route
  11. root_open_udp_sock
  12. root_connect_udp_sock
  13. root_bind_udp_sock
  14. root_send_udp
  15. root_recv_udp
  16. root_bootp_init_ext
  17. root_bootp_close
  18. root_bootp_open
  19. root_bootp_send
  20. root_bootp_string
  21. root_do_bootp_ext
  22. root_bootp_recv
  23. root_auto_config
  24. root_nfs_name
  25. root_nfs_print
  26. root_nfs_addrs
  27. root_nfs_setup
  28. nfs_root_init
  29. root_nfs_open
  30. root_nfs_close
  31. root_nfs_bind
  32. root_nfs_call
  33. root_nfs_header
  34. root_nfs_get_port
  35. root_nfs_ports
  36. root_nfs_get_handle
  37. root_nfs_do_mount
  38. nfs_root_mount

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

/* [previous][next][first][last][top][bottom][index][help] */