aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPravin B Shelar <pshelar@nicira.com>2014-09-15 22:28:44 -0400
committerPravin B Shelar <pshelar@nicira.com>2014-09-16 02:28:13 -0400
commit8c8b1b83fcdd0f05e1f66ed6f8a2e831d5d374a2 (patch)
tree639e2202b5ded18df0c38daabedcdeeb3e6c2482 /net
parent83c8df26a3b654871c0503fcf6eac61777e12ea1 (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')
-rw-r--r--net/openvswitch/actions.c3
-rw-r--r--net/openvswitch/datapath.c20
-rw-r--r--net/openvswitch/datapath.h8
-rw-r--r--net/openvswitch/flow.c7
-rw-r--r--net/openvswitch/flow.h3
-rw-r--r--net/openvswitch/vport-gre.c23
-rw-r--r--net/openvswitch/vport-vxlan.c21
-rw-r--r--net/openvswitch/vport.c12
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. */
240void ovs_dp_process_received_packet(struct sk_buff *skb) 240void 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
284out: 276out:
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 */
103struct ovs_skb_cb { 103struct 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
184extern struct notifier_block ovs_dp_device_notifier; 184extern struct notifier_block ovs_dp_device_notifier;
185extern struct genl_family dp_vport_genl_family; 185extern struct genl_family dp_vport_genl_family;
186 186
187void ovs_dp_process_received_packet(struct sk_buff *); 187void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key);
188void ovs_dp_detach_port(struct vport *); 188void ovs_dp_detach_port(struct vport *);
189int ovs_dp_upcall(struct datapath *, struct sk_buff *, 189int 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
609int ovs_flow_key_extract(struct sk_buff *skb, struct sw_flow_key *key) 609int 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 *,
187void ovs_flow_stats_clear(struct sw_flow *); 187void ovs_flow_stats_clear(struct sw_flow *);
188u64 ovs_flow_used_time(unsigned long flow_jiffies); 188u64 ovs_flow_used_time(unsigned long flow_jiffies);
189 189
190int ovs_flow_key_extract(struct sk_buff *skb, struct sw_flow_key *key); 190int 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. */
192int ovs_flow_key_extract_userspace(const struct nlattr *attr, 193int 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)
63static struct sk_buff *__build_header(struct sk_buff *skb, 63static 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,
129static int gre_tnl_send(struct vport *vport, struct sk_buff *skb) 129static 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);
197err_free_rt: 198err_free_rt:
198 ip_rt_put(rt); 199 ip_rt_put(rt);
199error: 200error:
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/**