1/*- 2 * Copyright (c) 2010 Isilon Systems, Inc. 3 * Copyright (c) 2010 iX Systems, Inc. 4 * Copyright (c) 2010 Panasas, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice unmodified, this list of conditions, and the following 12 * disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28#ifndef _LINUX_NETDEVICE_H_ 29#define _LINUX_NETDEVICE_H_ 30 31#include <linux/types.h> 32 33#include <sys/socket.h> 34 35#include <net/if_types.h> 36#include <net/if.h> 37#include <net/if_var.h> 38#include <net/if_dl.h> 39 40#include <linux/completion.h> 41#include <linux/device.h> 42#include <linux/ethtool.h> 43#include <linux/workqueue.h> 44#include <linux/net.h> 45#include <linux/notifier.h> 46 47struct net { 48}; 49 50extern struct net init_net; 51 52#define MAX_ADDR_LEN 20 53 54#define net_device ifnet 55 56#define dev_get_by_index(n, idx) ifnet_byindex_ref((idx)) 57#define dev_hold(d) if_ref((d)) 58#define dev_put(d) if_rele((d)) 59 60#define netif_running(dev) !!((dev)->if_drv_flags & IFF_DRV_RUNNING) 61#define netif_oper_up(dev) !!((dev)->if_flags & IFF_UP) 62#define netif_carrier_ok(dev) netif_running(dev) 63 64static inline void * 65netdev_priv(const struct net_device *dev) 66{ 67 return (dev->if_softc); 68} 69 70static inline void 71_handle_ifnet_link_event(void *arg, struct ifnet *ifp, int linkstate) 72{ 73 struct notifier_block *nb; 74 75 nb = arg; 76 if (linkstate == LINK_STATE_UP) 77 nb->notifier_call(nb, NETDEV_UP, ifp); 78 else 79 nb->notifier_call(nb, NETDEV_DOWN, ifp); 80} 81 82static inline void 83_handle_ifnet_arrival_event(void *arg, struct ifnet *ifp) 84{ 85 struct notifier_block *nb; 86 87 nb = arg; 88 nb->notifier_call(nb, NETDEV_REGISTER, ifp); 89} 90 91static inline void 92_handle_ifnet_departure_event(void *arg, struct ifnet *ifp) 93{ 94 struct notifier_block *nb; 95 96 nb = arg; 97 nb->notifier_call(nb, NETDEV_UNREGISTER, ifp); 98} 99 100static inline int 101register_netdevice_notifier(struct notifier_block *nb) 102{ 103 104 nb->tags[NETDEV_UP] = EVENTHANDLER_REGISTER( 105 ifnet_link_event, _handle_ifnet_link_event, nb, 0); 106 nb->tags[NETDEV_REGISTER] = EVENTHANDLER_REGISTER( 107 ifnet_arrival_event, _handle_ifnet_arrival_event, nb, 0); 108 nb->tags[NETDEV_UNREGISTER] = EVENTHANDLER_REGISTER( 109 ifnet_departure_event, _handle_ifnet_departure_event, nb, 0); 110 return (0); 111} 112 113static inline int 114unregister_netdevice_notifier(struct notifier_block *nb) 115{ 116 117 EVENTHANDLER_DEREGISTER(ifnet_link_event, nb->tags[NETDEV_UP]); 118 EVENTHANDLER_DEREGISTER(ifnet_arrival_event, nb->tags[NETDEV_REGISTER]); 119 EVENTHANDLER_DEREGISTER(ifnet_departure_event, 120 nb->tags[NETDEV_UNREGISTER]); 121 return (0); 122} 123 124#define rtnl_lock() 125#define rtnl_unlock() 126 127static inline int 128dev_mc_delete(struct net_device *dev, void *addr, int alen, int all) 129{ 130 struct sockaddr_dl sdl; 131 132 if (alen > sizeof(sdl.sdl_data)) 133 return (-EINVAL); 134 memset(&sdl, 0, sizeof(sdl)); 135 sdl.sdl_len = sizeof(sdl); 136 sdl.sdl_family = AF_LINK; 137 sdl.sdl_alen = alen; 138 memcpy(&sdl.sdl_data, addr, alen); 139 140 return -if_delmulti(dev, (struct sockaddr *)&sdl); 141} 142 143static inline int 144dev_mc_add(struct net_device *dev, void *addr, int alen, int newonly) 145{ 146 struct sockaddr_dl sdl; 147 148 if (alen > sizeof(sdl.sdl_data)) 149 return (-EINVAL); 150 memset(&sdl, 0, sizeof(sdl)); 151 sdl.sdl_len = sizeof(sdl); 152 sdl.sdl_family = AF_LINK; 153 sdl.sdl_alen = alen; 154 memcpy(&sdl.sdl_data, addr, alen); 155 156 return -if_addmulti(dev, (struct sockaddr *)&sdl, NULL); 157} 158 159#endif /* _LINUX_NETDEVICE_H_ */ 160