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