Merge branch 'net_ovs' of git://git.kernel.org/pub/scm/linux/kernel/git/pshelar/openvswitch
Pravin B Shelar says: ==================== Open vSwitch Following fixes are accumulated in ovs-repo. Three of them are related to protocol processing, one is related to memory leak in case of error and one is to fix race. Patch "Validate IPv6 flow key and mask values" has conflicts with net-next, Let me know if you want me to send the patch for net-next. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
c6ab766e81
|
@ -246,11 +246,11 @@ static void update_ipv6_checksum(struct sk_buff *skb, u8 l4_proto,
|
||||||
{
|
{
|
||||||
int transport_len = skb->len - skb_transport_offset(skb);
|
int transport_len = skb->len - skb_transport_offset(skb);
|
||||||
|
|
||||||
if (l4_proto == IPPROTO_TCP) {
|
if (l4_proto == NEXTHDR_TCP) {
|
||||||
if (likely(transport_len >= sizeof(struct tcphdr)))
|
if (likely(transport_len >= sizeof(struct tcphdr)))
|
||||||
inet_proto_csum_replace16(&tcp_hdr(skb)->check, skb,
|
inet_proto_csum_replace16(&tcp_hdr(skb)->check, skb,
|
||||||
addr, new_addr, 1);
|
addr, new_addr, 1);
|
||||||
} else if (l4_proto == IPPROTO_UDP) {
|
} else if (l4_proto == NEXTHDR_UDP) {
|
||||||
if (likely(transport_len >= sizeof(struct udphdr))) {
|
if (likely(transport_len >= sizeof(struct udphdr))) {
|
||||||
struct udphdr *uh = udp_hdr(skb);
|
struct udphdr *uh = udp_hdr(skb);
|
||||||
|
|
||||||
|
@ -261,6 +261,10 @@ static void update_ipv6_checksum(struct sk_buff *skb, u8 l4_proto,
|
||||||
uh->check = CSUM_MANGLED_0;
|
uh->check = CSUM_MANGLED_0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (l4_proto == NEXTHDR_ICMP) {
|
||||||
|
if (likely(transport_len >= sizeof(struct icmp6hdr)))
|
||||||
|
inet_proto_csum_replace16(&icmp6_hdr(skb)->icmp6_cksum,
|
||||||
|
skb, addr, new_addr, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -722,8 +726,6 @@ static int do_execute_actions(struct datapath *dp, struct sk_buff *skb,
|
||||||
|
|
||||||
case OVS_ACTION_ATTR_SAMPLE:
|
case OVS_ACTION_ATTR_SAMPLE:
|
||||||
err = sample(dp, skb, key, a);
|
err = sample(dp, skb, key, a);
|
||||||
if (unlikely(err)) /* skb already freed. */
|
|
||||||
return err;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1265,7 +1265,7 @@ static size_t ovs_dp_cmd_msg_size(void)
|
||||||
return msgsize;
|
return msgsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called with ovs_mutex or RCU read lock. */
|
/* Called with ovs_mutex. */
|
||||||
static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb,
|
static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb,
|
||||||
u32 portid, u32 seq, u32 flags, u8 cmd)
|
u32 portid, u32 seq, u32 flags, u8 cmd)
|
||||||
{
|
{
|
||||||
|
@ -1555,7 +1555,7 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info)
|
||||||
if (!reply)
|
if (!reply)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
rcu_read_lock();
|
ovs_lock();
|
||||||
dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
|
dp = lookup_datapath(sock_net(skb->sk), info->userhdr, info->attrs);
|
||||||
if (IS_ERR(dp)) {
|
if (IS_ERR(dp)) {
|
||||||
err = PTR_ERR(dp);
|
err = PTR_ERR(dp);
|
||||||
|
@ -1564,12 +1564,12 @@ static int ovs_dp_cmd_get(struct sk_buff *skb, struct genl_info *info)
|
||||||
err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid,
|
err = ovs_dp_cmd_fill_info(dp, reply, info->snd_portid,
|
||||||
info->snd_seq, 0, OVS_DP_CMD_NEW);
|
info->snd_seq, 0, OVS_DP_CMD_NEW);
|
||||||
BUG_ON(err < 0);
|
BUG_ON(err < 0);
|
||||||
rcu_read_unlock();
|
ovs_unlock();
|
||||||
|
|
||||||
return genlmsg_reply(reply, info);
|
return genlmsg_reply(reply, info);
|
||||||
|
|
||||||
err_unlock_free:
|
err_unlock_free:
|
||||||
rcu_read_unlock();
|
ovs_unlock();
|
||||||
kfree_skb(reply);
|
kfree_skb(reply);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -1581,8 +1581,8 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
||||||
int skip = cb->args[0];
|
int skip = cb->args[0];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
rcu_read_lock();
|
ovs_lock();
|
||||||
list_for_each_entry_rcu(dp, &ovs_net->dps, list_node) {
|
list_for_each_entry(dp, &ovs_net->dps, list_node) {
|
||||||
if (i >= skip &&
|
if (i >= skip &&
|
||||||
ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).portid,
|
ovs_dp_cmd_fill_info(dp, skb, NETLINK_CB(cb->skb).portid,
|
||||||
cb->nlh->nlmsg_seq, NLM_F_MULTI,
|
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)
|
||||||
break;
|
break;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
ovs_unlock();
|
||||||
|
|
||||||
cb->args[0] = i;
|
cb->args[0] = i;
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,7 @@ static bool match_validate(const struct sw_flow_match *match,
|
||||||
if (match->key->eth.type == htons(ETH_P_ARP)
|
if (match->key->eth.type == htons(ETH_P_ARP)
|
||||||
|| match->key->eth.type == htons(ETH_P_RARP)) {
|
|| match->key->eth.type == htons(ETH_P_RARP)) {
|
||||||
key_expected |= 1 << OVS_KEY_ATTR_ARP;
|
key_expected |= 1 << OVS_KEY_ATTR_ARP;
|
||||||
if (match->mask && (match->mask->key.eth.type == htons(0xffff)))
|
if (match->mask && (match->mask->key.tp.src == htons(0xff)))
|
||||||
mask_allowed |= 1 << OVS_KEY_ATTR_ARP;
|
mask_allowed |= 1 << OVS_KEY_ATTR_ARP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -689,6 +689,13 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs,
|
||||||
ipv6_key->ipv6_frag, OVS_FRAG_TYPE_MAX);
|
ipv6_key->ipv6_frag, OVS_FRAG_TYPE_MAX);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ipv6_key->ipv6_label & htonl(0xFFF00000)) {
|
||||||
|
OVS_NLERR("IPv6 flow label %x is out of range (max=%x).\n",
|
||||||
|
ntohl(ipv6_key->ipv6_label), (1 << 20) - 1);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
SW_FLOW_KEY_PUT(match, ipv6.label,
|
SW_FLOW_KEY_PUT(match, ipv6.label,
|
||||||
ipv6_key->ipv6_label, is_mask);
|
ipv6_key->ipv6_label, is_mask);
|
||||||
SW_FLOW_KEY_PUT(match, ip.proto,
|
SW_FLOW_KEY_PUT(match, ip.proto,
|
||||||
|
|
Loading…
Reference in a new issue