diff options
author | Patrick McHardy <kaber@trash.net> | 2007-03-29 14:46:52 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-03-29 14:46:52 -0400 |
commit | c01003c20563d1e75ec9828d21743919d2b43977 (patch) | |
tree | 21cae8933e8a4908d8e8c24244a627bf0c997e77 /include/net/pkt_cls.h | |
parent | db8b22550d4b83f0910d27a34d05aa16f7f7159f (diff) |
[IFB]: Fix crash on input device removal
The input_device pointer is not refcounted, which means the device may
disappear while packets are queued, causing a crash when ifb passes packets
with a stale skb->dev pointer to netif_rx().
Fix by storing the interface index instead and do a lookup where neccessary.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Acked-by: Jamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/pkt_cls.h')
-rw-r--r-- | include/net/pkt_cls.h | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index b902d24a3256..02647fe3d74b 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h | |||
@@ -352,10 +352,13 @@ tcf_change_indev(struct tcf_proto *tp, char *indev, struct rtattr *indev_tlv) | |||
352 | static inline int | 352 | static inline int |
353 | tcf_match_indev(struct sk_buff *skb, char *indev) | 353 | tcf_match_indev(struct sk_buff *skb, char *indev) |
354 | { | 354 | { |
355 | struct net_device *dev; | ||
356 | |||
355 | if (indev[0]) { | 357 | if (indev[0]) { |
356 | if (!skb->input_dev) | 358 | if (!skb->iif) |
357 | return 0; | 359 | return 0; |
358 | if (strcmp(indev, skb->input_dev->name)) | 360 | dev = __dev_get_by_index(skb->iif); |
361 | if (!dev || strcmp(indev, dev->name)) | ||
359 | return 0; | 362 | return 0; |
360 | } | 363 | } |
361 | 364 | ||