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

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