xref: /haiku/src/add-ons/kernel/network/stack/datalink.cpp (revision e6b30aee0fd7a23d6a6baab9f3718945a0cd838a)
1 /*
2  * Copyright 2006-2007, Haiku, Inc. All Rights Reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  *		Axel Dörfler, axeld@pinc-software.de
7  *		Hugo Santos, hugosantos@gmail.com
8  */
9 
10 
11 #include "datalink.h"
12 #include "domains.h"
13 #include "interfaces.h"
14 #include "routes.h"
15 #include "stack_private.h"
16 #include "utility.h"
17 
18 #include <net_device.h>
19 #include <KernelExport.h>
20 #include <util/AutoLock.h>
21 
22 #include <net/if.h>
23 #include <net/if_media.h>
24 #include <net/route.h>
25 #include <sys/sockio.h>
26 
27 #include <new>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31 
32 
33 struct datalink_protocol : net_protocol {
34 	struct net_domain_private *domain;
35 };
36 
37 struct interface_protocol : net_datalink_protocol {
38 	struct net_device_module_info *device_module;
39 	struct net_device *device;
40 };
41 
42 
43 static status_t
44 device_reader_thread(void *_interface)
45 {
46 	net_device_interface *interface = (net_device_interface *)_interface;
47 	net_device *device = interface->device;
48 	status_t status = B_OK;
49 
50 	RecursiveLocker locker(interface->rx_lock);
51 
52 	while (device->flags & IFF_UP) {
53 		locker.Unlock();
54 
55 		net_buffer *buffer;
56 		status = device->module->receive_data(device, &buffer);
57 
58 		locker.Lock();
59 
60 		if (status == B_OK) {
61 			// feed device monitors
62 			DeviceMonitorList::Iterator iterator =
63 				interface->monitor_funcs.GetIterator();
64 			while (iterator.HasNext()) {
65 				net_device_monitor *monitor = iterator.Next();
66 				monitor->receive(monitor, buffer);
67 			}
68 
69 			buffer->interface = NULL;
70 			buffer->type = interface->deframe_func(interface->device, buffer);
71 			if (buffer->type < 0) {
72 				gNetBufferModule.free(buffer);
73 				continue;
74 			}
75 
76 			fifo_enqueue_buffer(&interface->receive_queue, buffer);
77 		} else {
78 			// In case of error, give the other threads some
79 			// time to run since this is a near real time thread.
80 			//
81 			// TODO: can this value be lower? 1000 works fine in
82 			//       my system. 10ms seems a bit too much and adds
83 			//       as latency.
84 			snooze(10000);
85 		}
86 
87 		// if the interface went down IFF_UP was removed
88 		// and the receive_data() above should have been
89 		// interrupted. One check should be enough, specially
90 		// considering the snooze above.
91 	}
92 
93 	return status;
94 }
95 
96 
97 static struct sockaddr **
98 interface_address(net_interface *interface, int32 option)
99 {
100 	switch (option) {
101 		case SIOCSIFADDR:
102 		case SIOCGIFADDR:
103 			return &interface->address;
104 
105 		case SIOCSIFNETMASK:
106 		case SIOCGIFNETMASK:
107 			return &interface->mask;
108 
109 		case SIOCSIFBRDADDR:
110 		case SIOCSIFDSTADDR:
111 		case SIOCGIFBRDADDR:
112 		case SIOCGIFDSTADDR:
113 			return &interface->destination;
114 
115 		default:
116 			return NULL;
117 	}
118 }
119 
120 
121 void
122 remove_default_routes(net_interface_private *interface, int32 option)
123 {
124 	net_route route;
125 	route.destination = interface->address;
126 	route.gateway = NULL;
127 	route.interface = interface;
128 
129 	if (interface->mask != NULL
130 		&& (option == SIOCSIFNETMASK || option == SIOCSIFADDR)) {
131 		route.mask = interface->mask;
132 		route.flags = 0;
133 		remove_route(interface->domain, &route);
134 	}
135 
136 	if (option == SIOCSIFADDR) {
137 		route.mask = NULL;
138 		route.flags = RTF_LOCAL | RTF_HOST;
139 		remove_route(interface->domain, &route);
140 	}
141 }
142 
143 
144 void
145 add_default_routes(net_interface_private *interface, int32 option)
146 {
147 	net_route route;
148 	route.destination = interface->address;
149 	route.gateway = NULL;
150 	route.interface = interface;
151 
152 	if (interface->mask != NULL
153 		&& (option == SIOCSIFNETMASK || option == SIOCSIFADDR)) {
154 		route.mask = interface->mask;
155 		route.flags = 0;
156 		add_route(interface->domain, &route);
157 	}
158 
159 	if (option == SIOCSIFADDR) {
160 		route.mask = NULL;
161 		route.flags = RTF_LOCAL | RTF_HOST;
162 		add_route(interface->domain, &route);
163 	}
164 }
165 
166 
167 static status_t
168 datalink_control_interface(net_domain_private *domain, int32 option,
169 	void *value, size_t *_length, size_t expected, bool getByName)
170 {
171 	if (*_length < expected)
172 		return B_BAD_VALUE;
173 
174 	ifreq request;
175 	memset(&request, 0, sizeof(request));
176 
177 	if (user_memcpy(&request, value, expected) < B_OK)
178 		return B_BAD_ADDRESS;
179 
180 	BenaphoreLocker _(domain->lock);
181 	net_interface *interface = NULL;
182 
183 	if (getByName)
184 		interface = find_interface(domain, request.ifr_name);
185 	else
186 		interface = find_interface(domain, request.ifr_index);
187 
188 	status_t status = (interface == NULL) ? ENODEV : B_OK;
189 
190 	switch (option) {
191 	case SIOCGIFINDEX:
192 		if (interface)
193 			request.ifr_index = interface->index;
194 		else
195 			request.ifr_index = 0;
196 		break;
197 
198 	case SIOCGIFNAME:
199 		if (interface)
200 			strlcpy(request.ifr_name, interface->name, IF_NAMESIZE);
201 		else
202 			status = B_BAD_VALUE; // TODO should be ENXIO?
203 		break;
204 	}
205 
206 	if (status < B_OK)
207 		return status;
208 
209 	return user_memcpy(value, &request, sizeof(ifreq));
210 }
211 
212 
213 //	#pragma mark - datalink module
214 
215 
216 status_t
217 datalink_control(net_domain *_domain, int32 option, void *value,
218 	size_t *_length)
219 {
220 	net_domain_private *domain = (net_domain_private *)_domain;
221 	if (domain == NULL || domain->family == AF_LINK) {
222 		// the AF_LINK family is already handled completely in the link protocol
223 		return B_BAD_VALUE;
224 	}
225 
226 	switch (option) {
227 		case SIOCGIFINDEX:
228 			return datalink_control_interface(domain, option, value, _length,
229 				IF_NAMESIZE, true);
230 		case SIOCGIFNAME:
231 			return datalink_control_interface(domain, option, value, _length,
232 				sizeof(ifreq), false);
233 
234 		case SIOCDIFADDR:
235 		case SIOCSIFFLAGS:
236 		{
237 			struct ifreq request;
238 			if (user_memcpy(&request, value, sizeof(struct ifreq)) < B_OK)
239 				return B_BAD_ADDRESS;
240 
241 			return domain_interface_control(domain, option, &request);
242 		}
243 
244 		case SIOCAIFADDR:
245 		{
246 			// add new interface address
247 			struct ifreq request;
248 			if (user_memcpy(&request, value, sizeof(struct ifreq)) < B_OK)
249 				return B_BAD_ADDRESS;
250 
251 			return add_interface_to_domain(domain, request);
252 		}
253 
254 		case SIOCGIFCOUNT:
255 		{
256 			// count number of interfaces
257 			struct ifconf config;
258 			config.ifc_value = count_domain_interfaces();
259 
260 			return user_memcpy(value, &config, sizeof(struct ifconf));
261 		}
262 
263 		case SIOCGIFCONF:
264 		{
265 			// retrieve ifreqs for all interfaces
266 			struct ifconf config;
267 			if (user_memcpy(&config, value, sizeof(struct ifconf)) < B_OK)
268 				return B_BAD_ADDRESS;
269 
270 			status_t result = list_domain_interfaces(config.ifc_buf,
271 				(size_t *)&config.ifc_len);
272 			if (result != B_OK)
273 				return result;
274 
275 			return user_memcpy(value, &config, sizeof(struct ifconf));
276 		}
277 
278 		case SIOCGRTSIZE:
279 		{
280 			// determine size of buffer to hold the routing table
281 			struct ifconf config;
282 			config.ifc_value = route_table_size(domain);
283 
284 			return user_memcpy(value, &config, sizeof(struct ifconf));
285 		}
286 		case SIOCGRTTABLE:
287 		{
288 			// retrieve all routes for this domain
289 			struct ifconf config;
290 			if (user_memcpy(&config, value, sizeof(struct ifconf)) < B_OK)
291 				return B_BAD_ADDRESS;
292 
293 			return list_routes(domain, config.ifc_buf, config.ifc_len);
294 		}
295 		case SIOCGETRT:
296 			return get_route_information(domain, value, *_length);
297 
298 		default:
299 		{
300 			// try to pass the request to an existing interface
301 			struct ifreq request;
302 			if (user_memcpy(&request, value, sizeof(struct ifreq)) < B_OK)
303 				return B_BAD_ADDRESS;
304 
305 			BenaphoreLocker _(domain->lock);
306 
307 			net_interface *interface = find_interface(domain,
308 				request.ifr_name);
309 			if (interface == NULL)
310 				return B_BAD_VALUE;
311 
312 			// pass the request into the datalink protocol stack
313 			return interface->first_info->control(
314 				interface->first_protocol, option, value, *_length);
315 		}
316 	}
317 	return B_BAD_VALUE;
318 }
319 
320 
321 status_t
322 datalink_send_data(struct net_route *route, net_buffer *buffer)
323 {
324 	net_interface_private *interface =
325 		(net_interface_private *)route->interface;
326 
327 	//dprintf("send buffer (%ld bytes) to interface %s (route flags %lx)\n",
328 	//	buffer->size, interface->name, route->flags);
329 
330 	if (route->flags & RTF_REJECT)
331 		return ENETUNREACH;
332 
333 	if (route->flags & RTF_LOCAL) {
334 		// we set the interface here so the buffer is delivered directly
335 		// to the domain in interfaces.cpp:device_consumer_thread()
336 		buffer->interface = interface;
337 		// this one goes back to the domain directly
338 		return fifo_enqueue_buffer(
339 			&interface->device_interface->receive_queue, buffer);
340 	}
341 
342 	if (route->flags & RTF_GATEWAY) {
343 		// this route involves a gateway, we need to use the gateway address
344 		// instead of the destination address:
345 		if (route->gateway == NULL)
346 			return B_MISMATCHED_VALUES;
347 		memcpy(buffer->destination, route->gateway, route->gateway->sa_len);
348 	}
349 
350 	// this goes out to the datalink protocols
351 	return interface->first_info->send_data(interface->first_protocol, buffer);
352 }
353 
354 
355 status_t
356 datalink_send_datagram(net_protocol *protocol, net_domain *domain,
357 	net_buffer *buffer)
358 {
359 	if (protocol == NULL && domain == NULL)
360 		return B_BAD_VALUE;
361 
362 	net_protocol_module_info *module = protocol ? protocol->module
363 		: domain->module;
364 
365 	if (domain == NULL)
366 		domain = protocol->module->get_domain(protocol);
367 
368 	net_route *route = NULL;
369 	status_t status = get_buffer_route(domain, buffer, &route);
370 	if (status < B_OK)
371 		return status;
372 
373 	status = module->send_routed_data(protocol, route, buffer);
374 	put_route(domain, route);
375 	return status;
376 }
377 
378 
379 /*!
380 	Tests if \a address is a local address in the domain.
381 	\param _interface will be set to the interface belonging to that address
382 		if non-NULL.
383 	\param _matchedType will be set to either zero or MSG_BCAST if non-NULL.
384 */
385 bool
386 datalink_is_local_address(net_domain *_domain, const struct sockaddr *address,
387 	net_interface **_interface, uint32 *_matchedType)
388 {
389 	net_domain_private *domain = (net_domain_private *)_domain;
390 	if (domain == NULL || address == NULL)
391 		return false;
392 
393 	BenaphoreLocker locker(domain->lock);
394 
395 	net_interface *interface = NULL;
396 	net_interface *fallback = NULL;
397 	uint32 matchedType = 0;
398 
399 	while (true) {
400 		interface = (net_interface *)list_get_next_item(
401 			&domain->interfaces, interface);
402 		if (interface == NULL)
403 			break;
404 		if (interface->address == NULL) {
405 			fallback = interface;
406 			continue;
407 		}
408 
409 		// check for matching unicast address first
410 		if (domain->address_module->equal_addresses(interface->address, address))
411 			break;
412 
413 		// check for matching broadcast address if interface support broadcasting
414 		if (interface->flags & IFF_BROADCAST
415 			&& domain->address_module->equal_addresses(interface->destination,
416 				address)) {
417 			matchedType = MSG_BCAST;
418 			break;
419 		}
420 	}
421 
422 	if (interface == NULL) {
423 		interface = fallback;
424 		if (interface == NULL)
425 			return false;
426 	}
427 
428 	if (_interface != NULL)
429 		*_interface = interface;
430 	if (_matchedType != NULL)
431 		*_matchedType = matchedType;
432 	return true;
433 }
434 
435 
436 net_interface *
437 datalink_get_interface_with_address(net_domain *_domain,
438 	const sockaddr *address)
439 {
440 	net_domain_private *domain = (net_domain_private *)_domain;
441 	if (domain == NULL)
442 		return NULL;
443 
444 	BenaphoreLocker _(domain->lock);
445 
446 	net_interface *interface = NULL;
447 
448 	while (true) {
449 		interface = (net_interface *)list_get_next_item(
450 			&domain->interfaces, interface);
451 		if (interface == NULL)
452 			break;
453 
454 		if (address == NULL)
455 			return interface;
456 
457 		if (domain->address_module->equal_addresses(interface->address,
458 				address))
459 			return interface;
460 	}
461 
462 	return NULL;
463 }
464 
465 
466 net_interface *
467 datalink_get_interface(net_domain *domain, uint32 index)
468 {
469 	if (index == 0)
470 		return datalink_get_interface_with_address(domain, NULL);
471 
472 	return find_interface(domain, index);
473 }
474 
475 
476 static status_t
477 datalink_std_ops(int32 op, ...)
478 {
479 	switch (op) {
480 		case B_MODULE_INIT:
481 		case B_MODULE_UNINIT:
482 			return B_OK;
483 
484 		default:
485 			return B_ERROR;
486 	}
487 }
488 
489 
490 //	#pragma mark - net_datalink_protocol
491 
492 
493 status_t
494 interface_protocol_init(struct net_interface *_interface, net_datalink_protocol **_protocol)
495 {
496 	net_interface_private *interface = (net_interface_private *)_interface;
497 
498 	interface_protocol *protocol = new (std::nothrow) interface_protocol;
499 	if (protocol == NULL)
500 		return B_NO_MEMORY;
501 
502 	protocol->device_module = interface->device->module;
503 	protocol->device = interface->device;
504 
505 	*_protocol = protocol;
506 	return B_OK;
507 }
508 
509 
510 status_t
511 interface_protocol_uninit(net_datalink_protocol *protocol)
512 {
513 	delete protocol;
514 	return B_OK;
515 }
516 
517 
518 status_t
519 interface_protocol_send_data(net_datalink_protocol *_protocol,
520 	net_buffer *buffer)
521 {
522 	interface_protocol *protocol = (interface_protocol *)_protocol;
523 	net_interface_private *interface = (net_interface_private *)protocol->interface;
524 
525 	// TODO: Need to think about this locking. We can't obtain the
526 	//       RX Lock here (nor would it make sense) as the ARP
527 	//       module calls send_data() with it's lock held (similiar
528 	//       to the domain lock, which would violate the locking
529 	//       protocol).
530 
531 	DeviceMonitorList::Iterator iterator =
532 		interface->device_interface->monitor_funcs.GetIterator();
533 	while (iterator.HasNext()) {
534 		net_device_monitor *monitor = iterator.Next();
535 		monitor->receive(monitor, buffer);
536 	}
537 
538 	return protocol->device_module->send_data(protocol->device, buffer);
539 }
540 
541 
542 status_t
543 interface_protocol_up(net_datalink_protocol *_protocol)
544 {
545 	interface_protocol *protocol = (interface_protocol *)_protocol;
546 	net_device_interface *deviceInterface =
547 		((net_interface_private *)protocol->interface)->device_interface;
548 	net_device *device = protocol->device;
549 
550 	// This function is called with the RX lock held.
551 
552 	if (deviceInterface->up_count != 0) {
553 		deviceInterface->up_count++;
554 		return B_OK;
555 	}
556 
557 	status_t status = protocol->device_module->up(device);
558 	if (status < B_OK)
559 		return status;
560 
561 	if (device->module->receive_data != NULL) {
562 		// give the thread a nice name
563 		char name[B_OS_NAME_LENGTH];
564 		snprintf(name, sizeof(name), "%s reader", device->name);
565 
566 		deviceInterface->reader_thread =
567 			spawn_kernel_thread(device_reader_thread, name,
568 				B_REAL_TIME_DISPLAY_PRIORITY - 10, deviceInterface);
569 		if (deviceInterface->reader_thread < B_OK)
570 			return deviceInterface->reader_thread;
571 	}
572 
573 	device->flags |= IFF_UP;
574 
575 	if (device->module->receive_data != NULL)
576 		resume_thread(deviceInterface->reader_thread);
577 
578 	deviceInterface->up_count = 1;
579 	return B_OK;
580 }
581 
582 
583 void
584 interface_protocol_down(net_datalink_protocol *_protocol)
585 {
586 	interface_protocol *protocol = (interface_protocol *)_protocol;
587 	net_device_interface *deviceInterface =
588 		((net_interface_private *)protocol->interface)->device_interface;
589 
590 	// This function is called with the RX lock held.
591 	if (deviceInterface->up_count == 0)
592 		return;
593 
594 	deviceInterface->up_count--;
595 
596 	domain_interface_went_down(protocol->interface);
597 
598 	if (deviceInterface->up_count > 0)
599 		return;
600 
601 	down_device_interface(deviceInterface);
602 }
603 
604 
605 status_t
606 interface_protocol_control(net_datalink_protocol *_protocol,
607 	int32 option, void *argument, size_t length)
608 {
609 	interface_protocol *protocol = (interface_protocol *)_protocol;
610 	net_interface_private *interface = (net_interface_private *)protocol->interface;
611 
612 	switch (option) {
613 		case SIOCSIFADDR:
614 		case SIOCSIFNETMASK:
615 		case SIOCSIFBRDADDR:
616 		case SIOCSIFDSTADDR:
617 		{
618 			// set logical interface address
619 			struct ifreq request;
620 			if (user_memcpy(&request, argument, sizeof(struct ifreq)) < B_OK)
621 				return B_BAD_ADDRESS;
622 
623 			sockaddr **_address = interface_address(interface, option);
624 			if (_address == NULL)
625 				return B_BAD_VALUE;
626 
627 			sockaddr *address = *_address;
628 			sockaddr *original = address;
629 
630 			// allocate new address if needed
631 			if (address == NULL
632 				|| (address->sa_len < request.ifr_addr.sa_len
633 					&& request.ifr_addr.sa_len > sizeof(struct sockaddr))) {
634 				address = (sockaddr *)malloc(
635 					max_c(request.ifr_addr.sa_len, sizeof(struct sockaddr)));
636 			}
637 
638 			// copy new address over
639 			if (address != NULL) {
640 				remove_default_routes(interface, option);
641 
642 				if (original != address) {
643 					free(original);
644 					*_address = address;
645 				}
646 
647 				memcpy(address, &request.ifr_addr, request.ifr_addr.sa_len);
648 				add_default_routes(interface, option);
649 			}
650 
651 			return address != NULL ? B_OK : B_NO_MEMORY;
652 		}
653 
654 		case SIOCGIFADDR:
655 		case SIOCGIFNETMASK:
656 		case SIOCGIFBRDADDR:
657 		case SIOCGIFDSTADDR:
658 		{
659 			// get logical interface address
660 			sockaddr **_address = interface_address(interface, option);
661 			if (_address == NULL)
662 				return B_BAD_VALUE;
663 
664 			struct ifreq request;
665 
666 			sockaddr *address = *_address;
667 			if (address != NULL)
668 				memcpy(&request.ifr_addr, address, address->sa_len);
669 			else {
670 				request.ifr_addr.sa_len = 2;
671 				request.ifr_addr.sa_family = AF_UNSPEC;
672 			}
673 
674 			// copy address over
675 			return user_memcpy(&((struct ifreq *)argument)->ifr_addr,
676 				&request.ifr_addr, request.ifr_addr.sa_len);
677 		}
678 
679 		case SIOCGIFFLAGS:
680 		{
681 			// get flags
682 			struct ifreq request;
683 			request.ifr_flags = interface->flags | interface->device->flags;
684 
685 			return user_memcpy(&((struct ifreq *)argument)->ifr_flags,
686 				&request.ifr_flags, sizeof(request.ifr_flags));
687 		}
688 
689 		case SIOCGIFPARAM:
690 		{
691 			// get interface parameter
692 			struct ifreq request;
693 			strlcpy(request.ifr_parameter.base_name, interface->base_name, IF_NAMESIZE);
694 			strlcpy(request.ifr_parameter.device,
695 				interface->device_interface->device->name, IF_NAMESIZE);
696 			request.ifr_parameter.sub_type = 0;
697 				// TODO: for now, we ignore the sub type...
698 
699 			return user_memcpy(&((struct ifreq *)argument)->ifr_parameter,
700 				&request.ifr_parameter, sizeof(request.ifr_parameter));
701 		}
702 
703 		case SIOCGIFSTATS:
704 		{
705 			// get stats
706 			return user_memcpy(&((struct ifreq *)argument)->ifr_stats,
707 				&interface->device_interface->device->stats,
708 				sizeof(struct ifreq_stats));
709 		}
710 
711 		case SIOCGIFTYPE:
712 		{
713 			// get type
714 			struct ifreq request;
715 			request.ifr_type = interface->type;
716 
717 			return user_memcpy(&((struct ifreq *)argument)->ifr_type,
718 				&request.ifr_type, sizeof(request.ifr_type));
719 		}
720 
721 		case SIOCGIFMTU:
722 		{
723 			// get MTU
724 			struct ifreq request;
725 			request.ifr_mtu = interface->mtu;
726 
727 			return user_memcpy(&((struct ifreq *)argument)->ifr_mtu,
728 				&request.ifr_mtu, sizeof(request.ifr_mtu));
729 		}
730 		case SIOCSIFMTU:
731 		{
732 			// set MTU
733 			struct ifreq request;
734 			if (user_memcpy(&request, argument, sizeof(struct ifreq)) < B_OK)
735 				return B_BAD_ADDRESS;
736 
737 			// check for valid bounds
738 			if (request.ifr_mtu < 100
739 				|| (uint32)request.ifr_mtu > interface->device->mtu)
740 				return B_BAD_VALUE;
741 
742 			interface->mtu = request.ifr_mtu;
743 			return B_OK;
744 		}
745 
746 		case SIOCSIFMEDIA:
747 		{
748 			// set media
749 			struct ifreq request;
750 			if (user_memcpy(&request, argument, sizeof(struct ifreq)) < B_OK)
751 				return B_BAD_ADDRESS;
752 
753 			return interface->device_interface->device->module->set_media(
754 				interface->device, request.ifr_media);
755 		}
756 		case SIOCGIFMEDIA:
757 		{
758 			// get media
759 			struct ifreq request;
760 			request.ifr_media = interface->device->media;
761 
762 			return user_memcpy(&((struct ifreq *)argument)->ifr_media,
763 				&request.ifr_media, sizeof(request.ifr_media));
764 		}
765 
766 		case SIOCGIFMETRIC:
767 		{
768 			// get metric
769 			struct ifreq request;
770 			request.ifr_metric = interface->metric;
771 
772 			return user_memcpy(&((struct ifreq *)argument)->ifr_metric,
773 				&request.ifr_metric, sizeof(request.ifr_metric));
774 		}
775 		case SIOCSIFMETRIC:
776 		{
777 			// set metric
778 			struct ifreq request;
779 			if (user_memcpy(&request, argument, sizeof(struct ifreq)) < B_OK)
780 				return B_BAD_ADDRESS;
781 
782 			interface->metric = request.ifr_metric;
783 			return B_OK;
784 		}
785 
786 		case SIOCADDRT:
787 		case SIOCDELRT:
788 			// interface related route options
789 			return control_routes(interface, option, argument, length);
790 	}
791 
792 	return protocol->device_module->control(protocol->device,
793 		option, argument, length);
794 }
795 
796 
797 static status_t
798 interface_protocol_join_multicast(net_datalink_protocol *_protocol,
799 	const sockaddr *address)
800 {
801 	interface_protocol *protocol = (interface_protocol *)_protocol;
802 
803 	return protocol->device_module->add_multicast(protocol->device, address);
804 }
805 
806 
807 static status_t
808 interface_protocol_leave_multicast(net_datalink_protocol *_protocol,
809 	const sockaddr *address)
810 {
811 	interface_protocol *protocol = (interface_protocol *)_protocol;
812 
813 	return protocol->device_module->remove_multicast(protocol->device,
814 		address);
815 }
816 
817 
818 net_datalink_module_info gNetDatalinkModule = {
819 	{
820 		NET_DATALINK_MODULE_NAME,
821 		0,
822 		datalink_std_ops
823 	},
824 
825 	datalink_control,
826 	datalink_send_data,
827 	datalink_send_datagram,
828 	datalink_is_local_address,
829 	datalink_get_interface,
830 	datalink_get_interface_with_address,
831 
832 	add_route,
833 	remove_route,
834 	get_route,
835 	get_buffer_route,
836 	put_route,
837 	register_route_info,
838 	unregister_route_info,
839 	update_route_info
840 };
841 
842 net_datalink_protocol_module_info gDatalinkInterfaceProtocolModule = {
843 	{
844 		NULL,
845 		0,
846 		NULL
847 	},
848 	interface_protocol_init,
849 	interface_protocol_uninit,
850 	interface_protocol_send_data,
851 	interface_protocol_up,
852 	interface_protocol_down,
853 	interface_protocol_control,
854 	interface_protocol_join_multicast,
855 	interface_protocol_leave_multicast,
856 };
857