diff options
Diffstat (limited to 'net/openvswitch')
-rw-r--r-- | net/openvswitch/actions.c | 10 | ||||
-rw-r--r-- | net/openvswitch/datapath.c | 14 | ||||
-rw-r--r-- | net/openvswitch/flow_netlink.c | 9 |
3 files changed, 21 insertions, 12 deletions
diff --git a/net/openvswitch/actions.c b/net/openvswitch/actions.c index 006886dbee36..8c4229b11c34 100644 --- a/net/openvswitch/actions.c +++ b/net/openvswitch/actions.c | |||
@@ -246,11 +246,11 @@ static void update_ipv6_checksum(struct sk_buff *skb, u8 l4_proto, | |||
246 | { | 246 | { |
247 | int transport_len = skb->len - skb_transport_offset(skb); | 247 | int transport_len = skb->len - skb_transport_offset(skb); |
248 | 248 | ||
249 | if (l4_proto == IPPROTO_TCP) { | 249 | if (l4_proto == NEXTHDR_TCP) { |
250 | if (likely(transport_len >= sizeof(struct tcphdr))) | 250 | if (likely(transport_len >= sizeof(struct tcphdr))) |
251 | inet_proto_csum_replace16(&tcp_hdr(skb)->check, skb, | 251 | inet_proto_csum_replace16(&tcp_hdr(skb)->check, skb, |
252 | addr, new_addr, 1); | 252 | addr, new_addr, 1); |
253 | } else if (l4_proto == IPPROTO_UDP) { | 253 | } else if (l4_proto == NEXTHDR_UDP) { |
254 | if (likely(transport_len >= sizeof(struct udphdr))) { | 254 | if (likely(transport_len >= sizeof(struct udphdr))) { |
255 | struct udphdr *uh = udp_hdr(skb); | 255 | struct udphdr *uh = udp_hdr(skb); |
256 | 256 | ||
@@ -261,6 +261,10 @@ static void update_ipv6_checksum(struct sk_buff *skb, u8 l4_proto, | |||
261 | uh->check = CSUM_MANGLED_0; | 261 | uh->check = CSUM_MANGLED_0; |
262 | } | 262 | } |
263 | } | 263 | } |
264 | } else if (l4_proto == NEXTHDR_ICMP) { | ||
265 | if (likely(transport_len >= sizeof(struct icmp6hdr))) | ||
266 | inet_proto_csum_replace16(&icmp6_hdr(skb)->icmp6_cksum, | ||
267 | skb, addr, new_addr, 1); | ||
264 | } | 268 | } |
265 | } | 269 | } |
266 | 270 | ||
@@ -722,8 +726,6 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb, | |||
722 | 726 | ||
723 | case OVS_ACTION_ATTR_SAMPLE: | 727 | case OVS_ACTION_ATTR_SAMPLE: |
724 | err = sample(dp, skb, key, a); | 728 | err = sample(dp, skb, key, a); |
725 | if (unlikely(err)) /* skb already freed. */ | ||
726 | return err; | ||
727 | break; | 729 | break; |
728 | } | 730 | } |
729 | 731 | ||
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index e6d7255183eb..f9e556b56086 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -1265,7 +1265,7 @@ static size_t ovs_dp_cmd_msg_size(void) | |||
1265 | return msgsize; | 1265 | return msgsize; |
1266 | } | 1266 | } |
1267 | 1267 | ||
1268 | /* Called with ovs_mutex or RCU read lock. */ | 1268 | /* Called with ovs_mutex. */ |
1269 | static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb, | 1269 | static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb, |
1270 | u32 portid, u32 seq, u32 flags, u8 cmd) | 1270 | u32 portid, u32 seq, u32 flags, u8 cmd) |
1271 | { | 1271 | { |
@@ -1555,7 +1555,7 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info) | |||
1555 | if (!reply) | 1555 | if (!reply) |
1556 | return -ENOMEM; | 1556 | return -ENOMEM; |
1557 | 1557 | ||
1558 | rcu_read_lock(); | 1558 | ovs_lock(); |
1559 | dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs); | 1559 | dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs); |
1560 | if (IS_ERR(dp)) { | 1560 | if (IS_ERR(dp)) { |
1561 | err = PTR_ERR(dp); | 1561 | err = PTR_ERR(dp); |
@@ -1564,12 +1564,12 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info) | |||
1564 | err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid, | 1564 | err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid, |
1565 | info->snd_seq, 0, OVS_DP_CMD_NEW); | 1565 | info->snd_seq, 0, OVS_DP_CMD_NEW); |
1566 | BUG_ON(err < 0); | 1566 | BUG_ON(err < 0); |
1567 | rcu_read_unlock(); | 1567 | ovs_unlock(); |
1568 | 1568 | ||
1569 | return genlmsg_reply(reply, info); | 1569 | return genlmsg_reply(reply, info); |
1570 | 1570 | ||
1571 | err_unlock_free: | 1571 | err_unlock_free: |
1572 | rcu_read_unlock(); | 1572 | ovs_unlock(); |
1573 | kfree_skb(reply); | 1573 | kfree_skb(reply); |
1574 | return err; | 1574 | return err; |
1575 | } | 1575 | } |
@@ -1581,8 +1581,8 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
1581 | int skip = cb->args[0]; | 1581 | int skip = cb->args[0]; |
1582 | int i = 0; | 1582 | int i = 0; |
1583 | 1583 | ||
1584 | rcu_read_lock(); | 1584 | ovs_lock(); |
1585 | list_for_each_entry_rcu(dp, &ovs_net->dps, list_node) { | 1585 | list_for_each_entry(dp, &ovs_net->dps, list_node) { |
1586 | if (i >= skip && | 1586 | if (i >= skip && |
1587 | ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).portid, | 1587 | ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).portid, |
1588 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 1588 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
@@ -1590,7 +1590,7 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
1590 | break; | 1590 | break; |
1591 | i++; | 1591 | i++; |
1592 | } | 1592 | } |
1593 | rcu_read_unlock(); | 1593 | ovs_unlock(); |
1594 | 1594 | ||
1595 | cb->args[0] = i; | 1595 | cb->args[0] = i; |
1596 | 1596 | ||
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index 939bcb32100f..089b195c064a 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c | |||
@@ -145,7 +145,7 @@ static bool match_validate(const struct sw_flow_match *match, | |||
145 | if (match->key->eth.type == htons(ETH_P_ARP) | 145 | if (match->key->eth.type == htons(ETH_P_ARP) |
146 | || match->key->eth.type == htons(ETH_P_RARP)) { | 146 | || match->key->eth.type == htons(ETH_P_RARP)) { |
147 | key_expected |= 1 << OVS_KEY_ATTR_ARP; | 147 | key_expected |= 1 << OVS_KEY_ATTR_ARP; |
148 | if (match->mask && (match->mask->key.eth.type == htons(0xffff))) | 148 | if (match->mask && (match->mask->key.tp.src == htons(0xff))) |
149 | mask_allowed |= 1 << OVS_KEY_ATTR_ARP; | 149 | mask_allowed |= 1 << OVS_KEY_ATTR_ARP; |
150 | } | 150 | } |
151 | 151 | ||
@@ -689,6 +689,13 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs, | |||
689 | ipv6_key->ipv6_frag, OVS_FRAG_TYPE_MAX); | 689 | ipv6_key->ipv6_frag, OVS_FRAG_TYPE_MAX); |
690 | return -EINVAL; | 690 | return -EINVAL; |
691 | } | 691 | } |
692 | |||
693 | if (!is_mask && ipv6_key->ipv6_label & htonl(0xFFF00000)) { | ||
694 | OVS_NLERR("IPv6 flow label %x is out of range (max=%x).\n", | ||
695 | ntohl(ipv6_key->ipv6_label), (1 << 20) - 1); | ||
696 | return -EINVAL; | ||
697 | } | ||
698 | |||
692 | SW_FLOW_KEY_PUT(match, ipv6.label, | 699 | SW_FLOW_KEY_PUT(match, ipv6.label, |
693 | ipv6_key->ipv6_label, is_mask); | 700 | ipv6_key->ipv6_label, is_mask); |
694 | SW_FLOW_KEY_PUT(match, ip.proto, | 701 | SW_FLOW_KEY_PUT(match, ip.proto, |