+/* GRE64 vport. */
+static const struct tnl_ops gre64_tnl_ops = {
+ .ipproto = IPPROTO_GRE,
+ .hdr_len = gre64_hdr_len,
+ .build_header = gre64_build_header,
+};
+
+static struct vport *gre64_create(const struct vport_parms *parms)
+{
+ struct net *net = ovs_dp_get_net(parms->dp);
+ struct ovs_net *ovs_net;
+ struct vport *vport;
+
+ ovs_net = net_generic(net, ovs_net_id);
+ if (rtnl_dereference(ovs_net->vport_net.gre64_vport))
+ return ERR_PTR(-EEXIST);
+
+ vport = ovs_tnl_create(parms, &ovs_gre64_vport_ops, &gre64_tnl_ops);
+
+ rcu_assign_pointer(ovs_net->vport_net.gre64_vport, vport);
+ return vport;
+}
+
+
+static void gre64_tnl_destroy(struct vport *vport)
+{
+ struct net *net = ovs_dp_get_net(vport->dp);
+ struct ovs_net *ovs_net;
+
+ ovs_net = net_generic(net, ovs_net_id);
+
+ rcu_assign_pointer(ovs_net->vport_net.gre64_vport, NULL);
+ ovs_tnl_destroy(vport);
+}
+