macvlan.c (e676f197a7a9aae9c75b0d9acc97e07de07dd1f0) | macvlan.c (f114890cdf84d753f6b41cd0cc44ba51d16313da) |
---|---|
1/* 2 * Copyright (c) 2007 Patrick McHardy <kaber@trash.net> 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 of 7 * the License, or (at your option) any later version. 8 * --- 16 unchanged lines hidden (view full) --- 25#include <linux/netdevice.h> 26#include <linux/etherdevice.h> 27#include <linux/ethtool.h> 28#include <linux/if_arp.h> 29#include <linux/if_vlan.h> 30#include <linux/if_link.h> 31#include <linux/if_macvlan.h> 32#include <linux/hash.h> | 1/* 2 * Copyright (c) 2007 Patrick McHardy <kaber@trash.net> 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License as 6 * published by the Free Software Foundation; either version 2 of 7 * the License, or (at your option) any later version. 8 * --- 16 unchanged lines hidden (view full) --- 25#include <linux/netdevice.h> 26#include <linux/etherdevice.h> 27#include <linux/ethtool.h> 28#include <linux/if_arp.h> 29#include <linux/if_vlan.h> 30#include <linux/if_link.h> 31#include <linux/if_macvlan.h> 32#include <linux/hash.h> |
33#include <linux/workqueue.h> | |
34#include <net/rtnetlink.h> 35#include <net/xfrm.h> 36 37#define MACVLAN_HASH_SIZE (1 << BITS_PER_BYTE) 38 39struct macvlan_port { 40 struct net_device *dev; 41 struct hlist_head vlan_hash[MACVLAN_HASH_SIZE]; 42 struct list_head vlans; 43 struct rcu_head rcu; | 33#include <net/rtnetlink.h> 34#include <net/xfrm.h> 35 36#define MACVLAN_HASH_SIZE (1 << BITS_PER_BYTE) 37 38struct macvlan_port { 39 struct net_device *dev; 40 struct hlist_head vlan_hash[MACVLAN_HASH_SIZE]; 41 struct list_head vlans; 42 struct rcu_head rcu; |
44 struct sk_buff_head bc_queue; 45 struct work_struct bc_work; | |
46 bool passthru; 47 int count; 48}; 49 | 43 bool passthru; 44 int count; 45}; 46 |
50struct macvlan_skb_cb { 51 const struct macvlan_dev *src; 52}; 53 54#define MACVLAN_SKB_CB(__skb) ((struct macvlan_skb_cb *)&((__skb)->cb[0])) 55 | |
56static void macvlan_port_destroy(struct net_device *dev); 57 58static struct macvlan_port *macvlan_port_get_rcu(const struct net_device *dev) 59{ 60 return rcu_dereference(dev->rx_handler_data); 61} 62 63static struct macvlan_port *macvlan_port_get_rtnl(const struct net_device *dev) --- 60 unchanged lines hidden (view full) --- 124 125static int macvlan_broadcast_one(struct sk_buff *skb, 126 const struct macvlan_dev *vlan, 127 const struct ethhdr *eth, bool local) 128{ 129 struct net_device *dev = vlan->dev; 130 131 if (local) | 47static void macvlan_port_destroy(struct net_device *dev); 48 49static struct macvlan_port *macvlan_port_get_rcu(const struct net_device *dev) 50{ 51 return rcu_dereference(dev->rx_handler_data); 52} 53 54static struct macvlan_port *macvlan_port_get_rtnl(const struct net_device *dev) --- 60 unchanged lines hidden (view full) --- 115 116static int macvlan_broadcast_one(struct sk_buff *skb, 117 const struct macvlan_dev *vlan, 118 const struct ethhdr *eth, bool local) 119{ 120 struct net_device *dev = vlan->dev; 121 122 if (local) |
132 return __dev_forward_skb(dev, skb); | 123 return dev_forward_skb(dev, skb); |
133 134 skb->dev = dev; 135 if (ether_addr_equal_64bits(eth->h_dest, dev->broadcast)) 136 skb->pkt_type = PACKET_BROADCAST; 137 else 138 skb->pkt_type = PACKET_MULTICAST; 139 | 124 125 skb->dev = dev; 126 if (ether_addr_equal_64bits(eth->h_dest, dev->broadcast)) 127 skb->pkt_type = PACKET_BROADCAST; 128 else 129 skb->pkt_type = PACKET_MULTICAST; 130 |
140 return 0; | 131 return netif_rx(skb); |
141} 142 143static u32 macvlan_hash_mix(const struct macvlan_dev *vlan) 144{ 145 return (u32)(((unsigned long)vlan) >> L1_CACHE_SHIFT); 146} 147 148 --- 30 unchanged lines hidden (view full) --- 179 if (!test_bit(hash, vlan->mc_filter)) 180 continue; 181 182 err = NET_RX_DROP; 183 nskb = skb_clone(skb, GFP_ATOMIC); 184 if (likely(nskb)) 185 err = macvlan_broadcast_one( 186 nskb, vlan, eth, | 132} 133 134static u32 macvlan_hash_mix(const struct macvlan_dev *vlan) 135{ 136 return (u32)(((unsigned long)vlan) >> L1_CACHE_SHIFT); 137} 138 139 --- 30 unchanged lines hidden (view full) --- 170 if (!test_bit(hash, vlan->mc_filter)) 171 continue; 172 173 err = NET_RX_DROP; 174 nskb = skb_clone(skb, GFP_ATOMIC); 175 if (likely(nskb)) 176 err = macvlan_broadcast_one( 177 nskb, vlan, eth, |
187 mode == MACVLAN_MODE_BRIDGE) ?: 188 netif_rx_ni(nskb); | 178 mode == MACVLAN_MODE_BRIDGE); |
189 macvlan_count_rx(vlan, skb->len + ETH_HLEN, 190 err == NET_RX_SUCCESS, 1); 191 } 192 } 193} 194 | 179 macvlan_count_rx(vlan, skb->len + ETH_HLEN, 180 err == NET_RX_SUCCESS, 1); 181 } 182 } 183} 184 |
195static void macvlan_process_broadcast(struct work_struct *w) | 185/* called under rcu_read_lock() from netif_receive_skb */ 186static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb) |
196{ | 187{ |
197 struct macvlan_port *port = container_of(w, struct macvlan_port, 198 bc_work); 199 struct sk_buff *skb; 200 struct sk_buff_head list; | 188 struct macvlan_port *port; 189 struct sk_buff *skb = *pskb; 190 const struct ethhdr *eth = eth_hdr(skb); 191 const struct macvlan_dev *vlan; 192 const struct macvlan_dev *src; 193 struct net_device *dev; 194 unsigned int len = 0; 195 int ret = NET_RX_DROP; |
201 | 196 |
202 skb_queue_head_init(&list); 203 204 spin_lock_bh(&port->bc_queue.lock); 205 skb_queue_splice_tail_init(&port->bc_queue, &list); 206 spin_unlock_bh(&port->bc_queue.lock); 207 208 while ((skb = __skb_dequeue(&list))) { 209 const struct macvlan_dev *src = MACVLAN_SKB_CB(skb)->src; 210 211 rcu_read_lock(); 212 | 197 port = macvlan_port_get_rcu(skb->dev); 198 if (is_multicast_ether_addr(eth->h_dest)) { 199 skb = ip_check_defrag(skb, IP_DEFRAG_MACVLAN); 200 if (!skb) 201 return RX_HANDLER_CONSUMED; 202 eth = eth_hdr(skb); 203 src = macvlan_hash_lookup(port, eth->h_source); |
213 if (!src) 214 /* frame comes from an external address */ 215 macvlan_broadcast(skb, port, NULL, 216 MACVLAN_MODE_PRIVATE | 217 MACVLAN_MODE_VEPA | 218 MACVLAN_MODE_PASSTHRU| 219 MACVLAN_MODE_BRIDGE); 220 else if (src->mode == MACVLAN_MODE_VEPA) 221 /* flood to everyone except source */ 222 macvlan_broadcast(skb, port, src->dev, 223 MACVLAN_MODE_VEPA | 224 MACVLAN_MODE_BRIDGE); | 204 if (!src) 205 /* frame comes from an external address */ 206 macvlan_broadcast(skb, port, NULL, 207 MACVLAN_MODE_PRIVATE | 208 MACVLAN_MODE_VEPA | 209 MACVLAN_MODE_PASSTHRU| 210 MACVLAN_MODE_BRIDGE); 211 else if (src->mode == MACVLAN_MODE_VEPA) 212 /* flood to everyone except source */ 213 macvlan_broadcast(skb, port, src->dev, 214 MACVLAN_MODE_VEPA | 215 MACVLAN_MODE_BRIDGE); |
225 else | 216 else if (src->mode == MACVLAN_MODE_BRIDGE) |
226 /* 227 * flood only to VEPA ports, bridge ports 228 * already saw the frame on the way out. 229 */ 230 macvlan_broadcast(skb, port, src->dev, 231 MACVLAN_MODE_VEPA); | 217 /* 218 * flood only to VEPA ports, bridge ports 219 * already saw the frame on the way out. 220 */ 221 macvlan_broadcast(skb, port, src->dev, 222 MACVLAN_MODE_VEPA); |
232 233 rcu_read_unlock(); 234 235 kfree_skb(skb); 236 } 237} 238 239static void macvlan_broadcast_enqueue(struct macvlan_port *port, 240 struct sk_buff *skb) 241{ 242 struct sk_buff *nskb; 243 int err = -ENOMEM; 244 245 nskb = skb_clone(skb, GFP_ATOMIC); 246 if (!nskb) 247 goto err; 248 249 spin_lock(&port->bc_queue.lock); 250 if (skb_queue_len(&port->bc_queue) < skb->dev->tx_queue_len) { 251 __skb_queue_tail(&port->bc_queue, nskb); 252 err = 0; 253 } 254 spin_unlock(&port->bc_queue.lock); 255 256 if (err) 257 goto free_nskb; 258 259 schedule_work(&port->bc_work); 260 return; 261 262free_nskb: 263 kfree_skb(nskb); 264err: 265 atomic_long_inc(&skb->dev->rx_dropped); 266} 267 268/* called under rcu_read_lock() from netif_receive_skb */ 269static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb) 270{ 271 struct macvlan_port *port; 272 struct sk_buff *skb = *pskb; 273 const struct ethhdr *eth = eth_hdr(skb); 274 const struct macvlan_dev *vlan; 275 const struct macvlan_dev *src; 276 struct net_device *dev; 277 unsigned int len = 0; 278 int ret = NET_RX_DROP; 279 280 port = macvlan_port_get_rcu(skb->dev); 281 if (is_multicast_ether_addr(eth->h_dest)) { 282 skb = ip_check_defrag(skb, IP_DEFRAG_MACVLAN); 283 if (!skb) 284 return RX_HANDLER_CONSUMED; 285 eth = eth_hdr(skb); 286 src = macvlan_hash_lookup(port, eth->h_source); 287 if (src && src->mode != MACVLAN_MODE_VEPA && 288 src->mode != MACVLAN_MODE_BRIDGE) { | 223 else { |
289 /* forward to original port. */ 290 vlan = src; | 224 /* forward to original port. */ 225 vlan = src; |
291 ret = macvlan_broadcast_one(skb, vlan, eth, 0) ?: 292 netif_rx(skb); | 226 ret = macvlan_broadcast_one(skb, vlan, eth, 0); |
293 goto out; 294 } 295 | 227 goto out; 228 } 229 |
296 MACVLAN_SKB_CB(skb)->src = src; 297 macvlan_broadcast_enqueue(port, skb); 298 | |
299 return RX_HANDLER_PASS; 300 } 301 302 if (port->passthru) 303 vlan = list_first_or_null_rcu(&port->vlans, 304 struct macvlan_dev, list); 305 else 306 vlan = macvlan_hash_lookup(port, eth->h_dest); --- 20 unchanged lines hidden (view full) --- 327 return RX_HANDLER_CONSUMED; 328} 329 330static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) 331{ 332 const struct macvlan_dev *vlan = netdev_priv(dev); 333 const struct macvlan_port *port = vlan->port; 334 const struct macvlan_dev *dest; | 230 return RX_HANDLER_PASS; 231 } 232 233 if (port->passthru) 234 vlan = list_first_or_null_rcu(&port->vlans, 235 struct macvlan_dev, list); 236 else 237 vlan = macvlan_hash_lookup(port, eth->h_dest); --- 20 unchanged lines hidden (view full) --- 258 return RX_HANDLER_CONSUMED; 259} 260 261static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) 262{ 263 const struct macvlan_dev *vlan = netdev_priv(dev); 264 const struct macvlan_port *port = vlan->port; 265 const struct macvlan_dev *dest; |
335 __u8 ip_summed = skb->ip_summed; | |
336 337 if (vlan->mode == MACVLAN_MODE_BRIDGE) { 338 const struct ethhdr *eth = (void *)skb->data; | 266 267 if (vlan->mode == MACVLAN_MODE_BRIDGE) { 268 const struct ethhdr *eth = (void *)skb->data; |
339 skb->ip_summed = CHECKSUM_UNNECESSARY; | |
340 341 /* send to other bridge ports directly */ 342 if (is_multicast_ether_addr(eth->h_dest)) { 343 macvlan_broadcast(skb, port, dev, MACVLAN_MODE_BRIDGE); 344 goto xmit_world; 345 } 346 347 dest = macvlan_hash_lookup(port, eth->h_dest); 348 if (dest && dest->mode == MACVLAN_MODE_BRIDGE) { 349 /* send to lowerdev first for its network taps */ 350 dev_forward_skb(vlan->lowerdev, skb); 351 352 return NET_XMIT_SUCCESS; 353 } 354 } 355 356xmit_world: | 269 270 /* send to other bridge ports directly */ 271 if (is_multicast_ether_addr(eth->h_dest)) { 272 macvlan_broadcast(skb, port, dev, MACVLAN_MODE_BRIDGE); 273 goto xmit_world; 274 } 275 276 dest = macvlan_hash_lookup(port, eth->h_dest); 277 if (dest && dest->mode == MACVLAN_MODE_BRIDGE) { 278 /* send to lowerdev first for its network taps */ 279 dev_forward_skb(vlan->lowerdev, skb); 280 281 return NET_XMIT_SUCCESS; 282 } 283 } 284 285xmit_world: |
357 skb->ip_summed = ip_summed; | |
358 skb->dev = vlan->lowerdev; 359 return dev_queue_xmit(skb); 360} 361 362static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb, 363 struct net_device *dev) 364{ 365 unsigned int len = skb->len; --- 462 unchanged lines hidden (view full) --- 828 return -ENOMEM; 829 830 port->passthru = false; 831 port->dev = dev; 832 INIT_LIST_HEAD(&port->vlans); 833 for (i = 0; i < MACVLAN_HASH_SIZE; i++) 834 INIT_HLIST_HEAD(&port->vlan_hash[i]); 835 | 286 skb->dev = vlan->lowerdev; 287 return dev_queue_xmit(skb); 288} 289 290static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb, 291 struct net_device *dev) 292{ 293 unsigned int len = skb->len; --- 462 unchanged lines hidden (view full) --- 756 return -ENOMEM; 757 758 port->passthru = false; 759 port->dev = dev; 760 INIT_LIST_HEAD(&port->vlans); 761 for (i = 0; i < MACVLAN_HASH_SIZE; i++) 762 INIT_HLIST_HEAD(&port->vlan_hash[i]); 763 |
836 skb_queue_head_init(&port->bc_queue); 837 INIT_WORK(&port->bc_work, macvlan_process_broadcast); 838 | |
839 err = netdev_rx_handler_register(dev, macvlan_handle_frame, port); 840 if (err) 841 kfree(port); 842 else 843 dev->priv_flags |= IFF_MACVLAN_PORT; 844 return err; 845} 846 847static void macvlan_port_destroy(struct net_device *dev) 848{ 849 struct macvlan_port *port = macvlan_port_get_rtnl(dev); 850 | 764 err = netdev_rx_handler_register(dev, macvlan_handle_frame, port); 765 if (err) 766 kfree(port); 767 else 768 dev->priv_flags |= IFF_MACVLAN_PORT; 769 return err; 770} 771 772static void macvlan_port_destroy(struct net_device *dev) 773{ 774 struct macvlan_port *port = macvlan_port_get_rtnl(dev); 775 |
851 cancel_work_sync(&port->bc_work); | |
852 dev->priv_flags &= ~IFF_MACVLAN_PORT; 853 netdev_rx_handler_unregister(dev); 854 kfree_rcu(port, rcu); 855} 856 857static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[]) 858{ 859 if (tb[IFLA_ADDRESS]) { --- 286 unchanged lines hidden --- | 776 dev->priv_flags &= ~IFF_MACVLAN_PORT; 777 netdev_rx_handler_unregister(dev); 778 kfree_rcu(port, rcu); 779} 780 781static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[]) 782{ 783 if (tb[IFLA_ADDRESS]) { --- 286 unchanged lines hidden --- |