1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (c) 2007-2014 Nicira, Inc. |
4 | */ |
5 | |
6 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
7 | |
8 | #include <linux/if.h> |
9 | #include <linux/skbuff.h> |
10 | #include <linux/ip.h> |
11 | #include <linux/if_tunnel.h> |
12 | #include <linux/if_vlan.h> |
13 | #include <linux/in.h> |
14 | #include <linux/in_route.h> |
15 | #include <linux/inetdevice.h> |
16 | #include <linux/jhash.h> |
17 | #include <linux/list.h> |
18 | #include <linux/kernel.h> |
19 | #include <linux/module.h> |
20 | #include <linux/workqueue.h> |
21 | #include <linux/rculist.h> |
22 | #include <net/route.h> |
23 | #include <net/xfrm.h> |
24 | |
25 | #include <net/icmp.h> |
26 | #include <net/ip.h> |
27 | #include <net/ip_tunnels.h> |
28 | #include <net/gre.h> |
29 | #include <net/net_namespace.h> |
30 | #include <net/netns/generic.h> |
31 | #include <net/protocol.h> |
32 | |
33 | #include "datapath.h" |
34 | #include "vport.h" |
35 | #include "vport-netdev.h" |
36 | |
37 | static struct vport_ops ovs_gre_vport_ops; |
38 | |
39 | static struct vport *gre_tnl_create(const struct vport_parms *parms) |
40 | { |
41 | struct net *net = ovs_dp_get_net(dp: parms->dp); |
42 | struct net_device *dev; |
43 | struct vport *vport; |
44 | int err; |
45 | |
46 | vport = ovs_vport_alloc(priv_size: 0, &ovs_gre_vport_ops, parms); |
47 | if (IS_ERR(ptr: vport)) |
48 | return vport; |
49 | |
50 | rtnl_lock(); |
51 | dev = gretap_fb_dev_create(net, name: parms->name, NET_NAME_USER); |
52 | if (IS_ERR(ptr: dev)) { |
53 | rtnl_unlock(); |
54 | ovs_vport_free(vport); |
55 | return ERR_CAST(ptr: dev); |
56 | } |
57 | |
58 | err = dev_change_flags(dev, flags: dev->flags | IFF_UP, NULL); |
59 | if (err < 0) { |
60 | rtnl_delete_link(dev, portid: 0, NULL); |
61 | rtnl_unlock(); |
62 | ovs_vport_free(vport); |
63 | return ERR_PTR(error: err); |
64 | } |
65 | |
66 | rtnl_unlock(); |
67 | return vport; |
68 | } |
69 | |
70 | static struct vport *gre_create(const struct vport_parms *parms) |
71 | { |
72 | struct vport *vport; |
73 | |
74 | vport = gre_tnl_create(parms); |
75 | if (IS_ERR(ptr: vport)) |
76 | return vport; |
77 | |
78 | return ovs_netdev_link(vport, name: parms->name); |
79 | } |
80 | |
81 | static struct vport_ops ovs_gre_vport_ops = { |
82 | .type = OVS_VPORT_TYPE_GRE, |
83 | .create = gre_create, |
84 | .send = dev_queue_xmit, |
85 | .destroy = ovs_netdev_tunnel_destroy, |
86 | }; |
87 | |
88 | static int __init ovs_gre_tnl_init(void) |
89 | { |
90 | return ovs_vport_ops_register(&ovs_gre_vport_ops); |
91 | } |
92 | |
93 | static void __exit ovs_gre_tnl_exit(void) |
94 | { |
95 | ovs_vport_ops_unregister(ops: &ovs_gre_vport_ops); |
96 | } |
97 | |
98 | module_init(ovs_gre_tnl_init); |
99 | module_exit(ovs_gre_tnl_exit); |
100 | |
101 | MODULE_DESCRIPTION("OVS: GRE switching port" ); |
102 | MODULE_LICENSE("GPL" ); |
103 | MODULE_ALIAS("vport-type-3" ); |
104 | |