blob: f54c3bb6a22b52b05da086e3033d368e0cb9e494 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Common code for low-level network console, dump, and debugger code
3 *
4 * Derived from netconsole, kgdb-over-ethernet, and netdump patches
5 */
6
7#ifndef _LINUX_NETPOLL_H
8#define _LINUX_NETPOLL_H
9
10#include <linux/netdevice.h>
11#include <linux/interrupt.h>
Matt Mackall53fb95d2005-08-11 19:27:43 -070012#include <linux/rcupdate.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include <linux/list.h>
14
Cong Wangb7394d22013-01-07 20:52:39 +000015union inet_addr {
16 __u32 all[4];
17 __be32 ip;
18 __be32 ip6[4];
19 struct in_addr in;
20 struct in6_addr in6;
21};
22
Linus Torvalds1da177e2005-04-16 15:20:36 -070023struct netpoll {
24 struct net_device *dev;
Stephen Hemmingerbf6bce72006-10-26 15:46:56 -070025 char dev_name[IFNAMSIZ];
26 const char *name;
Linus Torvalds1da177e2005-04-16 15:20:36 -070027 void (*rx_hook)(struct netpoll *, int, char *, int);
Stephen Hemminger5de4a472006-10-26 15:46:55 -070028
Cong Wangb7394d22013-01-07 20:52:39 +000029 union inet_addr local_ip, remote_ip;
30 bool ipv6;
Linus Torvalds1da177e2005-04-16 15:20:36 -070031 u16 local_port, remote_port;
Stephen Hemminger09538642007-11-19 19:23:29 -080032 u8 remote_mac[ETH_ALEN];
Daniel Borkmann508e14b2010-01-12 14:27:30 +000033
34 struct list_head rx; /* rx_np list element */
Amerigo Wang38e6bc12012-08-10 01:24:38 +000035 struct rcu_head rcu;
Jeff Moyer115c1d62005-06-22 22:05:31 -070036};
37
38struct netpoll_info {
Stephen Hemminger93ec2c72006-10-26 15:46:50 -070039 atomic_t refcnt;
Daniel Borkmann508e14b2010-01-12 14:27:30 +000040
David S. Millerd9452e92008-03-04 12:28:49 -080041 int rx_flags;
Jeff Moyerfbeec2e2005-06-22 22:05:59 -070042 spinlock_t rx_lock;
Daniel Borkmann508e14b2010-01-12 14:27:30 +000043 struct list_head rx_np; /* netpolls that registered an rx_hook */
44
Cong Wangb7394d22013-01-07 20:52:39 +000045 struct sk_buff_head neigh_tx; /* list of neigh requests to reply to */
Stephen Hemmingerb6cd27e2006-10-26 15:46:51 -070046 struct sk_buff_head txq;
Daniel Borkmann508e14b2010-01-12 14:27:30 +000047
David Howells6d5aefb2006-12-05 19:36:26 +000048 struct delayed_work tx_work;
WANG Cong0e34e932010-05-06 00:47:21 -070049
50 struct netpoll *netpoll;
Amerigo Wang38e6bc12012-08-10 01:24:38 +000051 struct rcu_head rcu;
Linus Torvalds1da177e2005-04-16 15:20:36 -070052};
53
Linus Torvalds1da177e2005-04-16 15:20:36 -070054void netpoll_send_udp(struct netpoll *np, const char *msg, int len);
Satyam Sharma0bcc1812007-08-10 15:35:05 -070055void netpoll_print_options(struct netpoll *np);
Linus Torvalds1da177e2005-04-16 15:20:36 -070056int netpoll_parse_options(struct netpoll *np, char *opt);
Amerigo Wang47be03a22012-08-10 01:24:37 +000057int __netpoll_setup(struct netpoll *np, struct net_device *ndev, gfp_t gfp);
Linus Torvalds1da177e2005-04-16 15:20:36 -070058int netpoll_setup(struct netpoll *np);
59int netpoll_trap(void);
60void netpoll_set_trap(int trap);
Herbert Xu8fdd95e2010-06-10 16:12:48 +000061void __netpoll_cleanup(struct netpoll *np);
Amerigo Wang38e6bc12012-08-10 01:24:38 +000062void __netpoll_free_rcu(struct netpoll *np);
Linus Torvalds1da177e2005-04-16 15:20:36 -070063void netpoll_cleanup(struct netpoll *np);
Amerigo Wang57c5d462012-08-10 01:24:40 +000064int __netpoll_rx(struct sk_buff *skb, struct netpoll_info *npinfo);
Neil Hormanc2355e12010-10-13 16:01:49 +000065void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb,
66 struct net_device *dev);
67static inline void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
68{
Amerigo Wang28996562012-08-10 01:24:42 +000069 unsigned long flags;
70 local_irq_save(flags);
Neil Hormanc2355e12010-10-13 16:01:49 +000071 netpoll_send_skb_on_dev(np, skb, np->dev);
Amerigo Wang28996562012-08-10 01:24:42 +000072 local_irq_restore(flags);
Neil Hormanc2355e12010-10-13 16:01:49 +000073}
74
Stephen Hemminger5de4a472006-10-26 15:46:55 -070075
Linus Torvalds1da177e2005-04-16 15:20:36 -070076
77#ifdef CONFIG_NETPOLL
Amerigo Wang77ab8a52012-08-10 01:24:46 +000078static inline bool netpoll_rx_on(struct sk_buff *skb)
Amerigo Wang91fe4a42012-08-10 01:24:41 +000079{
80 struct netpoll_info *npinfo = rcu_dereference_bh(skb->dev->npinfo);
81
82 return npinfo && (!list_empty(&npinfo->rx_np) || npinfo->rx_flags);
83}
84
David S. Millerffb27362010-05-06 01:20:10 -070085static inline bool netpoll_rx(struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070086{
Herbert Xude85d992010-06-10 16:12:44 +000087 struct netpoll_info *npinfo;
Jeff Moyerfbeec2e2005-06-22 22:05:59 -070088 unsigned long flags;
David S. Millerffb27362010-05-06 01:20:10 -070089 bool ret = false;
Jeff Moyer115c1d62005-06-22 22:05:31 -070090
Herbert Xuf0f9dea2010-09-17 16:55:03 -070091 local_irq_save(flags);
Herbert Xude85d992010-06-10 16:12:44 +000092
Amerigo Wang91fe4a42012-08-10 01:24:41 +000093 if (!netpoll_rx_on(skb))
Herbert Xude85d992010-06-10 16:12:44 +000094 goto out;
Jeff Moyer115c1d62005-06-22 22:05:31 -070095
Amerigo Wang91fe4a42012-08-10 01:24:41 +000096 npinfo = rcu_dereference_bh(skb->dev->npinfo);
Herbert Xuf0f9dea2010-09-17 16:55:03 -070097 spin_lock(&npinfo->rx_lock);
David S. Millerd9452e92008-03-04 12:28:49 -080098 /* check rx_flags again with the lock held */
Amerigo Wang57c5d462012-08-10 01:24:40 +000099 if (npinfo->rx_flags && __netpoll_rx(skb, npinfo))
David S. Millerffb27362010-05-06 01:20:10 -0700100 ret = true;
Herbert Xuf0f9dea2010-09-17 16:55:03 -0700101 spin_unlock(&npinfo->rx_lock);
Jeff Moyerfbeec2e2005-06-22 22:05:59 -0700102
Herbert Xude85d992010-06-10 16:12:44 +0000103out:
Herbert Xuf0f9dea2010-09-17 16:55:03 -0700104 local_irq_restore(flags);
Jeff Moyerfbeec2e2005-06-22 22:05:59 -0700105 return ret;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106}
107
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700108static inline int netpoll_receive_skb(struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109{
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700110 if (!list_empty(&skb->dev->napi_list))
111 return netpoll_rx(skb);
112 return 0;
113}
114
115static inline void *netpoll_poll_lock(struct napi_struct *napi)
116{
117 struct net_device *dev = napi->dev;
118
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700119 if (dev && dev->npinfo) {
120 spin_lock(&napi->poll_lock);
121 napi->poll_owner = smp_processor_id();
122 return napi;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700123 }
Matt Mackall53fb95d2005-08-11 19:27:43 -0700124 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125}
126
Matt Mackall53fb95d2005-08-11 19:27:43 -0700127static inline void netpoll_poll_unlock(void *have)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128{
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700129 struct napi_struct *napi = have;
Matt Mackall53fb95d2005-08-11 19:27:43 -0700130
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700131 if (napi) {
132 napi->poll_owner = -1;
133 spin_unlock(&napi->poll_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700134 }
135}
136
Amerigo Wang77ab8a52012-08-10 01:24:46 +0000137static inline bool netpoll_tx_running(struct net_device *dev)
Herbert Xuc18370f2010-06-10 16:12:49 +0000138{
139 return irqs_disabled();
140}
141
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142#else
John W. Linville969a6e52010-08-10 16:24:41 -0700143static inline bool netpoll_rx(struct sk_buff *skb)
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700144{
Amerigo Wang77ab8a52012-08-10 01:24:46 +0000145 return false;
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700146}
Amerigo Wang77ab8a52012-08-10 01:24:46 +0000147static inline bool netpoll_rx_on(struct sk_buff *skb)
Herbert Xud1c76af2009-03-16 10:50:02 -0700148{
Amerigo Wang77ab8a52012-08-10 01:24:46 +0000149 return false;
Herbert Xud1c76af2009-03-16 10:50:02 -0700150}
Stephen Hemmingerbea33482007-10-03 16:41:36 -0700151static inline int netpoll_receive_skb(struct sk_buff *skb)
152{
153 return 0;
154}
155static inline void *netpoll_poll_lock(struct napi_struct *napi)
156{
157 return NULL;
158}
159static inline void netpoll_poll_unlock(void *have)
160{
161}
162static inline void netpoll_netdev_init(struct net_device *dev)
163{
164}
Amerigo Wang77ab8a52012-08-10 01:24:46 +0000165static inline bool netpoll_tx_running(struct net_device *dev)
Herbert Xuc18370f2010-06-10 16:12:49 +0000166{
Amerigo Wang77ab8a52012-08-10 01:24:46 +0000167 return false;
Herbert Xuc18370f2010-06-10 16:12:49 +0000168}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700169#endif
170
171#endif