mctp.h 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Management Component Transport Protocol (MCTP)
  4. *
  5. * Copyright (c) 2021 Code Construct
  6. * Copyright (c) 2021 Google
  7. */
  8. #ifndef __NET_MCTP_H
  9. #define __NET_MCTP_H
  10. #include <linux/bits.h>
  11. #include <linux/mctp.h>
  12. #include <linux/netdevice.h>
  13. #include <net/net_namespace.h>
  14. #include <net/sock.h>
  15. /* MCTP packet definitions */
  16. struct mctp_hdr {
  17. u8 ver;
  18. u8 dest;
  19. u8 src;
  20. u8 flags_seq_tag;
  21. };
  22. #define MCTP_VER_MIN 1
  23. #define MCTP_VER_MAX 1
  24. /* Definitions for flags_seq_tag field */
  25. #define MCTP_HDR_FLAG_SOM BIT(7)
  26. #define MCTP_HDR_FLAG_EOM BIT(6)
  27. #define MCTP_HDR_FLAG_TO BIT(3)
  28. #define MCTP_HDR_FLAGS GENMASK(5, 3)
  29. #define MCTP_HDR_SEQ_SHIFT 4
  30. #define MCTP_HDR_SEQ_MASK GENMASK(1, 0)
  31. #define MCTP_HDR_TAG_SHIFT 0
  32. #define MCTP_HDR_TAG_MASK GENMASK(2, 0)
  33. #define MCTP_INITIAL_DEFAULT_NET 1
  34. static inline bool mctp_address_unicast(mctp_eid_t eid)
  35. {
  36. return eid >= 8 && eid < 255;
  37. }
  38. static inline bool mctp_address_broadcast(mctp_eid_t eid)
  39. {
  40. return eid == 255;
  41. }
  42. static inline bool mctp_address_null(mctp_eid_t eid)
  43. {
  44. return eid == 0;
  45. }
  46. static inline bool mctp_address_matches(mctp_eid_t match, mctp_eid_t eid)
  47. {
  48. return match == eid || match == MCTP_ADDR_ANY;
  49. }
  50. static inline struct mctp_hdr *mctp_hdr(struct sk_buff *skb)
  51. {
  52. return (struct mctp_hdr *)skb_network_header(skb);
  53. }
  54. /* socket implementation */
  55. struct mctp_sock {
  56. struct sock sk;
  57. /* bind() params */
  58. unsigned int bind_net;
  59. mctp_eid_t bind_addr;
  60. __u8 bind_type;
  61. /* sendmsg()/recvmsg() uses struct sockaddr_mctp_ext */
  62. bool addr_ext;
  63. /* list of mctp_sk_key, for incoming tag lookup. updates protected
  64. * by sk->net->keys_lock
  65. */
  66. struct hlist_head keys;
  67. /* mechanism for expiring allocated keys; will release an allocated
  68. * tag, and any netdev state for a request/response pairing
  69. */
  70. struct timer_list key_expiry;
  71. };
  72. /* Key for matching incoming packets to sockets or reassembly contexts.
  73. * Packets are matched on (src,dest,tag).
  74. *
  75. * Lifetime / locking requirements:
  76. *
  77. * - individual key data (ie, the struct itself) is protected by key->lock;
  78. * changes must be made with that lock held.
  79. *
  80. * - the lookup fields: peer_addr, local_addr and tag are set before the
  81. * key is added to lookup lists, and never updated.
  82. *
  83. * - A ref to the key must be held (throuh key->refs) if a pointer to the
  84. * key is to be accessed after key->lock is released.
  85. *
  86. * - a mctp_sk_key contains a reference to a struct sock; this is valid
  87. * for the life of the key. On sock destruction (through unhash), the key is
  88. * removed from lists (see below), and marked invalid.
  89. *
  90. * - these mctp_sk_keys appear on two lists:
  91. * 1) the struct mctp_sock->keys list
  92. * 2) the struct netns_mctp->keys list
  93. *
  94. * presences on these lists requires a (single) refcount to be held; both
  95. * lists are updated as a single operation.
  96. *
  97. * Updates and lookups in either list are performed under the
  98. * netns_mctp->keys lock. Lookup functions will need to lock the key and
  99. * take a reference before unlocking the keys_lock. Consequently, the list's
  100. * keys_lock *cannot* be acquired with the individual key->lock held.
  101. *
  102. * - a key may have a sk_buff attached as part of an in-progress message
  103. * reassembly (->reasm_head). The reasm data is protected by the individual
  104. * key->lock.
  105. *
  106. * - there are two destruction paths for a mctp_sk_key:
  107. *
  108. * - through socket unhash (see mctp_sk_unhash). This performs the list
  109. * removal under keys_lock.
  110. *
  111. * - where a key is established to receive a reply message: after receiving
  112. * the (complete) reply, or during reassembly errors. Here, we clean up
  113. * the reassembly context (marking reasm_dead, to prevent another from
  114. * starting), and remove the socket from the netns & socket lists.
  115. *
  116. * - through an expiry timeout, on a per-socket timer
  117. */
  118. struct mctp_sk_key {
  119. mctp_eid_t peer_addr;
  120. mctp_eid_t local_addr; /* MCTP_ADDR_ANY for local owned tags */
  121. __u8 tag; /* incoming tag match; invert TO for local */
  122. /* we hold a ref to sk when set */
  123. struct sock *sk;
  124. /* routing lookup list */
  125. struct hlist_node hlist;
  126. /* per-socket list */
  127. struct hlist_node sklist;
  128. /* lock protects against concurrent updates to the reassembly and
  129. * expiry data below.
  130. */
  131. spinlock_t lock;
  132. /* Keys are referenced during the output path, which may sleep */
  133. refcount_t refs;
  134. /* incoming fragment reassembly context */
  135. struct sk_buff *reasm_head;
  136. struct sk_buff **reasm_tailp;
  137. bool reasm_dead;
  138. u8 last_seq;
  139. /* key validity */
  140. bool valid;
  141. /* expiry timeout; valid (above) cleared on expiry */
  142. unsigned long expiry;
  143. /* free to use for device flow state tracking. Initialised to
  144. * zero on initial key creation
  145. */
  146. unsigned long dev_flow_state;
  147. struct mctp_dev *dev;
  148. /* a tag allocated with SIOCMCTPALLOCTAG ioctl will not expire
  149. * automatically on timeout or response, instead SIOCMCTPDROPTAG
  150. * is used.
  151. */
  152. bool manual_alloc;
  153. };
  154. struct mctp_skb_cb {
  155. unsigned int magic;
  156. unsigned int net;
  157. int ifindex; /* extended/direct addressing if set */
  158. mctp_eid_t src;
  159. unsigned char halen;
  160. unsigned char haddr[MAX_ADDR_LEN];
  161. };
  162. /* skb control-block accessors with a little extra debugging for initial
  163. * development.
  164. *
  165. * TODO: remove checks & mctp_skb_cb->magic; replace callers of __mctp_cb
  166. * with mctp_cb().
  167. *
  168. * __mctp_cb() is only for the initial ingress code; we should see ->magic set
  169. * at all times after this.
  170. */
  171. static inline struct mctp_skb_cb *__mctp_cb(struct sk_buff *skb)
  172. {
  173. struct mctp_skb_cb *cb = (void *)skb->cb;
  174. cb->magic = 0x4d435450;
  175. return cb;
  176. }
  177. static inline struct mctp_skb_cb *mctp_cb(struct sk_buff *skb)
  178. {
  179. struct mctp_skb_cb *cb = (void *)skb->cb;
  180. BUILD_BUG_ON(sizeof(struct mctp_skb_cb) > sizeof(skb->cb));
  181. WARN_ON(cb->magic != 0x4d435450);
  182. return (void *)(skb->cb);
  183. }
  184. /* If CONFIG_MCTP_FLOWS, we may add one of these as a SKB extension,
  185. * indicating the flow to the device driver.
  186. */
  187. struct mctp_flow {
  188. struct mctp_sk_key *key;
  189. };
  190. /* Route definition.
  191. *
  192. * These are held in the pernet->mctp.routes list, with RCU protection for
  193. * removed routes. We hold a reference to the netdev; routes need to be
  194. * dropped on NETDEV_UNREGISTER events.
  195. *
  196. * Updates to the route table are performed under rtnl; all reads under RCU,
  197. * so routes cannot be referenced over a RCU grace period. Specifically: A
  198. * caller cannot block between mctp_route_lookup and mctp_route_release()
  199. */
  200. struct mctp_route {
  201. mctp_eid_t min, max;
  202. struct mctp_dev *dev;
  203. unsigned int mtu;
  204. unsigned char type;
  205. int (*output)(struct mctp_route *route,
  206. struct sk_buff *skb);
  207. struct list_head list;
  208. refcount_t refs;
  209. struct rcu_head rcu;
  210. };
  211. /* route interfaces */
  212. struct mctp_route *mctp_route_lookup(struct net *net, unsigned int dnet,
  213. mctp_eid_t daddr);
  214. int mctp_local_output(struct sock *sk, struct mctp_route *rt,
  215. struct sk_buff *skb, mctp_eid_t daddr, u8 req_tag);
  216. void mctp_key_unref(struct mctp_sk_key *key);
  217. struct mctp_sk_key *mctp_alloc_local_tag(struct mctp_sock *msk,
  218. mctp_eid_t daddr, mctp_eid_t saddr,
  219. bool manual, u8 *tagp);
  220. /* routing <--> device interface */
  221. unsigned int mctp_default_net(struct net *net);
  222. int mctp_default_net_set(struct net *net, unsigned int index);
  223. int mctp_route_add_local(struct mctp_dev *mdev, mctp_eid_t addr);
  224. int mctp_route_remove_local(struct mctp_dev *mdev, mctp_eid_t addr);
  225. void mctp_route_remove_dev(struct mctp_dev *mdev);
  226. /* neighbour definitions */
  227. enum mctp_neigh_source {
  228. MCTP_NEIGH_STATIC,
  229. MCTP_NEIGH_DISCOVER,
  230. };
  231. struct mctp_neigh {
  232. struct mctp_dev *dev;
  233. mctp_eid_t eid;
  234. enum mctp_neigh_source source;
  235. unsigned char ha[MAX_ADDR_LEN];
  236. struct list_head list;
  237. struct rcu_head rcu;
  238. };
  239. int mctp_neigh_init(void);
  240. void mctp_neigh_exit(void);
  241. // ret_hwaddr may be NULL, otherwise must have space for MAX_ADDR_LEN
  242. int mctp_neigh_lookup(struct mctp_dev *dev, mctp_eid_t eid,
  243. void *ret_hwaddr);
  244. void mctp_neigh_remove_dev(struct mctp_dev *mdev);
  245. int mctp_routes_init(void);
  246. void mctp_routes_exit(void);
  247. void mctp_device_init(void);
  248. void mctp_device_exit(void);
  249. #endif /* __NET_MCTP_H */