macvlan.c (97eb3f24352ec6632c2127b35d8087d2a809a9b9) | macvlan.c (d5cd92448fded12c91f7574e49747c5f7d975a8d) |
---|---|
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 * --- 25 unchanged lines hidden (view full) --- 34#define MACVLAN_HASH_SIZE (1 << BITS_PER_BYTE) 35 36struct macvlan_port { 37 struct net_device *dev; 38 struct hlist_head vlan_hash[MACVLAN_HASH_SIZE]; 39 struct list_head vlans; 40 struct rcu_head rcu; 41 bool passthru; | 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 * --- 25 unchanged lines hidden (view full) --- 34#define MACVLAN_HASH_SIZE (1 << BITS_PER_BYTE) 35 36struct macvlan_port { 37 struct net_device *dev; 38 struct hlist_head vlan_hash[MACVLAN_HASH_SIZE]; 39 struct list_head vlans; 40 struct rcu_head rcu; 41 bool passthru; |
42 int count; |
|
42}; 43 | 43}; 44 |
45static void macvlan_port_destroy(struct net_device *dev); 46 |
|
44#define macvlan_port_get_rcu(dev) \ 45 ((struct macvlan_port *) rcu_dereference(dev->rx_handler_data)) 46#define macvlan_port_get(dev) ((struct macvlan_port *) dev->rx_handler_data) 47#define macvlan_port_exists(dev) (dev->priv_flags & IFF_MACVLAN_PORT) 48 49static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port, 50 const unsigned char *addr) 51{ --- 95 unchanged lines hidden (view full) --- 147 mode == MACVLAN_MODE_BRIDGE); 148 macvlan_count_rx(vlan, skb->len + ETH_HLEN, 149 err == NET_RX_SUCCESS, 1); 150 } 151 } 152} 153 154/* called under rcu_read_lock() from netif_receive_skb */ | 47#define macvlan_port_get_rcu(dev) \ 48 ((struct macvlan_port *) rcu_dereference(dev->rx_handler_data)) 49#define macvlan_port_get(dev) ((struct macvlan_port *) dev->rx_handler_data) 50#define macvlan_port_exists(dev) (dev->priv_flags & IFF_MACVLAN_PORT) 51 52static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port, 53 const unsigned char *addr) 54{ --- 95 unchanged lines hidden (view full) --- 150 mode == MACVLAN_MODE_BRIDGE); 151 macvlan_count_rx(vlan, skb->len + ETH_HLEN, 152 err == NET_RX_SUCCESS, 1); 153 } 154 } 155} 156 157/* called under rcu_read_lock() from netif_receive_skb */ |
155static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb) | 158static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb) |
156{ 157 struct macvlan_port *port; | 159{ 160 struct macvlan_port *port; |
161 struct sk_buff *skb = *pskb; |
|
158 const struct ethhdr *eth = eth_hdr(skb); 159 const struct macvlan_dev *vlan; 160 const struct macvlan_dev *src; 161 struct net_device *dev; 162 unsigned int len = 0; 163 int ret = NET_RX_DROP; 164 165 port = macvlan_port_get_rcu(skb->dev); --- 13 unchanged lines hidden (view full) --- 179 MACVLAN_MODE_BRIDGE); 180 else if (src->mode == MACVLAN_MODE_BRIDGE) 181 /* 182 * flood only to VEPA ports, bridge ports 183 * already saw the frame on the way out. 184 */ 185 macvlan_broadcast(skb, port, src->dev, 186 MACVLAN_MODE_VEPA); | 162 const struct ethhdr *eth = eth_hdr(skb); 163 const struct macvlan_dev *vlan; 164 const struct macvlan_dev *src; 165 struct net_device *dev; 166 unsigned int len = 0; 167 int ret = NET_RX_DROP; 168 169 port = macvlan_port_get_rcu(skb->dev); --- 13 unchanged lines hidden (view full) --- 183 MACVLAN_MODE_BRIDGE); 184 else if (src->mode == MACVLAN_MODE_BRIDGE) 185 /* 186 * flood only to VEPA ports, bridge ports 187 * already saw the frame on the way out. 188 */ 189 macvlan_broadcast(skb, port, src->dev, 190 MACVLAN_MODE_VEPA); |
187 return skb; | 191 return RX_HANDLER_PASS; |
188 } 189 190 if (port->passthru) 191 vlan = list_first_entry(&port->vlans, struct macvlan_dev, list); 192 else 193 vlan = macvlan_hash_lookup(port, eth->h_dest); 194 if (vlan == NULL) | 192 } 193 194 if (port->passthru) 195 vlan = list_first_entry(&port->vlans, struct macvlan_dev, list); 196 else 197 vlan = macvlan_hash_lookup(port, eth->h_dest); 198 if (vlan == NULL) |
195 return skb; | 199 return RX_HANDLER_PASS; |
196 197 dev = vlan->dev; 198 if (unlikely(!(dev->flags & IFF_UP))) { 199 kfree_skb(skb); | 200 201 dev = vlan->dev; 202 if (unlikely(!(dev->flags & IFF_UP))) { 203 kfree_skb(skb); |
200 return NULL; | 204 return RX_HANDLER_CONSUMED; |
201 } 202 len = skb->len + ETH_HLEN; 203 skb = skb_share_check(skb, GFP_ATOMIC); 204 if (!skb) 205 goto out; 206 207 skb->dev = dev; 208 skb->pkt_type = PACKET_HOST; 209 210 ret = vlan->receive(skb); 211 212out: 213 macvlan_count_rx(vlan, len, ret == NET_RX_SUCCESS, 0); | 205 } 206 len = skb->len + ETH_HLEN; 207 skb = skb_share_check(skb, GFP_ATOMIC); 208 if (!skb) 209 goto out; 210 211 skb->dev = dev; 212 skb->pkt_type = PACKET_HOST; 213 214 ret = vlan->receive(skb); 215 216out: 217 macvlan_count_rx(vlan, len, ret == NET_RX_SUCCESS, 0); |
214 return NULL; | 218 return RX_HANDLER_CONSUMED; |
215} 216 217static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) 218{ 219 const struct macvlan_dev *vlan = netdev_priv(dev); 220 const struct macvlan_port *port = vlan->port; 221 const struct macvlan_dev *dest; | 219} 220 221static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) 222{ 223 const struct macvlan_dev *vlan = netdev_priv(dev); 224 const struct macvlan_port *port = vlan->port; 225 const struct macvlan_dev *dest; |
226 __u8 ip_summed = skb->ip_summed; |
|
222 223 if (vlan->mode == MACVLAN_MODE_BRIDGE) { 224 const struct ethhdr *eth = (void *)skb->data; | 227 228 if (vlan->mode == MACVLAN_MODE_BRIDGE) { 229 const struct ethhdr *eth = (void *)skb->data; |
230 skb->ip_summed = CHECKSUM_UNNECESSARY; |
|
225 226 /* send to other bridge ports directly */ 227 if (is_multicast_ether_addr(eth->h_dest)) { 228 macvlan_broadcast(skb, port, dev, MACVLAN_MODE_BRIDGE); 229 goto xmit_world; 230 } 231 232 dest = macvlan_hash_lookup(port, eth->h_dest); 233 if (dest && dest->mode == MACVLAN_MODE_BRIDGE) { 234 unsigned int length = skb->len + ETH_HLEN; 235 int ret = dest->forward(dest->dev, skb); 236 macvlan_count_rx(dest, length, 237 ret == NET_RX_SUCCESS, 0); 238 239 return NET_XMIT_SUCCESS; 240 } 241 } 242 243xmit_world: | 231 232 /* send to other bridge ports directly */ 233 if (is_multicast_ether_addr(eth->h_dest)) { 234 macvlan_broadcast(skb, port, dev, MACVLAN_MODE_BRIDGE); 235 goto xmit_world; 236 } 237 238 dest = macvlan_hash_lookup(port, eth->h_dest); 239 if (dest && dest->mode == MACVLAN_MODE_BRIDGE) { 240 unsigned int length = skb->len + ETH_HLEN; 241 int ret = dest->forward(dest->dev, skb); 242 macvlan_count_rx(dest, length, 243 ret == NET_RX_SUCCESS, 0); 244 245 return NET_XMIT_SUCCESS; 246 } 247 } 248 249xmit_world: |
250 skb->ip_summed = ip_summed; |
|
244 skb_set_dev(skb, vlan->lowerdev); 245 return dev_queue_xmit(skb); 246} 247 248netdev_tx_t macvlan_start_xmit(struct sk_buff *skb, 249 struct net_device *dev) 250{ 251 unsigned int len = skb->len; --- 196 unchanged lines hidden (view full) --- 448 return -ENOMEM; 449 450 return 0; 451} 452 453static void macvlan_uninit(struct net_device *dev) 454{ 455 struct macvlan_dev *vlan = netdev_priv(dev); | 251 skb_set_dev(skb, vlan->lowerdev); 252 return dev_queue_xmit(skb); 253} 254 255netdev_tx_t macvlan_start_xmit(struct sk_buff *skb, 256 struct net_device *dev) 257{ 258 unsigned int len = skb->len; --- 196 unchanged lines hidden (view full) --- 455 return -ENOMEM; 456 457 return 0; 458} 459 460static void macvlan_uninit(struct net_device *dev) 461{ 462 struct macvlan_dev *vlan = netdev_priv(dev); |
463 struct macvlan_port *port = vlan->port; |
|
456 457 free_percpu(vlan->pcpu_stats); | 464 465 free_percpu(vlan->pcpu_stats); |
466 467 port->count -= 1; 468 if (!port->count) 469 macvlan_port_destroy(port->dev); |
|
458} 459 460static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev, 461 struct rtnl_link_stats64 *stats) 462{ 463 struct macvlan_dev *vlan = netdev_priv(dev); 464 465 if (vlan->pcpu_stats) { --- 216 unchanged lines hidden (view full) --- 682 vlan->receive = receive; 683 vlan->forward = forward; 684 685 vlan->mode = MACVLAN_MODE_VEPA; 686 if (data && data[IFLA_MACVLAN_MODE]) 687 vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]); 688 689 if (vlan->mode == MACVLAN_MODE_PASSTHRU) { | 470} 471 472static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev, 473 struct rtnl_link_stats64 *stats) 474{ 475 struct macvlan_dev *vlan = netdev_priv(dev); 476 477 if (vlan->pcpu_stats) { --- 216 unchanged lines hidden (view full) --- 694 vlan->receive = receive; 695 vlan->forward = forward; 696 697 vlan->mode = MACVLAN_MODE_VEPA; 698 if (data && data[IFLA_MACVLAN_MODE]) 699 vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]); 700 701 if (vlan->mode == MACVLAN_MODE_PASSTHRU) { |
690 if (!list_empty(&port->vlans)) | 702 if (port->count) |
691 return -EINVAL; 692 port->passthru = true; 693 memcpy(dev->dev_addr, lowerdev->dev_addr, ETH_ALEN); 694 } 695 | 703 return -EINVAL; 704 port->passthru = true; 705 memcpy(dev->dev_addr, lowerdev->dev_addr, ETH_ALEN); 706 } 707 |
708 port->count += 1; |
|
696 err = register_netdevice(dev); 697 if (err < 0) 698 goto destroy_port; 699 700 list_add_tail(&vlan->list, &port->vlans); 701 netif_stacked_transfer_operstate(lowerdev, dev); 702 703 return 0; 704 705destroy_port: | 709 err = register_netdevice(dev); 710 if (err < 0) 711 goto destroy_port; 712 713 list_add_tail(&vlan->list, &port->vlans); 714 netif_stacked_transfer_operstate(lowerdev, dev); 715 716 return 0; 717 718destroy_port: |
706 if (list_empty(&port->vlans)) | 719 port->count -= 1; 720 if (!port->count) |
707 macvlan_port_destroy(lowerdev); 708 709 return err; 710} 711EXPORT_SYMBOL_GPL(macvlan_common_newlink); 712 713static int macvlan_newlink(struct net *src_net, struct net_device *dev, 714 struct nlattr *tb[], struct nlattr *data[]) 715{ 716 return macvlan_common_newlink(src_net, dev, tb, data, 717 netif_rx, 718 dev_forward_skb); 719} 720 721void macvlan_dellink(struct net_device *dev, struct list_head *head) 722{ 723 struct macvlan_dev *vlan = netdev_priv(dev); | 721 macvlan_port_destroy(lowerdev); 722 723 return err; 724} 725EXPORT_SYMBOL_GPL(macvlan_common_newlink); 726 727static int macvlan_newlink(struct net *src_net, struct net_device *dev, 728 struct nlattr *tb[], struct nlattr *data[]) 729{ 730 return macvlan_common_newlink(src_net, dev, tb, data, 731 netif_rx, 732 dev_forward_skb); 733} 734 735void macvlan_dellink(struct net_device *dev, struct list_head *head) 736{ 737 struct macvlan_dev *vlan = netdev_priv(dev); |
724 struct macvlan_port *port = vlan->port; | |
725 726 list_del(&vlan->list); 727 unregister_netdevice_queue(dev, head); | 738 739 list_del(&vlan->list); 740 unregister_netdevice_queue(dev, head); |
728 729 if (list_empty(&port->vlans)) 730 macvlan_port_destroy(port->dev); | |
731} 732EXPORT_SYMBOL_GPL(macvlan_dellink); 733 734static int macvlan_changelink(struct net_device *dev, 735 struct nlattr *tb[], struct nlattr *data[]) 736{ 737 struct macvlan_dev *vlan = netdev_priv(dev); 738 if (data && data[IFLA_MACVLAN_MODE]) --- 119 unchanged lines hidden --- | 741} 742EXPORT_SYMBOL_GPL(macvlan_dellink); 743 744static int macvlan_changelink(struct net_device *dev, 745 struct nlattr *tb[], struct nlattr *data[]) 746{ 747 struct macvlan_dev *vlan = netdev_priv(dev); 748 if (data && data[IFLA_MACVLAN_MODE]) --- 119 unchanged lines hidden --- |