From fb66fbd15b98e897841f326b6dd0842ba6bde1a9 Mon Sep 17 00:00:00 2001 From: Pravin B Shelar Date: Tue, 5 Aug 2014 13:49:57 -0700 Subject: [PATCH] datapath: Use tun_info only for egress tunnel path. 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 Acked-by: Andy Zhou --- datapath/actions.c | 8 +++----- datapath/datapath.c | 24 ++++-------------------- datapath/datapath.h | 10 ++++------ datapath/flow.c | 10 +++++----- datapath/flow.h | 3 ++- datapath/vport-geneve.c | 12 +++++++----- datapath/vport-gre.c | 16 +++++++++------- datapath/vport-lisp.c | 7 ++++--- datapath/vport-vxlan.c | 4 ++-- datapath/vport.c | 12 ++++++++++-- 10 files changed, 50 insertions(+), 56 deletions(-) diff --git a/datapath/actions.c b/datapath/actions.c index 6de65d398..efc64f142 100644 --- a/datapath/actions.c +++ b/datapath/actions.c @@ -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. */ diff --git a/datapath/datapath.c b/datapath/datapath.c index 91c65a0d8..19d41c885 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -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; diff --git a/datapath/datapath.h b/datapath/datapath.h index fb37fa197..cd2acbc58 100644 --- a/datapath/datapath.h +++ b/datapath/datapath.h @@ -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 *); diff --git a/datapath/flow.c b/datapath/flow.c index 1feca8567..d56812acd 100644 --- a/datapath/flow.c +++ b/datapath/flow.c @@ -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) > diff --git a/datapath/flow.h b/datapath/flow.h index ee63b8b5a..106feb86a 100644 --- a/datapath/flow.h +++ b/datapath/flow.h @@ -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, diff --git a/datapath/vport-geneve.c b/datapath/vport-geneve.c index 65a996fa8..b9615e1bd 100644 --- a/datapath/vport-geneve.c +++ b/datapath/vport-geneve.c @@ -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); diff --git a/datapath/vport-gre.c b/datapath/vport-gre.c index d2a26023c..70fce5861 100644 --- a/datapath/vport-gre.c +++ b/datapath/vport-gre.c @@ -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)); } diff --git a/datapath/vport-lisp.c b/datapath/vport-lisp.c index 81ecf923a..cdd325ef3 100644 --- a/datapath/vport-lisp.c +++ b/datapath/vport-lisp.c @@ -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)) { diff --git a/datapath/vport-vxlan.c b/datapath/vport-vxlan.c index d93a844d4..66784003a 100644 --- a/datapath/vport-vxlan.c +++ b/datapath/vport-vxlan.c @@ -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; diff --git a/datapath/vport.c b/datapath/vport.c index 5d250aae6..18d380320 100644 --- a/datapath/vport.c +++ b/datapath/vport.c @@ -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); } /** -- 2.20.1