Merge lp:~gandelman-a/ubuntu/precise/openvswitch/lp1044318 into lp:ubuntu/precise-proposed/openvswitch
- Precise (12.04)
- lp1044318
- Merge into precise-proposed
Proposed by
Adam Gandelman
Status: | Merged |
---|---|
Merge reported by: | Stéphane Graber |
Merged at revision: | not available |
Proposed branch: | lp:~gandelman-a/ubuntu/precise/openvswitch/lp1044318 |
Merge into: | lp:ubuntu/precise-proposed/openvswitch |
Diff against target: |
454 lines (+402/-0) 6 files modified
.pc/applied-patches (+1/-0) .pc/lp1044318-Reset-upper-layer-protocol-info.patch/datapath/vport-internal_dev.c (+330/-0) datapath/vport-internal_dev.c (+8/-0) debian/changelog (+10/-0) debian/patches/lp1044318-Reset-upper-layer-protocol-info.patch (+52/-0) debian/patches/series (+1/-0) |
To merge this branch: | bzr merge lp:~gandelman-a/ubuntu/precise/openvswitch/lp1044318 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Development Team | Pending | ||
Review via email: mp+123379@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
- 27. By Adam Gandelman
-
* Temporary PPA build to allow early RC1 testing while fix makes its way
out to precise-updates.
- debian/patches/ lp1044318- Reset-upper- layer-protocol- info.patch: Cherry - 28. By Adam Gandelman
-
Add .pc/lp1044318-
Reset-upper- layer-protocol- info.patch.
Revision history for this message
Stéphane Graber (stgraber) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file '.pc/applied-patches' |
2 | --- .pc/applied-patches 2012-07-26 11:23:06 +0000 |
3 | +++ .pc/applied-patches 2012-09-12 17:06:26 +0000 |
4 | @@ -1,2 +1,3 @@ |
5 | update_odputil_key_bytes.patch |
6 | fix_ftbfs_big_endian.patch |
7 | +lp1044318-Reset-upper-layer-protocol-info.patch |
8 | |
9 | === added directory '.pc/lp1044318-Reset-upper-layer-protocol-info.patch' |
10 | === added file '.pc/lp1044318-Reset-upper-layer-protocol-info.patch/.timestamp' |
11 | === added directory '.pc/lp1044318-Reset-upper-layer-protocol-info.patch/datapath' |
12 | === added file '.pc/lp1044318-Reset-upper-layer-protocol-info.patch/datapath/vport-internal_dev.c' |
13 | --- .pc/lp1044318-Reset-upper-layer-protocol-info.patch/datapath/vport-internal_dev.c 1970-01-01 00:00:00 +0000 |
14 | +++ .pc/lp1044318-Reset-upper-layer-protocol-info.patch/datapath/vport-internal_dev.c 2012-09-12 17:06:26 +0000 |
15 | @@ -0,0 +1,330 @@ |
16 | +/* |
17 | + * Copyright (c) 2007-2011 Nicira Networks. |
18 | + * |
19 | + * This program is free software; you can redistribute it and/or |
20 | + * modify it under the terms of version 2 of the GNU General Public |
21 | + * License as published by the Free Software Foundation. |
22 | + * |
23 | + * This program is distributed in the hope that it will be useful, but |
24 | + * WITHOUT ANY WARRANTY; without even the implied warranty of |
25 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
26 | + * General Public License for more details. |
27 | + * |
28 | + * You should have received a copy of the GNU General Public License |
29 | + * along with this program; if not, write to the Free Software |
30 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
31 | + * 02110-1301, USA |
32 | + */ |
33 | + |
34 | +#include <linux/hardirq.h> |
35 | +#include <linux/if_vlan.h> |
36 | +#include <linux/kernel.h> |
37 | +#include <linux/netdevice.h> |
38 | +#include <linux/etherdevice.h> |
39 | +#include <linux/ethtool.h> |
40 | +#include <linux/skbuff.h> |
41 | +#include <linux/version.h> |
42 | + |
43 | +#include "checksum.h" |
44 | +#include "datapath.h" |
45 | +#include "vlan.h" |
46 | +#include "vport-generic.h" |
47 | +#include "vport-internal_dev.h" |
48 | +#include "vport-netdev.h" |
49 | + |
50 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0) |
51 | +#define HAVE_NET_DEVICE_OPS |
52 | +#endif |
53 | + |
54 | +struct internal_dev { |
55 | + struct vport *vport; |
56 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) |
57 | + struct net_device_stats stats; |
58 | +#endif |
59 | +}; |
60 | + |
61 | +static struct internal_dev *internal_dev_priv(struct net_device *netdev) |
62 | +{ |
63 | + return netdev_priv(netdev); |
64 | +} |
65 | + |
66 | +/* This function is only called by the kernel network layer.*/ |
67 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) |
68 | +static struct rtnl_link_stats64 *internal_dev_get_stats(struct net_device *netdev, |
69 | + struct rtnl_link_stats64 *stats) |
70 | +{ |
71 | +#else |
72 | +static struct net_device_stats *internal_dev_sys_stats(struct net_device *netdev) |
73 | +{ |
74 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22) |
75 | + struct net_device_stats *stats = &internal_dev_priv(netdev)->stats; |
76 | +#else |
77 | + struct net_device_stats *stats = &netdev->stats; |
78 | +#endif |
79 | +#endif |
80 | + struct vport *vport = ovs_internal_dev_get_vport(netdev); |
81 | + struct ovs_vport_stats vport_stats; |
82 | + |
83 | + ovs_vport_get_stats(vport, &vport_stats); |
84 | + |
85 | + /* The tx and rx stats need to be swapped because the |
86 | + * switch and host OS have opposite perspectives. */ |
87 | + stats->rx_packets = vport_stats.tx_packets; |
88 | + stats->tx_packets = vport_stats.rx_packets; |
89 | + stats->rx_bytes = vport_stats.tx_bytes; |
90 | + stats->tx_bytes = vport_stats.rx_bytes; |
91 | + stats->rx_errors = vport_stats.tx_errors; |
92 | + stats->tx_errors = vport_stats.rx_errors; |
93 | + stats->rx_dropped = vport_stats.tx_dropped; |
94 | + stats->tx_dropped = vport_stats.rx_dropped; |
95 | + |
96 | + return stats; |
97 | +} |
98 | + |
99 | +static int internal_dev_mac_addr(struct net_device *dev, void *p) |
100 | +{ |
101 | + struct sockaddr *addr = p; |
102 | + |
103 | + if (!is_valid_ether_addr(addr->sa_data)) |
104 | + return -EADDRNOTAVAIL; |
105 | + memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); |
106 | + return 0; |
107 | +} |
108 | + |
109 | +/* Called with rcu_read_lock_bh. */ |
110 | +static int internal_dev_xmit(struct sk_buff *skb, struct net_device *netdev) |
111 | +{ |
112 | + if (unlikely(compute_ip_summed(skb, true))) { |
113 | + kfree_skb(skb); |
114 | + return 0; |
115 | + } |
116 | + |
117 | + vlan_copy_skb_tci(skb); |
118 | + OVS_CB(skb)->flow = NULL; |
119 | + |
120 | + rcu_read_lock(); |
121 | + ovs_vport_receive(internal_dev_priv(netdev)->vport, skb); |
122 | + rcu_read_unlock(); |
123 | + return 0; |
124 | +} |
125 | + |
126 | +static int internal_dev_open(struct net_device *netdev) |
127 | +{ |
128 | + netif_start_queue(netdev); |
129 | + return 0; |
130 | +} |
131 | + |
132 | +static int internal_dev_stop(struct net_device *netdev) |
133 | +{ |
134 | + netif_stop_queue(netdev); |
135 | + return 0; |
136 | +} |
137 | + |
138 | +static void internal_dev_getinfo(struct net_device *netdev, |
139 | + struct ethtool_drvinfo *info) |
140 | +{ |
141 | + strcpy(info->driver, "openvswitch"); |
142 | +} |
143 | + |
144 | +static const struct ethtool_ops internal_dev_ethtool_ops = { |
145 | + .get_drvinfo = internal_dev_getinfo, |
146 | + .get_link = ethtool_op_get_link, |
147 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39) |
148 | + .get_sg = ethtool_op_get_sg, |
149 | + .set_sg = ethtool_op_set_sg, |
150 | + .get_tx_csum = ethtool_op_get_tx_csum, |
151 | + .set_tx_csum = ethtool_op_set_tx_hw_csum, |
152 | + .get_tso = ethtool_op_get_tso, |
153 | + .set_tso = ethtool_op_set_tso, |
154 | +#endif |
155 | +}; |
156 | + |
157 | +static int internal_dev_change_mtu(struct net_device *netdev, int new_mtu) |
158 | +{ |
159 | + if (new_mtu < 68) |
160 | + return -EINVAL; |
161 | + |
162 | + netdev->mtu = new_mtu; |
163 | + return 0; |
164 | +} |
165 | + |
166 | +static int internal_dev_do_ioctl(struct net_device *dev, |
167 | + struct ifreq *ifr, int cmd) |
168 | +{ |
169 | + if (ovs_dp_ioctl_hook) |
170 | + return ovs_dp_ioctl_hook(dev, ifr, cmd); |
171 | + |
172 | + return -EOPNOTSUPP; |
173 | +} |
174 | + |
175 | +static void internal_dev_destructor(struct net_device *dev) |
176 | +{ |
177 | + struct vport *vport = ovs_internal_dev_get_vport(dev); |
178 | + |
179 | + ovs_vport_free(vport); |
180 | + free_netdev(dev); |
181 | +} |
182 | + |
183 | +#ifdef HAVE_NET_DEVICE_OPS |
184 | +static const struct net_device_ops internal_dev_netdev_ops = { |
185 | + .ndo_open = internal_dev_open, |
186 | + .ndo_stop = internal_dev_stop, |
187 | + .ndo_start_xmit = internal_dev_xmit, |
188 | + .ndo_set_mac_address = internal_dev_mac_addr, |
189 | + .ndo_do_ioctl = internal_dev_do_ioctl, |
190 | + .ndo_change_mtu = internal_dev_change_mtu, |
191 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36) |
192 | + .ndo_get_stats64 = internal_dev_get_stats, |
193 | +#else |
194 | + .ndo_get_stats = internal_dev_sys_stats, |
195 | +#endif |
196 | +}; |
197 | +#endif |
198 | + |
199 | +static void do_setup(struct net_device *netdev) |
200 | +{ |
201 | + ether_setup(netdev); |
202 | + |
203 | +#ifdef HAVE_NET_DEVICE_OPS |
204 | + netdev->netdev_ops = &internal_dev_netdev_ops; |
205 | +#else |
206 | + netdev->do_ioctl = internal_dev_do_ioctl; |
207 | + netdev->get_stats = internal_dev_sys_stats; |
208 | + netdev->hard_start_xmit = internal_dev_xmit; |
209 | + netdev->open = internal_dev_open; |
210 | + netdev->stop = internal_dev_stop; |
211 | + netdev->set_mac_address = internal_dev_mac_addr; |
212 | + netdev->change_mtu = internal_dev_change_mtu; |
213 | +#endif |
214 | + |
215 | + netdev->priv_flags &= ~IFF_TX_SKB_SHARING; |
216 | + netdev->destructor = internal_dev_destructor; |
217 | + SET_ETHTOOL_OPS(netdev, &internal_dev_ethtool_ops); |
218 | + netdev->tx_queue_len = 0; |
219 | + |
220 | + netdev->features = NETIF_F_LLTX | NETIF_F_SG | NETIF_F_FRAGLIST | |
221 | + NETIF_F_HIGHDMA | NETIF_F_HW_CSUM | NETIF_F_TSO; |
222 | + |
223 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) |
224 | + netdev->vlan_features = netdev->features; |
225 | + netdev->features |= NETIF_F_HW_VLAN_TX; |
226 | +#endif |
227 | + |
228 | +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39) |
229 | + netdev->hw_features = netdev->features & ~NETIF_F_LLTX; |
230 | +#endif |
231 | + random_ether_addr(netdev->dev_addr); |
232 | +} |
233 | + |
234 | +static struct vport *internal_dev_create(const struct vport_parms *parms) |
235 | +{ |
236 | + struct vport *vport; |
237 | + struct netdev_vport *netdev_vport; |
238 | + struct internal_dev *internal_dev; |
239 | + int err; |
240 | + |
241 | + vport = ovs_vport_alloc(sizeof(struct netdev_vport), |
242 | + &ovs_internal_vport_ops, parms); |
243 | + if (IS_ERR(vport)) { |
244 | + err = PTR_ERR(vport); |
245 | + goto error; |
246 | + } |
247 | + |
248 | + netdev_vport = netdev_vport_priv(vport); |
249 | + |
250 | + netdev_vport->dev = alloc_netdev(sizeof(struct internal_dev), |
251 | + parms->name, do_setup); |
252 | + if (!netdev_vport->dev) { |
253 | + err = -ENOMEM; |
254 | + goto error_free_vport; |
255 | + } |
256 | + |
257 | + internal_dev = internal_dev_priv(netdev_vport->dev); |
258 | + internal_dev->vport = vport; |
259 | + |
260 | + err = register_netdevice(netdev_vport->dev); |
261 | + if (err) |
262 | + goto error_free_netdev; |
263 | + |
264 | + dev_set_promiscuity(netdev_vport->dev, 1); |
265 | + netif_start_queue(netdev_vport->dev); |
266 | + |
267 | + return vport; |
268 | + |
269 | +error_free_netdev: |
270 | + free_netdev(netdev_vport->dev); |
271 | +error_free_vport: |
272 | + ovs_vport_free(vport); |
273 | +error: |
274 | + return ERR_PTR(err); |
275 | +} |
276 | + |
277 | +static void internal_dev_destroy(struct vport *vport) |
278 | +{ |
279 | + struct netdev_vport *netdev_vport = netdev_vport_priv(vport); |
280 | + |
281 | + netif_stop_queue(netdev_vport->dev); |
282 | + dev_set_promiscuity(netdev_vport->dev, -1); |
283 | + |
284 | + /* unregister_netdevice() waits for an RCU grace period. */ |
285 | + unregister_netdevice(netdev_vport->dev); |
286 | +} |
287 | + |
288 | +static int internal_dev_recv(struct vport *vport, struct sk_buff *skb) |
289 | +{ |
290 | + struct net_device *netdev = netdev_vport_priv(vport)->dev; |
291 | + int len; |
292 | + |
293 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37) |
294 | + if (unlikely(vlan_deaccel_tag(skb))) |
295 | + return 0; |
296 | +#endif |
297 | + |
298 | + len = skb->len; |
299 | + skb->dev = netdev; |
300 | + skb->pkt_type = PACKET_HOST; |
301 | + skb->protocol = eth_type_trans(skb, netdev); |
302 | + forward_ip_summed(skb, false); |
303 | + |
304 | + netif_rx(skb); |
305 | + |
306 | +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29) |
307 | + netdev->last_rx = jiffies; |
308 | +#endif |
309 | + |
310 | + return len; |
311 | +} |
312 | + |
313 | +const struct vport_ops ovs_internal_vport_ops = { |
314 | + .type = OVS_VPORT_TYPE_INTERNAL, |
315 | + .flags = VPORT_F_REQUIRED | VPORT_F_FLOW, |
316 | + .create = internal_dev_create, |
317 | + .destroy = internal_dev_destroy, |
318 | + .set_addr = ovs_netdev_set_addr, |
319 | + .get_name = ovs_netdev_get_name, |
320 | + .get_addr = ovs_netdev_get_addr, |
321 | + .get_kobj = ovs_netdev_get_kobj, |
322 | + .get_dev_flags = ovs_netdev_get_dev_flags, |
323 | + .is_running = ovs_netdev_is_running, |
324 | + .get_operstate = ovs_netdev_get_operstate, |
325 | + .get_ifindex = ovs_netdev_get_ifindex, |
326 | + .get_mtu = ovs_netdev_get_mtu, |
327 | + .send = internal_dev_recv, |
328 | +}; |
329 | + |
330 | +int ovs_is_internal_dev(const struct net_device *netdev) |
331 | +{ |
332 | +#ifdef HAVE_NET_DEVICE_OPS |
333 | + return netdev->netdev_ops == &internal_dev_netdev_ops; |
334 | +#else |
335 | + return netdev->open == internal_dev_open; |
336 | +#endif |
337 | +} |
338 | + |
339 | +struct vport *ovs_internal_dev_get_vport(struct net_device *netdev) |
340 | +{ |
341 | + if (!ovs_is_internal_dev(netdev)) |
342 | + return NULL; |
343 | + |
344 | + return internal_dev_priv(netdev)->vport; |
345 | +} |
346 | |
347 | === modified file 'datapath/vport-internal_dev.c' |
348 | --- datapath/vport-internal_dev.c 2012-01-30 23:36:00 +0000 |
349 | +++ datapath/vport-internal_dev.c 2012-09-12 17:06:26 +0000 |
350 | @@ -25,6 +25,9 @@ |
351 | #include <linux/skbuff.h> |
352 | #include <linux/version.h> |
353 | |
354 | +#include <net/dst.h> |
355 | +#include <net/xfrm.h> |
356 | + |
357 | #include "checksum.h" |
358 | #include "datapath.h" |
359 | #include "vlan.h" |
360 | @@ -281,6 +284,11 @@ |
361 | #endif |
362 | |
363 | len = skb->len; |
364 | + |
365 | + skb_dst_drop(skb); |
366 | + nf_reset(skb); |
367 | + secpath_reset(skb); |
368 | + |
369 | skb->dev = netdev; |
370 | skb->pkt_type = PACKET_HOST; |
371 | skb->protocol = eth_type_trans(skb, netdev); |
372 | |
373 | === modified file 'debian/changelog' |
374 | --- debian/changelog 2012-07-26 11:23:06 +0000 |
375 | +++ debian/changelog 2012-09-12 17:06:26 +0000 |
376 | @@ -1,3 +1,13 @@ |
377 | +openvswitch (1.4.0-1ubuntu1.3~ppa) precise; urgency=low |
378 | + |
379 | + * Temporary PPA build to allow early RC1 testing while fix makes its way |
380 | + out to precise-updates. |
381 | + - debian/patches/lp1044318-Reset-upper-layer-protocol-info.patch: Cherry |
382 | + picked upstream patch to avoid critical issues with SNAT/DNAT when OVS |
383 | + is chained with other Linux components. (LP: #1044318) |
384 | + |
385 | + -- Adam Gandelman <adamg@canonical.com> Fri, 07 Sep 2012 15:38:56 -0700 |
386 | + |
387 | openvswitch (1.4.0-1ubuntu1.2) precise-proposed; urgency=low |
388 | |
389 | * debian/patches/fix_ftbfs_big_endian.patch: Fix FTBFS on PPC. |
390 | |
391 | === added file 'debian/patches/lp1044318-Reset-upper-layer-protocol-info.patch' |
392 | --- debian/patches/lp1044318-Reset-upper-layer-protocol-info.patch 1970-01-01 00:00:00 +0000 |
393 | +++ debian/patches/lp1044318-Reset-upper-layer-protocol-info.patch 2012-09-12 17:06:26 +0000 |
394 | @@ -0,0 +1,52 @@ |
395 | +From: Adam Gandelman <adamg@canonical.com> |
396 | +Author: Jesse Gross <jesse@nicira.com> |
397 | +Date: Fri Sep 7 12:10:58 PDT 2012 |
398 | +Bug-Ubuntu: https://bugs.launchpad.net/quantum/+bug/1044318 |
399 | +X-Git-Url: http://openvswitch.org/cgi-bin/gitweb.cgi?p=openvswitch;a=commitdiff_plain;h=53e6421bc83918ac2d00ba5516f205fa7e394140 |
400 | +Subject: datapath: Reset upper layer protocol info on internal devices. |
401 | + |
402 | +datapath: Reset upper layer protocol info on internal devices. |
403 | + |
404 | +It's possible that packets that are sent on internal devices (from |
405 | +the OVS perspective) have already traversed the local IP stack. |
406 | +After they go through the internal device, they will again travel |
407 | +through the IP stack which may get confused by the presence of |
408 | +existing information in the skb. The problem can be observed |
409 | +when switching between namespaces. This clears out that information |
410 | +to avoid problems but deliberately leaves other metadata alone. |
411 | +This is to provide maximum flexibility in chaining together OVS |
412 | +and other Linux components. |
413 | + |
414 | +Bug #10995 |
415 | + |
416 | +Signed-off-by: Jesse Gross <jesse@nicira.com> |
417 | +Acked-by: Ben Pfaff <blp@nicira.com> |
418 | +--- |
419 | + |
420 | + |
421 | +Index: openvswitch/datapath/vport-internal_dev.c |
422 | +=================================================================== |
423 | +--- openvswitch.orig/datapath/vport-internal_dev.c 2012-09-07 12:06:26.436795000 -0700 |
424 | ++++ openvswitch/datapath/vport-internal_dev.c 2012-09-07 12:09:09.223267544 -0700 |
425 | +@@ -25,6 +25,9 @@ |
426 | + #include <linux/skbuff.h> |
427 | + #include <linux/version.h> |
428 | + |
429 | ++#include <net/dst.h> |
430 | ++#include <net/xfrm.h> |
431 | ++ |
432 | + #include "checksum.h" |
433 | + #include "datapath.h" |
434 | + #include "vlan.h" |
435 | +@@ -281,6 +284,11 @@ |
436 | + #endif |
437 | + |
438 | + len = skb->len; |
439 | ++ |
440 | ++ skb_dst_drop(skb); |
441 | ++ nf_reset(skb); |
442 | ++ secpath_reset(skb); |
443 | ++ |
444 | + skb->dev = netdev; |
445 | + skb->pkt_type = PACKET_HOST; |
446 | + skb->protocol = eth_type_trans(skb, netdev); |
447 | |
448 | === modified file 'debian/patches/series' |
449 | --- debian/patches/series 2012-07-26 11:23:06 +0000 |
450 | +++ debian/patches/series 2012-09-12 17:06:26 +0000 |
451 | @@ -1,2 +1,3 @@ |
452 | update_odputil_key_bytes.patch |
453 | fix_ftbfs_big_endian.patch |
454 | +lp1044318-Reset-upper-layer-protocol-info.patch |
I'm seeing this in -proposed, marking it as merged.