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

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