Skip to content

Commit 67737c4

Browse files
jk-ozlabsdavem330
authored andcommitted
mctp: Pass flow data & flow release events to drivers
Now that we have an extension for MCTP data in skbs, populate the flow when a key has been created for the packet, and add a device driver operation to inform of flow destruction. Includes a fix for a warning with test builds: Reported-by: kernel test robot <lkp@intel.com> Signed-off-by: Jeremy Kerr <jk@codeconstruct.com.au> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 78476d3 commit 67737c4

File tree

4 files changed

+126
-2
lines changed

4 files changed

+126
-2
lines changed

include/net/mctp.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,12 @@ struct mctp_sk_key {
152152

153153
/* expiry timeout; valid (above) cleared on expiry */
154154
unsigned long expiry;
155+
156+
/* free to use for device flow state tracking. Initialised to
157+
* zero on initial key creation
158+
*/
159+
unsigned long dev_flow_state;
160+
struct mctp_dev *dev;
155161
};
156162

157163
struct mctp_skb_cb {

include/net/mctpdevice.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,17 @@
1414
#include <linux/types.h>
1515
#include <linux/refcount.h>
1616

17+
struct mctp_sk_key;
18+
1719
struct mctp_dev {
1820
struct net_device *dev;
1921

2022
refcount_t refs;
2123

2224
unsigned int net;
2325

26+
const struct mctp_netdev_ops *ops;
27+
2428
/* Only modified under RTNL. Reads have addrs_lock held */
2529
u8 *addrs;
2630
size_t num_addrs;
@@ -29,12 +33,24 @@ struct mctp_dev {
2933
struct rcu_head rcu;
3034
};
3135

36+
struct mctp_netdev_ops {
37+
void (*release_flow)(struct mctp_dev *dev,
38+
struct mctp_sk_key *key);
39+
};
40+
3241
#define MCTP_INITIAL_DEFAULT_NET 1
3342

3443
struct mctp_dev *mctp_dev_get_rtnl(const struct net_device *dev);
3544
struct mctp_dev *__mctp_dev_get(const struct net_device *dev);
3645

46+
int mctp_register_netdev(struct net_device *dev,
47+
const struct mctp_netdev_ops *ops);
48+
void mctp_unregister_netdev(struct net_device *dev);
49+
3750
void mctp_dev_hold(struct mctp_dev *mdev);
3851
void mctp_dev_put(struct mctp_dev *mdev);
3952

53+
void mctp_dev_set_key(struct mctp_dev *dev, struct mctp_sk_key *key);
54+
void mctp_dev_release_key(struct mctp_dev *dev, struct mctp_sk_key *key);
55+
4056
#endif /* __NET_MCTPDEVICE_H */

net/mctp/device.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,24 @@ void mctp_dev_put(struct mctp_dev *mdev)
260260
}
261261
}
262262

263+
void mctp_dev_release_key(struct mctp_dev *dev, struct mctp_sk_key *key)
264+
__must_hold(&key->lock)
265+
{
266+
if (!dev)
267+
return;
268+
if (dev->ops && dev->ops->release_flow)
269+
dev->ops->release_flow(dev, key);
270+
key->dev = NULL;
271+
mctp_dev_put(dev);
272+
}
273+
274+
void mctp_dev_set_key(struct mctp_dev *dev, struct mctp_sk_key *key)
275+
__must_hold(&key->lock)
276+
{
277+
mctp_dev_hold(dev);
278+
key->dev = dev;
279+
}
280+
263281
static struct mctp_dev *mctp_add_dev(struct net_device *dev)
264282
{
265283
struct mctp_dev *mdev;
@@ -414,6 +432,39 @@ static int mctp_dev_notify(struct notifier_block *this, unsigned long event,
414432
return NOTIFY_OK;
415433
}
416434

435+
static int mctp_register_netdevice(struct net_device *dev,
436+
const struct mctp_netdev_ops *ops)
437+
{
438+
struct mctp_dev *mdev;
439+
440+
mdev = mctp_add_dev(dev);
441+
if (IS_ERR(mdev))
442+
return PTR_ERR(mdev);
443+
444+
mdev->ops = ops;
445+
446+
return register_netdevice(dev);
447+
}
448+
449+
int mctp_register_netdev(struct net_device *dev,
450+
const struct mctp_netdev_ops *ops)
451+
{
452+
int rc;
453+
454+
rtnl_lock();
455+
rc = mctp_register_netdevice(dev, ops);
456+
rtnl_unlock();
457+
458+
return rc;
459+
}
460+
EXPORT_SYMBOL_GPL(mctp_register_netdev);
461+
462+
void mctp_unregister_netdev(struct net_device *dev)
463+
{
464+
unregister_netdev(dev);
465+
}
466+
EXPORT_SYMBOL_GPL(mctp_unregister_netdev);
467+
417468
static struct rtnl_af_ops mctp_af_ops = {
418469
.family = AF_MCTP,
419470
.fill_link_af = mctp_fill_link_af,

net/mctp/route.c

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
static const unsigned int mctp_message_maxlen = 64 * 1024;
3030
static const unsigned long mctp_key_lifetime = 6 * CONFIG_HZ;
3131

32+
static void mctp_flow_prepare_output(struct sk_buff *skb, struct mctp_dev *dev);
33+
3234
/* route output callbacks */
3335
static int mctp_route_discard(struct mctp_route *route, struct sk_buff *skb)
3436
{
@@ -152,8 +154,19 @@ static struct mctp_sk_key *mctp_key_alloc(struct mctp_sock *msk,
152154

153155
void mctp_key_unref(struct mctp_sk_key *key)
154156
{
155-
if (refcount_dec_and_test(&key->refs))
156-
kfree(key);
157+
unsigned long flags;
158+
159+
if (!refcount_dec_and_test(&key->refs))
160+
return;
161+
162+
/* even though no refs exist here, the lock allows us to stay
163+
* consistent with the locking requirement of mctp_dev_release_key
164+
*/
165+
spin_lock_irqsave(&key->lock, flags);
166+
mctp_dev_release_key(key->dev, key);
167+
spin_unlock_irqrestore(&key->lock, flags);
168+
169+
kfree(key);
157170
}
158171

159172
static int mctp_key_add(struct mctp_sk_key *key, struct mctp_sock *msk)
@@ -204,6 +217,7 @@ static void __mctp_key_unlock_drop(struct mctp_sk_key *key, struct net *net,
204217
key->reasm_head = NULL;
205218
key->reasm_dead = true;
206219
key->valid = false;
220+
mctp_dev_release_key(key->dev, key);
207221
spin_unlock_irqrestore(&key->lock, flags);
208222

209223
spin_lock_irqsave(&net->mctp.keys_lock, flags);
@@ -222,6 +236,40 @@ static void __mctp_key_unlock_drop(struct mctp_sk_key *key, struct net *net,
222236

223237
}
224238

239+
#ifdef CONFIG_MCTP_FLOWS
240+
static void mctp_skb_set_flow(struct sk_buff *skb, struct mctp_sk_key *key)
241+
{
242+
struct mctp_flow *flow;
243+
244+
flow = skb_ext_add(skb, SKB_EXT_MCTP);
245+
if (!flow)
246+
return;
247+
248+
refcount_inc(&key->refs);
249+
flow->key = key;
250+
}
251+
252+
static void mctp_flow_prepare_output(struct sk_buff *skb, struct mctp_dev *dev)
253+
{
254+
struct mctp_sk_key *key;
255+
struct mctp_flow *flow;
256+
257+
flow = skb_ext_find(skb, SKB_EXT_MCTP);
258+
if (!flow)
259+
return;
260+
261+
key = flow->key;
262+
263+
if (WARN_ON(key->dev && key->dev != dev))
264+
return;
265+
266+
mctp_dev_set_key(dev, key);
267+
}
268+
#else
269+
static void mctp_skb_set_flow(struct sk_buff *skb, struct mctp_sk_key *key) {}
270+
static void mctp_flow_prepare_output(struct sk_buff *skb, struct mctp_dev *dev) {}
271+
#endif
272+
225273
static int mctp_frag_queue(struct mctp_sk_key *key, struct sk_buff *skb)
226274
{
227275
struct mctp_hdr *hdr = mctp_hdr(skb);
@@ -465,6 +513,8 @@ static int mctp_route_output(struct mctp_route *route, struct sk_buff *skb)
465513
return -EHOSTUNREACH;
466514
}
467515

516+
mctp_flow_prepare_output(skb, route->dev);
517+
468518
rc = dev_queue_xmit(skb);
469519
if (rc)
470520
rc = net_xmit_errno(rc);
@@ -803,6 +853,7 @@ int mctp_local_output(struct sock *sk, struct mctp_route *rt,
803853
rc = PTR_ERR(key);
804854
goto out_release;
805855
}
856+
mctp_skb_set_flow(skb, key);
806857
/* done with the key in this scope */
807858
mctp_key_unref(key);
808859
tag |= MCTP_HDR_FLAG_TO;

0 commit comments

Comments
 (0)