2019-05-29 17:12:43 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2013-06-18 04:50:33 +04:00
/*
2014-09-16 06:28:44 +04:00
* Copyright ( c ) 2007 - 2014 Nicira , Inc .
2013-06-18 04:50:33 +04:00
*/
# define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
# include <linux/if.h>
# include <linux/skbuff.h>
# include <linux/ip.h>
# include <linux/if_tunnel.h>
# include <linux/if_vlan.h>
# include <linux/in.h>
# include <linux/in_route.h>
# include <linux/inetdevice.h>
# include <linux/jhash.h>
# include <linux/list.h>
# include <linux/kernel.h>
2014-10-22 19:29:06 +04:00
# include <linux/module.h>
2013-06-18 04:50:33 +04:00
# include <linux/workqueue.h>
# include <linux/rculist.h>
# include <net/route.h>
# include <net/xfrm.h>
# include <net/icmp.h>
# include <net/ip.h>
# include <net/ip_tunnels.h>
# include <net/gre.h>
# include <net/net_namespace.h>
# include <net/netns/generic.h>
# include <net/protocol.h>
# include "datapath.h"
# include "vport.h"
2015-08-08 09:51:47 +03:00
# include "vport-netdev.h"
2013-06-18 04:50:33 +04:00
2014-10-22 19:29:06 +04:00
static struct vport_ops ovs_gre_vport_ops ;
2015-08-08 09:51:47 +03:00
static struct vport * gre_tnl_create ( const struct vport_parms * parms )
2013-06-18 04:50:33 +04:00
{
2015-08-08 09:51:47 +03:00
struct net * net = ovs_dp_get_net ( parms - > dp ) ;
struct net_device * dev ;
2014-06-28 23:34:53 +04:00
struct vport * vport ;
2016-08-09 18:24:50 +03:00
int err ;
2014-06-28 23:34:53 +04:00
2015-08-08 09:51:47 +03:00
vport = ovs_vport_alloc ( 0 , & ovs_gre_vport_ops , parms ) ;
if ( IS_ERR ( vport ) )
return vport ;
rtnl_lock ( ) ;
dev = gretap_fb_dev_create ( net , parms - > name , NET_NAME_USER ) ;
if ( IS_ERR ( dev ) ) {
rtnl_unlock ( ) ;
ovs_vport_free ( vport ) ;
return ERR_CAST ( dev ) ;
2013-06-18 04:50:33 +04:00
}
2018-12-06 20:05:42 +03:00
err = dev_change_flags ( dev , dev - > flags | IFF_UP , NULL ) ;
2016-08-09 18:24:50 +03:00
if ( err < 0 ) {
rtnl_delete_link ( dev ) ;
rtnl_unlock ( ) ;
ovs_vport_free ( vport ) ;
return ERR_PTR ( err ) ;
}
2013-06-18 04:50:33 +04:00
2016-08-09 18:24:50 +03:00
rtnl_unlock ( ) ;
2015-08-08 09:51:47 +03:00
return vport ;
2013-06-18 04:50:33 +04:00
}
static struct vport * gre_create ( const struct vport_parms * parms )
{
struct vport * vport ;
2015-08-08 09:51:47 +03:00
vport = gre_tnl_create ( parms ) ;
2013-06-18 04:50:33 +04:00
if ( IS_ERR ( vport ) )
2015-08-08 09:51:47 +03:00
return vport ;
2013-06-18 04:50:33 +04:00
2015-08-08 09:51:47 +03:00
return ovs_netdev_link ( vport , parms - > name ) ;
2013-06-18 04:50:33 +04:00
}
2014-10-22 19:29:06 +04:00
static struct vport_ops ovs_gre_vport_ops = {
2013-06-18 04:50:33 +04:00
. type = OVS_VPORT_TYPE_GRE ,
. create = gre_create ,
2015-10-21 09:00:10 +03:00
. send = dev_queue_xmit ,
2015-08-08 09:51:47 +03:00
. destroy = ovs_netdev_tunnel_destroy ,
2013-06-18 04:50:33 +04:00
} ;
2014-10-22 19:29:06 +04:00
static int __init ovs_gre_tnl_init ( void )
{
return ovs_vport_ops_register ( & ovs_gre_vport_ops ) ;
}
static void __exit ovs_gre_tnl_exit ( void )
{
ovs_vport_ops_unregister ( & ovs_gre_vport_ops ) ;
}
module_init ( ovs_gre_tnl_init ) ;
module_exit ( ovs_gre_tnl_exit ) ;
MODULE_DESCRIPTION ( " OVS: GRE switching port " ) ;
MODULE_LICENSE ( " GPL " ) ;
MODULE_ALIAS ( " vport-type-3 " ) ;