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 <pshe...@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 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev