aoenet.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /* Copyright (c) 2007 Coraid, Inc. See COPYING for GPL terms. */
  2. /*
  3. * aoenet.c
  4. * Ethernet portion of AoE driver
  5. */
  6. #include <linux/hdreg.h>
  7. #include <linux/blkdev.h>
  8. #include <linux/netdevice.h>
  9. #include <linux/moduleparam.h>
  10. #include <net/net_namespace.h>
  11. #include <asm/unaligned.h>
  12. #include "aoe.h"
  13. #define NECODES 5
  14. static char *aoe_errlist[] =
  15. {
  16. "no such error",
  17. "unrecognized command code",
  18. "bad argument parameter",
  19. "device unavailable",
  20. "config string present",
  21. "unsupported version"
  22. };
  23. enum {
  24. IFLISTSZ = 1024,
  25. };
  26. static char aoe_iflist[IFLISTSZ];
  27. module_param_string(aoe_iflist, aoe_iflist, IFLISTSZ, 0600);
  28. MODULE_PARM_DESC(aoe_iflist, "aoe_iflist=\"dev1 [dev2 ...]\"");
  29. #ifndef MODULE
  30. static int __init aoe_iflist_setup(char *str)
  31. {
  32. strncpy(aoe_iflist, str, IFLISTSZ);
  33. aoe_iflist[IFLISTSZ - 1] = '\0';
  34. return 1;
  35. }
  36. __setup("aoe_iflist=", aoe_iflist_setup);
  37. #endif
  38. int
  39. is_aoe_netif(struct net_device *ifp)
  40. {
  41. register char *p, *q;
  42. register int len;
  43. if (aoe_iflist[0] == '\0')
  44. return 1;
  45. p = aoe_iflist + strspn(aoe_iflist, WHITESPACE);
  46. for (; *p; p = q + strspn(q, WHITESPACE)) {
  47. q = p + strcspn(p, WHITESPACE);
  48. if (q != p)
  49. len = q - p;
  50. else
  51. len = strlen(p); /* last token in aoe_iflist */
  52. if (strlen(ifp->name) == len && !strncmp(ifp->name, p, len))
  53. return 1;
  54. if (q == p)
  55. break;
  56. }
  57. return 0;
  58. }
  59. int
  60. set_aoe_iflist(const char __user *user_str, size_t size)
  61. {
  62. if (size >= IFLISTSZ)
  63. return -EINVAL;
  64. if (copy_from_user(aoe_iflist, user_str, size)) {
  65. printk(KERN_INFO "aoe: copy from user failed\n");
  66. return -EFAULT;
  67. }
  68. aoe_iflist[size] = 0x00;
  69. return 0;
  70. }
  71. unsigned long long
  72. mac_addr(char addr[6])
  73. {
  74. __be64 n = 0;
  75. char *p = (char *) &n;
  76. memcpy(p + 2, addr, 6); /* (sizeof addr != 6) */
  77. return (unsigned long long) __be64_to_cpu(n);
  78. }
  79. void
  80. aoenet_xmit(struct sk_buff_head *queue)
  81. {
  82. struct sk_buff *skb, *tmp;
  83. skb_queue_walk_safe(queue, skb, tmp)
  84. dev_queue_xmit(skb);
  85. }
  86. /*
  87. * (1) len doesn't include the header by default. I want this.
  88. */
  89. static int
  90. aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, struct net_device *orig_dev)
  91. {
  92. struct aoe_hdr *h;
  93. u32 n;
  94. if (dev_net(ifp) != &init_net)
  95. goto exit;
  96. skb = skb_share_check(skb, GFP_ATOMIC);
  97. if (skb == NULL)
  98. return 0;
  99. if (skb_linearize(skb))
  100. goto exit;
  101. if (!is_aoe_netif(ifp))
  102. goto exit;
  103. skb_push(skb, ETH_HLEN); /* (1) */
  104. h = (struct aoe_hdr *) skb_mac_header(skb);
  105. n = get_unaligned_be32(&h->tag);
  106. if ((h->verfl & AOEFL_RSP) == 0 || (n & 1<<31))
  107. goto exit;
  108. if (h->verfl & AOEFL_ERR) {
  109. n = h->err;
  110. if (n > NECODES)
  111. n = 0;
  112. if (net_ratelimit())
  113. printk(KERN_ERR
  114. "%s%d.%d@%s; ecode=%d '%s'\n",
  115. "aoe: error packet from ",
  116. get_unaligned_be16(&h->major),
  117. h->minor, skb->dev->name,
  118. h->err, aoe_errlist[n]);
  119. goto exit;
  120. }
  121. switch (h->cmd) {
  122. case AOECMD_ATA:
  123. aoecmd_ata_rsp(skb);
  124. break;
  125. case AOECMD_CFG:
  126. aoecmd_cfg_rsp(skb);
  127. break;
  128. default:
  129. printk(KERN_INFO "aoe: unknown cmd %d\n", h->cmd);
  130. }
  131. exit:
  132. dev_kfree_skb(skb);
  133. return 0;
  134. }
  135. static struct packet_type aoe_pt = {
  136. .type = __constant_htons(ETH_P_AOE),
  137. .func = aoenet_rcv,
  138. };
  139. int __init
  140. aoenet_init(void)
  141. {
  142. dev_add_pack(&aoe_pt);
  143. return 0;
  144. }
  145. void
  146. aoenet_exit(void)
  147. {
  148. dev_remove_pack(&aoe_pt);
  149. }