Skip to content

Commit

Permalink
mctp: Add initial routing framework
Browse files Browse the repository at this point in the history
Add a simple routing table, and a couple of route output handlers, and
the mctp packet_type & handler.

Includes changes from Matt Johnston <[email protected]>.

Signed-off-by: Jeremy Kerr <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
jk-ozlabs authored and davem330 committed Jul 29, 2021
1 parent 583be98 commit 889b7da
Show file tree
Hide file tree
Showing 8 changed files with 441 additions and 1 deletion.
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -11040,6 +11040,7 @@ S: Maintained
F: drivers/net/mctp/
F: include/net/mctp.h
F: include/net/mctpdevice.h
F: include/net/netns/mctp.h
F: net/mctp/

MAN-PAGES: MANUAL PAGES FOR LINUX -- Sections 2, 3, 4, 5, and 7
Expand Down
75 changes: 75 additions & 0 deletions include/net/mctp.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#include <linux/bits.h>
#include <linux/mctp.h>
#include <net/net_namespace.h>

/* MCTP packet definitions */
struct mctp_hdr {
Expand All @@ -33,6 +34,8 @@ struct mctp_hdr {
#define MCTP_HDR_TAG_SHIFT 0
#define MCTP_HDR_TAG_MASK GENMASK(2, 0)

#define MCTP_HEADER_MAXLEN 4

static inline bool mctp_address_ok(mctp_eid_t eid)
{
return eid >= 8 && eid < 255;
Expand All @@ -43,6 +46,78 @@ static inline struct mctp_hdr *mctp_hdr(struct sk_buff *skb)
return (struct mctp_hdr *)skb_network_header(skb);
}

struct mctp_skb_cb {
unsigned int magic;
unsigned int net;
mctp_eid_t src;
};

/* skb control-block accessors with a little extra debugging for initial
* development.
*
* TODO: remove checks & mctp_skb_cb->magic; replace callers of __mctp_cb
* with mctp_cb().
*
* __mctp_cb() is only for the initial ingress code; we should see ->magic set
* at all times after this.
*/
static inline struct mctp_skb_cb *__mctp_cb(struct sk_buff *skb)
{
struct mctp_skb_cb *cb = (void *)skb->cb;

cb->magic = 0x4d435450;
return cb;
}

static inline struct mctp_skb_cb *mctp_cb(struct sk_buff *skb)
{
struct mctp_skb_cb *cb = (void *)skb->cb;

WARN_ON(cb->magic != 0x4d435450);
return (void *)(skb->cb);
}

/* Route definition.
*
* These are held in the pernet->mctp.routes list, with RCU protection for
* removed routes. We hold a reference to the netdev; routes need to be
* dropped on NETDEV_UNREGISTER events.
*
* Updates to the route table are performed under rtnl; all reads under RCU,
* so routes cannot be referenced over a RCU grace period. Specifically: A
* caller cannot block between mctp_route_lookup and passing the route to
* mctp_do_route.
*/
struct mctp_route {
mctp_eid_t min, max;

struct mctp_dev *dev;
unsigned int mtu;
int (*output)(struct mctp_route *route,
struct sk_buff *skb);

struct list_head list;
refcount_t refs;
struct rcu_head rcu;
};

/* route interfaces */
struct mctp_route *mctp_route_lookup(struct net *net, unsigned int dnet,
mctp_eid_t daddr);

int mctp_do_route(struct mctp_route *rt, struct sk_buff *skb);

int mctp_local_output(struct sock *sk, struct mctp_route *rt,
struct sk_buff *skb, mctp_eid_t daddr, u8 req_tag);

/* routing <--> device interface */
int mctp_route_add_local(struct mctp_dev *mdev, mctp_eid_t addr);
int mctp_route_remove_local(struct mctp_dev *mdev, mctp_eid_t addr);
void mctp_route_remove_dev(struct mctp_dev *mdev);

int mctp_routes_init(void);
void mctp_routes_exit(void);

void mctp_device_init(void);
void mctp_device_exit(void);

Expand Down
4 changes: 4 additions & 0 deletions include/net/net_namespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <net/netns/xdp.h>
#include <net/netns/smc.h>
#include <net/netns/bpf.h>
#include <net/netns/mctp.h>
#include <linux/ns_common.h>
#include <linux/idr.h>
#include <linux/skbuff.h>
Expand Down Expand Up @@ -167,6 +168,9 @@ struct net {
#ifdef CONFIG_XDP_SOCKETS
struct netns_xdp xdp;
#endif
#if IS_ENABLED(CONFIG_MCTP)
struct netns_mctp mctp;
#endif
#if IS_ENABLED(CONFIG_CRYPTO_USER)
struct sock *crypto_nlsk;
#endif
Expand Down
16 changes: 16 additions & 0 deletions include/net/netns/mctp.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* MCTP per-net structures
*/

#ifndef __NETNS_MCTP_H__
#define __NETNS_MCTP_H__

#include <linux/types.h>

struct netns_mctp {
/* Only updated under RTNL, entries freed via RCU */
struct list_head routes;
};

#endif /* __NETNS_MCTP_H__ */
2 changes: 1 addition & 1 deletion net/mctp/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_MCTP) += mctp.o
mctp-objs := af_mctp.o device.o
mctp-objs := af_mctp.o device.o route.o
7 changes: 7 additions & 0 deletions net/mctp/af_mctp.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,16 @@ static __init int mctp_init(void)
if (rc)
goto err_unreg_sock;

rc = mctp_routes_init();
if (rc)
goto err_unreg_proto;

mctp_device_init();

return 0;

err_unreg_proto:
proto_unregister(&mctp_proto);
err_unreg_sock:
sock_unregister(PF_MCTP);

Expand All @@ -170,6 +176,7 @@ static __init int mctp_init(void)
static __exit void mctp_exit(void)
{
mctp_device_exit();
mctp_routes_exit();
proto_unregister(&mctp_proto);
sock_unregister(PF_MCTP);
}
Expand Down
8 changes: 8 additions & 0 deletions net/mctp/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ static int mctp_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,

kfree(tmp_addrs);

mctp_route_add_local(mdev, addr->s_addr);

return 0;
}

Expand Down Expand Up @@ -240,6 +242,11 @@ static int mctp_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh,
if (!pos)
return -ENOENT;

rc = mctp_route_remove_local(mdev, addr->s_addr);
// we can ignore -ENOENT in the case a route was already removed
if (rc < 0 && rc != -ENOENT)
return rc;

spin_lock_irqsave(&mdev->addrs_lock, flags);
memmove(pos, pos + 1, mdev->num_addrs - 1 - (pos - mdev->addrs));
mdev->num_addrs--;
Expand Down Expand Up @@ -334,6 +341,7 @@ static void mctp_unregister(struct net_device *dev)

RCU_INIT_POINTER(mdev->dev->mctp_ptr, NULL);

mctp_route_remove_dev(mdev);
kfree(mdev->addrs);

mctp_dev_destroy(mdev);
Expand Down
Loading

0 comments on commit 889b7da

Please sign in to comment.