This source file includes following definitions.
- wanpipe_generic_getcard
- wanpipe_generic_name
- wanpipe_generic_register
- wanpipe_generic_unregister
- wanpipe_generic_start
- wanpipe_generic_ioctl
- wanpipe_generic_watchdog
- wanpipe_generic_open
- wanpipe_generic_close
- wanpipe_generic_input
- wp_lite_set_proto
- wp_lite_set_te1_cfg
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 #include <sys/types.h>
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/proc.h>
39 #include <sys/syslog.h>
40 #include <sys/ioccom.h>
41 #include <sys/conf.h>
42 #include <sys/malloc.h>
43 #include <sys/errno.h>
44 #include <sys/exec.h>
45 #include <sys/mbuf.h>
46 #include <sys/sockio.h>
47 #include <sys/socket.h>
48 #include <sys/kernel.h>
49 #include <sys/device.h>
50 #include <sys/time.h>
51 #include <sys/timeout.h>
52
53 #include "bpfilter.h"
54 #if NBPFILTER > 0
55 # include <net/bpf.h>
56 #endif
57 #include <net/if.h>
58 #include <net/if_media.h>
59 #include <net/netisr.h>
60 #include <net/if_sppp.h>
61 #include <netinet/in_systm.h>
62 #include <netinet/in.h>
63
64 #include <netinet/udp.h>
65 #include <netinet/ip.h>
66
67 #include <dev/pci/if_san_common.h>
68 #include <dev/pci/if_san_obsd.h>
69
70
71 #ifdef _DEBUG_
72 #define STATIC
73 #else
74 #define STATIC static
75 #endif
76
77 #define PPP_HEADER_LEN 4
78
79
80 static sdla_t *wanpipe_generic_getcard(struct ifnet *);
81 static int wanpipe_generic_ioctl(struct ifnet *, u_long, caddr_t);
82 static void wanpipe_generic_watchdog(struct ifnet*);
83 static void wanpipe_generic_start(struct ifnet *);
84
85
86 static char *san_ifname_format = "san%d";
87
88
89
90 static sdla_t *
91 wanpipe_generic_getcard(struct ifnet *ifp)
92 {
93 sdla_t* card;
94
95 if (ifp->if_softc == NULL) {
96 log(LOG_INFO, "%s: Invalid device private structure pointer\n",
97 ifp->if_xname);
98 return (NULL);
99 }
100 card = ((sdla_t*)((wanpipe_common_t*)ifp->if_softc)->card);
101 if (card == NULL) {
102 log(LOG_INFO, "%s: Invalid Sangoma device card\n",
103 ifp->if_xname);
104 return (NULL);
105 }
106 return (card);
107 }
108
109 int
110 wanpipe_generic_name(sdla_t *card, char *ifname, int len)
111 {
112 static int ifunit = 0;
113
114 snprintf(ifname, len, san_ifname_format, ifunit++);
115 return (0);
116 }
117
118 int
119 wanpipe_generic_register(sdla_t *card, struct ifnet *ifp, char *ifname)
120 {
121 wanpipe_common_t* common = WAN_IFP_TO_COMMON(ifp);
122
123 if (ifname == NULL || strlen(ifname) > IFNAMSIZ)
124 return (EINVAL);
125 else
126 bcopy(ifname, ifp->if_xname, strlen(ifname));
127
128 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
129 IFQ_SET_READY(&ifp->if_snd);
130 ifp->if_mtu = PP_MTU;
131 ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
132 common->protocol = IF_PROTO_CISCO;
133
134 ((struct sppp *)ifp)->pp_flags |= PP_CISCO;
135 ((struct sppp *)ifp)->pp_flags |= PP_KEEPALIVE;
136 ((struct sppp *)ifp)->pp_framebytes = 3;
137
138 ifp->if_ioctl = wanpipe_generic_ioctl;
139 ifp->if_start = wanpipe_generic_start;
140 ifp->if_watchdog = wanpipe_generic_watchdog;
141
142 if_attach(ifp);
143 if_alloc_sadl(ifp);
144 sppp_attach(ifp);
145
146 #if NBPFILTER > 0
147 bpfattach(&ifp->if_bpf, ifp, DLT_PPP, PPP_HEADER_LEN);
148 #endif
149
150 return (0);
151 }
152
153 void
154 wanpipe_generic_unregister(struct ifnet *ifp)
155 {
156 log(LOG_INFO, "%s: Unregister interface!\n", ifp->if_xname);
157
158 sppp_detach(ifp);
159 if_free_sadl(ifp);
160 if_detach(ifp);
161 }
162
163 static void
164 wanpipe_generic_start(struct ifnet *ifp)
165 {
166 sdla_t *card;
167 struct mbuf *opkt;
168 int err = 0;
169
170 if ((card = wanpipe_generic_getcard(ifp)) == NULL)
171 return;
172
173 while (1) {
174 if (sppp_isempty(ifp)) {
175
176 break;
177 }
178
179 if ((opkt = sppp_dequeue(ifp)) == NULL) {
180
181 break;
182 }
183 if (card->iface_send == NULL) {
184 m_freem(opkt);
185 break;
186 }
187
188 #if NBPFILTER > 0
189 if (ifp->if_bpf)
190 bpf_mtap(ifp->if_bpf, opkt, BPF_DIRECTION_OUT);
191 #endif
192
193 if (wan_mbuf_to_buffer(&opkt)) {
194 m_freem(opkt);
195 break;
196 }
197
198 err = card->iface_send(opkt, ifp);
199 if (err)
200 break;
201 }
202 }
203
204
205 static int
206 wanpipe_generic_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
207 {
208 struct proc *p = curproc;
209 struct ifreq *ifr = (struct ifreq*)data;
210 sdla_t *card;
211 wanpipe_common_t* common = WAN_IFP_TO_COMMON(ifp);
212 struct if_settings ifsettings;
213 unsigned long ts_map;
214 int err = 0, s;
215
216 if ((card = wanpipe_generic_getcard(ifp)) == NULL)
217 return (EINVAL);
218
219 s = splnet();
220
221 switch (cmd) {
222 case SIOCSIFADDR:
223
224 log(LOG_INFO, "%s: Bringing interface up.\n",
225 ifp->if_xname);
226 if (card->iface_up)
227 card->iface_up(ifp);
228 wanpipe_generic_start(ifp);
229 err = 1;
230 break;
231
232 case SIOCSIFMEDIA:
233
234 if (card->state != WAN_DISCONNECTED) {
235 log(LOG_INFO, "%s: Unable to change media type!\n",
236 ifp->if_xname);
237 err = EINVAL;
238 } else
239 err = ifmedia_ioctl(ifp, ifr, &common->ifm, cmd);
240 goto ioctl_out;
241
242 case SIOCGIFMEDIA:
243 err = ifmedia_ioctl(ifp, ifr, &common->ifm, cmd);
244 goto ioctl_out;
245
246 case SIOCSIFTIMESLOT:
247 if ((err = suser(p, p->p_acflag)) != 0)
248 goto ioctl_out;
249 if (card->state != WAN_DISCONNECTED) {
250 log(LOG_INFO, "%s: Unable to change timeslot map!\n",
251 ifp->if_xname);
252 err = EINVAL;
253 goto ioctl_out;
254 }
255
256 err = copyin(ifr->ifr_data, &ts_map, sizeof(ts_map));
257 if (err == 0)
258 sdla_te_settimeslot(card, ts_map);
259
260 goto ioctl_out;
261
262 case SIOCGIFTIMESLOT:
263 ts_map = sdla_te_gettimeslot(card);
264 err = copyout(ifr->ifr_data, &ts_map, sizeof(ts_map));
265 goto ioctl_out;
266
267 case SIOCSIFFLAGS:
268
269
270
271
272
273 err = 1;
274 if ((ifp->if_flags & IFF_UP) == 0) {
275 if ((ifp->if_flags & IFF_RUNNING) == 0)
276 break;
277
278 log(LOG_INFO, "%s: Bringing interface down.\n",
279 ifp->if_xname);
280 if (card->iface_down)
281 card->iface_down(ifp);
282 } else {
283 if (ifp->if_flags & IFF_RUNNING)
284 break;
285 log(LOG_INFO, "%s: Bringing interface up.\n",
286 ifp->if_xname);
287 if (card->iface_up)
288 card->iface_up(ifp);
289 wanpipe_generic_start(ifp);
290 }
291 break;
292
293 case SIOC_WANPIPE_DEVICE:
294 err = copyin(ifr->ifr_data, &ifsettings,
295 sizeof(struct if_settings));
296
297 if (err) {
298 log(LOG_INFO, "%s: Failed to copy from user space!\n",
299 card->devname);
300 goto ioctl_out;
301 }
302
303 switch (ifsettings.type) {
304 case IF_GET_PROTO:
305 ifsettings.type = common->protocol;
306 err = copyout(&ifsettings, ifr->ifr_data,
307 sizeof(struct if_settings));
308 if (err)
309 log(LOG_INFO,
310 "%s: Failed to copy to uspace!\n",
311 card->devname);
312 break;
313
314 case IF_PROTO_CISCO:
315 case IF_PROTO_PPP:
316 if ((err = suser(p, p->p_acflag)) != 0)
317 goto ioctl_out;
318 err = wp_lite_set_proto(ifp, (struct ifreq*)data);
319 break;
320
321 case IF_IFACE_T1:
322 case IF_IFACE_E1:
323 if ((err = suser(p, p->p_acflag)) != 0)
324 goto ioctl_out;
325 err = wp_lite_set_te1_cfg(ifp, (struct ifreq*)data);
326 break;
327
328 default:
329 if (card->iface_ioctl)
330 err = card->iface_ioctl(ifp, cmd,
331 (struct ifreq*)data);
332 break;
333 }
334 goto ioctl_out;
335
336 default:
337 if (card->iface_ioctl) {
338
339 err = card->iface_ioctl(ifp, cmd, (struct ifreq*)data);
340 }
341 break;
342 }
343
344 if (err)
345 err = sppp_ioctl(ifp, cmd, data);
346
347 ioctl_out:
348 splx(s);
349 return (err);
350 }
351
352 static void
353 wanpipe_generic_watchdog(struct ifnet *ifp)
354 {
355 return;
356 }
357
358 int
359 wanpipe_generic_open(struct ifnet *ifp)
360 {
361 return (0);
362 }
363
364 int
365 wanpipe_generic_close(struct ifnet *ifp)
366 {
367 return (0);
368 }
369
370 int
371 wanpipe_generic_input(struct ifnet *ifp, struct mbuf *m)
372 {
373 sdla_t *card;
374 #if NBPFILTER > 0
375 #endif
376
377 if ((card = wanpipe_generic_getcard(ifp)) == NULL) {
378 return (-EINVAL);
379 }
380 m->m_pkthdr.rcvif = ifp;
381 #if NBPFILTER > 0
382 if (ifp->if_bpf)
383 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_IN);
384 #endif
385 ifp->if_ipackets ++;
386 sppp_input(ifp, m);
387 return (0);
388 }
389
390 int
391 wp_lite_set_proto(struct ifnet *ifp, struct ifreq *ifr)
392 {
393 wanpipe_common_t *common;
394 struct if_settings *ifsettings;
395 int err = 0;
396
397 if ((common = ifp->if_softc) == NULL) {
398 log(LOG_INFO, "%s: Private structure is null!\n",
399 ifp->if_xname);
400 return (EINVAL);
401 }
402
403 ifsettings = (struct if_settings*) ifr->ifr_data;
404
405 switch (ifsettings->type) {
406 case IF_PROTO_CISCO:
407 if (common->protocol == IF_PROTO_CISCO)
408 return 0;
409 ((struct sppp *)ifp)->pp_flags |= PP_CISCO;
410 ((struct sppp *)ifp)->pp_flags |= PP_KEEPALIVE;
411 common->protocol = IF_PROTO_CISCO;
412 break;
413 case IF_PROTO_PPP:
414 if (common->protocol == IF_PROTO_PPP)
415 return 0;
416 ((struct sppp *)ifp)->pp_flags &= ~PP_CISCO;
417 ((struct sppp *)ifp)->pp_flags |= PP_KEEPALIVE;
418 common->protocol = IF_PROTO_PPP;
419 break;
420 }
421
422 err = sppp_ioctl(ifp, SIOCSIFFLAGS, ifr);
423 return (err);
424 }
425
426 int
427 wp_lite_set_te1_cfg(struct ifnet *ifp, struct ifreq *ifr)
428 {
429 sdla_t *card;
430 struct if_settings *ifsettings;
431 sdla_te_cfg_t te_cfg;
432 int err = 0;
433
434 if ((card = wanpipe_generic_getcard(ifp)) == NULL)
435 return (EINVAL);
436
437 ifsettings = (struct if_settings*)ifr->ifr_data;
438 err = copyin(ifsettings->ifs_te1, &te_cfg, sizeof(sdla_te_cfg_t));
439
440 if (ifsettings->flags & SANCFG_CLOCK_FLAG)
441 card->fe_te.te_cfg.te_clock = te_cfg.te_clock;
442
443 switch (ifsettings->type) {
444 case IF_IFACE_T1:
445 if (ifsettings->flags & SANCFG_LBO_FLAG)
446 card->fe_te.te_cfg.lbo = te_cfg.lbo;
447 break;
448 }
449
450 return (err);
451 }