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

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