xref: /openbmc/linux/include/net/mctp.h (revision 4d8b9319282ae84f5a17b28d8b5b5d1e7e537312)
12c8e2e9aSJeremy Kerr /* SPDX-License-Identifier: GPL-2.0 */
22c8e2e9aSJeremy Kerr /*
32c8e2e9aSJeremy Kerr  * Management Component Transport Protocol (MCTP)
42c8e2e9aSJeremy Kerr  *
52c8e2e9aSJeremy Kerr  * Copyright (c) 2021 Code Construct
62c8e2e9aSJeremy Kerr  * Copyright (c) 2021 Google
72c8e2e9aSJeremy Kerr  */
82c8e2e9aSJeremy Kerr 
92c8e2e9aSJeremy Kerr #ifndef __NET_MCTP_H
102c8e2e9aSJeremy Kerr #define __NET_MCTP_H
112c8e2e9aSJeremy Kerr 
122c8e2e9aSJeremy Kerr #include <linux/bits.h>
13583be982SJeremy Kerr #include <linux/mctp.h>
14889b7da2SJeremy Kerr #include <net/net_namespace.h>
152c8e2e9aSJeremy Kerr 
162c8e2e9aSJeremy Kerr /* MCTP packet definitions */
172c8e2e9aSJeremy Kerr struct mctp_hdr {
182c8e2e9aSJeremy Kerr 	u8	ver;
192c8e2e9aSJeremy Kerr 	u8	dest;
202c8e2e9aSJeremy Kerr 	u8	src;
212c8e2e9aSJeremy Kerr 	u8	flags_seq_tag;
222c8e2e9aSJeremy Kerr };
232c8e2e9aSJeremy Kerr 
242c8e2e9aSJeremy Kerr #define MCTP_VER_MIN	1
252c8e2e9aSJeremy Kerr #define MCTP_VER_MAX	1
262c8e2e9aSJeremy Kerr 
272c8e2e9aSJeremy Kerr /* Definitions for flags_seq_tag field */
282c8e2e9aSJeremy Kerr #define MCTP_HDR_FLAG_SOM	BIT(7)
292c8e2e9aSJeremy Kerr #define MCTP_HDR_FLAG_EOM	BIT(6)
302c8e2e9aSJeremy Kerr #define MCTP_HDR_FLAG_TO	BIT(3)
312c8e2e9aSJeremy Kerr #define MCTP_HDR_FLAGS		GENMASK(5, 3)
322c8e2e9aSJeremy Kerr #define MCTP_HDR_SEQ_SHIFT	4
332c8e2e9aSJeremy Kerr #define MCTP_HDR_SEQ_MASK	GENMASK(1, 0)
342c8e2e9aSJeremy Kerr #define MCTP_HDR_TAG_SHIFT	0
352c8e2e9aSJeremy Kerr #define MCTP_HDR_TAG_MASK	GENMASK(2, 0)
362c8e2e9aSJeremy Kerr 
37889b7da2SJeremy Kerr #define MCTP_HEADER_MAXLEN	4
38889b7da2SJeremy Kerr 
39583be982SJeremy Kerr static inline bool mctp_address_ok(mctp_eid_t eid)
40583be982SJeremy Kerr {
41583be982SJeremy Kerr 	return eid >= 8 && eid < 255;
42583be982SJeremy Kerr }
43583be982SJeremy Kerr 
44583be982SJeremy Kerr static inline struct mctp_hdr *mctp_hdr(struct sk_buff *skb)
45583be982SJeremy Kerr {
46583be982SJeremy Kerr 	return (struct mctp_hdr *)skb_network_header(skb);
47583be982SJeremy Kerr }
48583be982SJeremy Kerr 
49889b7da2SJeremy Kerr struct mctp_skb_cb {
50889b7da2SJeremy Kerr 	unsigned int	magic;
51889b7da2SJeremy Kerr 	unsigned int	net;
52889b7da2SJeremy Kerr 	mctp_eid_t	src;
53889b7da2SJeremy Kerr };
54889b7da2SJeremy Kerr 
55889b7da2SJeremy Kerr /* skb control-block accessors with a little extra debugging for initial
56889b7da2SJeremy Kerr  * development.
57889b7da2SJeremy Kerr  *
58889b7da2SJeremy Kerr  * TODO: remove checks & mctp_skb_cb->magic; replace callers of __mctp_cb
59889b7da2SJeremy Kerr  * with mctp_cb().
60889b7da2SJeremy Kerr  *
61889b7da2SJeremy Kerr  * __mctp_cb() is only for the initial ingress code; we should see ->magic set
62889b7da2SJeremy Kerr  * at all times after this.
63889b7da2SJeremy Kerr  */
64889b7da2SJeremy Kerr static inline struct mctp_skb_cb *__mctp_cb(struct sk_buff *skb)
65889b7da2SJeremy Kerr {
66889b7da2SJeremy Kerr 	struct mctp_skb_cb *cb = (void *)skb->cb;
67889b7da2SJeremy Kerr 
68889b7da2SJeremy Kerr 	cb->magic = 0x4d435450;
69889b7da2SJeremy Kerr 	return cb;
70889b7da2SJeremy Kerr }
71889b7da2SJeremy Kerr 
72889b7da2SJeremy Kerr static inline struct mctp_skb_cb *mctp_cb(struct sk_buff *skb)
73889b7da2SJeremy Kerr {
74889b7da2SJeremy Kerr 	struct mctp_skb_cb *cb = (void *)skb->cb;
75889b7da2SJeremy Kerr 
76889b7da2SJeremy Kerr 	WARN_ON(cb->magic != 0x4d435450);
77889b7da2SJeremy Kerr 	return (void *)(skb->cb);
78889b7da2SJeremy Kerr }
79889b7da2SJeremy Kerr 
80889b7da2SJeremy Kerr /* Route definition.
81889b7da2SJeremy Kerr  *
82889b7da2SJeremy Kerr  * These are held in the pernet->mctp.routes list, with RCU protection for
83889b7da2SJeremy Kerr  * removed routes. We hold a reference to the netdev; routes need to be
84889b7da2SJeremy Kerr  * dropped on NETDEV_UNREGISTER events.
85889b7da2SJeremy Kerr  *
86889b7da2SJeremy Kerr  * Updates to the route table are performed under rtnl; all reads under RCU,
87889b7da2SJeremy Kerr  * so routes cannot be referenced over a RCU grace period. Specifically: A
88889b7da2SJeremy Kerr  * caller cannot block between mctp_route_lookup and passing the route to
89889b7da2SJeremy Kerr  * mctp_do_route.
90889b7da2SJeremy Kerr  */
91889b7da2SJeremy Kerr struct mctp_route {
92889b7da2SJeremy Kerr 	mctp_eid_t		min, max;
93889b7da2SJeremy Kerr 
94889b7da2SJeremy Kerr 	struct mctp_dev		*dev;
95889b7da2SJeremy Kerr 	unsigned int		mtu;
96889b7da2SJeremy Kerr 	int			(*output)(struct mctp_route *route,
97889b7da2SJeremy Kerr 					  struct sk_buff *skb);
98889b7da2SJeremy Kerr 
99889b7da2SJeremy Kerr 	struct list_head	list;
100889b7da2SJeremy Kerr 	refcount_t		refs;
101889b7da2SJeremy Kerr 	struct rcu_head		rcu;
102889b7da2SJeremy Kerr };
103889b7da2SJeremy Kerr 
104889b7da2SJeremy Kerr /* route interfaces */
105889b7da2SJeremy Kerr struct mctp_route *mctp_route_lookup(struct net *net, unsigned int dnet,
106889b7da2SJeremy Kerr 				     mctp_eid_t daddr);
107889b7da2SJeremy Kerr 
108889b7da2SJeremy Kerr int mctp_do_route(struct mctp_route *rt, struct sk_buff *skb);
109889b7da2SJeremy Kerr 
110889b7da2SJeremy Kerr int mctp_local_output(struct sock *sk, struct mctp_route *rt,
111889b7da2SJeremy Kerr 		      struct sk_buff *skb, mctp_eid_t daddr, u8 req_tag);
112889b7da2SJeremy Kerr 
113889b7da2SJeremy Kerr /* routing <--> device interface */
11406d2f4c5SMatt Johnston unsigned int mctp_default_net(struct net *net);
11506d2f4c5SMatt Johnston int mctp_default_net_set(struct net *net, unsigned int index);
116889b7da2SJeremy Kerr int mctp_route_add_local(struct mctp_dev *mdev, mctp_eid_t addr);
117889b7da2SJeremy Kerr int mctp_route_remove_local(struct mctp_dev *mdev, mctp_eid_t addr);
118889b7da2SJeremy Kerr void mctp_route_remove_dev(struct mctp_dev *mdev);
119889b7da2SJeremy Kerr 
120*4d8b9319SMatt Johnston /* neighbour definitions */
121*4d8b9319SMatt Johnston enum mctp_neigh_source {
122*4d8b9319SMatt Johnston 	MCTP_NEIGH_STATIC,
123*4d8b9319SMatt Johnston 	MCTP_NEIGH_DISCOVER,
124*4d8b9319SMatt Johnston };
125*4d8b9319SMatt Johnston 
126*4d8b9319SMatt Johnston struct mctp_neigh {
127*4d8b9319SMatt Johnston 	struct mctp_dev		*dev;
128*4d8b9319SMatt Johnston 	mctp_eid_t		eid;
129*4d8b9319SMatt Johnston 	enum mctp_neigh_source	source;
130*4d8b9319SMatt Johnston 
131*4d8b9319SMatt Johnston 	unsigned char		ha[MAX_ADDR_LEN];
132*4d8b9319SMatt Johnston 
133*4d8b9319SMatt Johnston 	struct list_head	list;
134*4d8b9319SMatt Johnston 	struct rcu_head		rcu;
135*4d8b9319SMatt Johnston };
136*4d8b9319SMatt Johnston 
137*4d8b9319SMatt Johnston int mctp_neigh_init(void);
138*4d8b9319SMatt Johnston void mctp_neigh_exit(void);
139*4d8b9319SMatt Johnston 
140*4d8b9319SMatt Johnston // ret_hwaddr may be NULL, otherwise must have space for MAX_ADDR_LEN
141*4d8b9319SMatt Johnston int mctp_neigh_lookup(struct mctp_dev *dev, mctp_eid_t eid,
142*4d8b9319SMatt Johnston 		      void *ret_hwaddr);
143*4d8b9319SMatt Johnston void mctp_neigh_remove_dev(struct mctp_dev *mdev);
144*4d8b9319SMatt Johnston 
145889b7da2SJeremy Kerr int mctp_routes_init(void);
146889b7da2SJeremy Kerr void mctp_routes_exit(void);
147889b7da2SJeremy Kerr 
148583be982SJeremy Kerr void mctp_device_init(void);
149583be982SJeremy Kerr void mctp_device_exit(void);
150583be982SJeremy Kerr 
1512c8e2e9aSJeremy Kerr #endif /* __NET_MCTP_H */
152