Merge branch 'sfc-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/bwh/sfc
authorDavid S. Miller <davem@davemloft.net>
Thu, 10 May 2012 02:49:57 +0000 (22:49 -0400)
committerDavid S. Miller <davem@davemloft.net>
Thu, 10 May 2012 02:49:57 +0000 (22:49 -0400)
drivers/net/ethernet/realtek/r8169.c
net/openvswitch/datapath.c
net/openvswitch/flow.c

index f54509377efad8354345176fdb9c1951a9fdd4de..ce6b44d1f2529ed82fe61e66582657a671a5385a 100644 (file)
 #define R8169_MSG_DEFAULT \
        (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN)
 
-#define TX_BUFFS_AVAIL(tp) \
-       (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1)
+#define TX_SLOTS_AVAIL(tp) \
+       (tp->dirty_tx + NUM_TX_DESC - tp->cur_tx)
+
+/* A skbuff with nr_frags needs nr_frags+1 entries in the tx queue */
+#define TX_FRAGS_READY_FOR(tp,nr_frags) \
+       (TX_SLOTS_AVAIL(tp) >= (nr_frags + 1))
 
 /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
    The RTL chips use a 64 element hash table based on the Ethernet CRC. */
@@ -5115,7 +5119,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
        u32 opts[2];
        int frags;
 
-       if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) {
+       if (unlikely(!TX_FRAGS_READY_FOR(tp, skb_shinfo(skb)->nr_frags))) {
                netif_err(tp, drv, dev, "BUG! Tx Ring full when queue awake!\n");
                goto err_stop_0;
        }
@@ -5169,7 +5173,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
 
        mmiowb();
 
-       if (TX_BUFFS_AVAIL(tp) < MAX_SKB_FRAGS) {
+       if (!TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) {
                /* Avoid wrongly optimistic queue wake-up: rtl_tx thread must
                 * not miss a ring update when it notices a stopped queue.
                 */
@@ -5183,7 +5187,7 @@ static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
                 * can't.
                 */
                smp_mb();
-               if (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)
+               if (TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS))
                        netif_wake_queue(dev);
        }
 
@@ -5306,7 +5310,7 @@ static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
                 */
                smp_mb();
                if (netif_queue_stopped(dev) &&
-                   (TX_BUFFS_AVAIL(tp) >= MAX_SKB_FRAGS)) {
+                   TX_FRAGS_READY_FOR(tp, MAX_SKB_FRAGS)) {
                        netif_wake_queue(dev);
                }
                /*
index e44e631ea952d3aadd1770f1e85b69b38b004325..777716bc80f7c2ad183a7309c037f4cc9c84fffa 100644 (file)
@@ -421,6 +421,19 @@ static int validate_sample(const struct nlattr *attr,
        return validate_actions(actions, key, depth + 1);
 }
 
+static int validate_tp_port(const struct sw_flow_key *flow_key)
+{
+       if (flow_key->eth.type == htons(ETH_P_IP)) {
+               if (flow_key->ipv4.tp.src && flow_key->ipv4.tp.dst)
+                       return 0;
+       } else if (flow_key->eth.type == htons(ETH_P_IPV6)) {
+               if (flow_key->ipv6.tp.src && flow_key->ipv6.tp.dst)
+                       return 0;
+       }
+
+       return -EINVAL;
+}
+
 static int validate_set(const struct nlattr *a,
                        const struct sw_flow_key *flow_key)
 {
@@ -462,18 +475,13 @@ static int validate_set(const struct nlattr *a,
                if (flow_key->ip.proto != IPPROTO_TCP)
                        return -EINVAL;
 
-               if (!flow_key->ipv4.tp.src || !flow_key->ipv4.tp.dst)
-                       return -EINVAL;
-
-               break;
+               return validate_tp_port(flow_key);
 
        case OVS_KEY_ATTR_UDP:
                if (flow_key->ip.proto != IPPROTO_UDP)
                        return -EINVAL;
 
-               if (!flow_key->ipv4.tp.src || !flow_key->ipv4.tp.dst)
-                       return -EINVAL;
-               break;
+               return validate_tp_port(flow_key);
 
        default:
                return -EINVAL;
@@ -1641,10 +1649,9 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info)
        reply = ovs_vport_cmd_build_info(vport, info->snd_pid, info->snd_seq,
                                         OVS_VPORT_CMD_NEW);
        if (IS_ERR(reply)) {
-               err = PTR_ERR(reply);
                netlink_set_err(init_net.genl_sock, 0,
-                               ovs_dp_vport_multicast_group.id, err);
-               return 0;
+                               ovs_dp_vport_multicast_group.id, PTR_ERR(reply));
+               goto exit_unlock;
        }
 
        genl_notify(reply, genl_info_net(info), info->snd_pid,
index 1252c3081ef12740a0b818fbd58ae3ab6e9b870e..2a11ec2383eede7b653a36d09b46f1048e6f0434 100644 (file)
@@ -183,7 +183,8 @@ void ovs_flow_used(struct sw_flow *flow, struct sk_buff *skb)
        u8 tcp_flags = 0;
 
        if (flow->key.eth.type == htons(ETH_P_IP) &&
-           flow->key.ip.proto == IPPROTO_TCP) {
+           flow->key.ip.proto == IPPROTO_TCP &&
+           likely(skb->len >= skb_transport_offset(skb) + sizeof(struct tcphdr))) {
                u8 *tcp = (u8 *)tcp_hdr(skb);
                tcp_flags = *(tcp + TCP_FLAGS_OFFSET) & TCP_FLAG_MASK;
        }