diff options
Diffstat (limited to 'net/openvswitch/datapath.c')
| -rw-r--r-- | net/openvswitch/datapath.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index e44e631ea952..777716bc80f7 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
| @@ -421,6 +421,19 @@ static int validate_sample(const struct nlattr *attr, | |||
| 421 | return validate_actions(actions, key, depth + 1); | 421 | return validate_actions(actions, key, depth + 1); |
| 422 | } | 422 | } |
| 423 | 423 | ||
| 424 | static int validate_tp_port(const struct sw_flow_key *flow_key) | ||
| 425 | { | ||
| 426 | if (flow_key->eth.type == htons(ETH_P_IP)) { | ||
| 427 | if (flow_key->ipv4.tp.src && flow_key->ipv4.tp.dst) | ||
| 428 | return 0; | ||
| 429 | } else if (flow_key->eth.type == htons(ETH_P_IPV6)) { | ||
| 430 | if (flow_key->ipv6.tp.src && flow_key->ipv6.tp.dst) | ||
| 431 | return 0; | ||
| 432 | } | ||
| 433 | |||
| 434 | return -EINVAL; | ||
| 435 | } | ||
| 436 | |||
| 424 | static int validate_set(const struct nlattr *a, | 437 | static int validate_set(const struct nlattr *a, |
| 425 | const struct sw_flow_key *flow_key) | 438 | const struct sw_flow_key *flow_key) |
| 426 | { | 439 | { |
| @@ -462,18 +475,13 @@ static int validate_set(const struct nlattr *a, | |||
| 462 | if (flow_key->ip.proto != IPPROTO_TCP) | 475 | if (flow_key->ip.proto != IPPROTO_TCP) |
| 463 | return -EINVAL; | 476 | return -EINVAL; |
| 464 | 477 | ||
| 465 | if (!flow_key->ipv4.tp.src || !flow_key->ipv4.tp.dst) | 478 | return validate_tp_port(flow_key); |
| 466 | return -EINVAL; | ||
| 467 | |||
| 468 | break; | ||
| 469 | 479 | ||
| 470 | case OVS_KEY_ATTR_UDP: | 480 | case OVS_KEY_ATTR_UDP: |
| 471 | if (flow_key->ip.proto != IPPROTO_UDP) | 481 | if (flow_key->ip.proto != IPPROTO_UDP) |
| 472 | return -EINVAL; | 482 | return -EINVAL; |
| 473 | 483 | ||
| 474 | if (!flow_key->ipv4.tp.src || !flow_key->ipv4.tp.dst) | 484 | return validate_tp_port(flow_key); |
| 475 | return -EINVAL; | ||
| 476 | break; | ||
| 477 | 485 | ||
| 478 | default: | 486 | default: |
| 479 | return -EINVAL; | 487 | return -EINVAL; |
| @@ -1641,10 +1649,9 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info) | |||
| 1641 | reply = ovs_vport_cmd_build_info(vport, info->snd_pid, info->snd_seq, | 1649 | reply = ovs_vport_cmd_build_info(vport, info->snd_pid, info->snd_seq, |
| 1642 | OVS_VPORT_CMD_NEW); | 1650 | OVS_VPORT_CMD_NEW); |
| 1643 | if (IS_ERR(reply)) { | 1651 | if (IS_ERR(reply)) { |
| 1644 | err = PTR_ERR(reply); | ||
| 1645 | netlink_set_err(init_net.genl_sock, 0, | 1652 | netlink_set_err(init_net.genl_sock, 0, |
| 1646 | ovs_dp_vport_multicast_group.id, err); | 1653 | ovs_dp_vport_multicast_group.id, PTR_ERR(reply)); |
| 1647 | return 0; | 1654 | goto exit_unlock; |
| 1648 | } | 1655 | } |
| 1649 | 1656 | ||
| 1650 | genl_notify(reply, genl_info_net(info), info->snd_pid, | 1657 | genl_notify(reply, genl_info_net(info), info->snd_pid, |
