View | Details | Raw Unified | Return to bug 194663 | Differences between
and this patch

Collapse All | Expand All

(-)aoenet.c (-124 / +199 lines)
Lines 52-66 Link Here
52
52
53
#include <dev/aoe/aoe.h>
53
#include <dev/aoe/aoe.h>
54
54
55
#ifdef VIMAGE
56
#include <sys/jail.h>
57
#define _aoenet_ifnet V_ifnet
58
#else
59
#define _aoenet_ifnet ifnet
60
#endif
61
55
/*
62
/*
56
 * FORCE_NETWORK_HOOK is defined to support kernels that have not been patched
63
 * FORCE_NETWORK_HOOK is defined to support kernels that have not been patched
57
 * to recognize AoE packets.
64
 * to recognize AoE packets.
58
 */ 
65
 */ 
66
59
#ifdef FORCE_NETWORK_HOOK
67
#ifdef FORCE_NETWORK_HOOK
60
static const u_char etherbroadcastaddr[ETHER_ADDR_LEN] =
68
static const u_char etherbroadcastaddr[ETHER_ADDR_LEN] =
61
                         { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
69
	{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
62
static void (*old_ether_input)(struct ifnet *, struct mbuf *) = NULL;
70
typedef void (*ether_input_t)(struct ifnet *, struct mbuf *);
71
static ether_input_t old_ether_inputs[128]; // TODO: What happens if V_if_indexlim>128 ?
72
//static int ether_inputs_n = 0;
63
#endif
73
#endif
74
64
extern boolean_t aoe_exiting;
75
extern boolean_t aoe_exiting;
65
struct ifqueue aoeintrq;
76
struct ifqueue aoeintrq;
66
77
Lines 77-87 Link Here
77
#define NECODES (sizeof(aoe_errlist) /  sizeof(char *) - 1)
88
#define NECODES (sizeof(aoe_errlist) /  sizeof(char *) - 1)
78
#if (__FreeBSD_version < 600000)
89
#if (__FreeBSD_version < 600000)
79
#define IFPADDR(ifp) (((struct arpcom *) (ifp))->ac_enaddr)
90
#define IFPADDR(ifp) (((struct arpcom *) (ifp))->ac_enaddr)
80
#else
91
#elif (__FreeBSD_version < 700000)
81
#define IFPADDR(ifp) IFP2ENADDR(ifp) 
92
#define IFPADDR(ifp) IFP2ENADDR(ifp) 
93
#else
94
#include <net/if_dl.h>
95
#define IFPADDR(ifp) IF_LLADDR(ifp)
82
#endif
96
#endif
97
                                  
83
#define IFLISTSZ 1024
98
#define IFLISTSZ 1024
84
85
static char aoe_iflist[IFLISTSZ];
99
static char aoe_iflist[IFLISTSZ];
86
100
87
static int sysctl_aoe_iflist(SYSCTL_HANDLER_ARGS);
101
static int sysctl_aoe_iflist(SYSCTL_HANDLER_ARGS);
Lines 160-166 Link Here
160
        register char *p, *q;
174
        register char *p, *q;
161
        register int len;
175
        register int len;
162
176
177
#if __FreeBSD_version >= 1100030
178
        switch (ifp->if_type) {
179
#else
163
        switch (ifp->if_data.ifi_type) {
180
        switch (ifp->if_data.ifi_type) {
181
#endif
164
        default:
182
        default:
165
                return (FALSE);
183
                return (FALSE);
166
        case IFT_ETHER:
184
        case IFT_ETHER:
Lines 190-208 Link Here
190
/* 
208
/* 
191
 * a dummy "free" function for mbuf ext buffer 
209
 * a dummy "free" function for mbuf ext buffer 
192
 */
210
 */
211
#if __FreeBSD_version >= 1000050
212
#if __FreeBSD_version >= 1100028
213
static void
214
#else
215
static int
216
#endif
217
nilfn(struct mbuf *m, void *a, void *b)
218
{
219
#if __FreeBSD_version < 1100028
220
	return EXT_FREE_OK;
221
#endif
222
}
223
#else
193
static void
224
static void
194
nilfn(void *a, void *b)
225
nilfn(void *a, void *b)
195
{
226
{
196
}
227
}
228
#endif
197
229
198
/* Create a mbuf chain and point to our data section(s). */
230
/* Create a mbuf chain and point to our data section(s). */
199
static struct mbuf *
231
static struct mbuf *
200
frame_mbufinit(struct frame *f)
232
frame_mbufinit(struct frame *f)
201
{
233
{
202
        struct mbuf *m;
234
	struct mbuf *m;
203
235
204
	if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL)
236
	if ((m = m_gethdr(M_NOWAIT, MT_DATA)) == NULL) {
237
		IPRINTK("m_gethdr failed\n");
205
		return (NULL);
238
		return (NULL);
239
	}
206
	m->m_len = AOEHDRSZ;
240
	m->m_len = AOEHDRSZ;
207
	m->m_pkthdr.len = f->f_mlen;
241
	m->m_pkthdr.len = f->f_mlen;
208
	MH_ALIGN(m, AOEHDRSZ);
242
	MH_ALIGN(m, AOEHDRSZ);
Lines 210-234 Link Here
210
	m->m_pkthdr.rcvif = NULL;
244
	m->m_pkthdr.rcvif = NULL;
211
	m->m_next = NULL;
245
	m->m_next = NULL;
212
	
246
	
213
        if (f->f_data) {   
247
	if (f->f_data) {   
214
                struct mbuf *m1;
248
		struct mbuf *m1;
215
                u_int len;
249
		u_int len;
216
250
217
                len = f->f_mlen - AOEHDRSZ;
251
		len = f->f_mlen - AOEHDRSZ;
218
		if ((m1 = m_get(M_DONTWAIT, MT_DATA)) == NULL) {
252
		if ((m1 = m_get(M_NOWAIT, MT_DATA)) == NULL) {
219
			m_freem(m);
253
			m_freem(m);
254
			IPRINTK("m_get failed\n");
220
			return (NULL);
255
			return (NULL);
221
		}
256
		}
222
		m->m_next = m1;
257
		m->m_next = m1;
223
258
259
#if __FreeBSD_version >= 1100028
260
		m1->m_ext.ext_cnt = NULL;
261
#else
224
		m1->m_ext.ref_cnt = NULL;
262
		m1->m_ext.ref_cnt = NULL;
263
#endif
225
		MEXTADD(m1, f->f_data, len, nilfn, 
264
		MEXTADD(m1, f->f_data, len, nilfn, 
226
			NULL, 0, EXT_NET_DRV);
265
#if (__FreeBSD_version >= 800000)
266
		        f->f_data,
267
#endif
268
		        NULL, 0, EXT_NET_DRV);
227
		m1->m_len = len;
269
		m1->m_len = len;
228
		m1->m_next = NULL;
270
		m1->m_next = NULL;
229
        }
271
	}
230
272
231
        return (m);
273
	return (m);
232
}
274
}
233
275
234
int
276
int
Lines 236-246 Link Here
236
{
278
{
237
	struct mbuf *m;
279
	struct mbuf *m;
238
280
281
#ifdef VIMAGE
282
	CURVNET_SET_QUIET(d->ad_ifp->if_vnet);
283
#endif
284
	
239
	m = frame_mbufinit(f);
285
	m = frame_mbufinit(f);
240
	if (m == NULL) 
286
	if (m == NULL)
241
		return (ENOMEM);	
287
		return (ENOMEM);
242
288
243
	return (ether_output_frame(d->ad_ifp, m));
289
	int ret = ether_output_frame(d->ad_ifp, m);
290
#ifdef VIMAGE
291
	CURVNET_RESTORE();
292
#endif
293
	
294
	return ret;
244
}
295
}
245
296
246
void
297
void
Lines 250-255 Link Here
250
	struct aoe_cfghdr *ch;
301
	struct aoe_cfghdr *ch;
251
	struct mbuf *m, *m0;
302
	struct mbuf *m, *m0;
252
	struct ifnet *ifp;
303
	struct ifnet *ifp;
304
305
#ifdef VIMAGE
306
	CURVNET_SET_QUIET(CRED_TO_VNET(curthread->td_ucred));
307
#endif
253
	
308
	
254
	m0 = m_gethdr(M_NOWAIT, MT_DATA);
309
	m0 = m_gethdr(M_NOWAIT, MT_DATA);
255
	if (m0 == NULL) {
310
	if (m0 == NULL) {
Lines 264-269 Link Here
264
	bzero(h, sizeof(*h) + sizeof(*ch));
319
	bzero(h, sizeof(*h) + sizeof(*ch));
265
	m0->m_flags |= M_BCAST;
320
	m0->m_flags |= M_BCAST;
266
321
322
	
267
	memset(h->ah_dst, 0xff, sizeof(h->ah_dst));
323
	memset(h->ah_dst, 0xff, sizeof(h->ah_dst));
268
	h->ah_type = htons(ETHERTYPE_AOE);
324
	h->ah_type = htons(ETHERTYPE_AOE);
269
	h->ah_verfl = AOE_HVER;
325
	h->ah_verfl = AOE_HVER;
Lines 271-290 Link Here
271
	h->ah_minor = aoeminor;
327
	h->ah_minor = aoeminor;
272
	h->ah_cmd = AOECMD_CFG;
328
	h->ah_cmd = AOECMD_CFG;
273
329
330
	
274
	IFNET_RLOCK();
331
	IFNET_RLOCK();
275
	TAILQ_FOREACH(ifp, &ifnet, if_link) {
332
	TAILQ_FOREACH(ifp, &_aoenet_ifnet, if_link) {
276
		if (!is_aoe_netif(ifp))
333
		if (!is_aoe_netif(ifp))
277
			continue;
334
			continue;
278
		memcpy(h->ah_src, IFPADDR(ifp), sizeof(h->ah_src));
335
		memcpy(h->ah_src, IFPADDR(ifp), sizeof(h->ah_src));
279
		m = m_copypacket(m0, M_DONTWAIT);
336
		m = m_copypacket(m0, M_NOWAIT);
280
		if (m == NULL) {
337
		if (m == NULL) {
281
			IPRINTK("m_copypacket failure\n");
338
			IPRINTK("m_copypacket failure\n");
282
			continue;
339
			continue;
283
		}
340
		}
284
		ether_output_frame(ifp, m);
341
		ether_output_frame(ifp, m);
342
	
285
	}
343
	}
286
	IFNET_RUNLOCK();
344
	IFNET_RUNLOCK();
287
345
346
#ifdef VIMAGE
347
	CURVNET_RESTORE();
348
#endif
349
	
288
	m_freem(m0);
350
	m_freem(m0);
289
}
351
}
290
352
Lines 297-304 Link Here
297
u_int
359
u_int
298
aoenet_maxsize(struct ifnet *ifp)
360
aoenet_maxsize(struct ifnet *ifp)
299
{
361
{
362
363
	//IPRINTK("MTU %ld HDR %ld DEV_BSIZE %d\n",ifp->if_mtu, AOEHDRSZ, DEV_BSIZE);
300
	/* max payload size of packet based on interface mtu setting */
364
	/* max payload size of packet based on interface mtu setting */
365
#if __FreeBSD_version >= 1100030
366
	return ((ifp->if_mtu - AOEHDRSZ) & ~(DEV_BSIZE - 1));
367
#else
301
	return ((ifp->if_data.ifi_mtu - AOEHDRSZ) & ~(DEV_BSIZE - 1));
368
	return ((ifp->if_data.ifi_mtu - AOEHDRSZ) & ~(DEV_BSIZE - 1));
369
#endif
302
}
370
}
303
371
304
372
Lines 353-433 Link Here
353
static void
421
static void
354
aoe_ether_input(struct ifnet *ifp, struct mbuf *m)
422
aoe_ether_input(struct ifnet *ifp, struct mbuf *m)
355
{
423
{
356
        struct ether_header *eh;
424
	struct ether_header *eh;
357
        u_short etype;
425
	u_short etype;
358
                
426
                
359
        /*
427
	/*
360
         * Do consistency checks to verify assumptions
428
	 * Do consistency checks to verify assumptions
361
         * made by code past this point.
429
	 * made by code past this point.
362
         */
430
	 */
363
        if ((m->m_flags & M_PKTHDR) == 0) {
431
	if ((m->m_flags & M_PKTHDR) == 0) {
364
                if_printf(ifp, "discard frame w/o packet header\n");
432
		if_printf(ifp, "discard frame w/o packet header\n");
365
                ifp->if_ierrors++;
433
#if __FreeBSD_version >= 1100036
366
                m_freem(m);
434
		if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
367
                return;
435
#else
436
		ifp->if_ierrors++;
437
#endif
438
		m_freem(m);
439
		return;
368
	}
440
	}
369
	
441
	
370
        if (m->m_len < ETHER_HDR_LEN) {
442
	if (m->m_len < ETHER_HDR_LEN) {
371
                if_printf(ifp, "discard frame w/o leading ethernet "
443
		if_printf(ifp, "discard frame w/o leading ethernet "
372
                                "header (len %u pkt len %u)\n",
444
		          "header (len %u pkt len %u)\n",
373
                                m->m_len, m->m_pkthdr.len);
445
		          m->m_len, m->m_pkthdr.len);
374
                ifp->if_ierrors++;
446
#if __FreeBSD_version >= 1100036
375
                m_freem(m);
447
		if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
376
                return;
448
#else
377
        }
449
		ifp->if_ierrors++;
378
        eh = mtod(m, struct ether_header *);
450
#endif
379
        etype = ntohs(eh->ether_type);
451
		m_freem(m);
452
		return;
453
	}
454
	eh = mtod(m, struct ether_header *);
455
	etype = ntohs(eh->ether_type);
380
	if (etype != ETHERTYPE_AOE) {
456
	if (etype != ETHERTYPE_AOE) {
381
		(*old_ether_input)(ifp, m);
457
		(*old_ether_inputs[ifp->if_index])(ifp, m);
382
		return;
458
		return;
383
	}
459
	}
384
        if (m->m_pkthdr.len >
460
	if (m->m_pkthdr.len >
385
            ETHER_MAX_FRAME(ifp, etype, m->m_flags & M_HASFCS)) {
461
	    ETHER_MAX_FRAME(ifp, etype, m->m_flags & M_HASFCS)) {
386
                if_printf(ifp, "discard oversize frame "
462
		/*if_printf(ifp, "discard oversize frame "
387
                                "(ether type %x flags %x len %u > max %lu)\n",
463
		          "(ether type %x flags %x len %u > max %u)\n",
388
                                etype, m->m_flags, m->m_pkthdr.len,
464
		          etype, m->m_flags, m->m_pkthdr.len,
389
                                ETHER_MAX_FRAME(ifp, etype,
465
		          (int) ETHER_MAX_FRAME(ifp, etype,
390
                                                m->m_flags & M_HASFCS));
466
		          m->m_flags & M_HASFCS));*/
391
                ifp->if_ierrors++;
467
#if __FreeBSD_version >= 1100036
392
                m_freem(m);
468
		if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
393
                return;
469
#else
394
        }
470
		ifp->if_ierrors++;
395
        if (m->m_pkthdr.rcvif == NULL) {
471
#endif
396
                if_printf(ifp, "discard frame w/o interface pointer\n");
472
		m_freem(m);
397
                ifp->if_ierrors++;
473
		return;
398
                m_freem(m);
399
                return;
400
	}
474
	}
401
        /*
475
	if (m->m_pkthdr.rcvif == NULL) {
402
         * Give bpf a chance at the AoE packet.
476
		if_printf(ifp, "discard frame w/o interface pointer\n");
403
         */
477
#if __FreeBSD_version >= 1100036
404
       	BPF_MTAP(ifp, m);
478
		if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
479
#else
480
		ifp->if_ierrors++;
481
#endif
482
		m_freem(m);
483
		return;
484
	}
485
	/*
486
	 * Give bpf a chance at the AoE packet.
487
	 */
488
	BPF_MTAP(ifp, m);
405
489
406
        if (ifp->if_flags & IFF_MONITOR) {
490
	if (ifp->if_flags & IFF_MONITOR) {
407
                /*
491
		/*
408
                 * Interface marked for monitoring; discard packet.
492
		 * Interface marked for monitoring; discard packet.
409
                 */
493
		 */
410
                m_freem(m);
494
		m_freem(m);
411
                return;
495
		return;
412
        }
496
	}
413
497
414
        /* If the CRC is still on the packet, trim it off. */
498
	/* If the CRC is still on the packet, trim it off. */
415
        if (m->m_flags & M_HASFCS) {
499
	if (m->m_flags & M_HASFCS) {
416
                m_adj(m, -ETHER_CRC_LEN);
500
		m_adj(m, -ETHER_CRC_LEN);
417
                m->m_flags &= ~M_HASFCS;
501
		m->m_flags &= ~M_HASFCS;
418
        }
502
	}
419
503
420
        ifp->if_ibytes += m->m_pkthdr.len;
504
#if __FreeBSD_version >= 1100036
505
	if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len);
506
#else
507
	ifp->if_ibytes += m->m_pkthdr.len;
508
#endif
421
509
422
        if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
510
	if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
423
                if (bcmp(etherbroadcastaddr, eh->ether_dhost,
511
		if (bcmp(etherbroadcastaddr, eh->ether_dhost,
424
                    sizeof(etherbroadcastaddr)) == 0)
512
		         sizeof(etherbroadcastaddr)) == 0)
425
                        m->m_flags |= M_BCAST;
513
			m->m_flags |= M_BCAST;
426
                else
514
		else
427
                        m->m_flags |= M_MCAST;
515
			m->m_flags |= M_MCAST;
428
        }
516
	}
429
        if (m->m_flags & (M_BCAST|M_MCAST))
517
	if (m->m_flags & (M_BCAST|M_MCAST))
430
                ifp->if_imcasts++;
518
#if __FreeBSD_version >= 1100036
519
		if_inc_counter(ifp, IFCOUNTER_IMCASTS, 1);
520
#else
521
	ifp->if_imcasts++;
522
#endif
431
523
432
	aoeintr(m); 
524
	aoeintr(m); 
433
	/* netisr_dispatch(NETISR_AOE, m); */
525
	/* netisr_dispatch(NETISR_AOE, m); */
Lines 438-464 Link Here
438
sysctl_aoe_iflist(SYSCTL_HANDLER_ARGS)
530
sysctl_aoe_iflist(SYSCTL_HANDLER_ARGS)
439
{
531
{
440
	int error;
532
	int error;
533
534
441
#ifdef FORCE_NETWORK_HOOK
535
#ifdef FORCE_NETWORK_HOOK
442
	struct ifnet *ifp;
536
	struct ifnet *ifp;
443
#endif
537
	IFNET_RLOCK();
538
	TAILQ_FOREACH(ifp, &_aoenet_ifnet, if_link) {
539
		if (!is_aoe_netif(ifp)) 
540
			continue;
541
		// restore the if_input
542
		ifp->if_input = old_ether_inputs[ifp->if_index];
543
	}
544
	IFNET_RUNLOCK();
545
#endif 
444
546
445
	error = sysctl_handle_string(oidp, arg1, arg2, req);
547
	error = sysctl_handle_string(oidp, arg1, arg2, req);
446
548
447
#ifdef FORCE_NETWORK_HOOK
549
#ifdef FORCE_NETWORK_HOOK
448
	IFNET_RLOCK();
550
	IFNET_RLOCK();
449
	TAILQ_FOREACH(ifp, &ifnet, if_link) {
551
	TAILQ_FOREACH(ifp, &_aoenet_ifnet, if_link) {
450
		if (!is_aoe_netif(ifp)) {
552
		if (!is_aoe_netif(ifp))
451
			if (ifp->if_input == aoe_ether_input)
452
				ifp->if_input = old_ether_input;
453
			continue;
553
			continue;
454
		}
554
		// remember the if_input
455
		if (ifp->if_input !=  aoe_ether_input) 
555
		old_ether_inputs[ifp->if_index] = ifp->if_input;
456
			ifp->if_input = aoe_ether_input;
556
		// now take it over
457
		
557
		ifp->if_input = aoe_ether_input;
458
	}
558
	}
459
	IFNET_RUNLOCK();
559
	IFNET_RUNLOCK();
460
#endif /* FORCE_NETWORK_HOOK */
560
#endif /* FORCE_NETWORK_HOOK */
461
561
562
	// send broadcast to discover devices
462
	aoecmd_cfg(0xffff, 0xff);
563
	aoecmd_cfg(0xffff, 0xff);
463
	
564
	
464
	return (error);
565
	return (error);
Lines 467-492 Link Here
467
void
568
void
468
aoenet_init(void)
569
aoenet_init(void)
469
{
570
{
470
#ifdef FORCE_NETWORK_HOOK
571
#ifndef FORCE_NETWORK_HOOK 
471
	struct ifnet *ifp;
472
473
	IFNET_RLOCK();
474
	TAILQ_FOREACH(ifp, &ifnet, if_link) {
475
        	switch (ifp->if_data.ifi_type) {
476
        	case IFT_ETHER:
477
        	case IFT_FASTETHER:
478
        	case IFT_GIGABITETHERNET:
479
                	break;
480
        	default:
481
               		continue; 
482
        	}
483
		if (old_ether_input == NULL) 
484
			old_ether_input = ifp->if_input;
485
		else if (old_ether_input != ifp->if_input)
486
			IPRINTK("ifp->if_input != ether_input\n");
487
	}
488
	IFNET_RUNLOCK();
489
#else 
490
	aoeintrq.ifq_maxlen = IFQ_MAXLEN;
572
	aoeintrq.ifq_maxlen = IFQ_MAXLEN;
491
	mtx_init(&aoeintrq.ifq_mtx, "aoe_inq", NULL, MTX_DEF);
573
	mtx_init(&aoeintrq.ifq_mtx, "aoe_inq", NULL, MTX_DEF);
492
	netisr_register(NETISR_AOE, aoeintr, &aoeintrq, NETISR_MPSAFE);
574
	netisr_register(NETISR_AOE, aoeintr, &aoeintrq, NETISR_MPSAFE);
Lines 498-516 Link Here
498
{
580
{
499
#ifdef FORCE_NETWORK_HOOK
581
#ifdef FORCE_NETWORK_HOOK
500
	struct ifnet *ifp;
582
	struct ifnet *ifp;
501
502
	IFNET_RLOCK();
583
	IFNET_RLOCK();
503
	TAILQ_FOREACH(ifp, &ifnet, if_link) {
584
	TAILQ_FOREACH(ifp, &_aoenet_ifnet, if_link) {
504
        	switch (ifp->if_data.ifi_type) {
585
		if (!is_aoe_netif(ifp)) 
505
        	case IFT_ETHER:
586
			continue;
506
        	case IFT_FASTETHER:
587
		// restore the if_input
507
        	case IFT_GIGABITETHERNET:
588
		ifp->if_input = old_ether_inputs[ifp->if_index];
508
                	break;
509
        	default:
510
               		continue; 
511
        	}
512
		if (ifp->if_input == aoe_ether_input)
513
			ifp->if_input = old_ether_input;
514
	}
589
	}
515
	IFNET_RUNLOCK();
590
	IFNET_RUNLOCK();
516
#else 
591
#else 

Return to bug 194663