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> 15*833ef3b9SJeremy Kerr #include <net/sock.h> 162c8e2e9aSJeremy Kerr 172c8e2e9aSJeremy Kerr /* MCTP packet definitions */ 182c8e2e9aSJeremy Kerr struct mctp_hdr { 192c8e2e9aSJeremy Kerr u8 ver; 202c8e2e9aSJeremy Kerr u8 dest; 212c8e2e9aSJeremy Kerr u8 src; 222c8e2e9aSJeremy Kerr u8 flags_seq_tag; 232c8e2e9aSJeremy Kerr }; 242c8e2e9aSJeremy Kerr 252c8e2e9aSJeremy Kerr #define MCTP_VER_MIN 1 262c8e2e9aSJeremy Kerr #define MCTP_VER_MAX 1 272c8e2e9aSJeremy Kerr 282c8e2e9aSJeremy Kerr /* Definitions for flags_seq_tag field */ 292c8e2e9aSJeremy Kerr #define MCTP_HDR_FLAG_SOM BIT(7) 302c8e2e9aSJeremy Kerr #define MCTP_HDR_FLAG_EOM BIT(6) 312c8e2e9aSJeremy Kerr #define MCTP_HDR_FLAG_TO BIT(3) 322c8e2e9aSJeremy Kerr #define MCTP_HDR_FLAGS GENMASK(5, 3) 332c8e2e9aSJeremy Kerr #define MCTP_HDR_SEQ_SHIFT 4 342c8e2e9aSJeremy Kerr #define MCTP_HDR_SEQ_MASK GENMASK(1, 0) 352c8e2e9aSJeremy Kerr #define MCTP_HDR_TAG_SHIFT 0 362c8e2e9aSJeremy Kerr #define MCTP_HDR_TAG_MASK GENMASK(2, 0) 372c8e2e9aSJeremy Kerr 38889b7da2SJeremy Kerr #define MCTP_HEADER_MAXLEN 4 39889b7da2SJeremy Kerr 40583be982SJeremy Kerr static inline bool mctp_address_ok(mctp_eid_t eid) 41583be982SJeremy Kerr { 42583be982SJeremy Kerr return eid >= 8 && eid < 255; 43583be982SJeremy Kerr } 44583be982SJeremy Kerr 45583be982SJeremy Kerr static inline struct mctp_hdr *mctp_hdr(struct sk_buff *skb) 46583be982SJeremy Kerr { 47583be982SJeremy Kerr return (struct mctp_hdr *)skb_network_header(skb); 48583be982SJeremy Kerr } 49583be982SJeremy Kerr 50*833ef3b9SJeremy Kerr /* socket implementation */ 51*833ef3b9SJeremy Kerr struct mctp_sock { 52*833ef3b9SJeremy Kerr struct sock sk; 53*833ef3b9SJeremy Kerr 54*833ef3b9SJeremy Kerr /* bind() params */ 55*833ef3b9SJeremy Kerr int bind_net; 56*833ef3b9SJeremy Kerr mctp_eid_t bind_addr; 57*833ef3b9SJeremy Kerr __u8 bind_type; 58*833ef3b9SJeremy Kerr 59*833ef3b9SJeremy Kerr /* list of mctp_sk_key, for incoming tag lookup. updates protected 60*833ef3b9SJeremy Kerr * by sk->net->keys_lock 61*833ef3b9SJeremy Kerr */ 62*833ef3b9SJeremy Kerr struct hlist_head keys; 63*833ef3b9SJeremy Kerr }; 64*833ef3b9SJeremy Kerr 65*833ef3b9SJeremy Kerr /* Key for matching incoming packets to sockets or reassembly contexts. 66*833ef3b9SJeremy Kerr * Packets are matched on (src,dest,tag). 67*833ef3b9SJeremy Kerr * 68*833ef3b9SJeremy Kerr * Lifetime requirements: 69*833ef3b9SJeremy Kerr * 70*833ef3b9SJeremy Kerr * - keys are free()ed via RCU 71*833ef3b9SJeremy Kerr * 72*833ef3b9SJeremy Kerr * - a mctp_sk_key contains a reference to a struct sock; this is valid 73*833ef3b9SJeremy Kerr * for the life of the key. On sock destruction (through unhash), the key is 74*833ef3b9SJeremy Kerr * removed from lists (see below), and will not be observable after a RCU 75*833ef3b9SJeremy Kerr * grace period. 76*833ef3b9SJeremy Kerr * 77*833ef3b9SJeremy Kerr * any RX occurring within that grace period may still queue to the socket, 78*833ef3b9SJeremy Kerr * but will hit the SOCK_DEAD case before the socket is freed. 79*833ef3b9SJeremy Kerr * 80*833ef3b9SJeremy Kerr * - these mctp_sk_keys appear on two lists: 81*833ef3b9SJeremy Kerr * 1) the struct mctp_sock->keys list 82*833ef3b9SJeremy Kerr * 2) the struct netns_mctp->keys list 83*833ef3b9SJeremy Kerr * 84*833ef3b9SJeremy Kerr * updates to either list are performed under the netns_mctp->keys 85*833ef3b9SJeremy Kerr * lock. 86*833ef3b9SJeremy Kerr * 87*833ef3b9SJeremy Kerr * - there is a single destruction path for a mctp_sk_key - through socket 88*833ef3b9SJeremy Kerr * unhash (see mctp_sk_unhash). This performs the list removal under 89*833ef3b9SJeremy Kerr * keys_lock. 90*833ef3b9SJeremy Kerr */ 91*833ef3b9SJeremy Kerr struct mctp_sk_key { 92*833ef3b9SJeremy Kerr mctp_eid_t peer_addr; 93*833ef3b9SJeremy Kerr mctp_eid_t local_addr; 94*833ef3b9SJeremy Kerr __u8 tag; /* incoming tag match; invert TO for local */ 95*833ef3b9SJeremy Kerr 96*833ef3b9SJeremy Kerr /* we hold a ref to sk when set */ 97*833ef3b9SJeremy Kerr struct sock *sk; 98*833ef3b9SJeremy Kerr 99*833ef3b9SJeremy Kerr /* routing lookup list */ 100*833ef3b9SJeremy Kerr struct hlist_node hlist; 101*833ef3b9SJeremy Kerr 102*833ef3b9SJeremy Kerr /* per-socket list */ 103*833ef3b9SJeremy Kerr struct hlist_node sklist; 104*833ef3b9SJeremy Kerr 105*833ef3b9SJeremy Kerr struct rcu_head rcu; 106*833ef3b9SJeremy Kerr }; 107*833ef3b9SJeremy Kerr 108889b7da2SJeremy Kerr struct mctp_skb_cb { 109889b7da2SJeremy Kerr unsigned int magic; 110889b7da2SJeremy Kerr unsigned int net; 111889b7da2SJeremy Kerr mctp_eid_t src; 112889b7da2SJeremy Kerr }; 113889b7da2SJeremy Kerr 114889b7da2SJeremy Kerr /* skb control-block accessors with a little extra debugging for initial 115889b7da2SJeremy Kerr * development. 116889b7da2SJeremy Kerr * 117889b7da2SJeremy Kerr * TODO: remove checks & mctp_skb_cb->magic; replace callers of __mctp_cb 118889b7da2SJeremy Kerr * with mctp_cb(). 119889b7da2SJeremy Kerr * 120889b7da2SJeremy Kerr * __mctp_cb() is only for the initial ingress code; we should see ->magic set 121889b7da2SJeremy Kerr * at all times after this. 122889b7da2SJeremy Kerr */ 123889b7da2SJeremy Kerr static inline struct mctp_skb_cb *__mctp_cb(struct sk_buff *skb) 124889b7da2SJeremy Kerr { 125889b7da2SJeremy Kerr struct mctp_skb_cb *cb = (void *)skb->cb; 126889b7da2SJeremy Kerr 127889b7da2SJeremy Kerr cb->magic = 0x4d435450; 128889b7da2SJeremy Kerr return cb; 129889b7da2SJeremy Kerr } 130889b7da2SJeremy Kerr 131889b7da2SJeremy Kerr static inline struct mctp_skb_cb *mctp_cb(struct sk_buff *skb) 132889b7da2SJeremy Kerr { 133889b7da2SJeremy Kerr struct mctp_skb_cb *cb = (void *)skb->cb; 134889b7da2SJeremy Kerr 135889b7da2SJeremy Kerr WARN_ON(cb->magic != 0x4d435450); 136889b7da2SJeremy Kerr return (void *)(skb->cb); 137889b7da2SJeremy Kerr } 138889b7da2SJeremy Kerr 139889b7da2SJeremy Kerr /* Route definition. 140889b7da2SJeremy Kerr * 141889b7da2SJeremy Kerr * These are held in the pernet->mctp.routes list, with RCU protection for 142889b7da2SJeremy Kerr * removed routes. We hold a reference to the netdev; routes need to be 143889b7da2SJeremy Kerr * dropped on NETDEV_UNREGISTER events. 144889b7da2SJeremy Kerr * 145889b7da2SJeremy Kerr * Updates to the route table are performed under rtnl; all reads under RCU, 146889b7da2SJeremy Kerr * so routes cannot be referenced over a RCU grace period. Specifically: A 147889b7da2SJeremy Kerr * caller cannot block between mctp_route_lookup and passing the route to 148889b7da2SJeremy Kerr * mctp_do_route. 149889b7da2SJeremy Kerr */ 150889b7da2SJeremy Kerr struct mctp_route { 151889b7da2SJeremy Kerr mctp_eid_t min, max; 152889b7da2SJeremy Kerr 153889b7da2SJeremy Kerr struct mctp_dev *dev; 154889b7da2SJeremy Kerr unsigned int mtu; 155889b7da2SJeremy Kerr int (*output)(struct mctp_route *route, 156889b7da2SJeremy Kerr struct sk_buff *skb); 157889b7da2SJeremy Kerr 158889b7da2SJeremy Kerr struct list_head list; 159889b7da2SJeremy Kerr refcount_t refs; 160889b7da2SJeremy Kerr struct rcu_head rcu; 161889b7da2SJeremy Kerr }; 162889b7da2SJeremy Kerr 163889b7da2SJeremy Kerr /* route interfaces */ 164889b7da2SJeremy Kerr struct mctp_route *mctp_route_lookup(struct net *net, unsigned int dnet, 165889b7da2SJeremy Kerr mctp_eid_t daddr); 166889b7da2SJeremy Kerr 167889b7da2SJeremy Kerr int mctp_do_route(struct mctp_route *rt, struct sk_buff *skb); 168889b7da2SJeremy Kerr 169889b7da2SJeremy Kerr int mctp_local_output(struct sock *sk, struct mctp_route *rt, 170889b7da2SJeremy Kerr struct sk_buff *skb, mctp_eid_t daddr, u8 req_tag); 171889b7da2SJeremy Kerr 172889b7da2SJeremy Kerr /* routing <--> device interface */ 17306d2f4c5SMatt Johnston unsigned int mctp_default_net(struct net *net); 17406d2f4c5SMatt Johnston int mctp_default_net_set(struct net *net, unsigned int index); 175889b7da2SJeremy Kerr int mctp_route_add_local(struct mctp_dev *mdev, mctp_eid_t addr); 176889b7da2SJeremy Kerr int mctp_route_remove_local(struct mctp_dev *mdev, mctp_eid_t addr); 177889b7da2SJeremy Kerr void mctp_route_remove_dev(struct mctp_dev *mdev); 178889b7da2SJeremy Kerr 1794d8b9319SMatt Johnston /* neighbour definitions */ 1804d8b9319SMatt Johnston enum mctp_neigh_source { 1814d8b9319SMatt Johnston MCTP_NEIGH_STATIC, 1824d8b9319SMatt Johnston MCTP_NEIGH_DISCOVER, 1834d8b9319SMatt Johnston }; 1844d8b9319SMatt Johnston 1854d8b9319SMatt Johnston struct mctp_neigh { 1864d8b9319SMatt Johnston struct mctp_dev *dev; 1874d8b9319SMatt Johnston mctp_eid_t eid; 1884d8b9319SMatt Johnston enum mctp_neigh_source source; 1894d8b9319SMatt Johnston 1904d8b9319SMatt Johnston unsigned char ha[MAX_ADDR_LEN]; 1914d8b9319SMatt Johnston 1924d8b9319SMatt Johnston struct list_head list; 1934d8b9319SMatt Johnston struct rcu_head rcu; 1944d8b9319SMatt Johnston }; 1954d8b9319SMatt Johnston 1964d8b9319SMatt Johnston int mctp_neigh_init(void); 1974d8b9319SMatt Johnston void mctp_neigh_exit(void); 1984d8b9319SMatt Johnston 1994d8b9319SMatt Johnston // ret_hwaddr may be NULL, otherwise must have space for MAX_ADDR_LEN 2004d8b9319SMatt Johnston int mctp_neigh_lookup(struct mctp_dev *dev, mctp_eid_t eid, 2014d8b9319SMatt Johnston void *ret_hwaddr); 2024d8b9319SMatt Johnston void mctp_neigh_remove_dev(struct mctp_dev *mdev); 2034d8b9319SMatt Johnston 204889b7da2SJeremy Kerr int mctp_routes_init(void); 205889b7da2SJeremy Kerr void mctp_routes_exit(void); 206889b7da2SJeremy Kerr 207583be982SJeremy Kerr void mctp_device_init(void); 208583be982SJeremy Kerr void mctp_device_exit(void); 209583be982SJeremy Kerr 2102c8e2e9aSJeremy Kerr #endif /* __NET_MCTP_H */ 211