diff options
author | David S. Miller <davem@davemloft.net> | 2012-03-09 17:34:20 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-03-09 17:34:20 -0500 |
commit | b2d3298e0916fa059712691c85a0e97becc4ab9f (patch) | |
tree | c7d5ea46a9dbf9cebdb122df4aaf0beda6e7621e /net/openvswitch | |
parent | 1a0bdadb4e36abac63b0a9787f372aac30c11a9e (diff) | |
parent | a7f4255f906f60f72e00aad2fb000939449ff32e (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Diffstat (limited to 'net/openvswitch')
-rw-r--r-- | net/openvswitch/actions.c | 44 | ||||
-rw-r--r-- | net/openvswitch/datapath.c | 3 |
2 files changed, 35 insertions, 12 deletions
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 2725d1bdf291..48badffaafc1 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2007-2011 Nicira Networks. | 2 | * Copyright (c) 2007-2012 Nicira Networks. |
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 |
@@ -145,9 +145,16 @@ static void set_ip_addr(struct sk_buff *skb, struct iphdr *nh, | |||
145 | inet_proto_csum_replace4(&tcp_hdr(skb)->check, skb, | 145 | inet_proto_csum_replace4(&tcp_hdr(skb)->check, skb, |
146 | *addr, new_addr, 1); | 146 | *addr, new_addr, 1); |
147 | } else if (nh->protocol == IPPROTO_UDP) { | 147 | } else if (nh->protocol == IPPROTO_UDP) { |
148 | if (likely(transport_len >= sizeof(struct udphdr))) | 148 | if (likely(transport_len >= sizeof(struct udphdr))) { |
149 | inet_proto_csum_replace4(&udp_hdr(skb)->check, skb, | 149 | struct udphdr *uh = udp_hdr(skb); |
150 | *addr, new_addr, 1); | 150 | |
151 | if (uh->check || skb->ip_summed == CHECKSUM_PARTIAL) { | ||
152 | inet_proto_csum_replace4(&uh->check, skb, | ||
153 | *addr, new_addr, 1); | ||
154 | if (!uh->check) | ||
155 | uh->check = CSUM_MANGLED_0; | ||
156 | } | ||
157 | } | ||
151 | } | 158 | } |
152 | 159 | ||
153 | csum_replace4(&nh->check, *addr, new_addr); | 160 | csum_replace4(&nh->check, *addr, new_addr); |
@@ -197,8 +204,22 @@ static void set_tp_port(struct sk_buff *skb, __be16 *port, | |||
197 | skb->rxhash = 0; | 204 | skb->rxhash = 0; |
198 | } | 205 | } |
199 | 206 | ||
200 | static int set_udp_port(struct sk_buff *skb, | 207 | static void set_udp_port(struct sk_buff *skb, __be16 *port, __be16 new_port) |
201 | const struct ovs_key_udp *udp_port_key) | 208 | { |
209 | struct udphdr *uh = udp_hdr(skb); | ||
210 | |||
211 | if (uh->check && skb->ip_summed != CHECKSUM_PARTIAL) { | ||
212 | set_tp_port(skb, port, new_port, &uh->check); | ||
213 | |||
214 | if (!uh->check) | ||
215 | uh->check = CSUM_MANGLED_0; | ||
216 | } else { | ||
217 | *port = new_port; | ||
218 | skb->rxhash = 0; | ||
219 | } | ||
220 | } | ||
221 | |||
222 | static int set_udp(struct sk_buff *skb, const struct ovs_key_udp *udp_port_key) | ||
202 | { | 223 | { |
203 | struct udphdr *uh; | 224 | struct udphdr *uh; |
204 | int err; | 225 | int err; |
@@ -210,16 +231,15 @@ static int set_udp_port(struct sk_buff *skb, | |||
210 | 231 | ||
211 | uh = udp_hdr(skb); | 232 | uh = udp_hdr(skb); |
212 | if (udp_port_key->udp_src != uh->source) | 233 | if (udp_port_key->udp_src != uh->source) |
213 | set_tp_port(skb, &uh->source, udp_port_key->udp_src, &uh->check); | 234 | set_udp_port(skb, &uh->source, udp_port_key->udp_src); |
214 | 235 | ||
215 | if (udp_port_key->udp_dst != uh->dest) | 236 | if (udp_port_key->udp_dst != uh->dest) |
216 | set_tp_port(skb, &uh->dest, udp_port_key->udp_dst, &uh->check); | 237 | set_udp_port(skb, &uh->dest, udp_port_key->udp_dst); |
217 | 238 | ||
218 | return 0; | 239 | return 0; |
219 | } | 240 | } |
220 | 241 | ||
221 | static int set_tcp_port(struct sk_buff *skb, | 242 | static int set_tcp(struct sk_buff *skb, const struct ovs_key_tcp *tcp_port_key) |
222 | const struct ovs_key_tcp *tcp_port_key) | ||
223 | { | 243 | { |
224 | struct tcphdr *th; | 244 | struct tcphdr *th; |
225 | int err; | 245 | int err; |
@@ -328,11 +348,11 @@ static int execute_set_action(struct sk_buff *skb, | |||
328 | break; | 348 | break; |
329 | 349 | ||
330 | case OVS_KEY_ATTR_TCP: | 350 | case OVS_KEY_ATTR_TCP: |
331 | err = set_tcp_port(skb, nla_data(nested_attr)); | 351 | err = set_tcp(skb, nla_data(nested_attr)); |
332 | break; | 352 | break; |
333 | 353 | ||
334 | case OVS_KEY_ATTR_UDP: | 354 | case OVS_KEY_ATTR_UDP: |
335 | err = set_udp_port(skb, nla_data(nested_attr)); | 355 | err = set_udp(skb, nla_data(nested_attr)); |
336 | break; | 356 | break; |
337 | } | 357 | } |
338 | 358 | ||
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index ce64c18b8c79..2c030505b335 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -1521,6 +1521,9 @@ static struct vport *lookup_vport(struct ovs_header *ovs_header, | |||
1521 | vport = ovs_vport_locate(nla_data(a[OVS_VPORT_ATTR_NAME])); | 1521 | vport = ovs_vport_locate(nla_data(a[OVS_VPORT_ATTR_NAME])); |
1522 | if (!vport) | 1522 | if (!vport) |
1523 | return ERR_PTR(-ENODEV); | 1523 | return ERR_PTR(-ENODEV); |
1524 | if (ovs_header->dp_ifindex && | ||
1525 | ovs_header->dp_ifindex != get_dpifindex(vport->dp)) | ||
1526 | return ERR_PTR(-ENODEV); | ||
1524 | return vport; | 1527 | return vport; |
1525 | } else if (a[OVS_VPORT_ATTR_PORT_NO]) { | 1528 | } else if (a[OVS_VPORT_ATTR_PORT_NO]) { |
1526 | u32 port_no = nla_get_u32(a[OVS_VPORT_ATTR_PORT_NO]); | 1529 | u32 port_no = nla_get_u32(a[OVS_VPORT_ATTR_PORT_NO]); |