netdevice.h revision 273246
1/*- 2 * Copyright (c) 2010 Isilon Systems, Inc. 3 * Copyright (c) 2010 iX Systems, Inc. 4 * Copyright (c) 2010 Panasas, Inc. 5 * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice unmodified, this list of conditions, and the following 13 * disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29#ifndef _LINUX_NETDEVICE_H_ 30#define _LINUX_NETDEVICE_H_ 31 32#include <linux/types.h> 33 34#include <sys/socket.h> 35 36#include <net/if_types.h> 37#include <net/if.h> 38#include <net/if_var.h> 39#include <net/if_dl.h> 40 41#include <linux/completion.h> 42#include <linux/device.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 void 101_handle_iflladdr_event(void *arg, struct ifnet *ifp) 102{ 103 struct notifier_block *nb; 104 105 nb = arg; 106 nb->notifier_call(nb, NETDEV_CHANGEADDR, ifp); 107} 108 109static inline void 110_handle_ifaddr_event(void *arg, struct ifnet *ifp) 111{ 112 struct notifier_block *nb; 113 114 nb = arg; 115 nb->notifier_call(nb, NETDEV_CHANGEIFADDR, ifp); 116} 117 118static inline int 119register_netdevice_notifier(struct notifier_block *nb) 120{ 121 122 nb->tags[NETDEV_UP] = EVENTHANDLER_REGISTER( 123 ifnet_link_event, _handle_ifnet_link_event, nb, 0); 124 nb->tags[NETDEV_REGISTER] = EVENTHANDLER_REGISTER( 125 ifnet_arrival_event, _handle_ifnet_arrival_event, nb, 0); 126 nb->tags[NETDEV_UNREGISTER] = EVENTHANDLER_REGISTER( 127 ifnet_departure_event, _handle_ifnet_departure_event, nb, 0); 128 nb->tags[NETDEV_CHANGEADDR] = EVENTHANDLER_REGISTER( 129 iflladdr_event, _handle_iflladdr_event, nb, 0); 130 131 return (0); 132} 133 134static inline int 135register_inetaddr_notifier(struct notifier_block *nb) 136{ 137 138 nb->tags[NETDEV_CHANGEIFADDR] = EVENTHANDLER_REGISTER( 139 ifaddr_event, _handle_ifaddr_event, nb, 0); 140 return (0); 141} 142 143static inline int 144unregister_netdevice_notifier(struct notifier_block *nb) 145{ 146 147 EVENTHANDLER_DEREGISTER(ifnet_link_event, nb->tags[NETDEV_UP]); 148 EVENTHANDLER_DEREGISTER(ifnet_arrival_event, nb->tags[NETDEV_REGISTER]); 149 EVENTHANDLER_DEREGISTER(ifnet_departure_event, 150 nb->tags[NETDEV_UNREGISTER]); 151 EVENTHANDLER_DEREGISTER(iflladdr_event, 152 nb->tags[NETDEV_CHANGEADDR]); 153 154 return (0); 155} 156 157static inline int 158unregister_inetaddr_notifier(struct notifier_block *nb) 159{ 160 161 EVENTHANDLER_DEREGISTER(ifaddr_event, 162 nb->tags[NETDEV_CHANGEIFADDR]); 163 164 return (0); 165} 166 167 168#define rtnl_lock() 169#define rtnl_unlock() 170 171static inline int 172dev_mc_delete(struct net_device *dev, void *addr, int alen, int all) 173{ 174 struct sockaddr_dl sdl; 175 176 if (alen > sizeof(sdl.sdl_data)) 177 return (-EINVAL); 178 memset(&sdl, 0, sizeof(sdl)); 179 sdl.sdl_len = sizeof(sdl); 180 sdl.sdl_family = AF_LINK; 181 sdl.sdl_alen = alen; 182 memcpy(&sdl.sdl_data, addr, alen); 183 184 return -if_delmulti(dev, (struct sockaddr *)&sdl); 185} 186 187static inline int 188dev_mc_add(struct net_device *dev, void *addr, int alen, int newonly) 189{ 190 struct sockaddr_dl sdl; 191 192 if (alen > sizeof(sdl.sdl_data)) 193 return (-EINVAL); 194 memset(&sdl, 0, sizeof(sdl)); 195 sdl.sdl_len = sizeof(sdl); 196 sdl.sdl_family = AF_LINK; 197 sdl.sdl_alen = alen; 198 memcpy(&sdl.sdl_data, addr, alen); 199 200 return -if_addmulti(dev, (struct sockaddr *)&sdl, NULL); 201} 202 203#endif /* _LINUX_NETDEVICE_H_ */ 204