diff options
| author | Pravin B Shelar <pshelar@nicira.com> | 2014-09-15 22:28:44 -0400 |
|---|---|---|
| committer | Pravin B Shelar <pshelar@nicira.com> | 2014-09-16 02:28:13 -0400 |
| commit | 8c8b1b83fcdd0f05e1f66ed6f8a2e831d5d374a2 (patch) | |
| tree | 639e2202b5ded18df0c38daabedcdeeb3e6c2482 /net/openvswitch | |
| parent | 83c8df26a3b654871c0503fcf6eac61777e12ea1 (diff) | |
openvswitch: Use tun_key only for egress tunnel path.
Currently tun_key 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>
Diffstat (limited to 'net/openvswitch')
| -rw-r--r-- | net/openvswitch/actions.c | 3 | ||||
| -rw-r--r-- | net/openvswitch/datapath.c | 20 | ||||
| -rw-r--r-- | net/openvswitch/datapath.h | 8 | ||||
| -rw-r--r-- | net/openvswitch/flow.c | 7 | ||||
| -rw-r--r-- | net/openvswitch/flow.h | 3 | ||||
| -rw-r--r-- | net/openvswitch/vport-gre.c | 23 | ||||
| -rw-r--r-- | net/openvswitch/vport-vxlan.c | 21 | ||||
| -rw-r--r-- | net/openvswitch/vport.c | 12 |
8 files changed, 50 insertions, 47 deletions
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 8a1eb562cdec..1cdb539d05bd 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c | |||
| @@ -510,7 +510,7 @@ static int execute_set_action(struct sk_buff *skb, | |||
| 510 | break; | 510 | break; |
| 511 | 511 | ||
| 512 | case OVS_KEY_ATTR_IPV4_TUNNEL: | 512 | case OVS_KEY_ATTR_IPV4_TUNNEL: |
| 513 | OVS_CB(skb)->tun_key = nla_data(nested_attr); | 513 | OVS_CB(skb)->egress_tun_key = nla_data(nested_attr); |
| 514 | break; | 514 | break; |
| 515 | 515 | ||
| 516 | case OVS_KEY_ATTR_ETHERNET: | 516 | case OVS_KEY_ATTR_ETHERNET: |
| @@ -613,7 +613,6 @@ int ovs_execute_actions(struct datapath *dp, struct sk_buff *skb, | |||
| 613 | { | 613 | { |
| 614 | struct sw_flow_actions *acts = rcu_dereference(OVS_CB(skb)->flow->sf_acts); | 614 | struct sw_flow_actions *acts = rcu_dereference(OVS_CB(skb)->flow->sf_acts); |
| 615 | 615 | ||
| 616 | OVS_CB(skb)->tun_key = NULL; | ||
| 617 | return do_execute_actions(dp, skb, key, | 616 | return do_execute_actions(dp, skb, key, |
| 618 | acts->actions, acts->actions_len); | 617 | acts->actions, acts->actions_len); |
| 619 | } | 618 | } |
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 0cce8e60d5ed..7e0819919b8a 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
| @@ -237,33 +237,25 @@ void ovs_dp_detach_port(struct vport *p) | |||
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | /* Must be called with rcu_read_lock. */ | 239 | /* Must be called with rcu_read_lock. */ |
| 240 | void ovs_dp_process_received_packet(struct sk_buff *skb) | 240 | void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key) |
| 241 | { | 241 | { |
| 242 | const struct vport *p = OVS_CB(skb)->input_vport; | 242 | const struct vport *p = OVS_CB(skb)->input_vport; |
| 243 | struct datapath *dp = p->dp; | 243 | struct datapath *dp = p->dp; |
| 244 | struct sw_flow *flow; | 244 | struct sw_flow *flow; |
| 245 | struct dp_stats_percpu *stats; | 245 | struct dp_stats_percpu *stats; |
| 246 | struct sw_flow_key key; | ||
| 247 | u64 *stats_counter; | 246 | u64 *stats_counter; |
| 248 | u32 n_mask_hit; | 247 | u32 n_mask_hit; |
| 249 | int error; | ||
| 250 | 248 | ||
| 251 | stats = this_cpu_ptr(dp->stats_percpu); | 249 | stats = this_cpu_ptr(dp->stats_percpu); |
| 252 | 250 | ||
| 253 | /* Extract flow from 'skb' into 'key'. */ | ||
| 254 | error = ovs_flow_key_extract(skb, &key); | ||
| 255 | if (unlikely(error)) { | ||
| 256 | kfree_skb(skb); | ||
| 257 | return; | ||
| 258 | } | ||
| 259 | |||
| 260 | /* Look up flow. */ | 251 | /* Look up flow. */ |
| 261 | flow = ovs_flow_tbl_lookup_stats(&dp->table, &key, &n_mask_hit); | 252 | flow = ovs_flow_tbl_lookup_stats(&dp->table, key, &n_mask_hit); |
| 262 | if (unlikely(!flow)) { | 253 | if (unlikely(!flow)) { |
| 263 | struct dp_upcall_info upcall; | 254 | struct dp_upcall_info upcall; |
| 255 | int error; | ||
| 264 | 256 | ||
| 265 | upcall.cmd = OVS_PACKET_CMD_MISS; | 257 | upcall.cmd = OVS_PACKET_CMD_MISS; |
| 266 | upcall.key = &key; | 258 | upcall.key = key; |
| 267 | upcall.userdata = NULL; | 259 | upcall.userdata = NULL; |
| 268 | upcall.portid = ovs_vport_find_upcall_portid(p, skb); | 260 | upcall.portid = ovs_vport_find_upcall_portid(p, skb); |
| 269 | error = ovs_dp_upcall(dp, skb, &upcall); | 261 | error = ovs_dp_upcall(dp, skb, &upcall); |
| @@ -277,8 +269,8 @@ void ovs_dp_process_received_packet(struct sk_buff *skb) | |||
| 277 | 269 | ||
| 278 | OVS_CB(skb)->flow = flow; | 270 | OVS_CB(skb)->flow = flow; |
| 279 | 271 | ||
| 280 | ovs_flow_stats_update(OVS_CB(skb)->flow, key.tp.flags, skb); | 272 | ovs_flow_stats_update(OVS_CB(skb)->flow, key->tp.flags, skb); |
| 281 | ovs_execute_actions(dp, skb, &key); | 273 | ovs_execute_actions(dp, skb, key); |
| 282 | stats_counter = &stats->n_hit; | 274 | stats_counter = &stats->n_hit; |
| 283 | 275 | ||
| 284 | out: | 276 | out: |
diff --git a/net/openvswitch/datapath.h b/net/openvswitch/datapath.h index 2b982fae6a11..25b0e888cb27 100644 --- a/net/openvswitch/datapath.h +++ b/net/openvswitch/datapath.h | |||
| @@ -95,15 +95,15 @@ struct datapath { | |||
| 95 | /** | 95 | /** |
| 96 | * struct ovs_skb_cb - OVS data in skb CB | 96 | * struct ovs_skb_cb - OVS data in skb CB |
| 97 | * @flow: The flow associated with this packet. May be %NULL if no flow. | 97 | * @flow: The flow associated with this packet. May be %NULL if no flow. |
| 98 | * @tun_key: Key for the tunnel that encapsulated this packet. NULL if the | 98 | * @egress_tun_key: Tunnel information about this packet on egress path. |
| 99 | * packet is not being tunneled. | 99 | * NULL if the packet is not being tunneled. |
| 100 | * @input_vport: The original vport packet came in on. This value is cached | 100 | * @input_vport: The original vport packet came in on. This value is cached |
| 101 | * when a packet is received by OVS. | 101 | * when a packet is received by OVS. |
| 102 | */ | 102 | */ |
| 103 | struct ovs_skb_cb { | 103 | struct ovs_skb_cb { |
| 104 | struct sw_flow *flow; | 104 | struct sw_flow *flow; |
| 105 | struct ovs_key_ipv4_tunnel *tun_key; | ||
| 106 | struct vport *input_vport; | 105 | struct vport *input_vport; |
| 106 | struct ovs_key_ipv4_tunnel *egress_tun_key; | ||
| 107 | }; | 107 | }; |
| 108 | #define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb) | 108 | #define OVS_CB(skb) ((struct ovs_skb_cb *)(skb)->cb) |
| 109 | 109 | ||
| @@ -184,7 +184,7 @@ static inline struct vport *ovs_vport_ovsl(const struct datapath *dp, int port_n | |||
| 184 | extern struct notifier_block ovs_dp_device_notifier; | 184 | extern struct notifier_block ovs_dp_device_notifier; |
| 185 | extern struct genl_family dp_vport_genl_family; | 185 | extern struct genl_family dp_vport_genl_family; |
| 186 | 186 | ||
| 187 | void ovs_dp_process_received_packet(struct sk_buff *); | 187 | void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key); |
| 188 | void ovs_dp_detach_port(struct vport *); | 188 | void ovs_dp_detach_port(struct vport *); |
| 189 | int ovs_dp_upcall(struct datapath *, struct sk_buff *, | 189 | int ovs_dp_upcall(struct datapath *, struct sk_buff *, |
| 190 | const struct dp_upcall_info *); | 190 | const struct dp_upcall_info *); |
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index d186eb65a391..bf8442071d75 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c | |||
| @@ -606,12 +606,13 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) | |||
| 606 | return 0; | 606 | return 0; |
| 607 | } | 607 | } |
| 608 | 608 | ||
| 609 | int ovs_flow_key_extract(struct sk_buff *skb, struct sw_flow_key *key) | 609 | int ovs_flow_key_extract(struct ovs_key_ipv4_tunnel *tun_key, |
| 610 | struct sk_buff *skb, struct sw_flow_key *key) | ||
| 610 | { | 611 | { |
| 611 | /* Extract metadata from packet. */ | 612 | /* Extract metadata from packet. */ |
| 612 | memset(key, 0, sizeof(*key)); | 613 | memset(key, 0, sizeof(*key)); |
| 613 | if (OVS_CB(skb)->tun_key) | 614 | if (tun_key) |
| 614 | memcpy(&key->tun_key, OVS_CB(skb)->tun_key, sizeof(key->tun_key)); | 615 | memcpy(&key->tun_key, tun_key, sizeof(key->tun_key)); |
| 615 | 616 | ||
| 616 | key->phy.priority = skb->priority; | 617 | key->phy.priority = skb->priority; |
| 617 | key->phy.in_port = OVS_CB(skb)->input_vport->port_no; | 618 | key->phy.in_port = OVS_CB(skb)->input_vport->port_no; |
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h index 251789b6ec45..3869a540365c 100644 --- a/net/openvswitch/flow.h +++ b/net/openvswitch/flow.h | |||
| @@ -187,7 +187,8 @@ void ovs_flow_stats_get(const struct sw_flow *, struct ovs_flow_stats *, | |||
| 187 | void ovs_flow_stats_clear(struct sw_flow *); | 187 | void ovs_flow_stats_clear(struct sw_flow *); |
| 188 | u64 ovs_flow_used_time(unsigned long flow_jiffies); | 188 | u64 ovs_flow_used_time(unsigned long flow_jiffies); |
| 189 | 189 | ||
| 190 | int ovs_flow_key_extract(struct sk_buff *skb, struct sw_flow_key *key); | 190 | int ovs_flow_key_extract(struct ovs_key_ipv4_tunnel *tun_key, |
| 191 | struct sk_buff *skb, struct sw_flow_key *key); | ||
| 191 | /* Extract key from packet coming from userspace. */ | 192 | /* Extract key from packet coming from userspace. */ |
| 192 | int ovs_flow_key_extract_userspace(const struct nlattr *attr, | 193 | int ovs_flow_key_extract_userspace(const struct nlattr *attr, |
| 193 | struct sk_buff *skb, | 194 | struct sk_buff *skb, |
diff --git a/net/openvswitch/vport-gre.c b/net/openvswitch/vport-gre.c index f49148a07da2..309cca6e816f 100644 --- a/net/openvswitch/vport-gre.c +++ b/net/openvswitch/vport-gre.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2007-2013 Nicira, Inc. | 2 | * Copyright (c) 2007-2014 Nicira, Inc. |
| 3 | * | 3 | * |
| 4 | * This program is free software; you can redistribute it and/or | 4 | * This program is free software; you can redistribute it and/or |
| 5 | * modify it under the terms of version 2 of the GNU General Public | 5 | * modify it under the terms of version 2 of the GNU General Public |
| @@ -63,7 +63,7 @@ static __be16 filter_tnl_flags(__be16 flags) | |||
| 63 | static struct sk_buff *__build_header(struct sk_buff *skb, | 63 | static struct sk_buff *__build_header(struct sk_buff *skb, |
| 64 | int tunnel_hlen) | 64 | int tunnel_hlen) |
| 65 | { | 65 | { |
| 66 | const struct ovs_key_ipv4_tunnel *tun_key = OVS_CB(skb)->tun_key; | 66 | const struct ovs_key_ipv4_tunnel *tun_key = OVS_CB(skb)->egress_tun_key; |
| 67 | struct tnl_ptk_info tpi; | 67 | struct tnl_ptk_info tpi; |
| 68 | 68 | ||
| 69 | skb = gre_handle_offloads(skb, !!(tun_key->tun_flags & TUNNEL_CSUM)); | 69 | skb = gre_handle_offloads(skb, !!(tun_key->tun_flags & TUNNEL_CSUM)); |
| @@ -129,6 +129,7 @@ static int gre_err(struct sk_buff *skb, u32 info, | |||
| 129 | static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | 129 | static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) |
| 130 | { | 130 | { |
| 131 | struct net *net = ovs_dp_get_net(vport->dp); | 131 | struct net *net = ovs_dp_get_net(vport->dp); |
| 132 | struct ovs_key_ipv4_tunnel *tun_key; | ||
| 132 | struct flowi4 fl; | 133 | struct flowi4 fl; |
| 133 | struct rtable *rt; | 134 | struct rtable *rt; |
| 134 | int min_headroom; | 135 | int min_headroom; |
| @@ -136,16 +137,17 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
| 136 | __be16 df; | 137 | __be16 df; |
| 137 | int err; | 138 | int err; |
| 138 | 139 | ||
| 139 | if (unlikely(!OVS_CB(skb)->tun_key)) { | 140 | if (unlikely(!OVS_CB(skb)->egress_tun_key)) { |
| 140 | err = -EINVAL; | 141 | err = -EINVAL; |
| 141 | goto error; | 142 | goto error; |
| 142 | } | 143 | } |
| 143 | 144 | ||
| 145 | tun_key = OVS_CB(skb)->egress_tun_key; | ||
| 144 | /* Route lookup */ | 146 | /* Route lookup */ |
| 145 | memset(&fl, 0, sizeof(fl)); | 147 | memset(&fl, 0, sizeof(fl)); |
| 146 | fl.daddr = OVS_CB(skb)->tun_key->ipv4_dst; | 148 | fl.daddr = tun_key->ipv4_dst; |
| 147 | fl.saddr = OVS_CB(skb)->tun_key->ipv4_src; | 149 | fl.saddr = tun_key->ipv4_src; |
| 148 | fl.flowi4_tos = RT_TOS(OVS_CB(skb)->tun_key->ipv4_tos); | 150 | fl.flowi4_tos = RT_TOS(tun_key->ipv4_tos); |
| 149 | fl.flowi4_mark = skb->mark; | 151 | fl.flowi4_mark = skb->mark; |
| 150 | fl.flowi4_proto = IPPROTO_GRE; | 152 | fl.flowi4_proto = IPPROTO_GRE; |
| 151 | 153 | ||
| @@ -153,7 +155,7 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
| 153 | if (IS_ERR(rt)) | 155 | if (IS_ERR(rt)) |
| 154 | return PTR_ERR(rt); | 156 | return PTR_ERR(rt); |
| 155 | 157 | ||
| 156 | tunnel_hlen = ip_gre_calc_hlen(OVS_CB(skb)->tun_key->tun_flags); | 158 | tunnel_hlen = ip_gre_calc_hlen(tun_key->tun_flags); |
| 157 | 159 | ||
| 158 | min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len | 160 | min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len |
| 159 | + tunnel_hlen + sizeof(struct iphdr) | 161 | + tunnel_hlen + sizeof(struct iphdr) |
| @@ -185,15 +187,14 @@ static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
| 185 | goto err_free_rt; | 187 | goto err_free_rt; |
| 186 | } | 188 | } |
| 187 | 189 | ||
| 188 | df = OVS_CB(skb)->tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? | 190 | df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? |
| 189 | htons(IP_DF) : 0; | 191 | htons(IP_DF) : 0; |
| 190 | 192 | ||
| 191 | skb->ignore_df = 1; | 193 | skb->ignore_df = 1; |
| 192 | 194 | ||
| 193 | return iptunnel_xmit(skb->sk, rt, skb, fl.saddr, | 195 | return iptunnel_xmit(skb->sk, rt, skb, fl.saddr, |
| 194 | OVS_CB(skb)->tun_key->ipv4_dst, IPPROTO_GRE, | 196 | tun_key->ipv4_dst, IPPROTO_GRE, |
| 195 | OVS_CB(skb)->tun_key->ipv4_tos, | 197 | tun_key->ipv4_tos, tun_key->ipv4_ttl, df, false); |
| 196 | OVS_CB(skb)->tun_key->ipv4_ttl, df, false); | ||
| 197 | err_free_rt: | 198 | err_free_rt: |
| 198 | ip_rt_put(rt); | 199 | ip_rt_put(rt); |
| 199 | error: | 200 | error: |
diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c index d8b7e247bebf..f19539bb8adc 100644 --- a/net/openvswitch/vport-vxlan.c +++ b/net/openvswitch/vport-vxlan.c | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (c) 2013 Nicira, Inc. | 2 | * Copyright (c) 2014 Nicira, Inc. |
| 3 | * Copyright (c) 2013 Cisco Systems, Inc. | 3 | * Copyright (c) 2013 Cisco Systems, Inc. |
| 4 | * | 4 | * |
| 5 | * This program is free software; you can redistribute it and/or | 5 | * This program is free software; you can redistribute it and/or |
| @@ -140,22 +140,24 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
| 140 | struct net *net = ovs_dp_get_net(vport->dp); | 140 | struct net *net = ovs_dp_get_net(vport->dp); |
| 141 | struct vxlan_port *vxlan_port = vxlan_vport(vport); | 141 | struct vxlan_port *vxlan_port = vxlan_vport(vport); |
| 142 | __be16 dst_port = inet_sk(vxlan_port->vs->sock->sk)->inet_sport; | 142 | __be16 dst_port = inet_sk(vxlan_port->vs->sock->sk)->inet_sport; |
| 143 | struct ovs_key_ipv4_tunnel *tun_key; | ||
| 143 | struct rtable *rt; | 144 | struct rtable *rt; |
| 144 | struct flowi4 fl; | 145 | struct flowi4 fl; |
| 145 | __be16 src_port; | 146 | __be16 src_port; |
| 146 | __be16 df; | 147 | __be16 df; |
| 147 | int err; | 148 | int err; |
| 148 | 149 | ||
| 149 | if (unlikely(!OVS_CB(skb)->tun_key)) { | 150 | if (unlikely(!OVS_CB(skb)->egress_tun_key)) { |
| 150 | err = -EINVAL; | 151 | err = -EINVAL; |
| 151 | goto error; | 152 | goto error; |
| 152 | } | 153 | } |
| 153 | 154 | ||
| 155 | tun_key = OVS_CB(skb)->egress_tun_key; | ||
| 154 | /* Route lookup */ | 156 | /* Route lookup */ |
| 155 | memset(&fl, 0, sizeof(fl)); | 157 | memset(&fl, 0, sizeof(fl)); |
| 156 | fl.daddr = OVS_CB(skb)->tun_key->ipv4_dst; | 158 | fl.daddr = tun_key->ipv4_dst; |
| 157 | fl.saddr = OVS_CB(skb)->tun_key->ipv4_src; | 159 | fl.saddr = tun_key->ipv4_src; |
| 158 | fl.flowi4_tos = RT_TOS(OVS_CB(skb)->tun_key->ipv4_tos); | 160 | fl.flowi4_tos = RT_TOS(tun_key->ipv4_tos); |
| 159 | fl.flowi4_mark = skb->mark; | 161 | fl.flowi4_mark = skb->mark; |
| 160 | fl.flowi4_proto = IPPROTO_UDP; | 162 | fl.flowi4_proto = IPPROTO_UDP; |
| 161 | 163 | ||
| @@ -165,7 +167,7 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
| 165 | goto error; | 167 | goto error; |
| 166 | } | 168 | } |
| 167 | 169 | ||
| 168 | df = OVS_CB(skb)->tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? | 170 | df = tun_key->tun_flags & TUNNEL_DONT_FRAGMENT ? |
| 169 | htons(IP_DF) : 0; | 171 | htons(IP_DF) : 0; |
| 170 | 172 | ||
| 171 | skb->ignore_df = 1; | 173 | skb->ignore_df = 1; |
| @@ -173,11 +175,10 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb) | |||
| 173 | src_port = udp_flow_src_port(net, skb, 0, 0, true); | 175 | src_port = udp_flow_src_port(net, skb, 0, 0, true); |
| 174 | 176 | ||
| 175 | err = vxlan_xmit_skb(vxlan_port->vs, rt, skb, | 177 | err = vxlan_xmit_skb(vxlan_port->vs, rt, skb, |
| 176 | fl.saddr, OVS_CB(skb)->tun_key->ipv4_dst, | 178 | fl.saddr, tun_key->ipv4_dst, |
| 177 | OVS_CB(skb)->tun_key->ipv4_tos, | 179 | tun_key->ipv4_tos, tun_key->ipv4_ttl, df, |
| 178 | OVS_CB(skb)->tun_key->ipv4_ttl, df, | ||
| 179 | src_port, dst_port, | 180 | src_port, dst_port, |
| 180 | htonl(be64_to_cpu(OVS_CB(skb)->tun_key->tun_id) << 8), | 181 | htonl(be64_to_cpu(tun_key->tun_id) << 8), |
| 181 | false); | 182 | false); |
| 182 | if (err < 0) | 183 | if (err < 0) |
| 183 | ip_rt_put(rt); | 184 | ip_rt_put(rt); |
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index acf31aa89e01..5df8377fcfb1 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c | |||
| @@ -435,6 +435,8 @@ void ovs_vport_receive(struct vport *vport, struct sk_buff *skb, | |||
| 435 | struct ovs_key_ipv4_tunnel *tun_key) | 435 | struct ovs_key_ipv4_tunnel *tun_key) |
| 436 | { | 436 | { |
| 437 | struct pcpu_sw_netstats *stats; | 437 | struct pcpu_sw_netstats *stats; |
| 438 | struct sw_flow_key key; | ||
| 439 | int error; | ||
| 438 | 440 | ||
| 439 | stats = this_cpu_ptr(vport->percpu_stats); | 441 | stats = this_cpu_ptr(vport->percpu_stats); |
| 440 | u64_stats_update_begin(&stats->syncp); | 442 | u64_stats_update_begin(&stats->syncp); |
| @@ -442,9 +444,15 @@ void ovs_vport_receive(struct vport *vport, struct sk_buff *skb, | |||
| 442 | stats->rx_bytes += skb->len; | 444 | stats->rx_bytes += skb->len; |
| 443 | u64_stats_update_end(&stats->syncp); | 445 | u64_stats_update_end(&stats->syncp); |
| 444 | 446 | ||
| 445 | OVS_CB(skb)->tun_key = tun_key; | ||
| 446 | OVS_CB(skb)->input_vport = vport; | 447 | OVS_CB(skb)->input_vport = vport; |
| 447 | ovs_dp_process_received_packet(skb); | 448 | OVS_CB(skb)->egress_tun_key = NULL; |
| 449 | /* Extract flow from 'skb' into 'key'. */ | ||
| 450 | error = ovs_flow_key_extract(tun_key, skb, &key); | ||
| 451 | if (unlikely(error)) { | ||
| 452 | kfree_skb(skb); | ||
| 453 | return; | ||
| 454 | } | ||
| 455 | ovs_dp_process_packet(skb, &key); | ||
| 448 | } | 456 | } |
| 449 | 457 | ||
| 450 | /** | 458 | /** |
