X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=datapath%2Fdatapath.c;h=a964c27f469e3618d854f47ff9da9068c40ea900;hb=d1993ffea5d91f28f39838e8bcb1c67bc6bec790;hp=826d8991eb2f371b5d17d0ba143d4297057ee64c;hpb=b2fda3effc787f265b5ad5dfa967ac00627bd075;p=openvswitch diff --git a/datapath/datapath.c b/datapath/datapath.c index 826d8991..a964c27f 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -53,6 +53,11 @@ #include "vlan.h" #include "vport-internal_dev.h" +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) || \ + LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0) +#error Kernels before 2.6.18 or after 3.0 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); @@ -79,7 +84,7 @@ EXPORT_SYMBOL(dp_ioctl_hook); static LIST_HEAD(dps); static struct vport *new_vport(const struct vport_parms *); -static int queue_control_packets(struct datapath *, struct sk_buff *, +static int queue_userspace_packets(struct datapath *, struct sk_buff *, const struct dp_upcall_info *); /* Must be called with rcu_read_lock, genl_mutex, or RTNL lock. */ @@ -284,7 +289,7 @@ void dp_process_received_packet(struct vport *p, struct sk_buff *skb) } if (is_frag && dp->drop_frags) { - kfree_skb(skb); + consume_skb(skb); stats_counter_off = offsetof(struct dp_stats_percpu, n_frags); goto out; } @@ -394,33 +399,28 @@ int dp_upcall(struct datapath *dp, struct sk_buff *skb, const struct dp_upcall_i WARN_ON_ONCE(skb_shared(skb)); - forward_ip_summed(skb); - - err = vswitch_skb_checksum_setup(skb); - if (err) - goto err_kfree_skb; + forward_ip_summed(skb, true); /* Break apart GSO packets into their component pieces. Otherwise * userspace may try to stuff a 64kB packet into a 1500-byte MTU. */ if (skb_is_gso(skb)) { struct sk_buff *nskb = skb_gso_segment(skb, NETIF_F_SG | NETIF_F_HW_CSUM); - kfree_skb(skb); - skb = nskb; - if (IS_ERR(skb)) { - err = PTR_ERR(skb); + if (IS_ERR(nskb)) { + kfree_skb(skb); + err = PTR_ERR(nskb); goto err; } + consume_skb(skb); + skb = nskb; } - err = queue_control_packets(dp, skb, upcall_info); + err = queue_userspace_packets(dp, skb, upcall_info); if (err) goto err; return 0; -err_kfree_skb: - kfree_skb(skb); err: local_bh_disable(); stats = per_cpu_ptr(dp->stats_percpu, smp_processor_id()); @@ -438,7 +438,7 @@ err: * 'upcall_info'. There will be only one packet unless we broke up a GSO * packet. */ -static int queue_control_packets(struct datapath *dp, struct sk_buff *skb, +static int queue_userspace_packets(struct datapath *dp, struct sk_buff *skb, const struct dp_upcall_info *upcall_info) { u32 group = packet_mc_group(dp, upcall_info->cmd); @@ -507,7 +507,7 @@ static int queue_control_packets(struct datapath *dp, struct sk_buff *skb, if (err) goto err_kfree_skbs; - kfree_skb(skb); + consume_skb(skb); skb = nskb; } while (skb); return 0; @@ -552,7 +552,7 @@ static int validate_actions(const struct nlattr *attr) nla_for_each_nested(a, attr, rem) { static const u32 action_lens[ODP_ACTION_ATTR_MAX + 1] = { [ODP_ACTION_ATTR_OUTPUT] = 4, - [ODP_ACTION_ATTR_CONTROLLER] = 8, + [ODP_ACTION_ATTR_USERSPACE] = 8, [ODP_ACTION_ATTR_SET_DL_TCI] = 2, [ODP_ACTION_ATTR_STRIP_VLAN] = 0, [ODP_ACTION_ATTR_SET_DL_SRC] = ETH_ALEN, @@ -565,7 +565,6 @@ static int validate_actions(const struct nlattr *attr) [ODP_ACTION_ATTR_SET_TUNNEL] = 8, [ODP_ACTION_ATTR_SET_PRIORITY] = 4, [ODP_ACTION_ATTR_POP_PRIORITY] = 0, - [ODP_ACTION_ATTR_DROP_SPOOFED_ARP] = 0, }; int type = nla_type(a); @@ -576,7 +575,7 @@ static int validate_actions(const struct nlattr *attr) case ODP_ACTION_ATTR_UNSPEC: return -EINVAL; - case ODP_ACTION_ATTR_CONTROLLER: + case ODP_ACTION_ATTR_USERSPACE: case ODP_ACTION_ATTR_STRIP_VLAN: case ODP_ACTION_ATTR_SET_DL_SRC: case ODP_ACTION_ATTR_SET_DL_DST: @@ -587,7 +586,6 @@ static int validate_actions(const struct nlattr *attr) case ODP_ACTION_ATTR_SET_TUNNEL: case ODP_ACTION_ATTR_SET_PRIORITY: case ODP_ACTION_ATTR_POP_PRIORITY: - case ODP_ACTION_ATTR_DROP_SPOOFED_ARP: /* No validation needed. */ break; @@ -655,7 +653,8 @@ static int odp_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info) int key_len; err = -EINVAL; - if (!a[ODP_PACKET_ATTR_PACKET] || !a[ODP_PACKET_ATTR_ACTIONS] || + if (!a[ODP_PACKET_ATTR_PACKET] || !a[ODP_PACKET_ATTR_KEY] || + !a[ODP_PACKET_ATTR_ACTIONS] || nla_len(a[ODP_PACKET_ATTR_PACKET]) < ETH_HLEN) goto err; @@ -694,6 +693,12 @@ static int odp_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info) goto err_flow_put; flow->tbl_node.hash = flow_hash(&flow->key, key_len); + err = flow_metadata_from_nlattrs(&flow->key.eth.in_port, + &flow->key.eth.tun_id, + a[ODP_PACKET_ATTR_KEY]); + if (err) + goto err_flow_put; + acts = flow_actions_alloc(a[ODP_PACKET_ATTR_ACTIONS]); err = PTR_ERR(acts); if (IS_ERR(acts)) @@ -725,6 +730,7 @@ err: static const struct nla_policy packet_policy[ODP_PACKET_ATTR_MAX + 1] = { [ODP_PACKET_ATTR_PACKET] = { .type = NLA_UNSPEC }, + [ODP_PACKET_ATTR_KEY] = { .type = NLA_NESTED }, [ODP_PACKET_ATTR_ACTIONS] = { .type = NLA_NESTED }, }; @@ -1904,7 +1910,9 @@ static int odp_vport_cmd_get(struct sk_buff *skb, struct genl_info *info) if (IS_ERR(reply)) goto exit_unlock; - err = genlmsg_reply(reply, info); + rcu_read_unlock(); + + return genlmsg_reply(reply, info); exit_unlock: rcu_read_unlock();