datapath: Use tun_info only for egress tunnel path.
authorPravin B Shelar <pshelar@nicira.com>
Tue, 5 Aug 2014 20:49:57 +0000 (13:49 -0700)
committerPravin B Shelar <pshelar@nicira.com>
Thu, 7 Aug 2014 05:12:25 +0000 (22:12 -0700)
Currently tun_info is used for passing tunnel information
on ingress and egress path, this cause confusion.  Following
patch removes its use on ingress path make it egress only parameter.

Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Acked-by: Andy Zhou <azhou@nicira.com>
datapath/actions.c
datapath/datapath.c
datapath/datapath.h
datapath/flow.c
datapath/flow.h
datapath/vport-geneve.c
datapath/vport-gre.c
datapath/vport-lisp.c
datapath/vport-vxlan.c
datapath/vport.c

index 6de65d3..efc64f1 100644 (file)
@@ -610,7 +610,7 @@ static int execute_set_action(struct sk_buff *skb,
                break;
 
        case OVS_KEY_ATTR_TUNNEL_INFO:
-               OVS_CB(skb)->tun_info = nla_data(nested_attr);
+               OVS_CB(skb)->egress_tun_info = nla_data(nested_attr);
                break;
 
        case OVS_KEY_ATTR_ETHERNET:
@@ -646,7 +646,7 @@ static int execute_set_action(struct sk_buff *skb,
 }
 
 static int execute_recirc(struct datapath *dp, struct sk_buff *skb,
-                                const struct nlattr *a)
+                         const struct nlattr *a)
 {
        struct sw_flow_key recirc_key;
        int err;
@@ -658,8 +658,7 @@ static int execute_recirc(struct datapath *dp, struct sk_buff *skb,
                return err;
        }
 
-
-       ovs_dp_process_packet_with_key(skb, &recirc_key, true);
+       ovs_dp_process_packet(skb, true);
 
        return 0;
 }
@@ -807,7 +806,6 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb, bool recirc)
                goto out_loop;
        }
 
-       OVS_CB(skb)->tun_info = NULL;
        error = do_execute_actions(dp, skb, acts->actions, acts->actions_len);
 
        /* Check whether sub-actions looped too much. */
index 91c65a0..19d41c8 100644 (file)
@@ -250,11 +250,11 @@ void ovs_dp_detach_port(struct vport *p)
        ovs_vport_del(p);
 }
 
-void ovs_dp_process_packet_with_key(struct sk_buff *skb,
-                                   struct sw_flow_key *pkt_key,
-                                   bool recirc)
+/* Must be called with rcu_read_lock. */
+void ovs_dp_process_packet(struct sk_buff *skb, bool recirc)
 {
        const struct vport *p = OVS_CB(skb)->input_vport;
+       struct sw_flow_key *pkt_key = OVS_CB(skb)->pkt_key;
        struct datapath *dp = p->dp;
        struct sw_flow *flow;
        struct dp_stats_percpu *stats;
@@ -262,7 +262,6 @@ void ovs_dp_process_packet_with_key(struct sk_buff *skb,
        u32 n_mask_hit;
 
        stats = this_cpu_ptr(dp->stats_percpu);
-       OVS_CB(skb)->pkt_key = pkt_key;
 
        /* Look up flow. */
        flow = ovs_flow_tbl_lookup_stats(&dp->table, pkt_key, skb_get_hash(skb),
@@ -293,22 +292,6 @@ out:
        u64_stats_update_end(&stats->sync);
 }
 
-/* Must be called with rcu_read_lock. */
-void ovs_dp_process_received_packet(struct sk_buff *skb)
-{
-       int error;
-       struct sw_flow_key key;
-
-       /* Extract flow from 'skb' into 'key'. */
-       error = ovs_flow_key_extract(skb, &key);
-       if (unlikely(error)) {
-               kfree_skb(skb);
-               return;
-       }
-
-       ovs_dp_process_packet_with_key(skb, &key, false);
-}
-
 int ovs_dp_upcall(struct datapath *dp, struct sk_buff *skb,
                  const struct dp_upcall_info *upcall_info)
 {
@@ -599,6 +582,7 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, struct genl_info *info)
 
        OVS_CB(packet)->flow = flow;
        OVS_CB(packet)->pkt_key = &flow->key;
+       OVS_CB(skb)->egress_tun_info = NULL;
        packet->priority = flow->key.phy.priority;
        packet->mark = flow->key.phy.skb_mark;
 
index fb37fa1..cd2acbc 100644 (file)
@@ -98,15 +98,15 @@ struct datapath {
  * struct ovs_skb_cb - OVS data in skb CB
  * @flow: The flow associated with this packet.  May be %NULL if no flow.
  * @pkt_key: The flow information extracted from the packet.  Must be nonnull.
- * @tun_info: Tunnel information about this packet.  NULL if the packet
- * is not being tunneled.
+ * @egress_tun_info: Tunnel information about this packet on egress path.
+ * NULL if the packet is not being tunneled.
  * @input_vport: The original vport packet came in on. This value is cached
  * when a packet is received by OVS.
  */
 struct ovs_skb_cb {
        struct sw_flow          *flow;
        struct sw_flow_key      *pkt_key;
-       struct ovs_tunnel_info  *tun_info;
+       struct ovs_tunnel_info  *egress_tun_info;
        struct vport    *input_vport;
 };
 #define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb)
@@ -188,9 +188,7 @@ extern struct notifier_block ovs_dp_device_notifier;
 extern struct genl_family dp_vport_genl_family;
 extern struct genl_multicast_group ovs_dp_vport_multicast_group;
 
-void ovs_dp_process_received_packet(struct sk_buff *);
-void ovs_dp_process_packet_with_key(struct sk_buff *,
-                                   struct sw_flow_key *pkt_key, bool recirc);
+void ovs_dp_process_packet(struct sk_buff *, bool recirc);
 void ovs_dp_detach_port(struct vport *);
 int ovs_dp_upcall(struct datapath *, struct sk_buff *,
                  const struct dp_upcall_info *);
index 1feca85..d56812a 100644 (file)
@@ -669,16 +669,16 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
                }
        }
 
+       OVS_CB(skb)->pkt_key = key;
        return 0;
 }
 
-int ovs_flow_key_extract(struct sk_buff *skb, struct sw_flow_key *key)
+int ovs_flow_key_extract(const struct ovs_tunnel_info *tun_info,
+                        struct sk_buff *skb,
+                        struct sw_flow_key *key)
 {
        /* Extract metadata from packet. */
-
-       if (OVS_CB(skb)->tun_info) {
-               struct ovs_tunnel_info *tun_info = OVS_CB(skb)->tun_info;
-
+       if (tun_info) {
                memcpy(&key->tun_key, &tun_info->tunnel, sizeof(key->tun_key));
 
                BUILD_BUG_ON(((1 << (sizeof(tun_info->options_len) * 8)) - 1) >
index ee63b8b..106feb8 100644 (file)
@@ -222,7 +222,8 @@ void ovs_flow_stats_get(const struct sw_flow *, struct ovs_flow_stats *,
 void ovs_flow_stats_clear(struct sw_flow *);
 u64 ovs_flow_used_time(unsigned long flow_jiffies);
 
-int ovs_flow_key_extract(struct sk_buff *skb, struct sw_flow_key *key);
+int ovs_flow_key_extract(const struct ovs_tunnel_info *tun_info,
+                        struct sk_buff *skb, struct sw_flow_key *key);
 /* Extract key from packet coming from userspace. */
 int ovs_flow_key_extract_userspace(const struct nlattr *attr,
                                   struct sk_buff *skb,
index 65a996f..b9615e1 100644 (file)
@@ -134,7 +134,7 @@ static void geneve_build_header(const struct vport *vport,
        struct geneve_port *geneve_port = geneve_vport(vport);
        struct udphdr *udph = udp_hdr(skb);
        struct genevehdr *geneveh = (struct genevehdr *)(udph + 1);
-       const struct ovs_tunnel_info *tun_info = OVS_CB(skb)->tun_info;
+       const struct ovs_tunnel_info *tun_info = OVS_CB(skb)->egress_tun_info;
 
        udph->dest = inet_sport(geneve_port->sock->sk);
        udph->source = vxlan_src_port(1, USHRT_MAX, skb);
@@ -363,10 +363,10 @@ static int geneve_send(struct vport *vport, struct sk_buff *skb)
        int sent_len;
        int err;
 
-       if (unlikely(!OVS_CB(skb)->tun_info))
+       if (unlikely(!OVS_CB(skb)->egress_tun_info))
                return -EINVAL;
 
-       tun_key = &OVS_CB(skb)->tun_info->tunnel;
+       tun_key = &OVS_CB(skb)->egress_tun_info->tunnel;
 
        /* Route lookup */
        saddr = tun_key->ipv4_src;
@@ -380,7 +380,8 @@ static int geneve_send(struct vport *vport, struct sk_buff *skb)
        }
 
        min_headroom = LL_RESERVED_SPACE(rt_dst(rt).dev) + rt_dst(rt).header_len
-                       + GENEVE_BASE_HLEN + OVS_CB(skb)->tun_info->options_len
+                       + GENEVE_BASE_HLEN
+                       + OVS_CB(skb)->egress_tun_info->options_len
                        + sizeof(struct iphdr)
                        + (vlan_tx_tag_present(skb) ? VLAN_HLEN : 0);
 
@@ -407,7 +408,8 @@ static int geneve_send(struct vport *vport, struct sk_buff *skb)
 
        skb_reset_inner_headers(skb);
 
-       __skb_push(skb, GENEVE_BASE_HLEN + OVS_CB(skb)->tun_info->options_len);
+       __skb_push(skb, GENEVE_BASE_HLEN +
+                       OVS_CB(skb)->egress_tun_info->options_len);
        skb_reset_transport_header(skb);
 
        geneve_build_header(vport, skb);
index d2a2602..70fce58 100644 (file)
@@ -66,9 +66,10 @@ static struct sk_buff *__build_header(struct sk_buff *skb,
                                      int tunnel_hlen,
                                      __be32 seq, __be16 gre64_flag)
 {
-       const struct ovs_key_ipv4_tunnel *tun_key = &OVS_CB(skb)->tun_info->tunnel;
+       const struct ovs_key_ipv4_tunnel *tun_key;
        struct tnl_ptk_info tpi;
 
+       tun_key = &OVS_CB(skb)->egress_tun_info->tunnel;
        skb = gre_handle_offloads(skb, !!(tun_key->tun_flags & TUNNEL_CSUM));
        if (IS_ERR(skb))
                return NULL;
@@ -140,7 +141,7 @@ static int __send(struct vport *vport, struct sk_buff *skb,
                  int tunnel_hlen,
                  __be32 seq, __be16 gre64_flag)
 {
-       struct ovs_key_ipv4_tunnel *tun_key = &OVS_CB(skb)->tun_info->tunnel;
+       struct ovs_key_ipv4_tunnel *tun_key;
        struct rtable *rt;
        int min_headroom;
        __be16 df;
@@ -148,6 +149,7 @@ static int __send(struct vport *vport, struct sk_buff *skb,
        int err;
 
        /* Route lookup */
+       tun_key = &OVS_CB(skb)->egress_tun_info->tunnel;
        saddr = tun_key->ipv4_src;
        rt = find_route(ovs_dp_get_net(vport->dp),
                        &saddr, tun_key->ipv4_dst,
@@ -284,10 +286,10 @@ static int gre_send(struct vport *vport, struct sk_buff *skb)
 {
        int hlen;
 
-       if (unlikely(!OVS_CB(skb)->tun_info))
+       if (unlikely(!OVS_CB(skb)->egress_tun_info))
                return -EINVAL;
 
-       hlen = ip_gre_calc_hlen(OVS_CB(skb)->tun_info->tunnel.tun_flags);
+       hlen = ip_gre_calc_hlen(OVS_CB(skb)->egress_tun_info->tunnel.tun_flags);
 
        return __send(vport, skb, hlen, 0, 0);
 }
@@ -358,13 +360,13 @@ static int gre64_send(struct vport *vport, struct sk_buff *skb)
                   GRE_HEADER_SECTION;          /* GRE SEQ */
        __be32 seq;
 
-       if (unlikely(!OVS_CB(skb)->tun_info))
+       if (unlikely(!OVS_CB(skb)->egress_tun_info))
                return -EINVAL;
 
-       if (OVS_CB(skb)->tun_info->tunnel.tun_flags & TUNNEL_CSUM)
+       if (OVS_CB(skb)->egress_tun_info->tunnel.tun_flags & TUNNEL_CSUM)
                hlen += GRE_HEADER_SECTION;
 
-       seq = be64_get_high32(OVS_CB(skb)->tun_info->tunnel.tun_id);
+       seq = be64_get_high32(OVS_CB(skb)->egress_tun_info->tunnel.tun_id);
        return __send(vport, skb, hlen, seq, (TUNNEL_KEY|TUNNEL_SEQ));
 }
 
index 81ecf92..cdd325e 100644 (file)
@@ -196,8 +196,9 @@ static void lisp_build_header(const struct vport *vport,
        struct lisp_port *lisp_port = lisp_vport(vport);
        struct udphdr *udph = udp_hdr(skb);
        struct lisphdr *lisph = (struct lisphdr *)(udph + 1);
-       const struct ovs_key_ipv4_tunnel *tun_key = &OVS_CB(skb)->tun_info->tunnel;
+       const struct ovs_key_ipv4_tunnel *tun_key;
 
+       tun_key = &OVS_CB(skb)->egress_tun_info->tunnel;
        udph->dest = lisp_port->dst_port;
        udph->source = htons(get_src_port(net, skb));
        udph->check = 0;
@@ -439,10 +440,10 @@ static int lisp_send(struct vport *vport, struct sk_buff *skb)
        int sent_len;
        int err;
 
-       if (unlikely(!OVS_CB(skb)->tun_info))
+       if (unlikely(!OVS_CB(skb)->egress_tun_info))
                return -EINVAL;
 
-       tun_key = &OVS_CB(skb)->tun_info->tunnel;
+       tun_key = &OVS_CB(skb)->egress_tun_info->tunnel;
 
        if (skb->protocol != htons(ETH_P_IP) &&
            skb->protocol != htons(ETH_P_IPV6)) {
index d93a844..6678400 100644 (file)
@@ -151,12 +151,12 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
        int port_max;
        int err;
 
-       if (unlikely(!OVS_CB(skb)->tun_info)) {
+       if (unlikely(!OVS_CB(skb)->egress_tun_info)) {
                err = -EINVAL;
                goto error;
        }
 
-       tun_key = &OVS_CB(skb)->tun_info->tunnel;
+       tun_key = &OVS_CB(skb)->egress_tun_info->tunnel;
 
        /* Route lookup */
        saddr = tun_key->ipv4_src;
index 5d250aa..18d3803 100644 (file)
@@ -475,6 +475,8 @@ void ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
                       struct ovs_tunnel_info *tun_info)
 {
        struct pcpu_sw_netstats *stats;
+       struct sw_flow_key key;
+       int error;
 
        stats = this_cpu_ptr(vport->percpu_stats);
        u64_stats_update_begin(&stats->syncp);
@@ -483,9 +485,15 @@ void ovs_vport_receive(struct vport *vport, struct sk_buff *skb,
        u64_stats_update_end(&stats->syncp);
 
        ovs_skb_init_inner_protocol(skb);
-       OVS_CB(skb)->tun_info = tun_info;
        OVS_CB(skb)->input_vport = vport;
-       ovs_dp_process_received_packet(skb);
+       OVS_CB(skb)->egress_tun_info = NULL;
+       error = ovs_flow_key_extract(tun_info, skb, &key);
+       if (unlikely(error)) {
+               kfree_skb(skb);
+               return;
+       }
+
+       ovs_dp_process_packet(skb, false);
 }
 
 /**