Blame view

Documentation/connector/cn_test.c 4.58 KB
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
1
2
3
  /*
   * 	cn_test.c
   * 
acb9c1b2f   Evgeniy Polyakov   connector: mainta...
4
   * 2004+ Copyright (c) Evgeniy Polyakov <zbr@ioremap.net>
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
   * All rights reserved.
   * 
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write to the Free Software
   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   */
37cf2b8d1   Mike Frysinger   connector: get te...
21
  #define pr_fmt(fmt) "cn_test: " fmt
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
22
23
24
25
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/moduleparam.h>
  #include <linux/skbuff.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
26
  #include <linux/slab.h>
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
27
  #include <linux/timer.h>
18a0c2361   Carlo Comin   [CONNECTOR]: Fix ...
28
  #include <linux/connector.h>
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
29

37cf2b8d1   Mike Frysinger   connector: get te...
30
  static struct cb_id cn_test_id = { CN_NETLINK_USERS + 3, 0x456 };
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
31
32
33
  static char cn_test_name[] = "cn_test";
  static struct sock *nls;
  static struct timer_list cn_test_timer;
7069331db   Philipp Reisner   connector: Provid...
34
  static void cn_test_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
35
  {
37cf2b8d1   Mike Frysinger   connector: get te...
36
37
38
39
40
  	pr_info("%s: %lu: idx=%x, val=%x, seq=%u, ack=%u, len=%d: %s.
  ",
  	        __func__, jiffies, msg->id.idx, msg->id.val,
  	        msg->seq, msg->ack, msg->len,
  	        msg->len ? (char *)msg->data : "");
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
41
  }
28f06c6f4   Jaswinder Singh Rajput   Documentation/con...
42
43
44
45
46
47
  /*
   * Do not remove this function even if no one is using it as
   * this is an example of how to get notifications about new
   * connector user registration
   */
  #if 0
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
  static int cn_test_want_notify(void)
  {
  	struct cn_ctl_msg *ctl;
  	struct cn_notify_req *req;
  	struct cn_msg *msg = NULL;
  	int size, size0;
  	struct sk_buff *skb;
  	struct nlmsghdr *nlh;
  	u32 group = 1;
  
  	size0 = sizeof(*msg) + sizeof(*ctl) + 3 * sizeof(*req);
  
  	size = NLMSG_SPACE(size0);
  
  	skb = alloc_skb(size, GFP_ATOMIC);
  	if (!skb) {
37cf2b8d1   Mike Frysinger   connector: get te...
64
65
  		pr_err("failed to allocate new skb with size=%u
  ", size);
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  		return -ENOMEM;
  	}
  
  	nlh = NLMSG_PUT(skb, 0, 0x123, NLMSG_DONE, size - sizeof(*nlh));
  
  	msg = (struct cn_msg *)NLMSG_DATA(nlh);
  
  	memset(msg, 0, size0);
  
  	msg->id.idx = -1;
  	msg->id.val = -1;
  	msg->seq = 0x123;
  	msg->ack = 0x345;
  	msg->len = size0 - sizeof(*msg);
  
  	ctl = (struct cn_ctl_msg *)(msg + 1);
  
  	ctl->idx_notify_num = 1;
  	ctl->val_notify_num = 2;
  	ctl->group = group;
  	ctl->len = msg->len - sizeof(*ctl);
  
  	req = (struct cn_notify_req *)(ctl + 1);
  
  	/*
  	 * Idx.
  	 */
  	req->first = cn_test_id.idx;
  	req->range = 10;
  
  	/*
  	 * Val 0.
  	 */
  	req++;
  	req->first = cn_test_id.val;
  	req->range = 10;
  
  	/*
  	 * Val 1.
  	 */
  	req++;
  	req->first = cn_test_id.val + 20;
  	req->range = 10;
18a0c2361   Carlo Comin   [CONNECTOR]: Fix ...
109
  	NETLINK_CB(skb).dst_group = ctl->group;
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
110
111
  	//netlink_broadcast(nls, skb, 0, ctl->group, GFP_ATOMIC);
  	netlink_unicast(nls, skb, 0, 0);
37cf2b8d1   Mike Frysinger   connector: get te...
112
113
  	pr_info("request was sent: group=0x%x
  ", ctl->group);
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
114
115
116
117
  
  	return 0;
  
  nlmsg_failure:
37cf2b8d1   Mike Frysinger   connector: get te...
118
119
  	pr_err("failed to send %u.%u
  ", msg->seq, msg->ack);
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
120
121
122
  	kfree_skb(skb);
  	return -EINVAL;
  }
28f06c6f4   Jaswinder Singh Rajput   Documentation/con...
123
  #endif
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
124
125
126
127
128
129
  
  static u32 cn_test_timer_counter;
  static void cn_test_timer_func(unsigned long __data)
  {
  	struct cn_msg *m;
  	char data[32];
37cf2b8d1   Mike Frysinger   connector: get te...
130
131
  	pr_debug("%s: timer fired with data %lu
  ", __func__, __data);
dd00cc486   Yoann Padioleau   some kmalloc/mems...
132
  	m = kzalloc(sizeof(*m) + sizeof(data), GFP_ATOMIC);
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
133
  	if (m) {
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
134
135
136
137
138
139
140
141
142
143
  
  		memcpy(&m->id, &cn_test_id, sizeof(m->id));
  		m->seq = cn_test_timer_counter;
  		m->len = sizeof(data);
  
  		m->len =
  		    scnprintf(data, sizeof(data), "counter = %u",
  			      cn_test_timer_counter) + 1;
  
  		memcpy(m + 1, data, m->len);
f82da7233   Andrew Morton   Documentation/con...
144
  		cn_netlink_send(m, 0, GFP_ATOMIC);
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
145
146
147
148
  		kfree(m);
  	}
  
  	cn_test_timer_counter++;
37cf2b8d1   Mike Frysinger   connector: get te...
149
  	mod_timer(&cn_test_timer, jiffies + msecs_to_jiffies(1000));
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
  }
  
  static int cn_test_init(void)
  {
  	int err;
  
  	err = cn_add_callback(&cn_test_id, cn_test_name, cn_test_callback);
  	if (err)
  		goto err_out;
  	cn_test_id.val++;
  	err = cn_add_callback(&cn_test_id, cn_test_name, cn_test_callback);
  	if (err) {
  		cn_del_callback(&cn_test_id);
  		goto err_out;
  	}
f82da7233   Andrew Morton   Documentation/con...
165
  	setup_timer(&cn_test_timer, cn_test_timer_func, 0);
37cf2b8d1   Mike Frysinger   connector: get te...
166
167
168
169
170
  	mod_timer(&cn_test_timer, jiffies + msecs_to_jiffies(1000));
  
  	pr_info("initialized with id={%u.%u}
  ",
  		cn_test_id.idx, cn_test_id.val);
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
  
  	return 0;
  
        err_out:
  	if (nls && nls->sk_socket)
  		sock_release(nls->sk_socket);
  
  	return err;
  }
  
  static void cn_test_fini(void)
  {
  	del_timer_sync(&cn_test_timer);
  	cn_del_callback(&cn_test_id);
  	cn_test_id.val--;
  	cn_del_callback(&cn_test_id);
  	if (nls && nls->sk_socket)
  		sock_release(nls->sk_socket);
  }
  
  module_init(cn_test_init);
  module_exit(cn_test_fini);
  
  MODULE_LICENSE("GPL");
acb9c1b2f   Evgeniy Polyakov   connector: mainta...
195
  MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
7672d0b54   Evgeniy Polyakov   [NET]: Add netlin...
196
  MODULE_DESCRIPTION("Connector's test module");