[ovs-dev] [PATCH upstream v3] net-ovs: Removal of kernel compatibility code from OVS

Pravin B Shelar pshelar at nicira.com
Wed Nov 16 22:01:00 UTC 2011


Fixed according to comments from Jesse.

v2-v3:
        - updated to latest OVS
        - removed white space changes.

v1-v2:
        - Fixed memleak.
        - Removed extra blank lines.
        - Removed flag, offset-stats and linkname from vport.
        - Inlined skb_clear_rxhash()
        - Fixed netdev-xmit()

--8<--------------------------cut here-------------------------->8--
Following patch deletes OVS compatibility code related to older kernel,
bridge, vlan etc and rearranges it for upstreaming.

Signed-off-by: Pravin B Shelar <pshelar at nicira.com>
---
 include/linux/openvswitch.h          |    8 +-
 net/openvswitch/actions.c            |   17 +--
 net/openvswitch/datapath.c           |  247 +++---------------------------
 net/openvswitch/datapath.h           |   23 ---
 net/openvswitch/dp_notify.c          |    8 +-
 net/openvswitch/flow.c               |   24 +---
 net/openvswitch/flow.h               |    8 +-
 net/openvswitch/vport-internal_dev.c |   87 -----------
 net/openvswitch/vport-netdev.c       |  276 +++-------------------------------
 net/openvswitch/vport-netdev.h       |    7 -
 net/openvswitch/vport.c              |  105 ++-----------
 net/openvswitch/vport.h              |   47 +------
 12 files changed, 71 insertions(+), 786 deletions(-)

diff --git a/include/linux/openvswitch.h b/include/linux/openvswitch.h
index 4f08136..4231a73 100644
--- a/include/linux/openvswitch.h
+++ b/include/linux/openvswitch.h
@@ -182,9 +182,6 @@ enum ovs_vport_type {
 	OVS_VPORT_TYPE_UNSPEC,
 	OVS_VPORT_TYPE_NETDEV,   /* network device */
 	OVS_VPORT_TYPE_INTERNAL, /* network device implemented by datapath */
-	OVS_VPORT_TYPE_PATCH = 100, /* virtual tunnel connecting two vports */
-	OVS_VPORT_TYPE_GRE,      /* GRE tunnel */
-	OVS_VPORT_TYPE_CAPWAP,   /* CAPWAP tunnel */
 	__OVS_VPORT_TYPE_MAX
 };
 
@@ -204,7 +201,6 @@ enum ovs_vport_type {
  * this port.  A value of zero indicates that upcalls should not be sent.
  * @OVS_VPORT_ATTR_STATS: A &struct ovs_vport_stats giving statistics for
  * packets sent or received through the vport.
- * @OVS_VPORT_ATTR_ADDRESS: A 6-byte Ethernet address for the vport.
  *
  * These attributes follow the &struct ovs_header within the Generic Netlink
  * payload for %OVS_VPORT_* commands.
@@ -213,7 +209,7 @@ enum ovs_vport_type {
  * %OVS_VPORT_ATTR_NAME attributes are required.  %OVS_VPORT_ATTR_PORT_NO is
  * optional; if not specified a free port number is automatically selected.
  * Whether %OVS_VPORT_ATTR_OPTIONS is required or optional depends on the type
- * of vport.  %OVS_VPORT_ATTR_STATS and %OVS_VPORT_ATTR_ADDRESS are optional,
+ * of vport.
  * and other attributes are ignored.
  *
  * For other requests, if %OVS_VPORT_ATTR_NAME is specified then it is used to
@@ -228,7 +224,6 @@ enum ovs_vport_attr {
 	OVS_VPORT_ATTR_OPTIONS, /* nested attributes, varies by vport type */
 	OVS_VPORT_ATTR_UPCALL_PID, /* u32 Netlink PID to receive upcalls */
 	OVS_VPORT_ATTR_STATS,	/* struct ovs_vport_stats */
-	OVS_VPORT_ATTR_ADDRESS = 100, /* hardware address */
 	__OVS_VPORT_ATTR_MAX
 };
 
@@ -278,7 +273,6 @@ enum ovs_key_attr {
 	OVS_KEY_ATTR_ICMPV6,    /* struct ovs_key_icmpv6 */
 	OVS_KEY_ATTR_ARP,       /* struct ovs_key_arp */
 	OVS_KEY_ATTR_ND,        /* struct ovs_key_nd */
-	OVS_KEY_ATTR_TUN_ID = 63, /* be64 tunnel ID */
 	__OVS_KEY_ATTR_MAX
 };
 
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c
index 03fef92..1e0671a 100644
--- a/net/openvswitch/actions.c
+++ b/net/openvswitch/actions.c
@@ -23,9 +23,7 @@
 #include <net/checksum.h>
 #include <net/dsfield.h>
 
-#include "checksum.h"
 #include "datapath.h"
-#include "vlan.h"
 #include "vport.h"
 
 static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
@@ -50,7 +48,7 @@ static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci)
 	if (unlikely(err))
 		return err;
 
-	if (get_ip_summed(skb) == OVS_CSUM_COMPLETE)
+	if (skb->ip_summed == CHECKSUM_COMPLETE)
 		skb->csum = csum_sub(skb->csum, csum_partial(skb->data
 					+ ETH_HLEN, VLAN_HLEN, 0));
 
@@ -73,7 +71,7 @@ static int pop_vlan(struct sk_buff *skb)
 	int err;
 
 	if (likely(vlan_tx_tag_present(skb))) {
-		vlan_set_tci(skb, 0);
+		skb->vlan_tci = 0;
 	} else {
 		if (unlikely(skb->protocol != htons(ETH_P_8021Q) ||
 			     skb->len < VLAN_ETH_HLEN))
@@ -107,7 +105,7 @@ static int push_vlan(struct sk_buff *skb, const struct ovs_action_push_vlan *vla
 		if (!__vlan_put_tag(skb, current_tag))
 			return -ENOMEM;
 
-		if (get_ip_summed(skb) == OVS_CSUM_COMPLETE)
+		if (skb->ip_summed == CHECKSUM_COMPLETE)
 			skb->csum = csum_add(skb->csum, csum_partial(skb->data
 					+ ETH_HLEN, VLAN_HLEN, 0));
 
@@ -146,7 +144,7 @@ static void set_ip_addr(struct sk_buff *skb, struct iphdr *nh,
 	}
 
 	csum_replace4(&nh->check, *addr, new_addr);
-	skb_clear_rxhash(skb);
+	skb->rxhash = 0;
 	*addr = new_addr;
 }
 
@@ -189,7 +187,7 @@ static void set_tp_port(struct sk_buff *skb, __be16 *port,
 {
 	inet_proto_csum_replace2(check, skb, *port, new_port, 0);
 	*port = new_port;
-	skb_clear_rxhash(skb);
+	skb->rxhash = 0;
 }
 
 static int set_udp_port(struct sk_buff *skb,
@@ -314,10 +312,6 @@ static int execute_set_action(struct sk_buff *skb,
 		skb->priority = nla_get_u32(nested_attr);
 		break;
 
-	case OVS_KEY_ATTR_TUN_ID:
-		OVS_CB(skb)->tun_id = nla_get_be64(nested_attr);
-		break;
-
 	case OVS_KEY_ATTR_ETHERNET:
 		err = set_eth_addr(skb, nla_data(nested_attr));
 		break;
@@ -441,7 +435,6 @@ int execute_actions(struct datapath *dp, struct sk_buff *skb)
 		goto out_loop;
 	}
 
-	OVS_CB(skb)->tun_id = 0;
 	error = do_execute_actions(dp, skb, acts->actions,
 					 acts->actions_len, false);
 
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index c7d2412..ffc40e3 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -43,21 +43,10 @@
 #include <linux/dmi.h>
 #include <net/genetlink.h>
 
-#include "checksum.h"
 #include "datapath.h"
 #include "flow.h"
-#include "vlan.h"
-#include "tunnel.h"
 #include "vport-internal_dev.h"
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) || \
-    LINUX_VERSION_CODE > KERNEL_VERSION(3,2,0)
-#error Kernels before 2.6.18 or after 3.2 are not supported by this version of Open vSwitch.
-#endif
-
-int (*dp_ioctl_hook)(struct net_device *dev, struct ifreq *rq, int cmd);
-EXPORT_SYMBOL(dp_ioctl_hook);
-
 /**
  * DOC: Locking:
  *
@@ -142,108 +131,13 @@ static int get_dpifindex(struct datapath *dp)
 	return ifindex;
 }
 
-static size_t br_nlmsg_size(void)
-{
-	return NLMSG_ALIGN(sizeof(struct ifinfomsg))
-	       + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
-	       + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
-	       + nla_total_size(4) /* IFLA_MASTER */
-	       + nla_total_size(4) /* IFLA_MTU */
-	       + nla_total_size(1); /* IFLA_OPERSTATE */
-}
-
-/* Caller must hold RTNL lock. */
-static int dp_fill_ifinfo(struct sk_buff *skb,
-			  const struct vport *port,
-			  int event, unsigned int flags)
-{
-	struct datapath *dp = port->dp;
-	struct ifinfomsg *hdr;
-	struct nlmsghdr *nlh;
-
-	if (!port->ops->get_ifindex)
-		return -ENODEV;
-
-	nlh = nlmsg_put(skb, 0, 0, event, sizeof(*hdr), flags);
-	if (nlh == NULL)
-		return -EMSGSIZE;
-
-	hdr = nlmsg_data(nlh);
-	hdr->ifi_family = AF_BRIDGE;
-	hdr->__ifi_pad = 0;
-	hdr->ifi_type = ARPHRD_ETHER;
-	hdr->ifi_index = port->ops->get_ifindex(port);
-	hdr->ifi_flags = port->ops->get_dev_flags(port);
-	hdr->ifi_change = 0;
-
-	NLA_PUT_STRING(skb, IFLA_IFNAME, port->ops->get_name(port));
-	NLA_PUT_U32(skb, IFLA_MASTER, get_dpifindex(dp));
-	NLA_PUT_U32(skb, IFLA_MTU, port->ops->get_mtu(port));
-#ifdef IFLA_OPERSTATE
-	NLA_PUT_U8(skb, IFLA_OPERSTATE,
-		   port->ops->is_running(port)
-			? port->ops->get_operstate(port)
-			: IF_OPER_DOWN);
-#endif
-
-	NLA_PUT(skb, IFLA_ADDRESS, ETH_ALEN, port->ops->get_addr(port));
-
-	return nlmsg_end(skb, nlh);
-
-nla_put_failure:
-	nlmsg_cancel(skb, nlh);
-	return -EMSGSIZE;
-}
-
-/* Caller must hold RTNL lock. */
-static void dp_ifinfo_notify(int event, struct vport *port)
-{
-	struct sk_buff *skb;
-	int err;
-
-	skb = nlmsg_new(br_nlmsg_size(), GFP_KERNEL);
-	if (!skb) {
-		err = -ENOBUFS;
-		goto err;
-	}
-
-	err = dp_fill_ifinfo(skb, port, event, 0);
-	if (err < 0) {
-		if (err == -ENODEV) {
-			goto out;
-		} else {
-			/* -EMSGSIZE implies BUG in br_nlmsg_size() */
-			WARN_ON(err == -EMSGSIZE);
-			goto err;
-		}
-	}
-
-	rtnl_notify(skb, &init_net, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
-
-	return;
-err:
-	rtnl_set_sk_err(&init_net, RTNLGRP_LINK, err);
-out:
-	kfree_skb(skb);
-}
-
-static void release_dp(struct kobject *kobj)
-{
-	struct datapath *dp = container_of(kobj, struct datapath, ifobj);
-	kfree(dp);
-}
-
-static struct kobj_type dp_ktype = {
-	.release = release_dp
-};
-
 static void destroy_dp_rcu(struct rcu_head *rcu)
 {
 	struct datapath *dp = container_of(rcu, struct datapath, rcu);
 
 	flow_tbl_destroy(dp->table);
 	free_percpu(dp->stats_percpu);
-	kobject_put(&dp->ifobj);
+	kfree(dp);
 }
 
 /* Called with RTNL lock and genl_lock. */
@@ -257,8 +151,6 @@ static struct vport *new_vport(const struct vport_parms *parms)
 
 		rcu_assign_pointer(dp->ports[parms->port_no], vport);
 		list_add(&vport->node, &dp->port_list);
-
-		dp_ifinfo_notify(RTM_NEWLINK, vport);
 	}
 
 	return vport;
@@ -269,10 +161,6 @@ void dp_detach_port(struct vport *p)
 {
 	ASSERT_RTNL();
 
-	if (p->port_no != OVSP_LOCAL)
-		dp_sysfs_del_if(p);
-	dp_ifinfo_notify(RTM_DELLINK, p);
-
 	/* First drop references to device. */
 	list_del(&p->node);
 	rcu_assign_pointer(p->dp->ports[p->port_no], NULL);
@@ -360,8 +248,6 @@ int dp_upcall(struct datapath *dp, struct sk_buff *skb,
 		goto err;
 	}
 
-	forward_ip_summed(skb, true);
-
 	if (!skb_is_gso(skb))
 		err = queue_userspace_packet(dp_ifindex, skb, upcall_info);
 	else
@@ -426,6 +312,19 @@ static int queue_gso_packets(int dp_ifindex, struct sk_buff *skb,
 	return err;
 }
 
+static inline int vlan_deaccel_tag(struct sk_buff *skb)
+{
+	if (!vlan_tx_tag_present(skb))
+		return 0;
+
+	skb = __vlan_put_tag(skb, vlan_tx_tag_get(skb));
+	if (unlikely(!skb))
+		return -ENOMEM;
+
+	skb->vlan_tci = 0;
+	return 0;
+}
+
 static int queue_userspace_packet(int dp_ifindex, struct sk_buff *skb,
 				  const struct dp_upcall_info *upcall_info)
 {
@@ -542,7 +441,6 @@ static int validate_set(const struct nlattr *a,
 	const struct ovs_key_ipv4 *ipv4_key;
 
 	case OVS_KEY_ATTR_PRIORITY:
-	case OVS_KEY_ATTR_TUN_ID:
 	case OVS_KEY_ATTR_ETHERNET:
 		break;
 
@@ -743,7 +641,6 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
 
 	err = flow_metadata_from_nlattrs(&flow->key.phy.priority,
 					 &flow->key.phy.in_port,
-					 &flow->key.phy.tun_id,
 					 a[OVS_PACKET_ATTR_KEY]);
 	if (err)
 		goto err_flow_put;
@@ -1087,7 +984,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, struct genl_info *info)
 		genl_notify(reply, genl_info_net(info), info->snd_pid,
 			   dp_flow_multicast_group.id, info->nlhdr, GFP_KERNEL);
 	else
-		netlink_set_err(INIT_NET_GENL_SOCK, 0,
+		netlink_set_err(init_net.genl_sock, 0,
 				dp_flow_multicast_group.id, PTR_ERR(reply));
 	return 0;
 
@@ -1232,9 +1129,7 @@ static struct genl_ops dp_flow_genl_ops[] = {
 };
 
 static const struct nla_policy datapath_policy[OVS_DP_ATTR_MAX + 1] = {
-#ifdef HAVE_NLA_NUL_STRING
 	[OVS_DP_ATTR_NAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 },
-#endif
 	[OVS_DP_ATTR_UPCALL_PID] = { .type = NLA_U32 },
 };
 
@@ -1301,11 +1196,6 @@ static struct sk_buff *ovs_dp_cmd_build_info(struct datapath *dp, u32 pid,
 	return skb;
 }
 
-static int ovs_dp_cmd_validate(struct nlattr *a[OVS_DP_ATTR_MAX + 1])
-{
-	return CHECK_NUL_STRING(a[OVS_DP_ATTR_NAME], IFNAMSIZ - 1);
-}
-
 /* Called with genl_mutex and optionally with RTNL lock also. */
 static struct datapath *lookup_datapath(struct ovs_header *ovs_header,
 					struct nlattr *a[OVS_DP_ATTR_MAX + 1])
@@ -1338,10 +1228,6 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
 	if (!a[OVS_DP_ATTR_NAME] || !a[OVS_DP_ATTR_UPCALL_PID])
 		goto err;
 
-	err = ovs_dp_cmd_validate(a);
-	if (err)
-		goto err;
-
 	rtnl_lock();
 	err = -ENODEV;
 	if (!try_module_get(THIS_MODULE))
@@ -1353,11 +1239,6 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
 		goto err_put_module;
 	INIT_LIST_HEAD(&dp->port_list);
 
-	/* Initialize kobject for bridge.  This will be added as
-	 * /sys/class/net/<devname>/brif later, if sysfs is enabled. */
-	dp->ifobj.kset = NULL;
-	kobject_init(&dp->ifobj, &dp_ktype);
-
 	/* Allocate table. */
 	err = -ENOMEM;
 	rcu_assign_pointer(dp->table, flow_tbl_alloc(TBL_MIN_BUCKETS));
@@ -1394,8 +1275,6 @@ static int ovs_dp_cmd_new(struct sk_buff *skb, struct genl_info *info)
 		goto err_destroy_local_port;
 
 	list_add_tail(&dp->list_node, &dps);
-	dp_sysfs_add_dp(dp);
-
 	rtnl_unlock();
 
 	genl_notify(reply, genl_info_net(info), info->snd_pid,
@@ -1425,10 +1304,6 @@ static int ovs_dp_cmd_del(struct sk_buff *skb, struct genl_info *info)
 	struct datapath *dp;
 	int err;
 
-	err = ovs_dp_cmd_validate(info->attrs);
-	if (err)
-		goto exit;
-
 	rtnl_lock();
 	dp = lookup_datapath(info->userhdr, info->attrs);
 	err = PTR_ERR(dp);
@@ -1445,7 +1320,6 @@ static int ovs_dp_cmd_del(struct sk_buff *skb, struct genl_info *info)
 		if (vport->port_no != OVSP_LOCAL)
 			dp_detach_port(vport);
 
-	dp_sysfs_del_dp(dp);
 	list_del(&dp->list_node);
 	dp_detach_port(get_vport_protected(dp, OVSP_LOCAL));
 
@@ -1466,7 +1340,6 @@ static int ovs_dp_cmd_del(struct sk_buff *skb, struct genl_info *info)
 
 exit_unlock:
 	rtnl_unlock();
-exit:
 	return err;
 }
 
@@ -1476,10 +1349,6 @@ static int ovs_dp_cmd_set(struct sk_buff *skb, struct genl_info *info)
 	struct datapath *dp;
 	int err;
 
-	err = ovs_dp_cmd_validate(info->attrs);
-	if (err)
-		return err;
-
 	dp = lookup_datapath(info->userhdr, info->attrs);
 	if (IS_ERR(dp))
 		return PTR_ERR(dp);
@@ -1488,7 +1357,7 @@ static int ovs_dp_cmd_set(struct sk_buff *skb, struct genl_info *info)
 				      info->snd_seq, OVS_DP_CMD_NEW);
 	if (IS_ERR(reply)) {
 		err = PTR_ERR(reply);
-		netlink_set_err(INIT_NET_GENL_SOCK, 0,
+		netlink_set_err(init_net.genl_sock, 0,
 				dp_datapath_multicast_group.id, err);
 		return 0;
 	}
@@ -1502,11 +1371,6 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info)
 {
 	struct sk_buff *reply;
 	struct datapath *dp;
-	int err;
-
-	err = ovs_dp_cmd_validate(info->attrs);
-	if (err)
-		return err;
 
 	dp = lookup_datapath(info->userhdr, info->attrs);
 	if (IS_ERR(dp))
@@ -1566,14 +1430,8 @@ static struct genl_ops dp_datapath_genl_ops[] = {
 };
 
 static const struct nla_policy vport_policy[OVS_VPORT_ATTR_MAX + 1] = {
-#ifdef HAVE_NLA_NUL_STRING
 	[OVS_VPORT_ATTR_NAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ - 1 },
 	[OVS_VPORT_ATTR_STATS] = { .len = sizeof(struct ovs_vport_stats) },
-	[OVS_VPORT_ATTR_ADDRESS] = { .len = ETH_ALEN },
-#else
-	[OVS_VPORT_ATTR_STATS] = { .minlen = sizeof(struct ovs_vport_stats) },
-	[OVS_VPORT_ATTR_ADDRESS] = { .minlen = ETH_ALEN },
-#endif
 	[OVS_VPORT_ATTR_PORT_NO] = { .type = NLA_U32 },
 	[OVS_VPORT_ATTR_TYPE] = { .type = NLA_U32 },
 	[OVS_VPORT_ATTR_UPCALL_PID] = { .type = NLA_U32 },
@@ -1619,9 +1477,6 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb,
 
 	vport_get_stats(vport, nla_data(nla));
 
-	NLA_PUT(skb, OVS_VPORT_ATTR_ADDRESS, ETH_ALEN,
-		vport->ops->get_addr(vport));
-
 	err = vport_get_options(vport, skb);
 	if (err == -EMSGSIZE)
 		goto error;
@@ -1654,11 +1509,6 @@ struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, u32 pid,
 	return skb;
 }
 
-static int ovs_vport_cmd_validate(struct nlattr *a[OVS_VPORT_ATTR_MAX + 1])
-{
-	return CHECK_NUL_STRING(a[OVS_VPORT_ATTR_NAME], IFNAMSIZ - 1);
-}
-
 /* Called with RTNL lock or RCU read lock. */
 static struct vport *lookup_vport(struct ovs_header *ovs_header,
 				  struct nlattr *a[OVS_VPORT_ATTR_MAX + 1])
@@ -1689,21 +1539,6 @@ static struct vport *lookup_vport(struct ovs_header *ovs_header,
 		return ERR_PTR(-EINVAL);
 }
 
-/* Called with RTNL lock. */
-static int change_vport(struct vport *vport,
-			struct nlattr *a[OVS_VPORT_ATTR_MAX + 1])
-{
-	int err = 0;
-
-	if (a[OVS_VPORT_ATTR_STATS])
-		vport_set_stats(vport, nla_data(a[OVS_VPORT_ATTR_STATS]));
-
-	if (a[OVS_VPORT_ATTR_ADDRESS])
-		err = vport_set_addr(vport, nla_data(a[OVS_VPORT_ATTR_ADDRESS]));
-
-	return err;
-}
-
 static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
 {
 	struct nlattr **a = info->attrs;
@@ -1720,10 +1555,6 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
 	    !a[OVS_VPORT_ATTR_UPCALL_PID])
 		goto exit;
 
-	err = ovs_vport_cmd_validate(a);
-	if (err)
-		goto exit;
-
 	rtnl_lock();
 	dp = get_dp(ovs_header->dp_ifindex);
 	err = -ENODEV;
@@ -1765,17 +1596,10 @@ static int ovs_vport_cmd_new(struct sk_buff *skb, struct genl_info *info)
 	if (IS_ERR(vport))
 		goto exit_unlock;
 
-	dp_sysfs_add_if(vport);
-
-	err = change_vport(vport, a);
-	if (!err) {
-		reply = ovs_vport_cmd_build_info(vport, info->snd_pid,
-						 info->snd_seq,
-						 OVS_VPORT_CMD_NEW);
-		if (IS_ERR(reply))
-			err = PTR_ERR(reply);
-	}
-	if (err) {
+	reply = ovs_vport_cmd_build_info(vport, info->snd_pid, info->snd_seq,
+					 OVS_VPORT_CMD_NEW);
+	if (IS_ERR(reply)) {
+		err = PTR_ERR(reply);
 		dp_detach_port(vport);
 		goto exit_unlock;
 	}
@@ -1796,10 +1620,6 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
 	struct vport *vport;
 	int err;
 
-	err = ovs_vport_cmd_validate(a);
-	if (err)
-		goto exit;
-
 	rtnl_lock();
 	vport = lookup_vport(info->userhdr, a);
 	err = PTR_ERR(vport);
@@ -1813,8 +1633,6 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
 
 	if (!err && a[OVS_VPORT_ATTR_OPTIONS])
 		err = vport_set_options(vport, a[OVS_VPORT_ATTR_OPTIONS]);
-	if (!err)
-		err = change_vport(vport, a);
 	if (!err && a[OVS_VPORT_ATTR_UPCALL_PID])
 		vport->upcall_pid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]);
 
@@ -1822,7 +1640,7 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
 					 OVS_VPORT_CMD_NEW);
 	if (IS_ERR(reply)) {
 		err = PTR_ERR(reply);
-		netlink_set_err(INIT_NET_GENL_SOCK, 0,
+		netlink_set_err(init_net.genl_sock, 0,
 				dp_vport_multicast_group.id, err);
 		return 0;
 	}
@@ -1832,7 +1650,6 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
 
 exit_unlock:
 	rtnl_unlock();
-exit:
 	return err;
 }
 
@@ -1843,10 +1660,6 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
 	struct vport *vport;
 	int err;
 
-	err = ovs_vport_cmd_validate(a);
-	if (err)
-		goto exit;
-
 	rtnl_lock();
 	vport = lookup_vport(info->userhdr, a);
 	err = PTR_ERR(vport);
@@ -1871,7 +1684,6 @@ static int ovs_vport_cmd_del(struct sk_buff *skb, struct genl_info *info)
 
 exit_unlock:
 	rtnl_unlock();
-exit:
 	return err;
 }
 
@@ -1883,10 +1695,6 @@ static int ovs_vport_cmd_get(struct sk_buff *skb, struct genl_info *info)
 	struct vport *vport;
 	int err;
 
-	err = ovs_vport_cmd_validate(a);
-	if (err)
-		goto exit;
-
 	rcu_read_lock();
 	vport = lookup_vport(ovs_header, a);
 	err = PTR_ERR(vport);
@@ -1905,7 +1713,6 @@ static int ovs_vport_cmd_get(struct sk_buff *skb, struct genl_info *info)
 
 exit_unlock:
 	rcu_read_unlock();
-exit:
 	return err;
 }
 
@@ -2032,16 +1839,11 @@ static int __init dp_init(void)
 
 	BUILD_BUG_ON(sizeof(struct ovs_skb_cb) > sizeof(dummy_skb->cb));
 
-	pr_info("Open vSwitch %s, built "__DATE__" "__TIME__"\n",
-		VERSION BUILDNR);
-
-	err = tnl_init();
-	if (err)
-		goto error;
+	pr_info("Open vSwitch switching datapath\n");
 
 	err = flow_init();
 	if (err)
-		goto error_tnl_exit;
+		goto error;
 
 	err = vport_init();
 	if (err)
@@ -2063,8 +1865,6 @@ error_vport_exit:
 	vport_exit();
 error_flow_exit:
 	flow_exit();
-error_tnl_exit:
-	tnl_exit();
 error:
 	return err;
 }
@@ -2076,7 +1876,6 @@ static void dp_cleanup(void)
 	unregister_netdevice_notifier(&dp_device_notifier);
 	vport_exit();
 	flow_exit();
-	tnl_exit();
 }
 
 module_init(dp_init);
diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h
index c7014c3..aa40809 100644
--- a/net/openvswitch/datapath.h
+++ b/net/openvswitch/datapath.h
@@ -19,11 +19,7 @@
 #include <linux/skbuff.h>
 #include <linux/version.h>
 
-#include "checksum.h"
-#include "compat.h"
 #include "flow.h"
-#include "dp_sysfs.h"
-#include "vlan.h"
 
 struct vport;
 
@@ -53,7 +49,6 @@ struct dp_stats_percpu {
  * struct datapath - datapath for flow-based packet switching
  * @rcu: RCU callback head for deferred destruction.
  * @list_node: Element in global 'dps' list.
- * @ifobj: Represents /sys/class/net/<devname>/brif.  Protected by RTNL.
  * @n_flows: Number of flows currently in flow table.
  * @table: Current flow table.  Protected by genl_lock and RCU.
  * @ports: Map from port number to &struct vport.  %OVSP_LOCAL port
@@ -68,7 +63,6 @@ struct dp_stats_percpu {
 struct datapath {
 	struct rcu_head rcu;
 	struct list_head list_node;
-	struct kobject ifobj;
 
 	/* Flow table. */
 	struct flow_table __rcu *table;
@@ -84,25 +78,9 @@ struct datapath {
 /**
  * struct ovs_skb_cb - OVS data in skb CB
  * @flow: The flow associated with this packet.  May be %NULL if no flow.
- * @tun_id: ID of the tunnel that encapsulated this packet.  It is 0 if the
- * @ip_summed: Consistently stores L4 checksumming status across different
- * kernel versions.
- * @csum_start: Stores the offset from which to start checksumming independent
- * of the transport header on all kernel versions.
- * packet was not received on a tunnel.
- * @vlan_tci: Provides a substitute for the skb->vlan_tci field on kernels
- * before 2.6.27.
  */
 struct ovs_skb_cb {
 	struct sw_flow		*flow;
-	__be64			tun_id;
-#ifdef NEED_CSUM_NORMALIZE
-	enum csum_type		ip_summed;
-	u16			csum_start;
-#endif
-#ifdef NEED_VLAN_FIELD
-	u16			vlan_tci;
-#endif
 };
 #define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb)
 
@@ -125,7 +103,6 @@ struct dp_upcall_info {
 
 extern struct notifier_block dp_device_notifier;
 extern struct genl_multicast_group dp_vport_multicast_group;
-extern int (*dp_ioctl_hook)(struct net_device *dev, struct ifreq *rq, int cmd);
 
 void dp_process_received_packet(struct vport *, struct sk_buff *);
 void dp_detach_port(struct vport *);
diff --git a/net/openvswitch/dp_notify.c b/net/openvswitch/dp_notify.c
index 07fd222..9baa743 100644
--- a/net/openvswitch/dp_notify.c
+++ b/net/openvswitch/dp_notify.c
@@ -41,7 +41,7 @@ static int dp_device_event(struct notifier_block *unused, unsigned long event,
 							 OVS_VPORT_CMD_DEL);
 			dp_detach_port(vport);
 			if (IS_ERR(reply)) {
-				netlink_set_err(INIT_NET_GENL_SOCK, 0,
+				netlink_set_err(init_net.genl_sock, 0,
 						dp_vport_multicast_group.id,
 						PTR_ERR(reply));
 				break;
@@ -53,12 +53,6 @@ static int dp_device_event(struct notifier_block *unused, unsigned long event,
 		}
 		break;
 
-	case NETDEV_CHANGENAME:
-		if (vport->port_no != OVSP_LOCAL) {
-			dp_sysfs_del_if(vport);
-			dp_sysfs_add_if(vport);
-		}
-		break;
 	}
 	return NOTIFY_DONE;
 }
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 4481319..574267b 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -34,8 +34,6 @@
 #include <net/ipv6.h>
 #include <net/ndisc.h>
 
-#include "vlan.h"
-
 static struct kmem_cache *flow_cache;
 static unsigned int hash_seed __read_mostly;
 
@@ -644,7 +642,6 @@ int flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
 	memset(key, 0, sizeof(*key));
 
 	key->phy.priority = skb->priority;
-	key->phy.tun_id = OVS_CB(skb)->tun_id;
 	key->phy.in_port = in_port;
 
 	skb_reset_mac_header(skb);
@@ -659,7 +656,7 @@ int flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
 	__skb_pull(skb, 2 * ETH_ALEN);
 
 	if (vlan_tx_tag_present(skb))
-		key->eth.tci = htons(vlan_get_tci(skb));
+		key->eth.tci = htons(skb->vlan_tci);
 	else if (eth->h_proto == htons(ETH_P_8021Q))
 		if (unlikely(parse_vlan(skb, key)))
 			return -ENOMEM;
@@ -861,9 +858,6 @@ const int ovs_key_lens[OVS_KEY_ATTR_MAX + 1] = {
 	[OVS_KEY_ATTR_ICMPV6] = sizeof(struct ovs_key_icmpv6),
 	[OVS_KEY_ATTR_ARP] = sizeof(struct ovs_key_arp),
 	[OVS_KEY_ATTR_ND] = sizeof(struct ovs_key_nd),
-
-	/* Not upstream. */
-	[OVS_KEY_ATTR_TUN_ID] = sizeof(__be64),
 };
 
 static int ipv4_flow_from_nlattrs(struct sw_flow_key *swkey, int *key_len,
@@ -1039,11 +1033,6 @@ int flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
 		swkey->phy.in_port = USHRT_MAX;
 	}
 
-	if (attrs & (1ULL << OVS_KEY_ATTR_TUN_ID)) {
-		swkey->phy.tun_id = nla_get_be64(a[OVS_KEY_ATTR_TUN_ID]);
-		attrs &= ~(1ULL << OVS_KEY_ATTR_TUN_ID);
-	}
-
 	/* Data attributes. */
 	if (!(attrs & (1 << OVS_KEY_ATTR_ETHERNET)))
 		return -EINVAL;
@@ -1170,7 +1159,6 @@ int flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
 /**
  * flow_metadata_from_nlattrs - parses Netlink attributes into a flow key.
  * @in_port: receives the extracted input port.
- * @tun_id: receives the extracted tunnel ID.
  * @key: Netlink attribute holding nested %OVS_KEY_ATTR_* Netlink attribute
  * sequence.
  *
@@ -1179,14 +1167,13 @@ int flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
  * get the metadata, that is, the parts of the flow key that cannot be
  * extracted from the packet itself.
  */
-int flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, __be64 *tun_id,
+int flow_metadata_from_nlattrs(u32 *priority, u16 *in_port,
 			       const struct nlattr *attr)
 {
 	const struct nlattr *nla;
 	int rem;
 
 	*in_port = USHRT_MAX;
-	*tun_id = 0;
 	*priority = 0;
 
 	nla_for_each_nested(nla, attr, rem) {
@@ -1201,10 +1188,6 @@ int flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, __be64 *tun_id,
 				*priority = nla_get_u32(nla);
 				break;
 
-			case OVS_KEY_ATTR_TUN_ID:
-				*tun_id = nla_get_be64(nla);
-				break;
-
 			case OVS_KEY_ATTR_IN_PORT:
 				if (nla_get_u32(nla) >= DP_MAX_PORTS)
 					return -EINVAL;
@@ -1226,9 +1209,6 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
 	if (swkey->phy.priority)
 		NLA_PUT_U32(skb, OVS_KEY_ATTR_PRIORITY, swkey->phy.priority);
 
-	if (swkey->phy.tun_id != cpu_to_be64(0))
-		NLA_PUT_BE64(skb, OVS_KEY_ATTR_TUN_ID, swkey->phy.tun_id);
-
 	if (swkey->phy.in_port != USHRT_MAX)
 		NLA_PUT_U32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port);
 
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h
index 40b1883..9c0fe24 100644
--- a/net/openvswitch/flow.h
+++ b/net/openvswitch/flow.h
@@ -32,7 +32,6 @@ struct sw_flow_actions {
 
 struct sw_flow_key {
 	struct {
-		__be64	tun_id;		/* Encapsulating tunnel ID. */
 		u32	priority;	/* Packet QoS priority. */
 		u16	in_port;	/* Input switch port (or USHRT_MAX). */
 	} phy;
@@ -139,7 +138,6 @@ u64 flow_used_time(unsigned long flow_jiffies);
  *                         struct  pad  nl hdr  total
  *                         ------  ---  ------  -----
  *  OVS_KEY_ATTR_PRIORITY      4    --     4      8
- *  OVS_KEY_ATTR_TUN_ID        8    --     4     12
  *  OVS_KEY_ATTR_IN_PORT       4    --     4      8
  *  OVS_KEY_ATTR_ETHERNET     12    --     4     16
  *  OVS_KEY_ATTR_8021Q         4    --     4      8
@@ -148,14 +146,14 @@ u64 flow_used_time(unsigned long flow_jiffies);
  *  OVS_KEY_ATTR_ICMPV6        2     2     4      8
  *  OVS_KEY_ATTR_ND           28    --     4     32
  *  -------------------------------------------------
- *  total                                       144
+ *  total                                       132
  */
-#define FLOW_BUFSIZE 144
+#define FLOW_BUFSIZE 132
 
 int flow_to_nlattrs(const struct sw_flow_key *, struct sk_buff *);
 int flow_from_nlattrs(struct sw_flow_key *swkey, int *key_lenp,
 		      const struct nlattr *);
-int flow_metadata_from_nlattrs(u32 *priority, u16 *in_port, __be64 *tun_id,
+int flow_metadata_from_nlattrs(u32 *priority, u16 *in_port,
 			       const struct nlattr *);
 
 #define TBL_MIN_BUCKETS		1024
diff --git a/net/openvswitch/vport-internal_dev.c b/net/openvswitch/vport-internal_dev.c
index 67f2826..422e808 100644
--- a/net/openvswitch/vport-internal_dev.c
+++ b/net/openvswitch/vport-internal_dev.c
@@ -15,22 +15,12 @@
 #include <linux/skbuff.h>
 #include <linux/version.h>
 
-#include "checksum.h"
 #include "datapath.h"
-#include "vlan.h"
-#include "vport-generic.h"
 #include "vport-internal_dev.h"
 #include "vport-netdev.h"
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)
-#define HAVE_NET_DEVICE_OPS
-#endif
-
 struct internal_dev {
 	struct vport *vport;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
-	struct net_device_stats stats;
-#endif
 };
 
 static struct internal_dev *internal_dev_priv(struct net_device *netdev)
@@ -39,19 +29,9 @@ static struct internal_dev *internal_dev_priv(struct net_device *netdev)
 }
 
 /* This function is only called by the kernel network layer.*/
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
 static struct rtnl_link_stats64 *internal_dev_get_stats(struct net_device *netdev,
 							struct rtnl_link_stats64 *stats)
 {
-#else
-static struct net_device_stats *internal_dev_sys_stats(struct net_device *netdev)
-{
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
-	struct net_device_stats *stats = &internal_dev_priv(netdev)->stats;
-#else
-	struct net_device_stats *stats = &netdev->stats;
-#endif
-#endif
 	struct vport *vport = internal_dev_get_vport(netdev);
 	struct ovs_vport_stats vport_stats;
 
@@ -84,12 +64,6 @@ static int internal_dev_mac_addr(struct net_device *dev, void *p)
 /* Called with rcu_read_lock_bh. */
 static int internal_dev_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
-	if (unlikely(compute_ip_summed(skb, true))) {
-		kfree_skb(skb);
-		return 0;
-	}
-
-	vlan_copy_skb_tci(skb);
 	OVS_CB(skb)->flow = NULL;
 
 	rcu_read_lock();
@@ -119,14 +93,6 @@ static void internal_dev_getinfo(struct net_device *netdev,
 static const struct ethtool_ops internal_dev_ethtool_ops = {
 	.get_drvinfo	= internal_dev_getinfo,
 	.get_link	= ethtool_op_get_link,
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39)
-	.get_sg		= ethtool_op_get_sg,
-	.set_sg		= ethtool_op_set_sg,
-	.get_tx_csum	= ethtool_op_get_tx_csum,
-	.set_tx_csum	= ethtool_op_set_tx_hw_csum,
-	.get_tso	= ethtool_op_get_tso,
-	.set_tso	= ethtool_op_set_tso,
-#endif
 };
 
 static int internal_dev_change_mtu(struct net_device *netdev, int new_mtu)
@@ -138,15 +104,6 @@ static int internal_dev_change_mtu(struct net_device *netdev, int new_mtu)
 	return 0;
 }
 
-static int internal_dev_do_ioctl(struct net_device *dev,
-				 struct ifreq *ifr, int cmd)
-{
-	if (dp_ioctl_hook)
-		return dp_ioctl_hook(dev, ifr, cmd);
-
-	return -EOPNOTSUPP;
-}
-
 static void internal_dev_destructor(struct net_device *dev)
 {
 	struct vport *vport = internal_dev_get_vport(dev);
@@ -155,37 +112,20 @@ static void internal_dev_destructor(struct net_device *dev)
 	free_netdev(dev);
 }
 
-#ifdef HAVE_NET_DEVICE_OPS
 static const struct net_device_ops internal_dev_netdev_ops = {
 	.ndo_open = internal_dev_open,
 	.ndo_stop = internal_dev_stop,
 	.ndo_start_xmit = internal_dev_xmit,
 	.ndo_set_mac_address = internal_dev_mac_addr,
-	.ndo_do_ioctl = internal_dev_do_ioctl,
 	.ndo_change_mtu = internal_dev_change_mtu,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
 	.ndo_get_stats64 = internal_dev_get_stats,
-#else
-	.ndo_get_stats = internal_dev_sys_stats,
-#endif
 };
-#endif
 
 static void do_setup(struct net_device *netdev)
 {
 	ether_setup(netdev);
 
-#ifdef HAVE_NET_DEVICE_OPS
 	netdev->netdev_ops = &internal_dev_netdev_ops;
-#else
-	netdev->do_ioctl = internal_dev_do_ioctl;
-	netdev->get_stats = internal_dev_sys_stats;
-	netdev->hard_start_xmit = internal_dev_xmit;
-	netdev->open = internal_dev_open;
-	netdev->stop = internal_dev_stop;
-	netdev->set_mac_address = internal_dev_mac_addr;
-	netdev->change_mtu = internal_dev_change_mtu;
-#endif
 
 	netdev->priv_flags &= ~IFF_TX_SKB_SHARING;
 	netdev->destructor = internal_dev_destructor;
@@ -195,14 +135,9 @@ static void do_setup(struct net_device *netdev)
 	netdev->features = NETIF_F_LLTX | NETIF_F_SG | NETIF_F_FRAGLIST |
 				NETIF_F_HIGHDMA | NETIF_F_HW_CSUM | NETIF_F_TSO;
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
 	netdev->vlan_features = netdev->features;
 	netdev->features |= NETIF_F_HW_VLAN_TX;
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
 	netdev->hw_features = netdev->features & ~NETIF_F_LLTX;
-#endif
 	random_ether_addr(netdev->dev_addr);
 }
 
@@ -265,50 +200,28 @@ static int internal_dev_recv(struct vport *vport, struct sk_buff *skb)
 	struct net_device *netdev = netdev_vport_priv(vport)->dev;
 	int len;
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
-	if (unlikely(vlan_deaccel_tag(skb)))
-		return 0;
-#endif
-
 	len = skb->len;
 	skb->dev = netdev;
 	skb->pkt_type = PACKET_HOST;
 	skb->protocol = eth_type_trans(skb, netdev);
-	forward_ip_summed(skb, false);
 
 	netif_rx(skb);
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29)
-	netdev->last_rx = jiffies;
-#endif
-
 	return len;
 }
 
 const struct vport_ops internal_vport_ops = {
 	.type		= OVS_VPORT_TYPE_INTERNAL,
-	.flags		= VPORT_F_REQUIRED | VPORT_F_FLOW,
 	.create		= internal_dev_create,
 	.destroy	= internal_dev_destroy,
-	.set_addr	= netdev_set_addr,
 	.get_name	= netdev_get_name,
-	.get_addr	= netdev_get_addr,
-	.get_kobj	= netdev_get_kobj,
-	.get_dev_flags	= netdev_get_dev_flags,
-	.is_running	= netdev_is_running,
-	.get_operstate	= netdev_get_operstate,
 	.get_ifindex	= netdev_get_ifindex,
-	.get_mtu	= netdev_get_mtu,
 	.send		= internal_dev_recv,
 };
 
 int is_internal_dev(const struct net_device *netdev)
 {
-#ifdef HAVE_NET_DEVICE_OPS
 	return netdev->netdev_ops == &internal_dev_netdev_ops;
-#else
-	return netdev->open == internal_dev_open;
-#endif
 }
 
 struct vport *internal_dev_get_vport(struct net_device *netdev)
diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c
index a9d9238..d4625f0 100644
--- a/net/openvswitch/vport-netdev.c
+++ b/net/openvswitch/vport-netdev.c
@@ -18,26 +18,30 @@
 
 #include <net/llc.h>
 
-#include "checksum.h"
 #include "datapath.h"
-#include "vlan.h"
 #include "vport-internal_dev.h"
 #include "vport-netdev.h"
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) && \
-	!defined(HAVE_VLAN_BUG_WORKAROUND)
-#include <linux/module.h>
+/* Must be called with rcu_read_lock. */
+static void netdev_port_receive(struct vport *vport, struct sk_buff *skb)
+{
+	if (unlikely(!vport)) {
+		kfree_skb(skb);
+		return;
+	}
 
-static int vlan_tso __read_mostly;
-module_param(vlan_tso, int, 0644);
-MODULE_PARM_DESC(vlan_tso, "Enable TSO for VLAN packets");
-#else
-#define vlan_tso true
-#endif
+	/* Make our own copy of the packet.  Otherwise we will mangle the
+	 * packet for anyone who came before us (e.g. tcpdump via AF_PACKET).
+	 * (No one comes after us, since we tell handle_bridge() that we took
+	 * the packet.) */
+	skb = skb_share_check(skb, GFP_ATOMIC);
+	if (unlikely(!skb))
+		return;
 
-static void netdev_port_receive(struct vport *vport, struct sk_buff *skb);
+	skb_push(skb, ETH_HLEN);
+	vport_receive(vport, skb);
+}
 
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
 /* Called with rcu_read_lock and bottom-halves disabled. */
 static rx_handler_result_t netdev_frame_hook(struct sk_buff **pskb)
 {
@@ -53,66 +57,6 @@ static rx_handler_result_t netdev_frame_hook(struct sk_buff **pskb)
 
 	return RX_HANDLER_CONSUMED;
 }
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
-/* Called with rcu_read_lock and bottom-halves disabled. */
-static struct sk_buff *netdev_frame_hook(struct sk_buff *skb)
-{
-	struct vport *vport;
-
-	if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
-		return skb;
-
-	vport = netdev_get_vport(skb->dev);
-
-	netdev_port_receive(vport, skb);
-
-	return NULL;
-}
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
-/*
- * Used as br_handle_frame_hook.  (Cannot run bridge at the same time, even on
- * different set of devices!)
- */
-/* Called with rcu_read_lock and bottom-halves disabled. */
-static struct sk_buff *netdev_frame_hook(struct net_bridge_port *p,
-					 struct sk_buff *skb)
-{
-	netdev_port_receive((struct vport *)p, skb);
-	return NULL;
-}
-#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-/*
- * Used as br_handle_frame_hook.  (Cannot run bridge at the same time, even on
- * different set of devices!)
- */
-/* Called with rcu_read_lock and bottom-halves disabled. */
-static int netdev_frame_hook(struct net_bridge_port *p, struct sk_buff **pskb)
-{
-	netdev_port_receive((struct vport *)p, *pskb);
-	return 1;
-}
-#else
-#error
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
-static int netdev_init(void) { return 0; }
-static void netdev_exit(void) { }
-#else
-static int netdev_init(void)
-{
-	/* Hook into callback used by the bridge to intercept packets.
-	 * Parasites we are. */
-	br_handle_frame_hook = netdev_frame_hook;
-
-	return 0;
-}
-
-static void netdev_exit(void)
-{
-	br_handle_frame_hook = NULL;
-}
-#endif
 
 static struct vport *netdev_create(const struct vport_parms *parms)
 {
@@ -148,9 +92,6 @@ static struct vport *netdev_create(const struct vport_parms *parms)
 		goto error_put;
 
 	dev_set_promiscuity(netdev_vport->dev, 1);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
-	dev_disable_lro(netdev_vport->dev);
-#endif
 	netdev_vport->dev->priv_flags |= IFF_OVS_DATAPATH;
 
 	return vport;
@@ -177,91 +118,18 @@ static void netdev_destroy(struct vport *vport)
 	vport_free(vport);
 }
 
-int netdev_set_addr(struct vport *vport, const unsigned char *addr)
-{
-	struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
-	struct sockaddr sa;
-
-	sa.sa_family = ARPHRD_ETHER;
-	memcpy(sa.sa_data, addr, ETH_ALEN);
-
-	return dev_set_mac_address(netdev_vport->dev, &sa);
-}
-
 const char *netdev_get_name(const struct vport *vport)
 {
 	const struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
 	return netdev_vport->dev->name;
 }
 
-const unsigned char *netdev_get_addr(const struct vport *vport)
-{
-	const struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
-	return netdev_vport->dev->dev_addr;
-}
-
-struct kobject *netdev_get_kobj(const struct vport *vport)
-{
-	const struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
-	return &netdev_vport->dev->NETDEV_DEV_MEMBER.kobj;
-}
-
-unsigned netdev_get_dev_flags(const struct vport *vport)
-{
-	const struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
-	return dev_get_flags(netdev_vport->dev);
-}
-
-int netdev_is_running(const struct vport *vport)
-{
-	const struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
-	return netif_running(netdev_vport->dev);
-}
-
-unsigned char netdev_get_operstate(const struct vport *vport)
-{
-	const struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
-	return netdev_vport->dev->operstate;
-}
-
 int netdev_get_ifindex(const struct vport *vport)
 {
 	const struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
 	return netdev_vport->dev->ifindex;
 }
 
-int netdev_get_mtu(const struct vport *vport)
-{
-	const struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
-	return netdev_vport->dev->mtu;
-}
-
-/* Must be called with rcu_read_lock. */
-static void netdev_port_receive(struct vport *vport, struct sk_buff *skb)
-{
-	if (unlikely(!vport)) {
-		kfree_skb(skb);
-		return;
-	}
-
-	/* Make our own copy of the packet.  Otherwise we will mangle the
-	 * packet for anyone who came before us (e.g. tcpdump via AF_PACKET).
-	 * (No one comes after us, since we tell handle_bridge() that we took
-	 * the packet.) */
-	skb = skb_share_check(skb, GFP_ATOMIC);
-	if (unlikely(!skb))
-		return;
-
-	skb_push(skb, ETH_HLEN);
-
-	if (unlikely(compute_ip_summed(skb, false))) {
-		kfree_skb(skb);
-		return;
-	}
-	vlan_copy_skb_tci(skb);
-
-	vport_receive(vport, skb);
-}
 
 static unsigned packet_length(const struct sk_buff *skb)
 {
@@ -273,19 +141,6 @@ static unsigned packet_length(const struct sk_buff *skb)
 	return length;
 }
 
-static bool dev_supports_vlan_tx(struct net_device *dev)
-{
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
-	/* Software fallback means every device supports vlan_tci on TX. */
-	return true;
-#elif defined(HAVE_VLAN_BUG_WORKAROUND)
-	return dev->features & NETIF_F_HW_VLAN_TX;
-#else
-	/* Assume that the driver is buggy. */
-	return false;
-#endif
-}
-
 static int netdev_send(struct vport *vport, struct sk_buff *skb)
 {
 	struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
@@ -303,64 +158,6 @@ static int netdev_send(struct vport *vport, struct sk_buff *skb)
 		goto error;
 
 	skb->dev = netdev_vport->dev;
-	forward_ip_summed(skb, true);
-
-	if (vlan_tx_tag_present(skb) && !dev_supports_vlan_tx(skb->dev)) {
-		int features;
-
-		features = netif_skb_features(skb);
-
-		if (!vlan_tso)
-			features &= ~(NETIF_F_TSO | NETIF_F_TSO6 |
-				      NETIF_F_UFO | NETIF_F_FSO);
-
-		if (netif_needs_gso(skb, features)) {
-			struct sk_buff *nskb;
-
-			nskb = skb_gso_segment(skb, features);
-			if (!nskb) {
-				if (unlikely(skb_cloned(skb) &&
-				    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) {
-					kfree_skb(skb);
-					return 0;
-				}
-
-				skb_shinfo(skb)->gso_type &= ~SKB_GSO_DODGY;
-				goto tag;
-			}
-
-			if (IS_ERR(nskb)) {
-				kfree_skb(skb);
-				return 0;
-			}
-			consume_skb(skb);
-			skb = nskb;
-
-			len = 0;
-			do {
-				nskb = skb->next;
-				skb->next = NULL;
-
-				skb = __vlan_put_tag(skb, vlan_tx_tag_get(skb));
-				if (likely(skb)) {
-					len += skb->len;
-					vlan_set_tci(skb, 0);
-					dev_queue_xmit(skb);
-				}
-
-				skb = nskb;
-			} while (skb);
-
-			return len;
-		}
-
-tag:
-		skb = __vlan_put_tag(skb, vlan_tx_tag_get(skb));
-		if (unlikely(!skb))
-			return 0;
-		vlan_set_tci(skb, 0);
-	}
-
 	len = skb->len;
 	dev_queue_xmit(skb);
 
@@ -375,54 +172,19 @@ error:
 /* Returns null if this device is not attached to a datapath. */
 struct vport *netdev_get_vport(struct net_device *dev)
 {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
-#if IFF_BRIDGE_PORT != IFF_OVS_DATAPATH
 	if (likely(dev->priv_flags & IFF_OVS_DATAPATH))
-#else
-	if (likely(rcu_access_pointer(dev->rx_handler) == netdev_frame_hook))
-#endif
-		return (struct vport *)rcu_dereference_rtnl(dev->rx_handler_data);
+		return (struct vport *)
+			rcu_dereference_rtnl(dev->rx_handler_data);
 	else
 		return NULL;
-#else
-	return (struct vport *)rcu_dereference_rtnl(dev->br_port);
-#endif
 }
 
 const struct vport_ops netdev_vport_ops = {
 	.type		= OVS_VPORT_TYPE_NETDEV,
-	.flags          = VPORT_F_REQUIRED,
-	.init		= netdev_init,
-	.exit		= netdev_exit,
 	.create		= netdev_create,
 	.destroy	= netdev_destroy,
-	.set_addr	= netdev_set_addr,
 	.get_name	= netdev_get_name,
-	.get_addr	= netdev_get_addr,
-	.get_kobj	= netdev_get_kobj,
-	.get_dev_flags	= netdev_get_dev_flags,
-	.is_running	= netdev_is_running,
-	.get_operstate	= netdev_get_operstate,
 	.get_ifindex	= netdev_get_ifindex,
-	.get_mtu	= netdev_get_mtu,
 	.send		= netdev_send,
 };
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
-/*
- * In kernels earlier than 2.6.36, Open vSwitch cannot safely coexist with
- * the Linux bridge module on any released version of Linux, because there
- * is only a single bridge hook function and only a single br_port member
- * in struct net_device.
- *
- * Declaring and exporting this symbol enforces mutual exclusion.  The bridge
- * module also exports the same symbol, so the module loader will refuse to
- * load both modules at the same time (e.g. "bridge: exports duplicate symbol
- * br_should_route_hook (owned by openvswitch_mod)").
- *
- * The use of "typeof" here avoids the need to track changes in the type of
- * br_should_route_hook over various kernel versions.
- */
-typeof(br_should_route_hook) br_should_route_hook;
-EXPORT_SYMBOL(br_should_route_hook);
-#endif
diff --git a/net/openvswitch/vport-netdev.h b/net/openvswitch/vport-netdev.h
index 9b138be..09136e8 100644
--- a/net/openvswitch/vport-netdev.h
+++ b/net/openvswitch/vport-netdev.h
@@ -25,15 +25,8 @@ netdev_vport_priv(const struct vport *vport)
 	return vport_priv(vport);
 }
 
-int netdev_set_addr(struct vport *, const unsigned char *addr);
 const char *netdev_get_name(const struct vport *);
-const unsigned char *netdev_get_addr(const struct vport *);
 const char *netdev_get_config(const struct vport *);
-struct kobject *netdev_get_kobj(const struct vport *);
-unsigned netdev_get_dev_flags(const struct vport *);
-int netdev_is_running(const struct vport *);
-unsigned char netdev_get_operstate(const struct vport *);
 int netdev_get_ifindex(const struct vport *);
-int netdev_get_mtu(const struct vport *);
 
 #endif /* vport_netdev.h */
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
index a6b686c..402258b 100644
--- a/net/openvswitch/vport.c
+++ b/net/openvswitch/vport.c
@@ -27,11 +27,6 @@
 static const struct vport_ops *base_vport_ops_list[] = {
 	&netdev_vport_ops,
 	&internal_vport_ops,
-	&patch_vport_ops,
-	&gre_vport_ops,
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
-	&capwap_vport_ops,
-#endif
 };
 
 static const struct vport_ops **vport_ops_list;
@@ -76,7 +71,7 @@ int vport_init(void)
 
 		if (!err)
 			vport_ops_list[n_vport_types++] = new_ops;
-		else if (new_ops->flags & VPORT_F_REQUIRED) {
+		else {
 			vport_exit();
 			goto error;
 		}
@@ -135,19 +130,6 @@ struct vport *vport_locate(const char *name)
 	return NULL;
 }
 
-static void release_vport(struct kobject *kobj)
-{
-	struct vport *p = container_of(kobj, struct vport, kobj);
-	kfree(p);
-}
-
-static struct kobj_type brport_ktype = {
-#ifdef CONFIG_SYSFS
-	.sysfs_ops = &brport_sysfs_ops,
-#endif
-	.release = release_vport
-};
-
 /**
  *	vport_alloc - allocate and initialize new vport
  *
@@ -180,11 +162,6 @@ struct vport *vport_alloc(int priv_size, const struct vport_ops *ops,
 	vport->upcall_pid = parms->upcall_pid;
 	vport->ops = ops;
 
-	/* Initialize kobject for bridge.  This will be added as
-	 * /sys/class/net/<devname>/brport later, if sysfs is enabled. */
-	vport->kobj.kset = NULL;
-	kobject_init(&vport->kobj, &brport_ktype);
-
 	vport->percpu_stats = alloc_percpu(struct vport_percpu_stats);
 	if (!vport->percpu_stats)
 		return ERR_PTR(-ENOMEM);
@@ -207,8 +184,7 @@ struct vport *vport_alloc(int priv_size, const struct vport_ops *ops,
 void vport_free(struct vport *vport)
 {
 	free_percpu(vport->percpu_stats);
-
-	kobject_put(&vport->kobj);
+	kfree(vport);
 }
 
 /**
@@ -283,51 +259,6 @@ void vport_del(struct vport *vport)
 }
 
 /**
- *	vport_set_addr - set device Ethernet address (for kernel callers)
- *
- * @vport: vport on which to set Ethernet address.
- * @addr: New address.
- *
- * Sets the Ethernet address of the given device.  Some devices may not support
- * setting the Ethernet address, in which case the result will always be
- * -EOPNOTSUPP.  RTNL lock must be held.
- */
-int vport_set_addr(struct vport *vport, const unsigned char *addr)
-{
-	ASSERT_RTNL();
-
-	if (!is_valid_ether_addr(addr))
-		return -EADDRNOTAVAIL;
-
-	if (vport->ops->set_addr)
-		return vport->ops->set_addr(vport, addr);
-	else
-		return -EOPNOTSUPP;
-}
-
-/**
- *	vport_set_stats - sets offset device stats
- *
- * @vport: vport on which to set stats
- * @stats: stats to set
- *
- * Provides a set of transmit, receive, and error stats to be added as an
- * offset to the collect data when stats are retreived.  Some devices may not
- * support setting the stats, in which case the result will always be
- * -EOPNOTSUPP.
- *
- * Must be called with RTNL lock.
- */
-void vport_set_stats(struct vport *vport, struct ovs_vport_stats *stats)
-{
-	ASSERT_RTNL();
-
-	spin_lock_bh(&vport->stats_lock);
-	vport->offset_stats = *stats;
-	spin_unlock_bh(&vport->stats_lock);
-}
-
-/**
  *	vport_get_stats - retrieve device stats
  *
  * @vport: vport from which to retrieve the stats
@@ -341,25 +272,23 @@ void vport_get_stats(struct vport *vport, struct ovs_vport_stats *stats)
 {
 	int i;
 
-	/* We potentially have 3 sources of stats that need to be
-	 * combined: those we have collected (split into err_stats and
-	 * percpu_stats), offset_stats from set_stats(), and device
-	 * error stats from netdev->get_stats() (for errors that happen
-	 * downstream and therefore aren't reported through our
-	 * vport_record_error() function).
-	 * Stats from first two sources are merged and reported by ovs over
-	 * OVS_VPORT_ATTR_STATS.
+	memset(stats, 0, sizeof(*stats));
+
+	/* We potentially have 2 sources of stats that need to be combined:
+	 * those we have collected (split into err_stats and percpu_stats) from
+	 * set_stats() and device error stats from netdev->get_stats() (for
+	 * errors that happen  downstream and therefore aren't reported through
+	 * our vport_record_error() function).
+	 * Stats from first source are reported by ovs (OVS_VPORT_ATTR_STATS).
 	 * netdev-stats can be directly read over netlink-ioctl.
 	 */
 
 	spin_lock_bh(&vport->stats_lock);
 
-	*stats = vport->offset_stats;
-
-	stats->rx_errors	+= vport->err_stats.rx_errors;
-	stats->tx_errors	+= vport->err_stats.tx_errors;
-	stats->tx_dropped	+= vport->err_stats.tx_dropped;
-	stats->rx_dropped	+= vport->err_stats.rx_dropped;
+	stats->rx_errors	= vport->err_stats.rx_errors;
+	stats->tx_errors	= vport->err_stats.tx_errors;
+	stats->tx_dropped	= vport->err_stats.tx_dropped;
+	stats->rx_dropped	= vport->err_stats.rx_dropped;
 
 	spin_unlock_bh(&vport->stats_lock);
 
@@ -439,11 +368,7 @@ void vport_receive(struct vport *vport, struct sk_buff *skb)
 	stats->rx_bytes += skb->len;
 	write_seqcount_end(&stats->seqlock);
 
-	if (!(vport->ops->flags & VPORT_F_FLOW))
-		OVS_CB(skb)->flow = NULL;
-
-	if (!(vport->ops->flags & VPORT_F_TUN_ID))
-		OVS_CB(skb)->tun_id = 0;
+	OVS_CB(skb)->flow = NULL;
 
 	dp_process_received_packet(vport, skb);
 }
diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h
index 3dbc68f..b75d387 100644
--- a/net/openvswitch/vport.h
+++ b/net/openvswitch/vport.h
@@ -30,8 +30,6 @@ void vport_del(struct vport *);
 
 struct vport *vport_locate(const char *name);
 
-int vport_set_addr(struct vport *, const unsigned char *);
-void vport_set_stats(struct vport *, struct ovs_vport_stats *);
 void vport_get_stats(struct vport *, struct ovs_vport_stats *);
 
 int vport_set_options(struct vport *, struct nlattr *options);
@@ -61,27 +59,19 @@ struct vport_err_stats {
  * @rcu: RCU callback head for deferred destruction.
  * @port_no: Index into @dp's @ports array.
  * @dp: Datapath to which this port belongs.
- * @kobj: Represents /sys/class/net/<devname>/brport.
- * @linkname: The name of the link from /sys/class/net/<datapath>/brif to this
- * &struct vport.  (We keep this around so that we can delete it if the
- * device gets renamed.)  Set to the null string when no link exists.
  * @node: Element in @dp's @port_list.
  * @upcall_pid: The Netlink port to use for packets received on this port that
  * miss the flow table.
  * @hash_node: Element in @dev_table hash table in vport.c.
  * @ops: Class structure.
  * @percpu_stats: Points to per-CPU statistics used and maintained by vport
- * @stats_lock: Protects @err_stats and @offset_stats.
+ * @stats_lock: Protects @err_stats;
  * @err_stats: Points to error statistics used and maintained by vport
- * @offset_stats: Added to actual statistics as a sop to compatibility with
- * XAPI for Citrix XenServer.  Deprecated.
  */
 struct vport {
 	struct rcu_head rcu;
 	u16 port_no;
 	struct datapath	*dp;
-	struct kobject kobj;
-	char linkname[IFNAMSIZ];
 	struct list_head node;
 	u32 upcall_pid;
 
@@ -92,13 +82,8 @@ struct vport {
 
 	spinlock_t stats_lock;
 	struct vport_err_stats err_stats;
-	struct ovs_vport_stats offset_stats;
 };
 
-#define VPORT_F_REQUIRED	(1 << 0) /* If init fails, module loading fails. */
-#define VPORT_F_FLOW		(1 << 1) /* Sets OVS_CB(skb)->flow. */
-#define VPORT_F_TUN_ID		(1 << 2) /* Sets OVS_CB(skb)->tun_id. */
-
 /**
  * struct vport_parms - parameters for creating a new vport
  *
@@ -124,11 +109,7 @@ struct vport_parms {
  * struct vport_ops - definition of a type of virtual port
  *
  * @type: %OVS_VPORT_TYPE_* value for this type of virtual port.
- * @flags: Flags of type VPORT_F_* that influence how the generic vport layer
- * handles this vport.
- * @init: Called at module initialization.  If VPORT_F_REQUIRED is set then the
- * failure of this function will cause the module to not load.  If the flag is
- * not set and initialzation fails then no vports of this type can be created.
+ * @init: Called at module initialization.
  * @exit: Called at module unload.
  * @create: Create a new vport configured as specified.  On success returns
  * a new vport allocated with vport_alloc(), otherwise an ERR_PTR() value.
@@ -139,24 +120,14 @@ struct vport_parms {
  * @get_options: Appends vport-specific attributes for the configuration of an
  * existing vport to a &struct sk_buff.  May be %NULL for a vport that does not
  * have any configuration.
- * @set_addr: Set the device's MAC address.  May be null if not supported.
  * @get_name: Get the device's name.
- * @get_addr: Get the device's MAC address.
  * @get_config: Get the device's configuration.
- * @get_kobj: Get the kobj associated with the device (may return null).
- * @get_dev_flags: Get the device's flags.
- * @is_running: Checks whether the device is running.
- * @get_operstate: Get the device's operating state.
  * @get_ifindex: Get the system interface index associated with the device.
  * May be null if the device does not have an ifindex.
- * @get_mtu: Get the device's MTU.  May be %NULL if the device does not have an
- * MTU (as e.g. some tunnels do not).  Must be implemented if @get_ifindex is
- * implemented.
  * @send: Send a packet on the device.  Returns the length of the packet sent.
  */
 struct vport_ops {
 	enum ovs_vport_type type;
-	u32 flags;
 
 	/* Called at module init and exit respectively. */
 	int (*init)(void);
@@ -169,22 +140,11 @@ struct vport_ops {
 	int (*set_options)(struct vport *, struct nlattr *);
 	int (*get_options)(const struct vport *, struct sk_buff *);
 
-	int (*set_addr)(struct vport *, const unsigned char *);
-
 	/* Called with rcu_read_lock or RTNL lock. */
 	const char *(*get_name)(const struct vport *);
-	const unsigned char *(*get_addr)(const struct vport *);
 	void (*get_config)(const struct vport *, void *);
-	struct kobject *(*get_kobj)(const struct vport *);
-
-	unsigned (*get_dev_flags)(const struct vport *);
-	int (*is_running)(const struct vport *);
-	unsigned char (*get_operstate)(const struct vport *);
-
 	int (*get_ifindex)(const struct vport *);
 
-	int (*get_mtu)(const struct vport *);
-
 	int (*send)(struct vport *, struct sk_buff *);
 };
 
@@ -237,8 +197,5 @@ void vport_record_error(struct vport *, enum vport_err_type err_type);
  * add yours to the list at the top of vport.c. */
 extern const struct vport_ops netdev_vport_ops;
 extern const struct vport_ops internal_vport_ops;
-extern const struct vport_ops patch_vport_ops;
-extern const struct vport_ops gre_vport_ops;
-extern const struct vport_ops capwap_vport_ops;
 
 #endif /* vport.h */
-- 
1.7.1




More information about the dev mailing list