aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/macvlan.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2010-01-30 07:23:40 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-03 23:20:33 -0500
commitfc0663d6b5e6d8e9b57f872a644c0aafd82361b7 (patch)
tree133f8fb33482f58cd9adcb7747cd51a81856436d /drivers/net/macvlan.c
parent8a83a00b0735190384a348156837918271034144 (diff)
macvlan: allow multiple driver backends
This makes it possible to hook into the macvlan driver from another kernel module. In particular, the goal is to extend it with the macvtap backend that provides a tun/tap compatible interface directly on the macvlan device. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/macvlan.c')
-rw-r--r--drivers/net/macvlan.c113
1 files changed, 49 insertions, 64 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index d32e0bdfc5e9..40faa368b07a 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -39,31 +39,6 @@ struct macvlan_port {
39 struct list_head vlans; 39 struct list_head vlans;
40}; 40};
41 41
42/**
43 * struct macvlan_rx_stats - MACVLAN percpu rx stats
44 * @rx_packets: number of received packets
45 * @rx_bytes: number of received bytes
46 * @multicast: number of received multicast packets
47 * @rx_errors: number of errors
48 */
49struct macvlan_rx_stats {
50 unsigned long rx_packets;
51 unsigned long rx_bytes;
52 unsigned long multicast;
53 unsigned long rx_errors;
54};
55
56struct macvlan_dev {
57 struct net_device *dev;
58 struct list_head list;
59 struct hlist_node hlist;
60 struct macvlan_port *port;
61 struct net_device *lowerdev;
62 struct macvlan_rx_stats *rx_stats;
63 enum macvlan_mode mode;
64};
65
66
67static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port, 42static struct macvlan_dev *macvlan_hash_lookup(const struct macvlan_port *port,
68 const unsigned char *addr) 43 const unsigned char *addr)
69{ 44{
@@ -118,31 +93,17 @@ static int macvlan_addr_busy(const struct macvlan_port *port,
118 return 0; 93 return 0;
119} 94}
120 95
121static inline void macvlan_count_rx(const struct macvlan_dev *vlan,
122 unsigned int len, bool success,
123 bool multicast)
124{
125 struct macvlan_rx_stats *rx_stats;
126
127 rx_stats = per_cpu_ptr(vlan->rx_stats, smp_processor_id());
128 if (likely(success)) {
129 rx_stats->rx_packets++;;
130 rx_stats->rx_bytes += len;
131 if (multicast)
132 rx_stats->multicast++;
133 } else {
134 rx_stats->rx_errors++;
135 }
136}
137 96
138static int macvlan_broadcast_one(struct sk_buff *skb, struct net_device *dev, 97static int macvlan_broadcast_one(struct sk_buff *skb,
98 const struct macvlan_dev *vlan,
139 const struct ethhdr *eth, bool local) 99 const struct ethhdr *eth, bool local)
140{ 100{
101 struct net_device *dev = vlan->dev;
141 if (!skb) 102 if (!skb)
142 return NET_RX_DROP; 103 return NET_RX_DROP;
143 104
144 if (local) 105 if (local)
145 return dev_forward_skb(dev, skb); 106 return vlan->forward(dev, skb);
146 107
147 skb->dev = dev; 108 skb->dev = dev;
148 if (!compare_ether_addr_64bits(eth->h_dest, 109 if (!compare_ether_addr_64bits(eth->h_dest,
@@ -151,7 +112,7 @@ static int macvlan_broadcast_one(struct sk_buff *skb, struct net_device *dev,
151 else 112 else
152 skb->pkt_type = PACKET_MULTICAST; 113 skb->pkt_type = PACKET_MULTICAST;
153 114
154 return netif_rx(skb); 115 return vlan->receive(skb);
155} 116}
156 117
157static void macvlan_broadcast(struct sk_buff *skb, 118static void macvlan_broadcast(struct sk_buff *skb,
@@ -175,7 +136,7 @@ static void macvlan_broadcast(struct sk_buff *skb,
175 continue; 136 continue;
176 137
177 nskb = skb_clone(skb, GFP_ATOMIC); 138 nskb = skb_clone(skb, GFP_ATOMIC);
178 err = macvlan_broadcast_one(nskb, vlan->dev, eth, 139 err = macvlan_broadcast_one(nskb, vlan, eth,
179 mode == MACVLAN_MODE_BRIDGE); 140 mode == MACVLAN_MODE_BRIDGE);
180 macvlan_count_rx(vlan, skb->len + ETH_HLEN, 141 macvlan_count_rx(vlan, skb->len + ETH_HLEN,
181 err == NET_RX_SUCCESS, 1); 142 err == NET_RX_SUCCESS, 1);
@@ -238,7 +199,7 @@ static struct sk_buff *macvlan_handle_frame(struct sk_buff *skb)
238 skb->dev = dev; 199 skb->dev = dev;
239 skb->pkt_type = PACKET_HOST; 200 skb->pkt_type = PACKET_HOST;
240 201
241 netif_rx(skb); 202 vlan->receive(skb);
242 return NULL; 203 return NULL;
243} 204}
244 205
@@ -260,7 +221,7 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev)
260 dest = macvlan_hash_lookup(port, eth->h_dest); 221 dest = macvlan_hash_lookup(port, eth->h_dest);
261 if (dest && dest->mode == MACVLAN_MODE_BRIDGE) { 222 if (dest && dest->mode == MACVLAN_MODE_BRIDGE) {
262 unsigned int length = skb->len + ETH_HLEN; 223 unsigned int length = skb->len + ETH_HLEN;
263 int ret = dev_forward_skb(dest->dev, skb); 224 int ret = dest->forward(dest->dev, skb);
264 macvlan_count_rx(dest, length, 225 macvlan_count_rx(dest, length,
265 ret == NET_RX_SUCCESS, 0); 226 ret == NET_RX_SUCCESS, 0);
266 227
@@ -273,8 +234,8 @@ xmit_world:
273 return dev_queue_xmit(skb); 234 return dev_queue_xmit(skb);
274} 235}
275 236
276static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb, 237netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
277 struct net_device *dev) 238 struct net_device *dev)
278{ 239{
279 int i = skb_get_queue_mapping(skb); 240 int i = skb_get_queue_mapping(skb);
280 struct netdev_queue *txq = netdev_get_tx_queue(dev, i); 241 struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
@@ -290,6 +251,7 @@ static netdev_tx_t macvlan_start_xmit(struct sk_buff *skb,
290 251
291 return ret; 252 return ret;
292} 253}
254EXPORT_SYMBOL_GPL(macvlan_start_xmit);
293 255
294static int macvlan_hard_header(struct sk_buff *skb, struct net_device *dev, 256static int macvlan_hard_header(struct sk_buff *skb, struct net_device *dev,
295 unsigned short type, const void *daddr, 257 unsigned short type, const void *daddr,
@@ -623,8 +585,11 @@ static int macvlan_get_tx_queues(struct net *net,
623 return 0; 585 return 0;
624} 586}
625 587
626static int macvlan_newlink(struct net *src_net, struct net_device *dev, 588int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
627 struct nlattr *tb[], struct nlattr *data[]) 589 struct nlattr *tb[], struct nlattr *data[],
590 int (*receive)(struct sk_buff *skb),
591 int (*forward)(struct net_device *dev,
592 struct sk_buff *skb))
628{ 593{
629 struct macvlan_dev *vlan = netdev_priv(dev); 594 struct macvlan_dev *vlan = netdev_priv(dev);
630 struct macvlan_port *port; 595 struct macvlan_port *port;
@@ -664,6 +629,8 @@ static int macvlan_newlink(struct net *src_net, struct net_device *dev,
664 vlan->lowerdev = lowerdev; 629 vlan->lowerdev = lowerdev;
665 vlan->dev = dev; 630 vlan->dev = dev;
666 vlan->port = port; 631 vlan->port = port;
632 vlan->receive = receive;
633 vlan->forward = forward;
667 634
668 vlan->mode = MACVLAN_MODE_VEPA; 635 vlan->mode = MACVLAN_MODE_VEPA;
669 if (data && data[IFLA_MACVLAN_MODE]) 636 if (data && data[IFLA_MACVLAN_MODE])
@@ -677,8 +644,17 @@ static int macvlan_newlink(struct net *src_net, struct net_device *dev,
677 netif_stacked_transfer_operstate(lowerdev, dev); 644 netif_stacked_transfer_operstate(lowerdev, dev);
678 return 0; 645 return 0;
679} 646}
647EXPORT_SYMBOL_GPL(macvlan_common_newlink);
680 648
681static void macvlan_dellink(struct net_device *dev, struct list_head *head) 649static int macvlan_newlink(struct net *src_net, struct net_device *dev,
650 struct nlattr *tb[], struct nlattr *data[])
651{
652 return macvlan_common_newlink(src_net, dev, tb, data,
653 netif_rx,
654 dev_forward_skb);
655}
656
657void macvlan_dellink(struct net_device *dev, struct list_head *head)
682{ 658{
683 struct macvlan_dev *vlan = netdev_priv(dev); 659 struct macvlan_dev *vlan = netdev_priv(dev);
684 struct macvlan_port *port = vlan->port; 660 struct macvlan_port *port = vlan->port;
@@ -689,6 +665,7 @@ static void macvlan_dellink(struct net_device *dev, struct list_head *head)
689 if (list_empty(&port->vlans)) 665 if (list_empty(&port->vlans))
690 macvlan_port_destroy(port->dev); 666 macvlan_port_destroy(port->dev);
691} 667}
668EXPORT_SYMBOL_GPL(macvlan_dellink);
692 669
693static int macvlan_changelink(struct net_device *dev, 670static int macvlan_changelink(struct net_device *dev,
694 struct nlattr *tb[], struct nlattr *data[]) 671 struct nlattr *tb[], struct nlattr *data[])
@@ -720,19 +697,27 @@ static const struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX + 1] = {
720 [IFLA_MACVLAN_MODE] = { .type = NLA_U32 }, 697 [IFLA_MACVLAN_MODE] = { .type = NLA_U32 },
721}; 698};
722 699
723static struct rtnl_link_ops macvlan_link_ops __read_mostly = { 700int macvlan_link_register(struct rtnl_link_ops *ops)
701{
702 /* common fields */
703 ops->priv_size = sizeof(struct macvlan_dev);
704 ops->get_tx_queues = macvlan_get_tx_queues;
705 ops->setup = macvlan_setup;
706 ops->validate = macvlan_validate;
707 ops->maxtype = IFLA_MACVLAN_MAX;
708 ops->policy = macvlan_policy;
709 ops->changelink = macvlan_changelink;
710 ops->get_size = macvlan_get_size;
711 ops->fill_info = macvlan_fill_info;
712
713 return rtnl_link_register(ops);
714};
715EXPORT_SYMBOL_GPL(macvlan_link_register);
716
717static struct rtnl_link_ops macvlan_link_ops = {
724 .kind = "macvlan", 718 .kind = "macvlan",
725 .priv_size = sizeof(struct macvlan_dev),
726 .get_tx_queues = macvlan_get_tx_queues,
727 .setup = macvlan_setup,
728 .validate = macvlan_validate,
729 .newlink = macvlan_newlink, 719 .newlink = macvlan_newlink,
730 .dellink = macvlan_dellink, 720 .dellink = macvlan_dellink,
731 .maxtype = IFLA_MACVLAN_MAX,
732 .policy = macvlan_policy,
733 .changelink = macvlan_changelink,
734 .get_size = macvlan_get_size,
735 .fill_info = macvlan_fill_info,
736}; 721};
737 722
738static int macvlan_device_event(struct notifier_block *unused, 723static int macvlan_device_event(struct notifier_block *unused,
@@ -761,7 +746,7 @@ static int macvlan_device_event(struct notifier_block *unused,
761 break; 746 break;
762 case NETDEV_UNREGISTER: 747 case NETDEV_UNREGISTER:
763 list_for_each_entry_safe(vlan, next, &port->vlans, list) 748 list_for_each_entry_safe(vlan, next, &port->vlans, list)
764 macvlan_dellink(vlan->dev, NULL); 749 vlan->dev->rtnl_link_ops->dellink(vlan->dev, NULL);
765 break; 750 break;
766 } 751 }
767 return NOTIFY_DONE; 752 return NOTIFY_DONE;
@@ -778,7 +763,7 @@ static int __init macvlan_init_module(void)
778 register_netdevice_notifier(&macvlan_notifier_block); 763 register_netdevice_notifier(&macvlan_notifier_block);
779 macvlan_handle_frame_hook = macvlan_handle_frame; 764 macvlan_handle_frame_hook = macvlan_handle_frame;
780 765
781 err = rtnl_link_register(&macvlan_link_ops); 766 err = macvlan_link_register(&macvlan_link_ops);
782 if (err < 0) 767 if (err < 0)
783 goto err1; 768 goto err1;
784 return 0; 769 return 0;