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  *      Swen Th=FCmmler :       Allow to specify the NFS options in nfs_root
  51  *                              without giving a path name. Fix BOOTP request
  52  *                              for domainname (domainname is NIS domain, not
  53  *                              DNS domain!). Skip dummy devices for BOOTP.
  54  *      Jacek Zapala    :       Fixed a bug which prevented server-ip address
  55  *                              from nfsroot parameter from being used.
  56  *
  57  */
  58 
  59 
  60 /* Define this to allow debugging output */
  61 #undef NFSROOT_DEBUG
  62 #undef NFSROOT_BOOTP_DEBUG
  63 
  64 
  65 #include <linux/config.h>
  66 #include <linux/types.h>
  67 #include <linux/string.h>
  68 #include <linux/kernel.h>
  69 #include <linux/sched.h>
  70 #include <linux/fs.h>
  71 #include <linux/random.h>
  72 #include <linux/fcntl.h>
  73 
  74 #include <asm/param.h>
  75 #include <linux/utsname.h>
  76 #include <linux/in.h>
  77 #include <linux/if.h>
  78 #include <linux/inet.h>
  79 #include <linux/net.h>
  80 #include <linux/netdevice.h>
  81 #include <linux/if_arp.h>
  82 #ifdef CONFIG_AX25
  83 #include <net/ax25.h>   /* For AX25_P_IP */
  84 #endif
  85 #include <linux/skbuff.h>
  86 #include <linux/socket.h>
  87 #include <linux/route.h>
  88 #include <linux/nfs.h>
  89 #include <linux/nfs_fs.h>
  90 #include <linux/nfs_mount.h>
  91 #include <linux/in.h>
  92 #include <net/route.h>
  93 #include <net/sock.h>
  94 
  95 #include <asm/segment.h>
  96 
  97 /* Range of privileged ports */
  98 #define STARTPORT       600
  99 #define ENDPORT         1023
 100 #define NPORTS          (ENDPORT - STARTPORT + 1)
 101 
 102 
 103 /* Define the timeout for waiting for a RARP/BOOTP reply */
 104 #define CONF_BASE_TIMEOUT       (HZ*5)  /* Initial timeout: 5 seconds */
 105 #define CONF_RETRIES            10      /* 10 retries */
 106 #define CONF_TIMEOUT_RANDOM     (HZ)    /* Maximum amount of randomization */
 107 #define CONF_TIMEOUT_MULT       *5/4    /* Speed of timeout growth */
 108 #define CONF_TIMEOUT_MAX        (HZ*30) /* Maximum allowed timeout */
 109 
 110 
 111 /* List of open devices */
 112 struct open_dev {
 113         struct device *dev;
 114         unsigned short old_flags;
 115         struct open_dev *next;
 116 };
 117 
 118 static struct open_dev *open_base = NULL;
 119 
 120 
 121 /* IP configuration */
 122 static struct device *root_dev = NULL;  /* Device selected for booting */
 123 static char user_dev_name[IFNAMSIZ];    /* Name of user-selected boot device */
 124 static struct sockaddr_in myaddr;       /* My IP address */
 125 static struct sockaddr_in server;       /* Server IP address */
 126 static struct sockaddr_in gateway;      /* Gateway IP address */
 127 static struct sockaddr_in netmask;      /* Netmask for local subnet */
 128 
 129 
 130 /* BOOTP/RARP variables */
 131 static int bootp_flag;                  /* User said: Use BOOTP! */
 132 static int rarp_flag;                   /* User said: Use RARP! */
 133 static int bootp_dev_count = 0;         /* Number of devices allowing BOOTP */
 134 static int rarp_dev_count = 0;          /* Number of devices allowing RARP */
 135 static struct sockaddr_in rarp_serv;    /* IP address of RARP server */
 136 
 137 #if defined(CONFIG_RNFS_BOOTP) || defined(CONFIG_RNFS_RARP)
 138 #define CONFIG_RNFS_DYNAMIC             /* Enable dynamic IP config */
 139 static volatile int pkt_arrived;        /* BOOTP/RARP packet detected */
 140 
 141 #define ARRIVED_BOOTP   1
 142 #define ARRIVED_RARP    2
 143 #endif
 144 
 145 
 146 /* NFS-related data */
 147 static struct nfs_mount_data nfs_data;          /* NFS mount info */
 148 static char nfs_path[NFS_MAXPATHLEN] = "";      /* Name of directory to mount */
 149 static int nfs_port;                            /* Port to connect to for NFS */
 150 
 151 
 152 /* Yes, we use sys_socket, but there's no include file for it */
 153 extern asmlinkage int sys_socket(int family, int type, int protocol);
 154 
 155 
 156 
 157 /***************************************************************************
 158 
 159                         Device Handling Subroutines
 160 
 161  ***************************************************************************/
 162 
 163 /*
 164  * Setup and initialize all network devices. If there is a user-preferred
 165  * interface, ignore all other interfaces.
 166  */
 167 static int root_dev_open(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 168 {
 169         struct open_dev *openp, **last;
 170         struct device *dev;
 171         unsigned short old_flags;
 172 
 173         last = &open_base;
 174         for (dev = dev_base; dev != NULL; dev = dev->next) {
 175                 if (dev->type < ARPHRD_SLIP &&
 176                     dev->family == AF_INET &&
 177                     !(dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) &&
 178                     (0 != strncmp(dev->name, "dummy", 5)) &&
 179                     (!user_dev_name[0] || !strcmp(dev->name, user_dev_name))) {
 180                         /* First up the interface */
 181                         old_flags = dev->flags;
 182                         dev->flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING;
 183                         if (!(old_flags & IFF_UP) && dev_open(dev)) {
 184                                 dev->flags = old_flags;
 185                                 continue;
 186                         }
 187                         openp = (struct open_dev *) kmalloc(sizeof(struct open_dev),
 188                                                 GFP_ATOMIC);
 189                         if (openp == NULL)
 190                                 continue;
 191                         openp->dev = dev;
 192                         openp->old_flags = old_flags;
 193                         *last = openp;
 194                         last = &openp->next;
 195                         bootp_dev_count++;
 196                         if (!(dev->flags & IFF_NOARP))
 197                                 rarp_dev_count++;
 198 #ifdef NFSROOT_DEBUG
 199                         printk(KERN_NOTICE "Root-NFS: Opened %s\n", dev->name);
 200 #endif
 201                 }
 202         }
 203         *last = NULL;
 204 
 205         if (!bootp_dev_count && !rarp_dev_count) {
 206                 printk(KERN_ERR "Root-NFS: Unable to open at least one network device\n");
 207                 return -1;
 208         }
 209         return 0;
 210 }
 211 
 212 
 213 /*
 214  *  Restore the state of all devices. However, keep the root device open
 215  *  for the upcoming mount.
 216  */
 217 static void root_dev_close(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 218 {
 219         struct open_dev *openp;
 220         struct open_dev *nextp;
 221 
 222         openp = open_base;
 223         while (openp != NULL) {
 224                 nextp = openp->next;
 225                 openp->next = NULL;
 226                 if (openp->dev != root_dev) {
 227                         if (!(openp->old_flags & IFF_UP))
 228                                 dev_close(openp->dev);
 229                         openp->dev->flags = openp->old_flags;
 230                 }
 231                 kfree_s(openp, sizeof(struct open_dev));
 232                 openp = nextp;
 233         }
 234 }
 235 
 236 
 237 
 238 /***************************************************************************
 239 
 240                               RARP Subroutines
 241 
 242  ***************************************************************************/
 243 
 244 #ifdef CONFIG_RNFS_RARP
 245 
 246 extern void arp_send(int type, int ptype, unsigned long target_ip,
 247                      struct device *dev, unsigned long src_ip,
 248                      unsigned char *dest_hw, unsigned char *src_hw,
 249                      unsigned char *target_hw);
 250 
 251 static int root_rarp_recv(struct sk_buff *skb, struct device *dev,
 252                           struct packet_type *pt);
 253 
 254 
 255 static struct packet_type rarp_packet_type = {
 256         0,                      /* Should be: __constant_htons(ETH_P_RARP)
 257                                  * - but this _doesn't_ come out constant! */
 258         NULL,                   /* Listen to all devices */
 259         root_rarp_recv,
 260         NULL,
 261         NULL
 262 };
 263 
 264 
 265 /*
 266  *  Register the packet type for RARP
 267  */
 268 static void root_rarp_open(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 269 {
 270         rarp_packet_type.type = htons(ETH_P_RARP);
 271         dev_add_pack(&rarp_packet_type);
 272 }
 273 
 274 
 275 /*
 276  *  Deregister the RARP packet type
 277  */
 278 static void root_rarp_close(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 279 {
 280         rarp_packet_type.type = htons(ETH_P_RARP);
 281         dev_remove_pack(&rarp_packet_type);
 282 }
 283 
 284 
 285 /*
 286  *  Receive RARP packets.
 287  */
 288 static int root_rarp_recv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
 289 {
 290         struct arphdr *rarp = (struct arphdr *)skb->h.raw;
 291         unsigned char *rarp_ptr = (unsigned char *) (rarp + 1);
 292         unsigned long sip, tip;
 293         unsigned char *sha, *tha;               /* s for "source", t for "target" */
 294 
 295         /* If this test doesn't pass, it's not IP, or we should ignore it anyway */
 296         if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd)) {
 297                 kfree_skb(skb, FREE_READ);
 298                 return 0;
 299         }
 300 
 301         /* If it's not a RARP reply, delete it. */
 302         if (rarp->ar_op != htons(ARPOP_RREPLY)) {
 303                 kfree_skb(skb, FREE_READ);
 304                 return 0;
 305         }
 306 
 307         /* If it's not ethernet or AX25, delete it. */
 308         if ((rarp->ar_pro != htons(ETH_P_IP) && dev->type != ARPHRD_AX25) ||
 309 #ifdef CONFIG_AX25
 310            (rarp->ar_pro != htons(AX25_P_IP) && dev->type == ARPHRD_AX25) ||
 311 #endif
 312             rarp->ar_pln != 4) {
 313                 kfree_skb(skb, FREE_READ);
 314                 return 0;
 315         }
 316 
 317         /* Extract variable width fields */
 318         sha = rarp_ptr;
 319         rarp_ptr += dev->addr_len;
 320         memcpy(&sip, rarp_ptr, 4);
 321         rarp_ptr += 4;
 322         tha = rarp_ptr;
 323         rarp_ptr += dev->addr_len;
 324         memcpy(&tip, rarp_ptr, 4);
 325 
 326         /* Discard packets which are not meant for us. */
 327         if (memcmp(tha, dev->dev_addr, dev->addr_len)) {
 328                 kfree_skb(skb, FREE_READ);
 329                 return 0;
 330         }
 331         /* Discard packets which are not from specified server. */
 332         if (rarp_flag && !bootp_flag &&
 333             rarp_serv.sin_addr.s_addr != INADDR_NONE &&
 334             rarp_serv.sin_addr.s_addr != sip) {
 335                 kfree_skb(skb, FREE_READ);
 336                 return 0;
 337         }
 338 
 339         /*
 340          * The packet is what we were looking for. Setup the global
 341          * variables.
 342          */
 343         cli();
 344         if (pkt_arrived) {
 345                 sti();
 346                 kfree_skb(skb, FREE_READ);
 347                 return 0;
 348         }
 349         pkt_arrived = ARRIVED_RARP;
 350         sti();
 351         root_dev = dev;
 352 
 353         if (myaddr.sin_addr.s_addr == INADDR_NONE) {
 354                 myaddr.sin_family = dev->family;
 355                 myaddr.sin_addr.s_addr = tip;
 356         }
 357         if (server.sin_addr.s_addr == INADDR_NONE) {
 358                 server.sin_family = dev->family;
 359                 server.sin_addr.s_addr = sip;
 360         }
 361         kfree_skb(skb, FREE_READ);
 362         return 0;
 363 }
 364 
 365 
 366 /*
 367  *  Send RARP request packet over all devices which allow RARP.
 368  */
 369 static void root_rarp_send(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 370 {
 371         struct open_dev *openp;
 372         struct device *dev;
 373         int num = 0;
 374 
 375         for (openp = open_base; openp != NULL; openp = openp->next) {
 376                 dev = openp->dev;
 377                 if (!(dev->flags & IFF_NOARP)) {
 378                         arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,
 379                                  dev->dev_addr, dev->dev_addr);
 380                         num++;
 381                 }
 382         }
 383 }
 384 #endif
 385 
 386 
 387 
 388 /***************************************************************************
 389 
 390                              BOOTP Subroutines
 391 
 392  ***************************************************************************/
 393 
 394 #ifdef CONFIG_RNFS_BOOTP
 395 
 396 static struct device *bootp_dev = NULL; /* Device selected as best BOOTP target */
 397 
 398 static int bootp_xmit_fd = -1;          /* Socket descriptor for transmit */
 399 static struct socket *bootp_xmit_sock;  /* The socket itself */
 400 static int bootp_recv_fd = -1;          /* Socket descriptor for receive */
 401 static struct socket *bootp_recv_sock;  /* The socket itself */
 402 
 403 struct bootp_pkt {              /* BOOTP packet format */
 404         u8 op;                  /* 1=request, 2=reply */
 405         u8 htype;               /* HW address type */
 406         u8 hlen;                /* HW address length */
 407         u8 hops;                /* Used only by gateways */
 408         u32 xid;                /* Transaction ID */
 409         u16 secs;               /* Seconds since we started */
 410         u16 flags;              /* Just what is says */
 411         u32 client_ip;          /* Client's IP address if known */
 412         u32 your_ip;            /* Assigned IP address */
 413         u32 server_ip;          /* Server's IP address */
 414         u32 relay_ip;           /* IP address of BOOTP relay */
 415         u8 hw_addr[16];         /* Client's HW address */
 416         u8 serv_name[64];       /* Server host name */
 417         u8 boot_file[128];      /* Name of boot file */
 418         u8 vendor_area[128];    /* Area for extensions */
 419 };
 420 
 421 #define BOOTP_REQUEST 1
 422 #define BOOTP_REPLY 2
 423 
 424 static struct bootp_pkt *xmit_bootp;    /* Packet being transmitted */
 425 static struct bootp_pkt *recv_bootp;    /* Packet being received */
 426 
 427 static int bootp_have_route = 0;        /* BOOTP route installed */
 428 
 429 
 430 /*
 431  *  Free BOOTP packet buffers
 432  */
 433 static void root_free_bootp(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 434 {
 435         if (xmit_bootp) {
 436                 kfree_s(xmit_bootp, sizeof(struct bootp_pkt));
 437                 xmit_bootp = NULL;
 438         }
 439         if (recv_bootp) {
 440                 kfree_s(recv_bootp, sizeof(struct bootp_pkt));
 441                 recv_bootp = NULL;
 442         }
 443 }
 444 
 445 
 446 /*
 447  *  Allocate memory for BOOTP packet buffers
 448  */
 449 static inline int root_alloc_bootp(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 450 {
 451         if (!(xmit_bootp = kmalloc(sizeof(struct bootp_pkt), GFP_KERNEL)) ||
 452             !(recv_bootp = kmalloc(sizeof(struct bootp_pkt), GFP_KERNEL))) {
 453                 printk("BOOTP: Out of memory!");
 454                 return -1;
 455         }
 456         return 0;
 457 }
 458 
 459 
 460 /*
 461  *  Create default route for BOOTP sending
 462  */
 463 static int root_add_bootp_route(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 464 {
 465         struct rtentry route;
 466 
 467         memset(&route, 0, sizeof(route));
 468         route.rt_dev = bootp_dev->name;
 469         route.rt_mss = bootp_dev->mtu;
 470         route.rt_flags = RTF_UP;
 471         ((struct sockaddr_in *) &(route.rt_dst)) -> sin_addr.s_addr = 0;
 472         ((struct sockaddr_in *) &(route.rt_dst)) -> sin_family = AF_INET;
 473         ((struct sockaddr_in *) &(route.rt_genmask)) -> sin_addr.s_addr = 0;
 474         ((struct sockaddr_in *) &(route.rt_genmask)) -> sin_family = AF_INET;
 475         if (ip_rt_new(&route)) {
 476                 printk(KERN_ERR "BOOTP: Adding of route failed!\n");
 477                 return -1;
 478         }
 479         bootp_have_route = 1;
 480         return 0;
 481 }
 482 
 483 
 484 /*
 485  *  Delete default route for BOOTP sending
 486  */
 487 static int root_del_bootp_route(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 488 {
 489         struct rtentry route;
 490 
 491         if (!bootp_have_route)
 492                 return 0;
 493         memset(&route, 0, sizeof(route));
 494         ((struct sockaddr_in *) &(route.rt_dst)) -> sin_addr.s_addr = 0;
 495         ((struct sockaddr_in *) &(route.rt_genmask)) -> sin_addr.s_addr = 0;
 496         if (ip_rt_kill(&route)) {
 497                 printk(KERN_ERR "BOOTP: Deleting of route failed!\n");
 498                 return -1;
 499         }
 500         bootp_have_route = 0;
 501         return 0;
 502 }
 503 
 504 
 505 /*
 506  *  Open UDP socket.
 507  */
 508 static int root_open_udp_sock(int *fd, struct socket **sock)
     /* [previous][next][first][last][top][bottom][index][help] */
 509 {
 510         struct file *file;
 511         struct inode *inode;
 512 
 513         *fd = sys_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 514         if (*fd >= 0) {
 515                 file = current->files->fd[*fd];
 516                 inode = file->f_inode;
 517                 *sock = &inode->u.socket_i;
 518                 return 0;
 519         }
 520 
 521         printk(KERN_ERR "BOOTP: Cannot open UDP socket!\n");
 522         return -1;
 523 }
 524 
 525 
 526 /*
 527  *  Connect UDP socket.
 528  */
 529 static int root_connect_udp_sock(struct socket *sock, u32 addr, u16 port)
     /* [previous][next][first][last][top][bottom][index][help] */
 530 {
 531         struct sockaddr_in sa;
 532         int result;
 533 
 534         sa.sin_family = AF_INET;
 535         sa.sin_addr.s_addr = htonl(addr);
 536         sa.sin_port = htons(port);
 537         result = sock->ops->connect(sock, (struct sockaddr *) &sa, sizeof(sa), 0);
 538         if (result < 0) {
 539                 printk(KERN_ERR "BOOTP: connect() failed\n");
 540                 return -1;
 541         }
 542         return 0;
 543 }
 544 
 545 
 546 /*
 547  *  Bind UDP socket.
 548  */
 549 static int root_bind_udp_sock(struct socket *sock, u32 addr, u16 port)
     /* [previous][next][first][last][top][bottom][index][help] */
 550 {
 551         struct sockaddr_in sa;
 552         int result;
 553 
 554         sa.sin_family = AF_INET;
 555         sa.sin_addr.s_addr = htonl(addr);
 556         sa.sin_port = htons(port);
 557         result = sock->ops->bind(sock, (struct sockaddr *) &sa, sizeof(sa));
 558         if (result < 0) {
 559                 printk(KERN_ERR "BOOTP: bind() failed\n");
 560                 return -1;
 561         }
 562         return 0;
 563 }
 564 
 565 
 566 /*
 567  *  Send UDP packet.
 568  */
 569 static inline int root_send_udp(struct socket *sock, void *buf, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
 570 {
 571         u32 oldfs;
 572         int result;
 573         struct msghdr msg;
 574         struct iovec iov;
 575 
 576         oldfs = get_fs();
 577         set_fs(get_ds());
 578         iov.iov_base = buf;
 579         iov.iov_len = size;
 580         msg.msg_name = NULL;
 581         msg.msg_iov = &iov;
 582         msg.msg_iovlen = 1;
 583         msg.msg_accrights = NULL;
 584         result = sock->ops->sendmsg(sock, &msg, size, 0, 0);
 585         set_fs(oldfs);
 586         return (result != size);
 587 }
 588 
 589 
 590 /*
 591  *  Try to receive UDP packet.
 592  */
 593 static inline int root_recv_udp(struct socket *sock, void *buf, int size)
     /* [previous][next][first][last][top][bottom][index][help] */
 594 {
 595         u32 oldfs;
 596         int result;
 597         struct msghdr msg;
 598         struct iovec iov;
 599 
 600         oldfs = get_fs();
 601         set_fs(get_ds());
 602         iov.iov_base = buf;
 603         iov.iov_len = size;
 604         msg.msg_name = NULL;
 605         msg.msg_iov = &iov;
 606         msg.msg_iovlen = 1;
 607         msg.msg_accrights = NULL;
 608         msg.msg_namelen = 0;
 609         result = sock->ops->recvmsg(sock, &msg, size, O_NONBLOCK, 0, &msg.msg_namelen);
 610         set_fs(oldfs);
 611         return result;
 612 }
 613 
 614 
 615 /*
 616  *  Initialize BOOTP extension fields in the request.
 617  */
 618 static void root_bootp_init_ext(u8 *e)
     /* [previous][next][first][last][top][bottom][index][help] */
 619 {
 620         *e++ = 99;              /* RFC1048 Magic Cookie */
 621         *e++ = 130;
 622         *e++ = 83;
 623         *e++ = 99;
 624         *e++ = 1;               /* Subnet mask request */
 625         *e++ = 4;
 626         e += 4;
 627         *e++ = 3;               /* Default gateway request */
 628         *e++ = 4;
 629         e += 4;
 630         *e++ = 12;              /* Host name request */
 631         *e++ = 32;
 632         e += 32;
 633         *e++ = 40;              /* NIS Domain name request */
 634         *e++ = 32;
 635         e += 32;
 636         *e++ = 17;              /* Boot path */
 637         *e++ = 32;
 638         e += 32;
 639         *e = 255;               /* End of the list */
 640 }
 641 
 642 
 643 /*
 644  *  Deinitialize the BOOTP mechanism.
 645  */
 646 static void root_bootp_close(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 647 {
 648         if (bootp_xmit_fd != -1)
 649                 sys_close(bootp_xmit_fd);
 650         if (bootp_recv_fd != -1)
 651                 sys_close(bootp_recv_fd);
 652         root_del_bootp_route();
 653         root_free_bootp();
 654 }
 655 
 656 
 657 /*
 658  *  Initialize the BOOTP mechanism.
 659  */
 660 static int root_bootp_open(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 661 {
 662         struct open_dev *openp;
 663         struct device *dev, *best_dev;
 664 
 665         /*
 666          * Select the best interface for BOOTP. We try to select a first
 667          * Ethernet-like interface. It's shame I know no simple way how to send
 668          * BOOTP's to all interfaces, but it doesn't apply to usual diskless
 669          * stations as they don't have multiple interfaces.
 670          */
 671 
 672         best_dev = NULL;
 673         for (openp = open_base; openp != NULL; openp = openp->next) {
 674                 dev = openp->dev;
 675                 if (dev->flags & IFF_BROADCAST) {
 676                         if (!best_dev ||
 677                            ((best_dev->flags & IFF_NOARP) && !(dev->flags & IFF_NOARP)))
 678                                 best_dev = dev;
 679                         }
 680                 }
 681 
 682         if (!best_dev) {
 683                 printk(KERN_ERR "BOOTP: This cannot happen!\n");
 684                 return -1;
 685         }
 686         bootp_dev = best_dev;
 687 
 688         /* Allocate memory for BOOTP packets */
 689         if (root_alloc_bootp())
 690                 return -1;
 691 
 692         /* Construct BOOTP request */
 693         memset(xmit_bootp, 0, sizeof(struct bootp_pkt));
 694         xmit_bootp->op = BOOTP_REQUEST;
 695         get_random_bytes(&xmit_bootp->xid, sizeof(xmit_bootp->xid));
 696         xmit_bootp->htype = best_dev->type;
 697         xmit_bootp->hlen = best_dev->addr_len;
 698         memcpy(xmit_bootp->hw_addr, best_dev->dev_addr, best_dev->addr_len);
 699         root_bootp_init_ext(xmit_bootp->vendor_area);
 700 #ifdef NFSROOT_BOOTP_DEBUG
 701         {
 702                 int x;
 703                 printk(KERN_NOTICE "BOOTP: XID=%08x, DE=%s, HT=%02x, HL=%02x, HA=",
 704                         xmit_bootp->xid,
 705                         best_dev->name,
 706                         xmit_bootp->htype,
 707                         xmit_bootp->hlen);
 708                 for(x=0; x<xmit_bootp->hlen; x++)
 709                         printk("%02x", xmit_bootp->hw_addr[x]);
 710                 printk("\n");
 711         }
 712 #endif
 713 
 714         /* Create default route to that interface */
 715         if (root_add_bootp_route())
 716                 return -1;
 717 
 718         /* Open the sockets */
 719         if (root_open_udp_sock(&bootp_xmit_fd, &bootp_xmit_sock) ||
 720             root_open_udp_sock(&bootp_recv_fd, &bootp_recv_sock))
 721                 return -1;
 722 
 723         /* Bind/connect the sockets */
 724         ((struct sock *) bootp_xmit_sock->data) -> broadcast = 1;
 725         ((struct sock *) bootp_xmit_sock->data) -> reuse = 1;
 726         ((struct sock *) bootp_recv_sock->data) -> reuse = 1;
 727         if (root_bind_udp_sock(bootp_recv_sock, INADDR_ANY, 68) ||
 728             root_bind_udp_sock(bootp_xmit_sock, INADDR_ANY, 68) ||
 729             root_connect_udp_sock(bootp_xmit_sock, INADDR_BROADCAST, 67))
 730                 return -1;
 731 
 732         return 0;
 733 }
 734 
 735 
 736 /*
 737  *  Send BOOTP request.
 738  */
 739 static int root_bootp_send(u32 jiffies)
     /* [previous][next][first][last][top][bottom][index][help] */
 740 {
 741         xmit_bootp->secs = htons(jiffies / HZ);
 742         return root_send_udp(bootp_xmit_sock, xmit_bootp, sizeof(struct bootp_pkt));
 743 }
 744 
 745 
 746 /*
 747  *  Copy BOOTP-supplied string if not already set.
 748  */
 749 static int root_bootp_string(char *dest, char *src, int len, int max)
     /* [previous][next][first][last][top][bottom][index][help] */
 750 {
 751         if (*dest || !len)
 752                 return 0;
 753         if (len > max-1)
 754                 len = max-1;
 755         strncpy(dest, src, len);
 756         dest[len] = '\0';
 757         return 1;
 758 }
 759 
 760 
 761 /*
 762  *  Process BOOTP extension.
 763  */
 764 static void root_do_bootp_ext(u8 *ext)
     /* [previous][next][first][last][top][bottom][index][help] */
 765 {
 766 #ifdef NFSROOT_BOOTP_DEBUG
 767         u8 *c;
 768 
 769         printk("BOOTP: Got extension %02x",*ext);
 770         for(c=ext+2; c<ext+2+ext[1]; c++)
 771                 printk(" %02x", *c);
 772         printk("\n");
 773 #endif
 774 
 775         switch (*ext++) {
 776                 case 1:         /* Subnet mask */
 777                         if (netmask.sin_addr.s_addr == INADDR_NONE)
 778                                 memcpy(&netmask.sin_addr.s_addr, ext+1, 4);
 779                         break;
 780                 case 3:         /* Default gateway */
 781                         if (gateway.sin_addr.s_addr == INADDR_NONE)
 782                                 memcpy(&gateway.sin_addr.s_addr, ext+1, 4);
 783                         break;
 784                 case 12:        /* Host name */
 785                         root_bootp_string(system_utsname.nodename, ext+1, *ext, __NEW_UTS_LEN);
 786                         break;
 787                 case 40:        /* NIS Domain name */
 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         if (server.sin_addr.s_addr==INADDR_NONE)
 834                 server.sin_addr.s_addr = recv_bootp->server_ip;
 835 
 836         /* Parse extensions */
 837         if (recv_bootp->vendor_area[0] == 99 && /* Check magic cookie */
 838             recv_bootp->vendor_area[1] == 130 &&
 839             recv_bootp->vendor_area[2] == 83 &&
 840             recv_bootp->vendor_area[3] == 99) {
 841                 ext = &recv_bootp->vendor_area[4];
 842                 end = (u8 *) recv_bootp + len;
 843                 while (ext < end && *ext != 255) {
 844                         if (*ext == 0)          /* Padding */
 845                                 ext++;
 846                         else {
 847                                 opt = ext;
 848                                 ext += ext[1] + 2;
 849                                 if (ext <= end)
 850                                         root_do_bootp_ext(opt);
 851                         }
 852                 }
 853         }
 854 }
 855 #endif
 856 
 857 
 858 
 859 /***************************************************************************
 860 
 861                         Dynamic configuration of IP.
 862 
 863  ***************************************************************************/
 864 
 865 #ifdef CONFIG_RNFS_DYNAMIC
 866 
 867 /*
 868  *  Determine client and server IP numbers and appropriate device by using
 869  *  the RARP and BOOTP protocols.
 870  */
 871 static int root_auto_config(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 872 {
 873         int retries;
 874         unsigned long timeout, jiff;
 875         unsigned long start_jiffies;
 876 
 877         /*
 878          * If neither BOOTP nor RARP was selected, return with an error. This
 879          * routine gets only called when some pieces of information are mis-
 880          * sing, and without BOOTP and RARP we are not able to get that in-
 881          * formation.
 882          */
 883         if (!bootp_flag && !rarp_flag) {
 884                 printk(KERN_ERR "Root-NFS: Neither RARP nor BOOTP selected.\n");
 885                 return -1;
 886         }
 887 
 888 #ifdef CONFIG_RNFS_BOOTP
 889         if (bootp_flag && !bootp_dev_count) {
 890                 printk(KERN_ERR "Root-NFS: No suitable device for BOOTP found.\n");
 891                 bootp_flag = 0;
 892         }
 893 #else
 894         bootp_flag = 0;
 895 #endif
 896 
 897 #ifdef CONFIG_RNFS_RARP
 898         if (rarp_flag && !rarp_dev_count) {
 899                 printk(KERN_ERR "Root-NFS: No suitable device for RARP found.\n");
 900                 rarp_flag = 0;
 901         }
 902 #else
 903         rarp_flag = 0;
 904 #endif
 905 
 906         if (!bootp_flag && !rarp_flag)
 907                 /* Error message already printed */
 908                 return -1;
 909 
 910         /*
 911          * Setup RARP and BOOTP protocols
 912          */
 913 #ifdef CONFIG_RNFS_RARP
 914         if (rarp_flag)
 915                 root_rarp_open();
 916 #endif
 917 #ifdef CONFIG_RNFS_BOOTP
 918         if (bootp_flag && root_bootp_open() < 0) {
 919                 root_bootp_close();
 920                 return -1;
 921         }
 922 #endif
 923 
 924         /*
 925          * Send requests and wait, until we get an answer. This loop
 926          * seems to be a terrible waste of CPU time, but actually there is
 927          * only one process running at all, so we don't need to use any
 928          * scheduler functions.
 929          * [Actually we could now, but the nothing else running note still 
 930          *  applies.. - AC]
 931          */
 932         printk(KERN_NOTICE "Sending %s%s%s requests...",
 933                 bootp_flag ? "BOOTP" : "",
 934                 bootp_flag && rarp_flag ? " and " : "",
 935                 rarp_flag ? "RARP" : "");
 936         start_jiffies = jiffies;
 937         retries = CONF_RETRIES;
 938         get_random_bytes(&timeout, sizeof(timeout));
 939         timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM);
 940         for(;;) {
 941 #ifdef CONFIG_RNFS_BOOTP
 942                 if (bootp_flag && root_bootp_send(jiffies - start_jiffies) < 0) {
 943                         printk(" BOOTP failed!\n");
 944                         root_bootp_close();
 945                         bootp_flag = 0;
 946                         if (!rarp_flag)
 947                                 break;
 948                 }
 949 #endif
 950 #ifdef CONFIG_RNFS_RARP
 951                 if (rarp_flag)
 952                         root_rarp_send();
 953 #endif
 954                 printk(".");
 955                 jiff = jiffies + timeout;
 956                 while (jiffies < jiff && !pkt_arrived)
 957 #ifdef CONFIG_RNFS_BOOTP
 958                         root_bootp_recv();
 959 #else
 960                         ;
 961 #endif
 962                 if (pkt_arrived)
 963                         break;
 964                 if (! --retries) {
 965                         printk(" timed out!\n");
 966                         break;
 967                 }
 968                 timeout = timeout CONF_TIMEOUT_MULT;
 969                 if (timeout > CONF_TIMEOUT_MAX)
 970                         timeout = CONF_TIMEOUT_MAX;
 971         }
 972 
 973 #ifdef CONFIG_RNFS_RARP
 974         if (rarp_flag)
 975                 root_rarp_close();
 976 #endif
 977 #ifdef CONFIG_RNFS_BOOTP
 978         if (bootp_flag)
 979                 root_bootp_close();
 980 #endif
 981 
 982         if (!pkt_arrived)
 983                 return -1;
 984 
 985         printk(" OK\n");
 986         printk(KERN_NOTICE "Root-NFS: Got %s answer from %s, ",
 987                 (pkt_arrived == ARRIVED_BOOTP) ? "BOOTP" : "RARP",
 988                 in_ntoa(server.sin_addr.s_addr));
 989         printk("my address is %s\n", in_ntoa(myaddr.sin_addr.s_addr));
 990 
 991         return 0;
 992 }
 993 #endif
 994 
 995 
 996 
 997 /***************************************************************************
 998 
 999                              Parsing of options
1000 
1001  ***************************************************************************/
1002 
1003 
1004 /*
1005  *  The following integer options are recognized
1006  */
1007 static struct nfs_int_opts {
1008         char *name;
1009         int  *val;
1010 } root_int_opts[] = {
1011         { "port",       &nfs_port },
1012         { "rsize",      &nfs_data.rsize },
1013         { "wsize",      &nfs_data.wsize },
1014         { "timeo",      &nfs_data.timeo },
1015         { "retrans",    &nfs_data.retrans },
1016         { "acregmin",   &nfs_data.acregmin },
1017         { "acregmax",   &nfs_data.acregmax },
1018         { "acdirmin",   &nfs_data.acdirmin },
1019         { "acdirmax",   &nfs_data.acdirmax },
1020         { NULL,         NULL }
1021 };
1022 
1023 
1024 /*
1025  *  And now the flag options
1026  */
1027 static struct nfs_bool_opts {
1028         char *name;
1029         int  and_mask;
1030         int  or_mask;
1031 } root_bool_opts[] = {
1032         { "soft",       ~NFS_MOUNT_SOFT,        NFS_MOUNT_SOFT },
1033         { "hard",       ~NFS_MOUNT_SOFT,        0 },
1034         { "intr",       ~NFS_MOUNT_INTR,        NFS_MOUNT_INTR },
1035         { "nointr",     ~NFS_MOUNT_INTR,        0 },
1036         { "posix",      ~NFS_MOUNT_POSIX,       NFS_MOUNT_POSIX },
1037         { "noposix",    ~NFS_MOUNT_POSIX,       0 },
1038         { "cto",        ~NFS_MOUNT_NOCTO,       0 },
1039         { "nocto",      ~NFS_MOUNT_NOCTO,       NFS_MOUNT_NOCTO },
1040         { "ac",         ~NFS_MOUNT_NOAC,        0 },
1041         { "noac",       ~NFS_MOUNT_NOAC,        NFS_MOUNT_NOAC },
1042         { NULL,         0,                      0 }
1043 };
1044 
1045 
1046 /*
1047  *  Prepare the NFS data structure and parse any options. This tries to
1048  *  set as many values in the nfs_data structure as known right now.
1049  */
1050 static int root_nfs_name(char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
1051 {
1052         char buf[NFS_MAXPATHLEN];
1053         char *cp, *cq, *options, *val;
1054         int octets = 0;
1055 
1056         /* It is possible to override the server IP number here */
1057         cp = cq = name;
1058         while (octets < 4) {
1059                 while (*cp >= '0' && *cp <= '9')
1060                         cp++;
1061                 if (cp == cq || cp - cq > 3)
1062                         break;
1063                 if (*cp == '.' || octets == 3)
1064                         octets++;
1065                 if (octets < 4)
1066                         cp++;
1067                 cq = cp;
1068         }
1069         if (octets == 4 && (*cp == ':' || *cp == '\0')) {
1070                 if (*cp == ':')
1071                         *cp++ = '\0';
1072                 server.sin_addr.s_addr = in_aton(name);
1073                 name = cp;
1074         }
1075 
1076         /* Clear the nfs_data structure and setup the server hostname */
1077         memset(&nfs_data, 0, sizeof(nfs_data));
1078         strncpy(nfs_data.hostname, in_ntoa(server.sin_addr.s_addr),
1079                                                 sizeof(nfs_data.hostname)-1);
1080 
1081         /* Set the name of the directory to mount */
1082         if (nfs_path[0] == '\0' || !strncmp(name, "default", 7))
1083                 strncpy(buf, name, NFS_MAXPATHLEN);
1084         else
1085                 strncpy(buf, nfs_path, NFS_MAXPATHLEN);
1086         if ((options = strchr(buf, ',')))
1087                 *options++ = '\0';
1088         if (!strcmp(buf, "default"))
1089                 strcpy(buf, NFS_ROOT);
1090         cp = in_ntoa(myaddr.sin_addr.s_addr);
1091         if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) {
1092                 printk(KERN_ERR "Root-NFS: Pathname for remote directory too long.\n");
1093                 return -1;
1094         }
1095         /* update nfs_path with path from nfsroot=... command line parameter */
1096         if (*buf)
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] */