blob: 57d6436e6f6ad44bb34c263ab9f27433d1651b73 [file] [log] [blame]
Thomas Gleixnerc9422992019-05-29 07:12:43 -07001// SPDX-License-Identifier: GPL-2.0-only
Jesse Grossccb13522011-10-25 19:26:31 -07002/*
Raju Subramaniancaf2ee12012-05-03 18:55:23 -07003 * Copyright (c) 2007-2012 Nicira, Inc.
Jesse Grossccb13522011-10-25 19:26:31 -07004 */
5
6#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
7
8#include <linux/if_arp.h>
9#include <linux/if_bridge.h>
10#include <linux/if_vlan.h>
11#include <linux/kernel.h>
12#include <linux/llc.h>
13#include <linux/rtnetlink.h>
14#include <linux/skbuff.h>
Jiri Pirko2537b4d2013-07-26 14:01:54 +020015#include <linux/openvswitch.h>
Thomas Grafdcc38c02015-07-29 13:52:06 +020016#include <linux/export.h>
Jesse Grossccb13522011-10-25 19:26:31 -070017
Thomas Graf614732e2015-07-21 10:44:06 +020018#include <net/ip_tunnels.h>
19#include <net/rtnetlink.h>
Jesse Grossccb13522011-10-25 19:26:31 -070020
21#include "datapath.h"
Thomas Graf614732e2015-07-21 10:44:06 +020022#include "vport.h"
Jesse Grossccb13522011-10-25 19:26:31 -070023#include "vport-internal_dev.h"
24#include "vport-netdev.h"
25
Thomas Graf62b9c8d2014-10-22 17:29:06 +020026static struct vport_ops ovs_netdev_vport_ops;
27
Jesse Grossccb13522011-10-25 19:26:31 -070028/* Must be called with rcu_read_lock. */
Pravin B Shelar8c876632015-08-29 17:44:07 -070029static void netdev_port_receive(struct sk_buff *skb)
Jesse Grossccb13522011-10-25 19:26:31 -070030{
Pravin B Shelar8c876632015-08-29 17:44:07 -070031 struct vport *vport;
32
33 vport = ovs_netdev_get_vport(skb->dev);
Jesse Grossd9d59082013-01-21 23:57:26 -080034 if (unlikely(!vport))
35 goto error;
36
37 if (unlikely(skb_warn_if_lro(skb)))
38 goto error;
Jesse Grossccb13522011-10-25 19:26:31 -070039
40 /* Make our own copy of the packet. Otherwise we will mangle the
41 * packet for anyone who came before us (e.g. tcpdump via AF_PACKET).
Cong Wangd176ca22013-02-22 19:41:26 +080042 */
Jesse Grossccb13522011-10-25 19:26:31 -070043 skb = skb_share_check(skb, GFP_ATOMIC);
44 if (unlikely(!skb))
45 return;
46
Jiri Benc217ac772016-11-10 16:28:24 +010047 if (skb->dev->type == ARPHRD_ETHER) {
48 skb_push(skb, ETH_HLEN);
49 skb_postpush_rcsum(skb, skb->data, ETH_HLEN);
50 }
Jiri Benc61adedf2015-08-20 13:56:25 +020051 ovs_vport_receive(vport, skb, skb_tunnel_info(skb));
Jesse Grossd9d59082013-01-21 23:57:26 -080052 return;
Jesse Grossd9d59082013-01-21 23:57:26 -080053error:
54 kfree_skb(skb);
Jesse Grossccb13522011-10-25 19:26:31 -070055}
56
57/* Called with rcu_read_lock and bottom-halves disabled. */
58static rx_handler_result_t netdev_frame_hook(struct sk_buff **pskb)
59{
60 struct sk_buff *skb = *pskb;
Jesse Grossccb13522011-10-25 19:26:31 -070061
62 if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
63 return RX_HANDLER_PASS;
64
Pravin B Shelar8c876632015-08-29 17:44:07 -070065 netdev_port_receive(skb);
Jesse Grossccb13522011-10-25 19:26:31 -070066 return RX_HANDLER_CONSUMED;
67}
68
Thomas Graf12eb18f2014-11-06 06:58:52 -080069static struct net_device *get_dpdev(const struct datapath *dp)
Jiri Pirko2537b4d2013-07-26 14:01:54 +020070{
71 struct vport *local;
72
73 local = ovs_vport_ovsl(dp, OVSP_LOCAL);
Thomas Grafbe4ace62015-07-21 10:44:04 +020074 return local->dev;
Jiri Pirko2537b4d2013-07-26 14:01:54 +020075}
76
Thomas Grafdcc38c02015-07-29 13:52:06 +020077struct vport *ovs_netdev_link(struct vport *vport, const char *name)
Jesse Grossccb13522011-10-25 19:26:31 -070078{
Jesse Grossccb13522011-10-25 19:26:31 -070079 int err;
80
Thomas Grafbe4ace62015-07-21 10:44:04 +020081 vport->dev = dev_get_by_name(ovs_dp_get_net(vport->dp), name);
82 if (!vport->dev) {
Jesse Grossccb13522011-10-25 19:26:31 -070083 err = -ENODEV;
84 goto error_free_vport;
85 }
86
Thomas Grafbe4ace62015-07-21 10:44:04 +020087 if (vport->dev->flags & IFF_LOOPBACK ||
Jiri Benc217ac772016-11-10 16:28:24 +010088 (vport->dev->type != ARPHRD_ETHER &&
89 vport->dev->type != ARPHRD_NONE) ||
Thomas Grafbe4ace62015-07-21 10:44:04 +020090 ovs_is_internal_dev(vport->dev)) {
Jesse Grossccb13522011-10-25 19:26:31 -070091 err = -EINVAL;
92 goto error_put;
93 }
94
Pravin B Shelar8e4e1712013-04-15 13:23:03 -070095 rtnl_lock();
Thomas Grafbe4ace62015-07-21 10:44:04 +020096 err = netdev_master_upper_dev_link(vport->dev,
David Ahern42ab19e2017-10-04 17:48:47 -070097 get_dpdev(vport->dp),
98 NULL, NULL, NULL);
Jiri Pirko2537b4d2013-07-26 14:01:54 +020099 if (err)
100 goto error_unlock;
101
Thomas Grafbe4ace62015-07-21 10:44:04 +0200102 err = netdev_rx_handler_register(vport->dev, netdev_frame_hook,
Jesse Grossccb13522011-10-25 19:26:31 -0700103 vport);
104 if (err)
Jiri Pirko2537b4d2013-07-26 14:01:54 +0200105 goto error_master_upper_dev_unlink;
Jesse Grossccb13522011-10-25 19:26:31 -0700106
Thomas Grafbe4ace62015-07-21 10:44:04 +0200107 dev_disable_lro(vport->dev);
108 dev_set_promiscuity(vport->dev, 1);
109 vport->dev->priv_flags |= IFF_OVS_DATAPATH;
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700110 rtnl_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -0700111
112 return vport;
113
Jiri Pirko2537b4d2013-07-26 14:01:54 +0200114error_master_upper_dev_unlink:
Thomas Grafbe4ace62015-07-21 10:44:04 +0200115 netdev_upper_dev_unlink(vport->dev, get_dpdev(vport->dp));
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700116error_unlock:
117 rtnl_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -0700118error_put:
Thomas Grafbe4ace62015-07-21 10:44:04 +0200119 dev_put(vport->dev);
Jesse Grossccb13522011-10-25 19:26:31 -0700120error_free_vport:
121 ovs_vport_free(vport);
Jesse Grossccb13522011-10-25 19:26:31 -0700122 return ERR_PTR(err);
123}
Thomas Grafdcc38c02015-07-29 13:52:06 +0200124EXPORT_SYMBOL_GPL(ovs_netdev_link);
Jesse Grossccb13522011-10-25 19:26:31 -0700125
Thomas Grafbe4ace62015-07-21 10:44:04 +0200126static struct vport *netdev_create(const struct vport_parms *parms)
127{
128 struct vport *vport;
129
130 vport = ovs_vport_alloc(0, &ovs_netdev_vport_ops, parms);
131 if (IS_ERR(vport))
132 return vport;
133
Thomas Grafdcc38c02015-07-29 13:52:06 +0200134 return ovs_netdev_link(vport, parms->name);
Thomas Grafbe4ace62015-07-21 10:44:04 +0200135}
136
Pravin B Shelara9020fd2015-08-07 23:51:33 -0700137static void vport_netdev_free(struct rcu_head *rcu)
Jesse Gross92eb1d42012-11-28 14:01:52 -0800138{
Thomas Grafbe4ace62015-07-21 10:44:04 +0200139 struct vport *vport = container_of(rcu, struct vport, rcu);
Jesse Gross92eb1d42012-11-28 14:01:52 -0800140
Thomas Graf614732e2015-07-21 10:44:06 +0200141 if (vport->dev)
142 dev_put(vport->dev);
Thomas Grafbe4ace62015-07-21 10:44:04 +0200143 ovs_vport_free(vport);
Jesse Gross92eb1d42012-11-28 14:01:52 -0800144}
145
Alexei Starovoitovb07c2652013-10-15 14:54:11 -0700146void ovs_netdev_detach_dev(struct vport *vport)
147{
Alexei Starovoitovb07c2652013-10-15 14:54:11 -0700148 ASSERT_RTNL();
Thomas Grafbe4ace62015-07-21 10:44:04 +0200149 vport->dev->priv_flags &= ~IFF_OVS_DATAPATH;
150 netdev_rx_handler_unregister(vport->dev);
151 netdev_upper_dev_unlink(vport->dev,
152 netdev_master_upper_dev_get(vport->dev));
153 dev_set_promiscuity(vport->dev, -1);
Alexei Starovoitovb07c2652013-10-15 14:54:11 -0700154}
155
Jesse Grossccb13522011-10-25 19:26:31 -0700156static void netdev_destroy(struct vport *vport)
157{
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700158 rtnl_lock();
Taehee Yoo44e37252019-07-06 01:05:46 +0900159 if (netif_is_ovs_port(vport->dev))
Alexei Starovoitovb07c2652013-10-15 14:54:11 -0700160 ovs_netdev_detach_dev(vport);
Pravin B Shelar8e4e1712013-04-15 13:23:03 -0700161 rtnl_unlock();
Jesse Grossccb13522011-10-25 19:26:31 -0700162
Pravin B Shelara9020fd2015-08-07 23:51:33 -0700163 call_rcu(&vport->rcu, vport_netdev_free);
Jesse Grossccb13522011-10-25 19:26:31 -0700164}
165
Pravin B Shelara9020fd2015-08-07 23:51:33 -0700166void ovs_netdev_tunnel_destroy(struct vport *vport)
167{
168 rtnl_lock();
Taehee Yoo44e37252019-07-06 01:05:46 +0900169 if (netif_is_ovs_port(vport->dev))
Pravin B Shelara9020fd2015-08-07 23:51:33 -0700170 ovs_netdev_detach_dev(vport);
171
Paolo Abeni13175302015-12-01 18:33:36 +0100172 /* We can be invoked by both explicit vport deletion and
173 * underlying netdev deregistration; delete the link only
174 * if it's not already shutting down.
175 */
176 if (vport->dev->reg_state == NETREG_REGISTERED)
177 rtnl_delete_link(vport->dev);
Pravin B Shelara9020fd2015-08-07 23:51:33 -0700178 dev_put(vport->dev);
Pravin B Shelara9020fd2015-08-07 23:51:33 -0700179 vport->dev = NULL;
180 rtnl_unlock();
181
182 call_rcu(&vport->rcu, vport_netdev_free);
183}
184EXPORT_SYMBOL_GPL(ovs_netdev_tunnel_destroy);
185
Jesse Grossccb13522011-10-25 19:26:31 -0700186/* Returns null if this device is not attached to a datapath. */
187struct vport *ovs_netdev_get_vport(struct net_device *dev)
188{
Taehee Yoo44e37252019-07-06 01:05:46 +0900189 if (likely(netif_is_ovs_port(dev)))
Jesse Grossccb13522011-10-25 19:26:31 -0700190 return (struct vport *)
191 rcu_dereference_rtnl(dev->rx_handler_data);
192 else
193 return NULL;
194}
195
Thomas Graf62b9c8d2014-10-22 17:29:06 +0200196static struct vport_ops ovs_netdev_vport_ops = {
Jesse Grossccb13522011-10-25 19:26:31 -0700197 .type = OVS_VPORT_TYPE_NETDEV,
198 .create = netdev_create,
199 .destroy = netdev_destroy,
Pravin B Shelaraec15922015-10-20 23:00:10 -0700200 .send = dev_queue_xmit,
Jesse Grossccb13522011-10-25 19:26:31 -0700201};
Thomas Graf62b9c8d2014-10-22 17:29:06 +0200202
203int __init ovs_netdev_init(void)
204{
Thomas Grafdcc38c02015-07-29 13:52:06 +0200205 return ovs_vport_ops_register(&ovs_netdev_vport_ops);
Thomas Graf62b9c8d2014-10-22 17:29:06 +0200206}
207
208void ovs_netdev_exit(void)
209{
210 ovs_vport_ops_unregister(&ovs_netdev_vport_ops);
211}