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

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