diff options
Diffstat (limited to 'net/openvswitch')
-rw-r--r-- | net/openvswitch/datapath.c | 63 | ||||
-rw-r--r-- | net/openvswitch/flow.c | 18 | ||||
-rw-r--r-- | net/openvswitch/vport-netdev.c | 10 |
3 files changed, 54 insertions, 37 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 29dbfcb65d92..d8277d29e710 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -322,7 +322,7 @@ static int queue_userspace_packet(int dp_ifindex, struct sk_buff *skb, | |||
322 | return -ENOMEM; | 322 | return -ENOMEM; |
323 | 323 | ||
324 | nskb = __vlan_put_tag(nskb, vlan_tx_tag_get(nskb)); | 324 | nskb = __vlan_put_tag(nskb, vlan_tx_tag_get(nskb)); |
325 | if (!skb) | 325 | if (!nskb) |
326 | return -ENOMEM; | 326 | return -ENOMEM; |
327 | 327 | ||
328 | nskb->vlan_tci = 0; | 328 | nskb->vlan_tci = 0; |
@@ -422,6 +422,19 @@ static int validate_sample(const struct nlattr *attr, | |||
422 | return validate_actions(actions, key, depth + 1); | 422 | return validate_actions(actions, key, depth + 1); |
423 | } | 423 | } |
424 | 424 | ||
425 | static int validate_tp_port(const struct sw_flow_key *flow_key) | ||
426 | { | ||
427 | if (flow_key->eth.type == htons(ETH_P_IP)) { | ||
428 | if (flow_key->ipv4.tp.src && flow_key->ipv4.tp.dst) | ||
429 | return 0; | ||
430 | } else if (flow_key->eth.type == htons(ETH_P_IPV6)) { | ||
431 | if (flow_key->ipv6.tp.src && flow_key->ipv6.tp.dst) | ||
432 | return 0; | ||
433 | } | ||
434 | |||
435 | return -EINVAL; | ||
436 | } | ||
437 | |||
425 | static int validate_set(const struct nlattr *a, | 438 | static int validate_set(const struct nlattr *a, |
426 | const struct sw_flow_key *flow_key) | 439 | const struct sw_flow_key *flow_key) |
427 | { | 440 | { |
@@ -463,18 +476,13 @@ static int validate_set(const struct nlattr *a, | |||
463 | if (flow_key->ip.proto != IPPROTO_TCP) | 476 | if (flow_key->ip.proto != IPPROTO_TCP) |
464 | return -EINVAL; | 477 | return -EINVAL; |
465 | 478 | ||
466 | if (!flow_key->ipv4.tp.src || !flow_key->ipv4.tp.dst) | 479 | return validate_tp_port(flow_key); |
467 | return -EINVAL; | ||
468 | |||
469 | break; | ||
470 | 480 | ||
471 | case OVS_KEY_ATTR_UDP: | 481 | case OVS_KEY_ATTR_UDP: |
472 | if (flow_key->ip.proto != IPPROTO_UDP) | 482 | if (flow_key->ip.proto != IPPROTO_UDP) |
473 | return -EINVAL; | 483 | return -EINVAL; |
474 | 484 | ||
475 | if (!flow_key->ipv4.tp.src || !flow_key->ipv4.tp.dst) | 485 | return validate_tp_port(flow_key); |
476 | return -EINVAL; | ||
477 | break; | ||
478 | 486 | ||
479 | default: | 487 | default: |
480 | return -EINVAL; | 488 | return -EINVAL; |
@@ -779,15 +787,18 @@ static int ovs_flow_cmd_fill_info(struct sw_flow *flow, struct datapath *dp, | |||
779 | tcp_flags = flow->tcp_flags; | 787 | tcp_flags = flow->tcp_flags; |
780 | spin_unlock_bh(&flow->lock); | 788 | spin_unlock_bh(&flow->lock); |
781 | 789 | ||
782 | if (used) | 790 | if (used && |
783 | NLA_PUT_U64(skb, OVS_FLOW_ATTR_USED, ovs_flow_used_time(used)); | 791 | nla_put_u64(skb, OVS_FLOW_ATTR_USED, ovs_flow_used_time(used))) |
792 | goto nla_put_failure; | ||
784 | 793 | ||
785 | if (stats.n_packets) | 794 | if (stats.n_packets && |
786 | NLA_PUT(skb, OVS_FLOW_ATTR_STATS, | 795 | nla_put(skb, OVS_FLOW_ATTR_STATS, |
787 | sizeof(struct ovs_flow_stats), &stats); | 796 | sizeof(struct ovs_flow_stats), &stats)) |
797 | goto nla_put_failure; | ||
788 | 798 | ||
789 | if (tcp_flags) | 799 | if (tcp_flags && |
790 | NLA_PUT_U8(skb, OVS_FLOW_ATTR_TCP_FLAGS, tcp_flags); | 800 | nla_put_u8(skb, OVS_FLOW_ATTR_TCP_FLAGS, tcp_flags)) |
801 | goto nla_put_failure; | ||
791 | 802 | ||
792 | /* If OVS_FLOW_ATTR_ACTIONS doesn't fit, skip dumping the actions if | 803 | /* If OVS_FLOW_ATTR_ACTIONS doesn't fit, skip dumping the actions if |
793 | * this is the first flow to be dumped into 'skb'. This is unusual for | 804 | * this is the first flow to be dumped into 'skb'. This is unusual for |
@@ -1169,7 +1180,8 @@ static int ovs_dp_cmd_fill_info(struct datapath *dp, struct sk_buff *skb, | |||
1169 | goto nla_put_failure; | 1180 | goto nla_put_failure; |
1170 | 1181 | ||
1171 | get_dp_stats(dp, &dp_stats); | 1182 | get_dp_stats(dp, &dp_stats); |
1172 | NLA_PUT(skb, OVS_DP_ATTR_STATS, sizeof(struct ovs_dp_stats), &dp_stats); | 1183 | if (nla_put(skb, OVS_DP_ATTR_STATS, sizeof(struct ovs_dp_stats), &dp_stats)) |
1184 | goto nla_put_failure; | ||
1173 | 1185 | ||
1174 | return genlmsg_end(skb, ovs_header); | 1186 | return genlmsg_end(skb, ovs_header); |
1175 | 1187 | ||
@@ -1469,14 +1481,16 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, | |||
1469 | 1481 | ||
1470 | ovs_header->dp_ifindex = get_dpifindex(vport->dp); | 1482 | ovs_header->dp_ifindex = get_dpifindex(vport->dp); |
1471 | 1483 | ||
1472 | NLA_PUT_U32(skb, OVS_VPORT_ATTR_PORT_NO, vport->port_no); | 1484 | if (nla_put_u32(skb, OVS_VPORT_ATTR_PORT_NO, vport->port_no) || |
1473 | NLA_PUT_U32(skb, OVS_VPORT_ATTR_TYPE, vport->ops->type); | 1485 | nla_put_u32(skb, OVS_VPORT_ATTR_TYPE, vport->ops->type) || |
1474 | NLA_PUT_STRING(skb, OVS_VPORT_ATTR_NAME, vport->ops->get_name(vport)); | 1486 | nla_put_string(skb, OVS_VPORT_ATTR_NAME, vport->ops->get_name(vport)) || |
1475 | NLA_PUT_U32(skb, OVS_VPORT_ATTR_UPCALL_PID, vport->upcall_pid); | 1487 | nla_put_u32(skb, OVS_VPORT_ATTR_UPCALL_PID, vport->upcall_pid)) |
1488 | goto nla_put_failure; | ||
1476 | 1489 | ||
1477 | ovs_vport_get_stats(vport, &vport_stats); | 1490 | ovs_vport_get_stats(vport, &vport_stats); |
1478 | NLA_PUT(skb, OVS_VPORT_ATTR_STATS, sizeof(struct ovs_vport_stats), | 1491 | if (nla_put(skb, OVS_VPORT_ATTR_STATS, sizeof(struct ovs_vport_stats), |
1479 | &vport_stats); | 1492 | &vport_stats)) |
1493 | goto nla_put_failure; | ||
1480 | 1494 | ||
1481 | err = ovs_vport_get_options(vport, skb); | 1495 | err = ovs_vport_get_options(vport, skb); |
1482 | if (err == -EMSGSIZE) | 1496 | if (err == -EMSGSIZE) |
@@ -1644,10 +1658,9 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info) | |||
1644 | reply = ovs_vport_cmd_build_info(vport, info->snd_pid, info->snd_seq, | 1658 | reply = ovs_vport_cmd_build_info(vport, info->snd_pid, info->snd_seq, |
1645 | OVS_VPORT_CMD_NEW); | 1659 | OVS_VPORT_CMD_NEW); |
1646 | if (IS_ERR(reply)) { | 1660 | if (IS_ERR(reply)) { |
1647 | err = PTR_ERR(reply); | ||
1648 | netlink_set_err(init_net.genl_sock, 0, | 1661 | netlink_set_err(init_net.genl_sock, 0, |
1649 | ovs_dp_vport_multicast_group.id, err); | 1662 | ovs_dp_vport_multicast_group.id, PTR_ERR(reply)); |
1650 | return 0; | 1663 | goto exit_unlock; |
1651 | } | 1664 | } |
1652 | 1665 | ||
1653 | genl_notify(reply, genl_info_net(info), info->snd_pid, | 1666 | genl_notify(reply, genl_info_net(info), info->snd_pid, |
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index 1115dcf70362..b7f38b161909 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c | |||
@@ -1176,11 +1176,13 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb) | |||
1176 | struct ovs_key_ethernet *eth_key; | 1176 | struct ovs_key_ethernet *eth_key; |
1177 | struct nlattr *nla, *encap; | 1177 | struct nlattr *nla, *encap; |
1178 | 1178 | ||
1179 | if (swkey->phy.priority) | 1179 | if (swkey->phy.priority && |
1180 | NLA_PUT_U32(skb, OVS_KEY_ATTR_PRIORITY, swkey->phy.priority); | 1180 | nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, swkey->phy.priority)) |
1181 | goto nla_put_failure; | ||
1181 | 1182 | ||
1182 | if (swkey->phy.in_port != USHRT_MAX) | 1183 | if (swkey->phy.in_port != USHRT_MAX && |
1183 | NLA_PUT_U32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port); | 1184 | nla_put_u32(skb, OVS_KEY_ATTR_IN_PORT, swkey->phy.in_port)) |
1185 | goto nla_put_failure; | ||
1184 | 1186 | ||
1185 | nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key)); | 1187 | nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key)); |
1186 | if (!nla) | 1188 | if (!nla) |
@@ -1190,8 +1192,9 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb) | |||
1190 | memcpy(eth_key->eth_dst, swkey->eth.dst, ETH_ALEN); | 1192 | memcpy(eth_key->eth_dst, swkey->eth.dst, ETH_ALEN); |
1191 | 1193 | ||
1192 | if (swkey->eth.tci || swkey->eth.type == htons(ETH_P_8021Q)) { | 1194 | if (swkey->eth.tci || swkey->eth.type == htons(ETH_P_8021Q)) { |
1193 | NLA_PUT_BE16(skb, OVS_KEY_ATTR_ETHERTYPE, htons(ETH_P_8021Q)); | 1195 | if (nla_put_be16(skb, OVS_KEY_ATTR_ETHERTYPE, htons(ETH_P_8021Q)) || |
1194 | NLA_PUT_BE16(skb, OVS_KEY_ATTR_VLAN, swkey->eth.tci); | 1196 | nla_put_be16(skb, OVS_KEY_ATTR_VLAN, swkey->eth.tci)) |
1197 | goto nla_put_failure; | ||
1195 | encap = nla_nest_start(skb, OVS_KEY_ATTR_ENCAP); | 1198 | encap = nla_nest_start(skb, OVS_KEY_ATTR_ENCAP); |
1196 | if (!swkey->eth.tci) | 1199 | if (!swkey->eth.tci) |
1197 | goto unencap; | 1200 | goto unencap; |
@@ -1202,7 +1205,8 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb) | |||
1202 | if (swkey->eth.type == htons(ETH_P_802_2)) | 1205 | if (swkey->eth.type == htons(ETH_P_802_2)) |
1203 | goto unencap; | 1206 | goto unencap; |
1204 | 1207 | ||
1205 | NLA_PUT_BE16(skb, OVS_KEY_ATTR_ETHERTYPE, swkey->eth.type); | 1208 | if (nla_put_be16(skb, OVS_KEY_ATTR_ETHERTYPE, swkey->eth.type)) |
1209 | goto nla_put_failure; | ||
1206 | 1210 | ||
1207 | if (swkey->eth.type == htons(ETH_P_IP)) { | 1211 | if (swkey->eth.type == htons(ETH_P_IP)) { |
1208 | struct ovs_key_ipv4 *ipv4_key; | 1212 | struct ovs_key_ipv4 *ipv4_key; |
diff --git a/net/openvswitch/vport-netdev.c b/net/openvswitch/vport-netdev.c index 54a456d0b407..6ea3551cc78c 100644 --- a/net/openvswitch/vport-netdev.c +++ b/net/openvswitch/vport-netdev.c | |||
@@ -140,9 +140,9 @@ int ovs_netdev_get_ifindex(const struct vport *vport) | |||
140 | return netdev_vport->dev->ifindex; | 140 | return netdev_vport->dev->ifindex; |
141 | } | 141 | } |
142 | 142 | ||
143 | static unsigned packet_length(const struct sk_buff *skb) | 143 | static unsigned int packet_length(const struct sk_buff *skb) |
144 | { | 144 | { |
145 | unsigned length = skb->len - ETH_HLEN; | 145 | unsigned int length = skb->len - ETH_HLEN; |
146 | 146 | ||
147 | if (skb->protocol == htons(ETH_P_8021Q)) | 147 | if (skb->protocol == htons(ETH_P_8021Q)) |
148 | length -= VLAN_HLEN; | 148 | length -= VLAN_HLEN; |
@@ -157,9 +157,9 @@ static int netdev_send(struct vport *vport, struct sk_buff *skb) | |||
157 | int len; | 157 | int len; |
158 | 158 | ||
159 | if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) { | 159 | if (unlikely(packet_length(skb) > mtu && !skb_is_gso(skb))) { |
160 | if (net_ratelimit()) | 160 | net_warn_ratelimited("%s: dropped over-mtu packet: %d > %d\n", |
161 | pr_warn("%s: dropped over-mtu packet: %d > %d\n", | 161 | ovs_dp_name(vport->dp), |
162 | ovs_dp_name(vport->dp), packet_length(skb), mtu); | 162 | packet_length(skb), mtu); |
163 | goto error; | 163 | goto error; |
164 | } | 164 | } |
165 | 165 | ||