datapath: net: add ETH_P_802_3_MIN
[sliver-openvswitch.git] / datapath / datapath.c
index a40ff47..bab29d2 100644 (file)
@@ -201,41 +201,37 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb)
        struct datapath *dp = p->dp;
        struct sw_flow *flow;
        struct dp_stats_percpu *stats;
+       struct sw_flow_key key;
        u64 *stats_counter;
        int error;
+       int key_len;
 
        stats = this_cpu_ptr(dp->stats_percpu);
 
-       if (!OVS_CB(skb)->flow) {
-               struct sw_flow_key key;
-               int key_len;
-
-               /* Extract flow from 'skb' into 'key'. */
-               error = ovs_flow_extract(skb, p->port_no, &key, &key_len);
-               if (unlikely(error)) {
-                       kfree_skb(skb);
-                       return;
-               }
-
-               /* Look up flow. */
-               flow = ovs_flow_tbl_lookup(rcu_dereference(dp->table),
-                                          &key, key_len);
-               if (unlikely(!flow)) {
-                       struct dp_upcall_info upcall;
-
-                       upcall.cmd = OVS_PACKET_CMD_MISS;
-                       upcall.key = &key;
-                       upcall.userdata = NULL;
-                       upcall.portid = p->upcall_portid;
-                       ovs_dp_upcall(dp, skb, &upcall);
-                       consume_skb(skb);
-                       stats_counter = &stats->n_missed;
-                       goto out;
-               }
+       /* Extract flow from 'skb' into 'key'. */
+       error = ovs_flow_extract(skb, p->port_no, &key, &key_len);
+       if (unlikely(error)) {
+               kfree_skb(skb);
+               return;
+       }
 
-               OVS_CB(skb)->flow = flow;
+       /* Look up flow. */
+       flow = ovs_flow_tbl_lookup(rcu_dereference(dp->table), &key, key_len);
+       if (unlikely(!flow)) {
+               struct dp_upcall_info upcall;
+
+               upcall.cmd = OVS_PACKET_CMD_MISS;
+               upcall.key = &key;
+               upcall.userdata = NULL;
+               upcall.portid = p->upcall_portid;
+               ovs_dp_upcall(dp, skb, &upcall);
+               consume_skb(skb);
+               stats_counter = &stats->n_missed;
+               goto out;
        }
 
+       OVS_CB(skb)->flow = flow;
+
        stats_counter = &stats->n_hit;
        ovs_flow_used(OVS_CB(skb)->flow, skb);
        ovs_execute_actions(dp, skb);
@@ -838,7 +834,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
        /* Normally, setting the skb 'protocol' field would be handled by a
         * call to eth_type_trans(), but it assumes there's a sending
         * device, which we may not have. */
-       if (ntohs(eth->h_proto) >= 1536)
+       if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN)
                packet->protocol = eth->h_proto;
        else
                packet->protocol = htons(ETH_P_802_2);
@@ -1860,10 +1856,8 @@ struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, u32 portid,
                return ERR_PTR(-ENOMEM);
 
        retval = ovs_vport_cmd_fill_info(vport, skb, portid, seq, 0, cmd);
-       if (retval < 0) {
-               kfree_skb(skb);
-               return ERR_PTR(retval);
-       }
+       BUG_ON(retval < 0);
+
        return skb;
 }
 
@@ -2009,10 +2003,16 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
            nla_get_u32(a[OVS_VPORT_ATTR_TYPE]) != vport->ops->type)
                err = -EINVAL;
 
+       reply = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+       if (!reply) {
+               err = -ENOMEM;
+               goto exit_unlock;
+       }
+
        if (!err && a[OVS_VPORT_ATTR_OPTIONS])
                err = ovs_vport_set_options(vport, a[OVS_VPORT_ATTR_OPTIONS]);
        if (err)
-               goto exit_unlock;
+               goto exit_free;
 
        if (a[OVS_VPORT_ATTR_STATS])
                ovs_vport_set_stats(vport, nla_data(a[OVS_VPORT_ATTR_STATS]));
@@ -2020,17 +2020,18 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
        if (a[OVS_VPORT_ATTR_UPCALL_PID])
                vport->upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]);
 
-       reply = ovs_vport_cmd_build_info(vport, info->snd_portid,
-                                        info->snd_seq, OVS_VPORT_CMD_NEW);
-       if (IS_ERR(reply)) {
-               netlink_set_err(GENL_SOCK(sock_net(skb->sk)), 0,
-                               ovs_dp_vport_multicast_group.id, PTR_ERR(reply));
-               goto exit_unlock;
-       }
+       err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid,
+                                     info->snd_seq, 0, OVS_VPORT_CMD_NEW);
+       BUG_ON(err < 0);
 
        genl_notify(reply, genl_info_net(info), info->snd_portid,
                    ovs_dp_vport_multicast_group.id, info->nlhdr, GFP_KERNEL);
 
+       rtnl_unlock();
+       return 0;
+
+exit_free:
+       kfree_skb(reply);
 exit_unlock:
        rtnl_unlock();
 exit: