rhel: openvswitch.spec.in: fix perms on logrotate and sysconfig.template
[sliver-openvswitch.git] / datapath / actions.c
index 61b903f..824791d 100644 (file)
@@ -1,13 +1,21 @@
 /*
- * Distributed under the terms of the GNU GPL version 2.
- * Copyright (c) 2007, 2008, 2009, 2010, 2011 Nicira Networks.
+ * Copyright (c) 2007-2011 Nicira Networks.
  *
- * Significant portions of this file may be copied from parts of the Linux
- * kernel, by Linus Torvalds and others.
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA
  */
 
-/* Functions for executing flow actions. */
-
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 
 #include <linux/skbuff.h>
@@ -23,7 +31,6 @@
 #include <net/checksum.h>
 #include <net/dsfield.h>
 
-#include "actions.h"
 #include "checksum.h"
 #include "datapath.h"
 #include "vlan.h"
@@ -43,8 +50,7 @@ static int make_writable(struct sk_buff *skb, int write_len)
 /* remove VLAN header from packet and update csum accrodingly. */
 static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci)
 {
-       struct ethhdr *eh;
-       struct vlan_ethhdr *veth;
+       struct vlan_hdr *vhdr;
        int err;
 
        err = make_writable(skb, VLAN_ETH_HLEN);
@@ -55,15 +61,15 @@ static int __pop_vlan_tci(struct sk_buff *skb, __be16 *current_tci)
                skb->csum = csum_sub(skb->csum, csum_partial(skb->data
                                        + ETH_HLEN, VLAN_HLEN, 0));
 
-       veth = (struct vlan_ethhdr *) skb->data;
-       *current_tci = veth->h_vlan_TCI;
+       vhdr = (struct vlan_hdr *)(skb->data + ETH_HLEN);
+       *current_tci = vhdr->h_vlan_TCI;
 
        memmove(skb->data + VLAN_HLEN, skb->data, 2 * ETH_ALEN);
+       __skb_pull(skb, VLAN_HLEN);
 
-       eh = (struct ethhdr *)__skb_pull(skb, VLAN_HLEN);
-
-       skb->protocol = eh->h_proto;
+       vlan_set_encap_proto(skb, vhdr);
        skb->mac_header += VLAN_HLEN;
+       skb_reset_mac_len(skb);
 
        return 0;
 }
@@ -97,7 +103,7 @@ static int pop_vlan(struct sk_buff *skb)
        return 0;
 }
 
-static int push_vlan(struct sk_buff *skb, const struct ovs_key_8021q *q_key)
+static int push_vlan(struct sk_buff *skb, const struct ovs_action_push_vlan *vlan)
 {
        if (unlikely(vlan_tx_tag_present(skb))) {
                u16 current_tag;
@@ -113,7 +119,7 @@ static int push_vlan(struct sk_buff *skb, const struct ovs_key_8021q *q_key)
                                        + ETH_HLEN, VLAN_HLEN, 0));
 
        }
-       __vlan_hwaccel_put_tag(skb, ntohs(q_key->q_tci));
+       __vlan_hwaccel_put_tag(skb, ntohs(vlan->vlan_tci) & ~VLAN_TAG_PRESENT);
        return 0;
 }
 
@@ -125,8 +131,8 @@ static int set_eth_addr(struct sk_buff *skb,
        if (unlikely(err))
                return err;
 
-       memcpy(eth_hdr(skb)->h_source, eth_key->eth_src, ETH_HLEN);
-       memcpy(eth_hdr(skb)->h_dest, eth_key->eth_dst, ETH_HLEN);
+       memcpy(eth_hdr(skb)->h_source, eth_key->eth_src, ETH_ALEN);
+       memcpy(eth_hdr(skb)->h_dest, eth_key->eth_dst, ETH_ALEN);
 
        return 0;
 }
@@ -248,7 +254,7 @@ static int do_output(struct datapath *dp, struct sk_buff *skb, int out_port)
                return -ENODEV;
        }
 
-       vport_send(vport, skb);
+       ovs_vport_send(vport, skb);
        return 0;
 }
 
@@ -277,7 +283,7 @@ static int output_userspace(struct datapath *dp, struct sk_buff *skb,
                }
        }
 
-       return dp_upcall(dp, skb, &upcall);
+       return ovs_dp_upcall(dp, skb, &upcall);
 }
 
 static int sample(struct datapath *dp, struct sk_buff *skb,
@@ -369,15 +375,13 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
                        output_userspace(dp, skb, a);
                        break;
 
-               case OVS_ACTION_ATTR_PUSH:
-                       /* Only supported push action is on vlan tag. */
-                       err = push_vlan(skb, nla_data(nla_data(a)));
+               case OVS_ACTION_ATTR_PUSH_VLAN:
+                       err = push_vlan(skb, nla_data(a));
                        if (unlikely(err)) /* skb already freed. */
                                return err;
                        break;
 
-               case OVS_ACTION_ATTR_POP:
-                       /* Only supported pop action is on vlan tag. */
+               case OVS_ACTION_ATTR_POP_VLAN:
                        err = pop_vlan(skb);
                        break;
 
@@ -422,13 +426,13 @@ static int loop_suppress(struct datapath *dp, struct sw_flow_actions *actions)
 {
        if (net_ratelimit())
                pr_warn("%s: flow looped %d times, dropping\n",
-                               dp_name(dp), MAX_LOOPS);
+                               ovs_dp_name(dp), MAX_LOOPS);
        actions->actions_len = 0;
        return -ELOOP;
 }
 
 /* Execute a list of actions against 'skb'. */
-int execute_actions(struct datapath *dp, struct sk_buff *skb)
+int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb)
 {
        struct sw_flow_actions *acts = rcu_dereference(OVS_CB(skb)->flow->sf_acts);
        struct loop_counter *loop;