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]); |
