From 03e02ed9836f03018a146f791ee65a3ec3ab7842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 3 Aug 2010 11:23:03 +0000 Subject: [PATCH] * Introduced a datalink layer (2) independent way of specifying the packet type one wants to receive. Changed ipv6_datagram to use that (but note that it currently does not compile). * Header cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37868 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/net/ethernet.h | 4 +- headers/private/net/net_buffer.h | 5 +- headers/private/net/net_datalink.h | 9 +- headers/private/net/net_device.h | 47 +++-- headers/private/net/net_socket.h | 111 +++++----- headers/private/net/net_stack.h | 190 ++++++++++-------- .../network/datalink_protocols/arp/arp.cpp | 8 +- .../ethernet_frame/ethernet_frame.cpp | 22 +- .../ipv6_datagram/ipv6_datagram.cpp | 12 +- .../loopback_frame/loopback_frame.cpp | 4 +- .../network/stack/device_interfaces.cpp | 33 +-- src/add-ons/kernel/network/stack/link.cpp | 4 +- 12 files changed, 247 insertions(+), 202 deletions(-) diff --git a/headers/private/net/ethernet.h b/headers/private/net/ethernet.h index cb6d5f0de6..20322e1986 100644 --- a/headers/private/net/ethernet.h +++ b/headers/private/net/ethernet.h @@ -1,5 +1,5 @@ /* - * Copyright 2006, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2010, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef ETHERNET_H @@ -22,7 +22,6 @@ struct ether_header { uint16 type; } _PACKED; -#define ETHER_FRAME_TYPE 0x00010000 // ethernet types #define ETHER_TYPE_IP 0x0800 @@ -32,4 +31,5 @@ struct ether_header { #define ETHER_TYPE_PPPOE_DISCOVERY 0x8863 // PPPoE discovery stage #define ETHER_TYPE_PPPOE 0x8864 // PPPoE session stage + #endif // ETHERNET_H diff --git a/headers/private/net/net_buffer.h b/headers/private/net/net_buffer.h index 6877c73865..b9f06a4602 100644 --- a/headers/private/net/net_buffer.h +++ b/headers/private/net/net_buffer.h @@ -6,10 +6,11 @@ #define NET_BUFFER_H -#include +#include #include -#include + +#include #define NET_BUFFER_MODULE_NAME "network/stack/buffer/v1" diff --git a/headers/private/net/net_datalink.h b/headers/private/net/net_datalink.h index 48f8d155a1..073e96bc4c 100644 --- a/headers/private/net/net_datalink.h +++ b/headers/private/net/net_datalink.h @@ -6,16 +6,21 @@ #define NET_DATALINK_H +#include + #include #include #include -#include - #define NET_DATALINK_MODULE_NAME "network/stack/datalink/v1" + +struct Checksum; +struct net_protocol; + + typedef struct net_datalink_protocol net_datalink_protocol; diff --git a/headers/private/net/net_device.h b/headers/private/net/net_device.h index cab7526c00..64e119501a 100644 --- a/headers/private/net/net_device.h +++ b/headers/private/net/net_device.h @@ -1,14 +1,17 @@ /* - * Copyright 2006-2007, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2010, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef NET_DEVICE_H #define NET_DEVICE_H +#include + #include -#include + +typedef struct net_buffer net_buffer; struct net_hardware_address { @@ -16,8 +19,8 @@ struct net_hardware_address { uint8 length; }; -struct net_device { - struct net_device_module_info *module; +typedef struct net_device { + struct net_device_module_info* module; char name[IF_NAMESIZE]; uint32 index; @@ -32,33 +35,33 @@ struct net_device { struct net_hardware_address address; struct ifreq_stats stats; -}; +} net_device; + struct net_device_module_info { struct module_info info; - status_t (*init_device)(const char *name, struct net_device **_device); - status_t (*uninit_device)(struct net_device *device); + status_t (*init_device)(const char* name, net_device** _device); + status_t (*uninit_device)(net_device* device); - status_t (*up)(struct net_device *device); - void (*down)(struct net_device *device); + status_t (*up)(net_device* device); + void (*down)(net_device* device); - status_t (*control)(struct net_device *device, int32 op, - void *argument, size_t length); + status_t (*control)(net_device* device, int32 op, void* argument, + size_t length); - status_t (*send_data)(struct net_device *device, - struct net_buffer *buffer); - status_t (*receive_data)(struct net_device *device, - struct net_buffer **_buffer); + status_t (*send_data)(net_device* device, net_buffer* buffer); + status_t (*receive_data)(net_device* device, net_buffer** _buffer); - status_t (*set_mtu)(struct net_device *device, size_t mtu); - status_t (*set_promiscuous)(struct net_device *device, bool promiscuous); - status_t (*set_media)(struct net_device *device, uint32 media); + status_t (*set_mtu)(net_device* device, size_t mtu); + status_t (*set_promiscuous)(net_device* device, bool promiscuous); + status_t (*set_media)(net_device* device, uint32 media); - status_t (*add_multicast)(struct net_device *device, - const struct sockaddr *address); - status_t (*remove_multicast)(struct net_device *device, - const struct sockaddr *address); + status_t (*add_multicast)(net_device* device, + const struct sockaddr* address); + status_t (*remove_multicast)(net_device* device, + const struct sockaddr* address); }; + #endif // NET_DEVICE_H diff --git a/headers/private/net/net_socket.h b/headers/private/net/net_socket.h index 527d8ad27d..d742749cc1 100644 --- a/headers/private/net/net_socket.h +++ b/headers/private/net/net_socket.h @@ -1,5 +1,5 @@ /* - * Copyright 2006-2009, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2010, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef NET_SOCKET_H @@ -11,14 +11,17 @@ #include + +struct net_stat; struct selectsync; #define NET_SOCKET_MODULE_NAME "network/stack/socket/v1" + typedef struct net_socket { - struct net_protocol *first_protocol; - struct net_protocol_module_info *first_info; + struct net_protocol* first_protocol; + struct net_protocol_module_info* first_info; int family; int type; @@ -40,79 +43,81 @@ typedef struct net_socket { status_t error; } net_socket; + struct net_socket_module_info { struct module_info info; status_t (*open_socket)(int family, int type, int protocol, - net_socket **_socket); - status_t (*close)(net_socket *socket); - void (*free)(net_socket *socket); + net_socket** _socket); + status_t (*close)(net_socket* socket); + void (*free)(net_socket* socket); - status_t (*readv)(net_socket *socket, const iovec *vecs, - size_t vecCount, size_t *_length); - status_t (*writev)(net_socket *socket, const iovec *vecs, - size_t vecCount, size_t *_length); - status_t (*control)(net_socket *socket, int32 op, void *data, + status_t (*readv)(net_socket* socket, const iovec* vecs, + size_t vecCount, size_t* _length); + status_t (*writev)(net_socket* socket, const iovec* vecs, + size_t vecCount, size_t* _length); + status_t (*control)(net_socket* socket, int32 op, void* data, size_t length); - ssize_t (*read_avail)(net_socket *socket); - ssize_t (*send_avail)(net_socket *socket); + ssize_t (*read_avail)(net_socket* socket); + ssize_t (*send_avail)(net_socket* socket); - status_t (*send_data)(net_socket *socket, net_buffer *buffer); - status_t (*receive_data)(net_socket *socket, size_t length, - uint32 flags, net_buffer **_buffer); + status_t (*send_data)(net_socket* socket, net_buffer* buffer); + status_t (*receive_data)(net_socket* socket, size_t length, + uint32 flags, net_buffer** _buffer); - status_t (*get_option)(net_socket *socket, int level, int option, - void *value, int *_length); - status_t (*set_option)(net_socket *socket, int level, int option, - const void *value, int length); + status_t (*get_option)(net_socket* socket, int level, int option, + void* value, int* _length); + status_t (*set_option)(net_socket* socket, int level, int option, + const void* value, int length); - status_t (*get_next_stat)(uint32 *cookie, int family, - struct net_stat *stat); + status_t (*get_next_stat)(uint32* cookie, int family, + struct net_stat* stat); // connections - bool (*acquire_socket)(net_socket *socket); - bool (*release_socket)(net_socket *socket); + bool (*acquire_socket)(net_socket* socket); + bool (*release_socket)(net_socket* socket); - status_t (*spawn_pending_socket)(net_socket *parent, - net_socket **_socket); - status_t (*dequeue_connected)(net_socket *parent, net_socket **_socket); - ssize_t (*count_connected)(net_socket *parent); - status_t (*set_max_backlog)(net_socket *socket, uint32 backlog); - bool (*has_parent)(net_socket *socket); - status_t (*set_connected)(net_socket *socket); - status_t (*set_aborted)(net_socket *socket); + status_t (*spawn_pending_socket)(net_socket* parent, + net_socket** _socket); + status_t (*dequeue_connected)(net_socket* parent, net_socket** _socket); + ssize_t (*count_connected)(net_socket* parent); + status_t (*set_max_backlog)(net_socket* socket, uint32 backlog); + bool (*has_parent)(net_socket* socket); + status_t (*set_connected)(net_socket* socket); + status_t (*set_aborted)(net_socket* socket); // notifications - status_t (*request_notification)(net_socket *socket, uint8 event, - struct selectsync *sync); - status_t (*cancel_notification)(net_socket *socket, uint8 event, - struct selectsync *sync); - status_t (*notify)(net_socket *socket, uint8 event, int32 value); + status_t (*request_notification)(net_socket* socket, uint8 event, + struct selectsync* sync); + status_t (*cancel_notification)(net_socket* socket, uint8 event, + struct selectsync* sync); + status_t (*notify)(net_socket* socket, uint8 event, int32 value); // standard socket API - int (*accept)(net_socket *socket, struct sockaddr *address, - socklen_t *_addressLength, net_socket **_acceptedSocket); - int (*bind)(net_socket *socket, const struct sockaddr *address, + int (*accept)(net_socket* socket, struct sockaddr* address, + socklen_t* _addressLength, net_socket** _acceptedSocket); + int (*bind)(net_socket* socket, const struct sockaddr* address, socklen_t addressLength); - int (*connect)(net_socket *socket, const struct sockaddr *address, + int (*connect)(net_socket* socket, const struct sockaddr* address, socklen_t addressLength); - int (*getpeername)(net_socket *socket, struct sockaddr *address, - socklen_t *_addressLength); - int (*getsockname)(net_socket *socket, struct sockaddr *address, - socklen_t *_addressLength); - int (*getsockopt)(net_socket *socket, int level, int option, - void *optionValue, int *_optionLength); - int (*listen)(net_socket *socket, int backlog); - ssize_t (*receive)(net_socket *socket, struct msghdr *, void *data, + int (*getpeername)(net_socket* socket, struct sockaddr* address, + socklen_t* _addressLength); + int (*getsockname)(net_socket* socket, struct sockaddr* address, + socklen_t* _addressLength); + int (*getsockopt)(net_socket* socket, int level, int option, + void* optionValue, int* _optionLength); + int (*listen)(net_socket* socket, int backlog); + ssize_t (*receive)(net_socket* socket, struct msghdr* , void* data, size_t length, int flags); - ssize_t (*send)(net_socket *socket, struct msghdr *, const void *data, + ssize_t (*send)(net_socket* socket, struct msghdr* , const void* data, size_t length, int flags); - int (*setsockopt)(net_socket *socket, int level, int option, - const void *optionValue, int optionLength); - int (*shutdown)(net_socket *socket, int direction); + int (*setsockopt)(net_socket* socket, int level, int option, + const void* optionValue, int optionLength); + int (*shutdown)(net_socket* socket, int direction); status_t (*socketpair)(int family, int type, int protocol, net_socket* _sockets[2]); }; + #endif // NET_SOCKET_H diff --git a/headers/private/net/net_stack.h b/headers/private/net/net_stack.h index 16de4a4486..6c66e5f563 100644 --- a/headers/private/net/net_stack.h +++ b/headers/private/net/net_stack.h @@ -1,16 +1,16 @@ /* - * Copyright 2006-2008, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2010, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. */ #ifndef NET_STACK_H #define NET_STACK_H +#include + #include #include -#include - #define NET_STACK_MODULE_NAME "network/stack/v1" @@ -18,15 +18,15 @@ struct net_address_module_info; struct net_protocol_module_info; -struct net_buffer; -struct net_device; -struct net_domain; -struct net_socket; +typedef struct net_buffer net_buffer; +typedef struct net_device net_device; +typedef struct net_domain net_domain; +typedef struct net_socket net_socket; + struct net_timer; -typedef struct ancillary_data_container ancillary_data_container; -struct net_fifo { +typedef struct net_fifo { mutex lock; sem_id notify; int32 waiting; @@ -35,22 +35,21 @@ struct net_fifo { size_t current_bytes; struct list buffers; -}; +} net_fifo; -typedef void (*net_timer_func)(struct net_timer *timer, void *data); +typedef void (*net_timer_func)(struct net_timer* timer, void* data); -struct net_timer { +typedef struct net_timer { struct list_link link; net_timer_func hook; - void *data; + void* data; bigtime_t due; uint32 flags; -}; +} net_timer; -typedef int32 (*net_deframe_func)(struct net_device *device, - struct net_buffer *buffer); -typedef status_t (*net_receive_func)(void *cookie, struct net_device *device, - struct net_buffer *buffer); +typedef status_t (*net_deframe_func)(net_device* device, net_buffer* buffer); +typedef status_t (*net_receive_func)(void* cookie, net_device* device, + net_buffer* buffer); enum { B_DEVICE_GOING_UP = 1, @@ -58,14 +57,14 @@ enum { B_DEVICE_BEING_REMOVED, }; -struct net_device_monitor { +typedef struct net_device_monitor { struct list_link link; - void *cookie; + void* cookie; - status_t (*receive)(struct net_device_monitor *monitor, - struct net_buffer *buffer); - void (*event)(struct net_device_monitor *monitor, int32 event); -}; + status_t (*receive)(struct net_device_monitor* monitor, + struct net_buffer* buffer); + void (*event)(struct net_device_monitor* monitor, int32 event); +} net_device_monitor; typedef struct ancillary_data_header { int level; @@ -73,98 +72,117 @@ typedef struct ancillary_data_header { size_t len; } ancillary_data_header; +typedef struct ancillary_data_container ancillary_data_container; + + +#define B_NET_FRAME_TYPE(super, sub) (((int32)(super) << 16) | (sub)) + // Use this when registering a device handler, see net/if_types.h for + // the possible "super" values. + + +// sub types +enum { + B_NET_FRAME_TYPE_IPV4 = 0x0001, + B_NET_FRAME_TYPE_IPV6 = 0x0002, + B_NET_FRAME_TYPE_IPX = 0x0003, + B_NET_FRAME_TYPE_APPLE_TALK = 0x0004, + + B_NET_FRAME_TYPE_ALL = 0x0000 +}; + + struct net_stack_module_info { module_info info; - status_t (*register_domain)(int family, const char *name, - struct net_protocol_module_info *module, - struct net_address_module_info *addressModule, - struct net_domain **_domain); - status_t (*unregister_domain)(struct net_domain *domain); - struct net_domain *(*get_domain)(int family); + status_t (*register_domain)(int family, const char* name, + struct net_protocol_module_info* module, + struct net_address_module_info* addressModule, + net_domain** _domain); + status_t (*unregister_domain)(net_domain* domain); + net_domain* (*get_domain)(int family); - status_t (*register_domain_protocols)(int family, int type, int protocol, ...); - status_t (*register_domain_datalink_protocols)(int family, int type, ...); - status_t (*register_domain_receiving_protocol)(int family, int type, - const char *moduleName); + status_t (*register_domain_protocols)(int family, int type, int protocol, + ...); + status_t (*register_domain_datalink_protocols)(int family, int type, + ...); + status_t (*register_domain_receiving_protocol)(int family, int type, + const char* moduleName); - status_t (*get_domain_receiving_protocol)(struct net_domain *domain, - uint32 type, struct net_protocol_module_info **_module); - status_t (*put_domain_receiving_protocol)(struct net_domain *domain, + status_t (*get_domain_receiving_protocol)(net_domain* domain, + uint32 type, struct net_protocol_module_info** _module); + status_t (*put_domain_receiving_protocol)(net_domain* domain, uint32 type); // devices - status_t (*register_device_deframer)(struct net_device *device, + status_t (*register_device_deframer)(net_device* device, net_deframe_func deframeFunc); - status_t (*unregister_device_deframer)(struct net_device *device); + status_t (*unregister_device_deframer)(net_device* device); - status_t (*register_domain_device_handler)(struct net_device *device, - int32 type, struct net_domain *domain); - status_t (*register_device_handler)(struct net_device *device, int32 type, - net_receive_func receiveFunc, void *cookie); - status_t (*unregister_device_handler)(struct net_device *device, int32 type); + status_t (*register_domain_device_handler)(net_device* device, + int32 type, net_domain* domain); + status_t (*register_device_handler)(net_device* device, + int32 type, net_receive_func receiveFunc, void* cookie); + status_t (*unregister_device_handler)(net_device* device, int32 type); - status_t (*register_device_monitor)(struct net_device *device, - struct net_device_monitor *monitor); - status_t (*unregister_device_monitor)(struct net_device *device, - struct net_device_monitor *monitor); + status_t (*register_device_monitor)(net_device* device, + struct net_device_monitor* monitor); + status_t (*unregister_device_monitor)(net_device* device, + struct net_device_monitor* monitor); - status_t (*device_link_changed)(struct net_device *device); - status_t (*device_removed)(struct net_device *device); + status_t (*device_link_changed)(net_device* device); + status_t (*device_removed)(net_device* device); - status_t (*device_enqueue_buffer)(struct net_device *device, - struct net_buffer *buffer); + status_t (*device_enqueue_buffer)(net_device* device, + net_buffer* buffer); // Utility Functions // notification - status_t (*notify_socket)(struct net_socket *socket, uint8 event, - int32 value); + status_t (*notify_socket)(net_socket* socket, uint8 event, int32 value); // checksum - uint16 (*checksum)(uint8 *buffer, size_t length); + uint16 (*checksum)(uint8* buffer, size_t length); // fifo - status_t (*init_fifo)(struct net_fifo *fifo, const char *name, - size_t maxBytes); - void (*uninit_fifo)(struct net_fifo *fifo); - status_t (*fifo_enqueue_buffer)(struct net_fifo *fifo, - struct net_buffer *buffer); - ssize_t (*fifo_dequeue_buffer)(struct net_fifo *fifo, uint32 flags, - bigtime_t timeout, struct net_buffer **_buffer); - status_t (*clear_fifo)(struct net_fifo *fifo); - status_t (*fifo_socket_enqueue_buffer)(struct net_fifo *fifo, - struct net_socket *socket, uint8 event, - struct net_buffer *buffer); + status_t (*init_fifo)(net_fifo* fifo, const char* name, size_t maxBytes); + void (*uninit_fifo)(net_fifo* fifo); + status_t (*fifo_enqueue_buffer)(net_fifo* fifo, net_buffer* buffer); + ssize_t (*fifo_dequeue_buffer)(net_fifo* fifo, uint32 flags, + bigtime_t timeout, net_buffer** _buffer); + status_t (*clear_fifo)(net_fifo* fifo); + status_t (*fifo_socket_enqueue_buffer)(net_fifo* fifo, + net_socket* socket, uint8 event, net_buffer* buffer); // timer - void (*init_timer)(struct net_timer *timer, net_timer_func hook, void *data); - void (*set_timer)(struct net_timer *timer, bigtime_t delay); - bool (*cancel_timer)(struct net_timer *timer); - status_t (*wait_for_timer)(struct net_timer *timer); - bool (*is_timer_active)(struct net_timer *timer); - bool (*is_timer_running)(struct net_timer *timer); + void (*init_timer)(net_timer* timer, net_timer_func hook, + void* data); + void (*set_timer)(net_timer* timer, bigtime_t delay); + bool (*cancel_timer)(net_timer* timer); + status_t (*wait_for_timer)(net_timer* timer); + bool (*is_timer_active)(net_timer* timer); + bool (*is_timer_running)(net_timer* timer); // syscall restart - bool (*is_syscall)(void); - bool (*is_restarted_syscall)(void); - void (*store_syscall_restart_timeout)(bigtime_t timeout); - bigtime_t (*restore_syscall_restart_timeout)(void); + bool (*is_syscall)(void); + bool (*is_restarted_syscall)(void); + void (*store_syscall_restart_timeout)(bigtime_t timeout); + bigtime_t (*restore_syscall_restart_timeout)(void); // ancillary data ancillary_data_container* (*create_ancillary_data_container)(); - void (*delete_ancillary_data_container)( + void (*delete_ancillary_data_container)( ancillary_data_container* container); - status_t (*add_ancillary_data)(ancillary_data_container *container, - const ancillary_data_header *header, const void *data, + status_t (*add_ancillary_data)(ancillary_data_container* container, + const ancillary_data_header* header, const void* data, void (*destructor)(const ancillary_data_header*, void*), - void **_allocatedData); - status_t (*remove_ancillary_data)(ancillary_data_container *container, - void *data, bool destroy); - void* (*move_ancillary_data)(ancillary_data_container *from, - ancillary_data_container *to); - void* (*next_ancillary_data)(ancillary_data_container *container, - void *previousData, ancillary_data_header *_header); + void** _allocatedData); + status_t (*remove_ancillary_data)(ancillary_data_container* container, + void* data, bool destroy); + void* (*move_ancillary_data)(ancillary_data_container* from, + ancillary_data_container* to); + void* (*next_ancillary_data)(ancillary_data_container* container, + void* previousData, ancillary_data_header* _header); }; + #endif // NET_STACK_H diff --git a/src/add-ons/kernel/network/datalink_protocols/arp/arp.cpp b/src/add-ons/kernel/network/datalink_protocols/arp/arp.cpp index 1e38cb61c7..1a7ee11a98 100644 --- a/src/add-ons/kernel/network/datalink_protocols/arp/arp.cpp +++ b/src/add-ons/kernel/network/datalink_protocols/arp/arp.cpp @@ -955,12 +955,12 @@ arp_init_protocol(net_interface* interface, net_domain* domain, return B_BAD_TYPE; status_t status = sStackModule->register_device_handler(interface->device, - ETHER_FRAME_TYPE | ETHER_TYPE_ARP, &arp_receive, NULL); + B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_ARP), &arp_receive, NULL); if (status != B_OK) return status; status = sStackModule->register_domain_device_handler( - interface->device, ETHER_FRAME_TYPE | ETHER_TYPE_IP, domain); + interface->device, B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_IP), domain); if (status != B_OK) return status; @@ -978,9 +978,9 @@ status_t arp_uninit_protocol(net_datalink_protocol *protocol) { sStackModule->unregister_device_handler(protocol->interface->device, - ETHER_FRAME_TYPE | ETHER_TYPE_ARP); + B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_ARP)); sStackModule->unregister_device_handler(protocol->interface->device, - ETHER_FRAME_TYPE | ETHER_TYPE_IP); + B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_IP)); delete protocol; return B_OK; diff --git a/src/add-ons/kernel/network/datalink_protocols/ethernet_frame/ethernet_frame.cpp b/src/add-ons/kernel/network/datalink_protocols/ethernet_frame/ethernet_frame.cpp index 25e13f0132..ed41f2c88c 100644 --- a/src/add-ons/kernel/network/datalink_protocols/ethernet_frame/ethernet_frame.cpp +++ b/src/add-ons/kernel/network/datalink_protocols/ethernet_frame/ethernet_frame.cpp @@ -61,17 +61,35 @@ ethernet_deframe(net_device* device, net_buffer* buffer) destination.sdl_family = AF_LINK; destination.sdl_index = device->index; destination.sdl_type = IFT_ETHER; + destination.sdl_e_type = type; destination.sdl_nlen = destination.sdl_slen = 0; destination.sdl_alen = ETHER_ADDRESS_LENGTH; memcpy(destination.sdl_data, header.destination, ETHER_ADDRESS_LENGTH); - // mark buffer if it was a broadcast/multicast packet + // Mark buffer if it was a broadcast/multicast packet if (!memcmp(header.destination, kBroadcastAddress, ETHER_ADDRESS_LENGTH)) buffer->flags |= MSG_BCAST; else if ((header.destination[0] & 0x01) != 0) buffer->flags |= MSG_MCAST; - return ETHER_FRAME_TYPE | type; + // Translate the ethernet specific type to a generic one if possible + switch (type) { + case ETHER_TYPE_IP: + buffer->type = B_NET_FRAME_TYPE_IPV4; + break; + case ETHER_TYPE_IPV6: + buffer->type = B_NET_FRAME_TYPE_IPV6; + break; + case ETHER_TYPE_IPX: + buffer->type = B_NET_FRAME_TYPE_IPX; + break; + + default: + buffer->type = B_NET_FRAME_TYPE(IFT_ETHER, type); + break; + } + + return B_OK; } diff --git a/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ipv6_datagram.cpp b/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ipv6_datagram.cpp index ee15c2d0cd..23713e34bf 100644 --- a/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ipv6_datagram.cpp +++ b/src/add-ons/kernel/network/datalink_protocols/ipv6_datagram/ipv6_datagram.cpp @@ -58,9 +58,6 @@ static net_protocol_module_info* sIPv6Module; net_protocol* sIPv6Protocol; static hash_table* sCache; static mutex sCacheLock; -// TODO ETHER_FRAME_TYPE doesn't belong there, we need Layer 2 -// independence. -static const int32 kIPv6FrameType = ETHER_FRAME_TYPE | ETHER_TYPE_IPV6; static const net_buffer* kDeletedBuffer = (net_buffer*)~0; // needed for IN6_IS_ADDR_UNSPECIFIED() macro @@ -887,12 +884,9 @@ ipv6_datalink_init(net_interface* interface, net_datalink_protocol** _protocol) memset(&protocol->hardware_address, 0, sizeof(sockaddr_dl)); - // We register ETHER_TYPE_IPV6 as most datalink protocols use it - // to identify IPv6 datagrams. In the future we may limit this. - status_t status = sStackModule->register_domain_device_handler( - interface->device, kIPv6FrameType, interface->domain); - if (status < B_OK) + interface->device, B_NET_FRAME_TYPE_IPV6, interface->domain); + if (status != B_OK) delete protocol; else *_protocol = protocol; @@ -905,7 +899,7 @@ static status_t ipv6_datalink_uninit(net_datalink_protocol* protocol) { sStackModule->unregister_device_handler(protocol->interface->device, - kIPv6FrameType); + B_NET_FRAME_TYPE_IPV6); delete protocol; return B_OK; } diff --git a/src/add-ons/kernel/network/datalink_protocols/loopback_frame/loopback_frame.cpp b/src/add-ons/kernel/network/datalink_protocols/loopback_frame/loopback_frame.cpp index 4f5522b54f..a91556518f 100644 --- a/src/add-ons/kernel/network/datalink_protocols/loopback_frame/loopback_frame.cpp +++ b/src/add-ons/kernel/network/datalink_protocols/loopback_frame/loopback_frame.cpp @@ -31,11 +31,11 @@ struct loopback_frame_protocol : net_datalink_protocol { struct net_buffer_module_info* gBufferModule; -int32 +status_t loopback_deframe(net_device* device, net_buffer* buffer) { // there is not that much to do... - return 0; + return B_OK; } diff --git a/src/add-ons/kernel/network/stack/device_interfaces.cpp b/src/add-ons/kernel/network/stack/device_interfaces.cpp index de97627ccc..2f11671d36 100644 --- a/src/add-ons/kernel/network/stack/device_interfaces.cpp +++ b/src/add-ons/kernel/network/stack/device_interfaces.cpp @@ -51,24 +51,16 @@ device_reader_thread(void* _interface) net_device* device = interface->device; status_t status = B_OK; - RecursiveLocker locker(interface->receive_lock); - while ((device->flags & IFF_UP) != 0) { - locker.Unlock(); - net_buffer* buffer; status = device->module->receive_data(device, &buffer); - - locker.Lock(); - if (status == B_OK) { // feed device monitors if (atomic_get(&interface->monitor_count) > 0) device_interface_monitor_receive(interface, buffer); buffer->interface_address = NULL; - buffer->type = interface->deframe_func(interface->device, buffer); - if (buffer->type < 0) { + if (interface->deframe_func(interface->device, buffer) != B_OK) { gNetBufferModule.free(buffer); continue; } @@ -102,20 +94,29 @@ device_consumer_thread(void* _interface) } if (buffer->interface_address != NULL) { - // if the interface is already specified, this buffer was + // If the interface is already specified, this buffer was // delivered locally. if (buffer->interface_address->domain->module->receive_data(buffer) == B_OK) buffer = NULL; } else { - // find handler for this packet - DeviceHandlerList::Iterator iterator = - interface->receive_funcs.GetIterator(); - while (buffer && iterator.HasNext()) { + sockaddr_dl& linkAddress = *(sockaddr_dl*)buffer->source; + int32 specificType = B_NET_FRAME_TYPE(linkAddress.sdl_type, + linkAddress.sdl_e_type); + + // Find handler for this packet + + RecursiveLocker locker(interface->receive_lock); + + DeviceHandlerList::Iterator iterator + = interface->receive_funcs.GetIterator(); + while (buffer != NULL && iterator.HasNext()) { net_device_handler* handler = iterator.Next(); - // if the handler returns B_OK, it consumed the buffer - if (handler->type == buffer->type + // If the handler returns B_OK, it consumed the buffer - first + // handler wins. + if ((handler->type == buffer->type + || handler->type == specificType) && handler->func(handler->cookie, device, buffer) == B_OK) buffer = NULL; } diff --git a/src/add-ons/kernel/network/stack/link.cpp b/src/add-ons/kernel/network/stack/link.cpp index 0294ccac21..4e9d53b42c 100644 --- a/src/add-ons/kernel/network/stack/link.cpp +++ b/src/add-ons/kernel/network/stack/link.cpp @@ -166,8 +166,8 @@ LinkProtocol::Bind(const sockaddr* address) sockaddr_dl& linkAddress = *(sockaddr_dl*)address; if (linkAddress.sdl_type != 0) { - fBoundType = ((uint32)linkAddress.sdl_type << 16) - | linkAddress.sdl_e_type; + fBoundType = B_NET_FRAME_TYPE(linkAddress.sdl_type, + linkAddress.sdl_e_type); // Bind to the type requested - this is needed in order to // receive any buffers // TODO: this could be easily changed by introducing catch all or rule