Merge lp:~gandelman-a/ubuntu/precise/openvswitch/lp1044318 into lp:ubuntu/precise-proposed/openvswitch

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
Reviewer Review Type Date Requested Status
Ubuntu Development Team Pending
Review via email: mp+123379@code.launchpad.net
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 :

I'm seeing this in -proposed, marking it as merged.

Preview Diff

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

Subscribers

People subscribed via source and target branches