Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Thu, 20 Sep 2007 19:42:47 +0000 (12:42 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Thu, 20 Sep 2007 19:42:47 +0000 (12:42 -0700)
* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
  [BNX2]: Add PHY workaround for 5709 A1.
  [PPP] L2TP: Fix skb handling in pppol2tp_xmit
  [PPP] L2TP: Fix skb handling in pppol2tp_recv_core
  [PPP] L2TP: Disallow non-UDP datagram sockets
  [PPP] pppoe: Fix double-free on skb after transmit failure
  [PKT_SCHED]: Fix 'SFQ qdisc crashes with limit of 2 packets'
  [NETFILTER]: MAINTAINERS update
  [NETFILTER]: nfnetlink_log: fix sending of multipart messages

MAINTAINERS
drivers/net/bnx2.c
drivers/net/pppoe.c
drivers/net/pppol2tp.c
net/netfilter/nfnetlink_log.c
net/sched/sch_sfq.c

index 9c54a5ef0ba7560232ee24fff40c3728fb277ecb..9a91d9e3f1f25c2e0aaded950fae19e4d6fa7e08 100644 (file)
@@ -2622,8 +2622,8 @@ P:        Harald Welte
 P:     Jozsef Kadlecsik
 P:     Patrick McHardy
 M:     kaber@trash.net
-L:     netfilter-devel@lists.netfilter.org
-L:     netfilter@lists.netfilter.org (subscribers-only)
+L:     netfilter-devel@vger.kernel.org
+L:     netfilter@vger.kernel.org
 L:     coreteam@netfilter.org
 W:     http://www.netfilter.org/
 W:     http://www.iptables.org/
@@ -2676,7 +2676,7 @@ M:        jmorris@namei.org
 P:     Hideaki YOSHIFUJI
 M:     yoshfuji@linux-ipv6.org
 P:     Patrick McHardy
-M:     kaber@coreworks.de
+M:     kaber@trash.net
 L:     netdev@vger.kernel.org
 T:     git kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6.git
 S:     Maintained
index 854d80c330ec8ab4449bddb23a1af1bf43927f0c..66eed22cbd21963e70b7edddc9929ef192dae186 100644 (file)
@@ -54,8 +54,8 @@
 
 #define DRV_MODULE_NAME                "bnx2"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "1.6.4"
-#define DRV_MODULE_RELDATE     "August 3, 2007"
+#define DRV_MODULE_VERSION     "1.6.5"
+#define DRV_MODULE_RELDATE     "September 20, 2007"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -6727,7 +6727,8 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
        } else if (CHIP_NUM(bp) == CHIP_NUM_5706 ||
                   CHIP_NUM(bp) == CHIP_NUM_5708)
                bp->phy_flags |= PHY_CRC_FIX_FLAG;
-       else if (CHIP_ID(bp) == CHIP_ID_5709_A0)
+       else if (CHIP_ID(bp) == CHIP_ID_5709_A0 ||
+                CHIP_ID(bp) == CHIP_ID_5709_A1)
                bp->phy_flags |= PHY_DIS_EARLY_DAC_FLAG;
 
        if ((CHIP_ID(bp) == CHIP_ID_5708_A0) ||
index 0d7f570b9a545eca66557ff3e903617a9f5b54f2..9b30cd600a643af5ba54f6c47c9be9e15f6c8dbe 100644 (file)
@@ -879,8 +879,7 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb)
        dev->hard_header(skb, dev, ETH_P_PPP_SES,
                         po->pppoe_pa.remote, NULL, data_len);
 
-       if (dev_queue_xmit(skb) < 0)
-               goto abort;
+       dev_queue_xmit(skb);
 
        return 1;
 
index 266e8b38fe10004366e78f3bce482add5037b407..abe91cb595f4fe723a561282f90ed4a1090ec495 100644 (file)
@@ -491,44 +491,46 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
        u16 hdrflags;
        u16 tunnel_id, session_id;
        int length;
-       struct udphdr *uh;
+       int offset;
 
        tunnel = pppol2tp_sock_to_tunnel(sock);
        if (tunnel == NULL)
                goto error;
 
+       /* UDP always verifies the packet length. */
+       __skb_pull(skb, sizeof(struct udphdr));
+
        /* Short packet? */
-       if (skb->len < sizeof(struct udphdr)) {
+       if (!pskb_may_pull(skb, 12)) {
                PRINTK(tunnel->debug, PPPOL2TP_MSG_DATA, KERN_INFO,
                       "%s: recv short packet (len=%d)\n", tunnel->name, skb->len);
                goto error;
        }
 
        /* Point to L2TP header */
-       ptr = skb->data + sizeof(struct udphdr);
+       ptr = skb->data;
 
        /* Get L2TP header flags */
        hdrflags = ntohs(*(__be16*)ptr);
 
        /* Trace packet contents, if enabled */
        if (tunnel->debug & PPPOL2TP_MSG_DATA) {
+               length = min(16u, skb->len);
+               if (!pskb_may_pull(skb, length))
+                       goto error;
+
                printk(KERN_DEBUG "%s: recv: ", tunnel->name);
 
-               for (length = 0; length < 16; length++)
-                       printk(" %02X", ptr[length]);
+               offset = 0;
+               do {
+                       printk(" %02X", ptr[offset]);
+               } while (++offset < length);
+
                printk("\n");
        }
 
        /* Get length of L2TP packet */
-       uh = (struct udphdr *) skb_transport_header(skb);
-       length = ntohs(uh->len) - sizeof(struct udphdr);
-
-       /* Too short? */
-       if (length < 12) {
-               PRINTK(tunnel->debug, PPPOL2TP_MSG_DATA, KERN_INFO,
-                      "%s: recv short L2TP packet (len=%d)\n", tunnel->name, length);
-               goto error;
-       }
+       length = skb->len;
 
        /* If type is control packet, it is handled by userspace. */
        if (hdrflags & L2TP_HDRFLAG_T) {
@@ -606,7 +608,6 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
                               "%s: recv data has no seq numbers when required. "
                               "Discarding\n", session->name);
                        session->stats.rx_seq_discards++;
-                       session->stats.rx_errors++;
                        goto discard;
                }
 
@@ -625,7 +626,6 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
                               "%s: recv data has no seq numbers when required. "
                               "Discarding\n", session->name);
                        session->stats.rx_seq_discards++;
-                       session->stats.rx_errors++;
                        goto discard;
                }
 
@@ -634,10 +634,14 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
        }
 
        /* If offset bit set, skip it. */
-       if (hdrflags & L2TP_HDRFLAG_O)
-               ptr += 2 + ntohs(*(__be16 *) ptr);
+       if (hdrflags & L2TP_HDRFLAG_O) {
+               offset = ntohs(*(__be16 *)ptr);
+               skb->transport_header += 2 + offset;
+               if (!pskb_may_pull(skb, skb_transport_offset(skb) + 2))
+                       goto discard;
+       }
 
-       skb_pull(skb, ptr - skb->data);
+       __skb_pull(skb, skb_transport_offset(skb));
 
        /* Skip PPP header, if present.  In testing, Microsoft L2TP clients
         * don't send the PPP header (PPP header compression enabled), but
@@ -673,7 +677,6 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
                         */
                        if (PPPOL2TP_SKB_CB(skb)->ns != session->nr) {
                                session->stats.rx_seq_discards++;
-                               session->stats.rx_errors++;
                                PRINTK(session->debug, PPPOL2TP_MSG_SEQ, KERN_DEBUG,
                                       "%s: oos pkt %hu len %d discarded, "
                                       "waiting for %hu, reorder_q_len=%d\n",
@@ -698,6 +701,7 @@ static int pppol2tp_recv_core(struct sock *sock, struct sk_buff *skb)
        return 0;
 
 discard:
+       session->stats.rx_errors++;
        kfree_skb(skb);
        sock_put(session->sock);
 
@@ -958,7 +962,6 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
        int data_len = skb->len;
        struct inet_sock *inet;
        __wsum csum = 0;
-       struct sk_buff *skb2 = NULL;
        struct udphdr *uh;
        unsigned int len;
 
@@ -989,41 +992,30 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
         */
        headroom = NET_SKB_PAD + sizeof(struct iphdr) +
                sizeof(struct udphdr) + hdr_len + sizeof(ppph);
-       if (skb_headroom(skb) < headroom) {
-               skb2 = skb_realloc_headroom(skb, headroom);
-               if (skb2 == NULL)
-                       goto abort;
-       } else
-               skb2 = skb;
-
-       /* Check that the socket has room */
-       if (atomic_read(&sk_tun->sk_wmem_alloc) < sk_tun->sk_sndbuf)
-               skb_set_owner_w(skb2, sk_tun);
-       else
-               goto discard;
+       if (skb_cow_head(skb, headroom))
+               goto abort;
 
        /* Setup PPP header */
-       skb_push(skb2, sizeof(ppph));
-       skb2->data[0] = ppph[0];
-       skb2->data[1] = ppph[1];
+       __skb_push(skb, sizeof(ppph));
+       skb->data[0] = ppph[0];
+       skb->data[1] = ppph[1];
 
        /* Setup L2TP header */
-       skb_push(skb2, hdr_len);
-       pppol2tp_build_l2tp_header(session, skb2->data);
+       pppol2tp_build_l2tp_header(session, __skb_push(skb, hdr_len));
 
        /* Setup UDP header */
        inet = inet_sk(sk_tun);
-       skb_push(skb2, sizeof(struct udphdr));
-       skb_reset_transport_header(skb2);
-       uh = (struct udphdr *) skb2->data;
+       __skb_push(skb, sizeof(*uh));
+       skb_reset_transport_header(skb);
+       uh = udp_hdr(skb);
        uh->source = inet->sport;
        uh->dest = inet->dport;
        uh->len = htons(sizeof(struct udphdr) + hdr_len + sizeof(ppph) + data_len);
        uh->check = 0;
 
-       /* Calculate UDP checksum if configured to do so */
+       /* *BROKEN* Calculate UDP checksum if configured to do so */
        if (sk_tun->sk_no_check != UDP_CSUM_NOXMIT)
-               csum = udp_csum_outgoing(sk_tun, skb2);
+               csum = udp_csum_outgoing(sk_tun, skb);
 
        /* Debug */
        if (session->send_seq)
@@ -1036,7 +1028,7 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
 
        if (session->debug & PPPOL2TP_MSG_DATA) {
                int i;
-               unsigned char *datap = skb2->data;
+               unsigned char *datap = skb->data;
 
                printk(KERN_DEBUG "%s: xmit:", session->name);
                for (i = 0; i < data_len; i++) {
@@ -1049,18 +1041,18 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
                printk("\n");
        }
 
-       memset(&(IPCB(skb2)->opt), 0, sizeof(IPCB(skb2)->opt));
-       IPCB(skb2)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
-                              IPSKB_REROUTED);
-       nf_reset(skb2);
+       memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
+       IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED |
+                             IPSKB_REROUTED);
+       nf_reset(skb);
 
        /* Get routing info from the tunnel socket */
-       dst_release(skb2->dst);
-       skb2->dst = sk_dst_get(sk_tun);
+       dst_release(skb->dst);
+       skb->dst = sk_dst_get(sk_tun);
 
        /* Queue the packet to IP for output */
-       len = skb2->len;
-       rc = ip_queue_xmit(skb2, 1);
+       len = skb->len;
+       rc = ip_queue_xmit(skb, 1);
 
        /* Update stats */
        if (rc >= 0) {
@@ -1073,17 +1065,12 @@ static int pppol2tp_xmit(struct ppp_channel *chan, struct sk_buff *skb)
                session->stats.tx_errors++;
        }
 
-       /* Free the original skb */
-       kfree_skb(skb);
-
        return 1;
 
-discard:
-       /* Free the new skb. Caller will free original skb. */
-       if (skb2 != skb)
-               kfree_skb(skb2);
 abort:
-       return 0;
+       /* Free the original skb */
+       kfree_skb(skb);
+       return 1;
 }
 
 /*****************************************************************************
@@ -1326,12 +1313,14 @@ static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id,
                goto err;
        }
 
+       sk = sock->sk;
+
        /* Quick sanity checks */
-       err = -ESOCKTNOSUPPORT;
-       if (sock->type != SOCK_DGRAM) {
+       err = -EPROTONOSUPPORT;
+       if (sk->sk_protocol != IPPROTO_UDP) {
                PRINTK(-1, PPPOL2TP_MSG_CONTROL, KERN_ERR,
-                      "tunl %hu: fd %d wrong type, got %d, expected %d\n",
-                      tunnel_id, fd, sock->type, SOCK_DGRAM);
+                      "tunl %hu: fd %d wrong protocol, got %d, expected %d\n",
+                      tunnel_id, fd, sk->sk_protocol, IPPROTO_UDP);
                goto err;
        }
        err = -EAFNOSUPPORT;
@@ -1343,7 +1332,6 @@ static struct sock *pppol2tp_prepare_tunnel_socket(int fd, u16 tunnel_id,
        }
 
        err = -ENOTCONN;
-       sk = sock->sk;
 
        /* Check if this socket has already been prepped */
        tunnel = (struct pppol2tp_tunnel *)sk->sk_user_data;
index e185a5b55913ce8b37af7de85b5e9a9f8b46f2e1..2351533a850755bebd1c9ca6b26c9462fd296cf8 100644 (file)
@@ -58,7 +58,6 @@ struct nfulnl_instance {
 
        unsigned int qlen;              /* number of nlmsgs in skb */
        struct sk_buff *skb;            /* pre-allocatd skb */
-       struct nlmsghdr *lastnlh;       /* netlink header of last msg in skb */
        struct timer_list timer;
        int peer_pid;                   /* PID of the peer process */
 
@@ -345,10 +344,12 @@ static struct sk_buff *nfulnl_alloc_skb(unsigned int inst_size,
 static int
 __nfulnl_send(struct nfulnl_instance *inst)
 {
-       int status;
+       int status = -1;
 
        if (inst->qlen > 1)
-               inst->lastnlh->nlmsg_type = NLMSG_DONE;
+               NLMSG_PUT(inst->skb, 0, 0,
+                         NLMSG_DONE,
+                         sizeof(struct nfgenmsg));
 
        status = nfnetlink_unicast(inst->skb, inst->peer_pid, MSG_DONTWAIT);
        if (status < 0) {
@@ -358,8 +359,8 @@ __nfulnl_send(struct nfulnl_instance *inst)
 
        inst->qlen = 0;
        inst->skb = NULL;
-       inst->lastnlh = NULL;
 
+nlmsg_failure:
        return status;
 }
 
@@ -538,7 +539,6 @@ __build_packet_message(struct nfulnl_instance *inst,
        }
 
        nlh->nlmsg_len = inst->skb->tail - old_tail;
-       inst->lastnlh = nlh;
        return 0;
 
 nlmsg_failure:
@@ -644,7 +644,8 @@ nfulnl_log_packet(unsigned int pf,
        }
 
        if (inst->qlen >= qthreshold ||
-           (inst->skb && size > skb_tailroom(inst->skb))) {
+           (inst->skb && size >
+            skb_tailroom(inst->skb) - sizeof(struct nfgenmsg))) {
                /* either the queue len is too high or we don't have
                 * enough room in the skb left. flush to userspace. */
                UDEBUG("flushing old skb\n");
index 9579573098598df19066e0910e181e68a94ef080..3a23e30bc79e3689dc1f16fc9c16d0d76f820865 100644 (file)
@@ -270,7 +270,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc* sch)
                        q->tail = x;
                }
        }
-       if (++sch->q.qlen < q->limit-1) {
+       if (++sch->q.qlen <= q->limit) {
                sch->bstats.bytes += skb->len;
                sch->bstats.packets++;
                return 0;
@@ -306,7 +306,7 @@ sfq_requeue(struct sk_buff *skb, struct Qdisc* sch)
                        q->tail = x;
                }
        }
-       if (++sch->q.qlen < q->limit - 1) {
+       if (++sch->q.qlen <= q->limit) {
                sch->qstats.requeues++;
                return 0;
        }
@@ -391,10 +391,10 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt)
        q->quantum = ctl->quantum ? : psched_mtu(sch->dev);
        q->perturb_period = ctl->perturb_period*HZ;
        if (ctl->limit)
-               q->limit = min_t(u32, ctl->limit, SFQ_DEPTH);
+               q->limit = min_t(u32, ctl->limit, SFQ_DEPTH - 2);
 
        qlen = sch->q.qlen;
-       while (sch->q.qlen >= q->limit-1)
+       while (sch->q.qlen > q->limit)
                sfq_drop(sch);
        qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen);
 
@@ -423,7 +423,7 @@ static int sfq_init(struct Qdisc *sch, struct rtattr *opt)
                q->dep[i+SFQ_DEPTH].next = i+SFQ_DEPTH;
                q->dep[i+SFQ_DEPTH].prev = i+SFQ_DEPTH;
        }
-       q->limit = SFQ_DEPTH;
+       q->limit = SFQ_DEPTH - 2;
        q->max_depth = 0;
        q->tail = SFQ_DEPTH;
        if (opt == NULL) {