Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
authorLinus Torvalds <torvalds@g5.osdl.org>
Thu, 8 Sep 2005 00:20:11 +0000 (17:20 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Thu, 8 Sep 2005 00:20:11 +0000 (17:20 -0700)
35 files changed:
crypto/cipher.c
drivers/net/arcnet/arcnet.c
include/linux/netfilter_ipv4/ip_conntrack.h
include/linux/netfilter_ipv4/ip_conntrack_core.h
include/linux/netfilter_ipv4/ip_nat_rule.h
include/linux/skbuff.h
include/net/ax25.h
net/ax25/af_ax25.c
net/ax25/ax25_addr.c
net/ax25/ax25_route.c
net/ax25/ax25_uid.c
net/core/sock.c
net/ipv4/ip_fragment.c
net/ipv4/netfilter/Kconfig
net/ipv4/netfilter/Makefile
net/ipv4/netfilter/ip_conntrack_amanda.c
net/ipv4/netfilter/ip_conntrack_core.c
net/ipv4/netfilter/ip_conntrack_ftp.c
net/ipv4/netfilter/ip_conntrack_irc.c
net/ipv4/netfilter/ip_conntrack_netbios_ns.c [new file with mode: 0644]
net/ipv4/netfilter/ip_conntrack_netlink.c
net/ipv4/netfilter/ip_conntrack_proto_tcp.c
net/ipv4/netfilter/ip_conntrack_standalone.c
net/ipv4/netfilter/ip_conntrack_tftp.c
net/ipv4/netfilter/ip_nat_rule.c
net/ipv4/netfilter/ip_nat_standalone.c
net/netfilter/nfnetlink_queue.c
net/netlink/af_netlink.c
net/netrom/af_netrom.c
net/netrom/nr_route.c
net/packet/af_packet.c
net/rose/af_rose.c
net/rose/rose_route.c
net/rose/rose_subr.c
net/socket.c

index 3df47f93c9db01e0a19da8af237ab800ae9d34b1..dfd4bcfc59758332d8ae82fc1d0db2e009c9b26a 100644 (file)
@@ -191,6 +191,8 @@ static unsigned int cbc_process_encrypt(const struct cipher_desc *desc,
        u8 *iv = desc->info;
        unsigned int done = 0;
 
+       nbytes -= bsize;
+
        do {
                xor(iv, src);
                fn(crypto_tfm_ctx(tfm), dst, iv);
@@ -198,7 +200,7 @@ static unsigned int cbc_process_encrypt(const struct cipher_desc *desc,
 
                src += bsize;
                dst += bsize;
-       } while ((done += bsize) < nbytes);
+       } while ((done += bsize) <= nbytes);
 
        return done;
 }
@@ -219,6 +221,8 @@ static unsigned int cbc_process_decrypt(const struct cipher_desc *desc,
        u8 *iv = desc->info;
        unsigned int done = 0;
 
+       nbytes -= bsize;
+
        do {
                u8 *tmp_dst = *dst_p;
 
@@ -230,7 +234,7 @@ static unsigned int cbc_process_decrypt(const struct cipher_desc *desc,
 
                src += bsize;
                dst += bsize;
-       } while ((done += bsize) < nbytes);
+       } while ((done += bsize) <= nbytes);
 
        return done;
 }
@@ -243,12 +247,14 @@ static unsigned int ecb_process(const struct cipher_desc *desc, u8 *dst,
        void (*fn)(void *, u8 *, const u8 *) = desc->crfn;
        unsigned int done = 0;
 
+       nbytes -= bsize;
+
        do {
                fn(crypto_tfm_ctx(tfm), dst, src);
 
                src += bsize;
                dst += bsize;
-       } while ((done += bsize) < nbytes);
+       } while ((done += bsize) <= nbytes);
 
        return done;
 }
index 4f9f69e22c1bd3c2f63c17f245d95f67e3565ca3..12ef52c193a39a2e1743bda3292110c4f76279d8 100644 (file)
@@ -597,7 +597,7 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
        struct ArcProto *proto;
        int txbuf;
        unsigned long flags;
-       int freeskb = 0;
+       int freeskb, retval;
 
        BUGMSG(D_DURING,
               "transmit requested (status=%Xh, txbufs=%d/%d, len=%d, protocol %x)\n",
@@ -615,7 +615,7 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
        if (skb->len - ARC_HDR_SIZE > XMTU && !proto->continue_tx) {
                BUGMSG(D_NORMAL, "fixme: packet too large: compensating badly!\n");
                dev_kfree_skb(skb);
-               return 0;       /* don't try again */
+               return NETDEV_TX_OK;    /* don't try again */
        }
 
        /* We're busy transmitting a packet... */
@@ -623,8 +623,11 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
 
        spin_lock_irqsave(&lp->lock, flags);
        AINTMASK(0);
-
-       txbuf = get_arcbuf(dev);
+       if(lp->next_tx == -1)
+               txbuf = get_arcbuf(dev);
+       else {
+               txbuf = -1;
+       }
        if (txbuf != -1) {
                if (proto->prepare_tx(dev, pkt, skb->len, txbuf) &&
                    !proto->ack_tx) {
@@ -638,6 +641,8 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
                        lp->outgoing.skb = skb;
                        lp->outgoing.pkt = pkt;
 
+                       freeskb = 0;
+
                        if (proto->continue_tx &&
                            proto->continue_tx(dev, txbuf)) {
                          BUGMSG(D_NORMAL,
@@ -645,10 +650,12 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
                                 "(proto='%c')\n", proto->suffix);
                        }
                }
-
+               retval = NETDEV_TX_OK;
+               dev->trans_start = jiffies;
                lp->next_tx = txbuf;
        } else {
-               freeskb = 1;
+               retval = NETDEV_TX_BUSY;
+               freeskb = 0;
        }
 
        BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS());
@@ -664,7 +671,7 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev)
        if (freeskb) {
                dev_kfree_skb(skb);
        }
-       return 0;               /* no need to try again */
+       return retval;          /* no need to try again */
 }
 
 
@@ -690,7 +697,6 @@ static int go_tx(struct net_device *dev)
        /* start sending */
        ACOMMAND(TXcmd | (lp->cur_tx << 3));
 
-       dev->trans_start = jiffies;
        lp->stats.tx_packets++;
        lp->lasttrans_dest = lp->lastload_dest;
        lp->lastload_dest = 0;
@@ -917,6 +923,9 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 
                        BUGMSG(D_RECON, "Network reconfiguration detected (status=%Xh)\n",
                               status);
+                       /* MYRECON bit is at bit 7 of diagstatus */
+                       if(diagstatus & 0x80)
+                               BUGMSG(D_RECON,"Put out that recon myself\n");
 
                        /* is the RECON info empty or old? */
                        if (!lp->first_recon || !lp->last_recon ||
index 088742befe4975dd3f9c08441c99da207f4aae20..7e033e9271a88efbb2b214e4834176147d33d28f 100644 (file)
@@ -263,6 +263,9 @@ struct ip_conntrack_expect
        /* Unique ID */
        unsigned int id;
 
+       /* Flags */
+       unsigned int flags;
+
 #ifdef CONFIG_IP_NF_NAT_NEEDED
        /* This is the original per-proto part, used to map the
         * expected connection the way the recipient expects. */
@@ -272,6 +275,8 @@ struct ip_conntrack_expect
 #endif
 };
 
+#define IP_CT_EXPECT_PERMANENT 0x1
+
 static inline struct ip_conntrack *
 tuplehash_to_ctrack(const struct ip_conntrack_tuple_hash *hash)
 {
index dc4d2a0575de9c666ac45428b81d47e634ac1805..907d4f5ca5dc50f2384ad69730f8c5686e085cf1 100644 (file)
@@ -52,7 +52,7 @@ static inline int ip_conntrack_confirm(struct sk_buff **pskb)
        return ret;
 }
 
-extern void __ip_ct_expect_unlink_destroy(struct ip_conntrack_expect *exp);
+extern void ip_ct_unlink_expect(struct ip_conntrack_expect *exp);
 
 extern struct list_head *ip_conntrack_hash;
 extern struct list_head ip_conntrack_expect_list;
index fecd2a06dcd81166c8fd2037e57bd4d5c3d22ccd..73b9552e6a8941eea8c3c30ba74c9bb96ad69c2e 100644 (file)
@@ -19,5 +19,10 @@ extern unsigned int
 alloc_null_binding(struct ip_conntrack *conntrack,
                   struct ip_nat_info *info,
                   unsigned int hooknum);
+
+extern unsigned int
+alloc_null_binding_confirmed(struct ip_conntrack *conntrack,
+                            struct ip_nat_info *info,
+                            unsigned int hooknum);
 #endif
 #endif /* _IP_NAT_RULE_H */
index 42edce6abe2349fc428c6321f81af81578ca5cb2..da7da9c0ed1b50e1f8dac7c08b919c104c287e30 100644 (file)
@@ -1251,7 +1251,7 @@ extern void skb_add_mtu(int mtu);
  *     This function converts the offset back to a struct timeval and stores
  *     it in stamp.
  */
-static inline void skb_get_timestamp(struct sk_buff *skb, struct timeval *stamp)
+static inline void skb_get_timestamp(const struct sk_buff *skb, struct timeval *stamp)
 {
        stamp->tv_sec  = skb->tstamp.off_sec;
        stamp->tv_usec = skb->tstamp.off_usec;
@@ -1270,7 +1270,7 @@ static inline void skb_get_timestamp(struct sk_buff *skb, struct timeval *stamp)
  *     This function converts a struct timeval to an offset and stores
  *     it in the skb.
  */
-static inline void skb_set_timestamp(struct sk_buff *skb, struct timeval *stamp)
+static inline void skb_set_timestamp(struct sk_buff *skb, const struct timeval *stamp)
 {
        skb->tstamp.off_sec  = stamp->tv_sec - skb_tv_base.tv_sec;
        skb->tstamp.off_usec = stamp->tv_usec - skb_tv_base.tv_usec;
index 926eed543023906328aa7a95908d9e54039bfc2c..364b046e9f478b545316236d592bf29039c3fad2 100644 (file)
@@ -257,7 +257,7 @@ extern struct sock *ax25_make_new(struct sock *, struct ax25_dev *);
 
 /* ax25_addr.c */
 extern ax25_address null_ax25_address;
-extern char *ax2asc(ax25_address *);
+extern char *ax2asc(char *buf, ax25_address *);
 extern ax25_address *asc2ax(char *);
 extern int  ax25cmp(ax25_address *, ax25_address *);
 extern int  ax25digicmp(ax25_digi *, ax25_digi *);
index ea43dfb774e228c3e044c283a7c6be11fd4195eb..ed705ddad56be0e9bb6b69580b681b1e5c91f6d0 100644 (file)
@@ -1874,6 +1874,7 @@ static void ax25_info_stop(struct seq_file *seq, void *v)
 static int ax25_info_show(struct seq_file *seq, void *v)
 {
        ax25_cb *ax25 = v;
+       char buf[11];
        int k;
 
 
@@ -1885,13 +1886,13 @@ static int ax25_info_show(struct seq_file *seq, void *v)
        seq_printf(seq, "%8.8lx %s %s%s ",
                   (long) ax25,
                   ax25->ax25_dev == NULL? "???" : ax25->ax25_dev->dev->name,
-                  ax2asc(&ax25->source_addr),
+                  ax2asc(buf, &ax25->source_addr),
                   ax25->iamdigi? "*":"");
-       seq_printf(seq, "%s", ax2asc(&ax25->dest_addr));
+       seq_printf(seq, "%s", ax2asc(buf, &ax25->dest_addr));
 
        for (k=0; (ax25->digipeat != NULL) && (k < ax25->digipeat->ndigi); k++) {
                seq_printf(seq, ",%s%s",
-                          ax2asc(&ax25->digipeat->calls[k]),
+                          ax2asc(buf, &ax25->digipeat->calls[k]),
                           ax25->digipeat->repeated[k]? "*":"");
        }
 
index f4fa6dfb846e6aa4cf2359584e4efed452dc8f58..dca179daf4150d3202e290709e611e13505dbd7d 100644 (file)
@@ -36,9 +36,8 @@ ax25_address null_ax25_address = {{0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00}};
 /*
  *     ax25 -> ascii conversion
  */
-char *ax2asc(ax25_address *a)
+char *ax2asc(char *buf, ax25_address *a)
 {
-       static char buf[11];
        char c, *s;
        int n;
 
index c288526da4ce194c65f49878f40cd686cedd1216..26b77d9722201232d7adfcb2bb27dcc3fb90e246 100644 (file)
@@ -298,6 +298,8 @@ static void ax25_rt_seq_stop(struct seq_file *seq, void *v)
 
 static int ax25_rt_seq_show(struct seq_file *seq, void *v)
 {
+       char buf[11];
+
        if (v == SEQ_START_TOKEN)
                seq_puts(seq, "callsign  dev  mode digipeaters\n");
        else {
@@ -308,7 +310,7 @@ static int ax25_rt_seq_show(struct seq_file *seq, void *v)
                if (ax25cmp(&ax25_rt->callsign, &null_ax25_address) == 0)
                        callsign = "default";
                else
-                       callsign = ax2asc(&ax25_rt->callsign);
+                       callsign = ax2asc(buf, &ax25_rt->callsign);
 
                seq_printf(seq, "%-9s %-4s",
                        callsign,
@@ -328,7 +330,8 @@ static int ax25_rt_seq_show(struct seq_file *seq, void *v)
 
                if (ax25_rt->digipeat != NULL)
                        for (i = 0; i < ax25_rt->digipeat->ndigi; i++)
-                               seq_printf(seq, " %s", ax2asc(&ax25_rt->digipeat->calls[i]));
+                               seq_printf(seq, " %s",
+                                    ax2asc(buf, &ax25_rt->digipeat->calls[i]));
 
                seq_puts(seq, "\n");
        }
index a8b3822f3ee42155032c914c31e80e1354b1fbfb..d53cc8615865f4b2e9ea7cc82452b57ddbbcef99 100644 (file)
@@ -168,12 +168,14 @@ static void ax25_uid_seq_stop(struct seq_file *seq, void *v)
 
 static int ax25_uid_seq_show(struct seq_file *seq, void *v)
 {
+       char buf[11];
+
        if (v == SEQ_START_TOKEN)
                seq_printf(seq, "Policy: %d\n", ax25_uid_policy);
        else {
                struct ax25_uid_assoc *pt = v;
 
-               seq_printf(seq, "%6d %s\n", pt->uid, ax2asc(&pt->call));
+               seq_printf(seq, "%6d %s\n", pt->uid, ax2asc(buf, &pt->call));
        }
        return 0;
 }
index c13594579bfb193009e22e2fbc0635cfd3a0b14b..ac63b56e23b29c45113df81fa226bc2c9568d758 100644 (file)
@@ -341,11 +341,11 @@ set_rcvbuf:
                                sock_reset_flag(sk, SOCK_LINGER);
                        else {
 #if (BITS_PER_LONG == 32)
-                               if (ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ)
+                               if ((unsigned int)ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ)
                                        sk->sk_lingertime = MAX_SCHEDULE_TIMEOUT;
                                else
 #endif
-                                       sk->sk_lingertime = ling.l_linger * HZ;
+                                       sk->sk_lingertime = (unsigned int)ling.l_linger * HZ;
                                sock_set_flag(sk, SOCK_LINGER);
                        }
                        break;
@@ -1529,6 +1529,8 @@ EXPORT_SYMBOL(proto_register);
 void proto_unregister(struct proto *prot)
 {
        write_lock(&proto_list_lock);
+       list_del(&prot->node);
+       write_unlock(&proto_list_lock);
 
        if (prot->slab != NULL) {
                kmem_cache_destroy(prot->slab);
@@ -1550,9 +1552,6 @@ void proto_unregister(struct proto *prot)
                kfree(name);
                prot->twsk_slab = NULL;
        }
-
-       list_del(&prot->node);
-       write_unlock(&proto_list_lock);
 }
 
 EXPORT_SYMBOL(proto_unregister);
index 9e6e683cc34d4396560b19bfc9b1d4f2bca2f9df..e7d26d9943c2d5aea36b465304b8b98db12a7abd 100644 (file)
@@ -457,7 +457,7 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
 
        if (pskb_pull(skb, ihl) == NULL)
                goto err;
-       if (pskb_trim(skb, end-offset))
+       if (pskb_trim_rcsum(skb, end-offset))
                goto err;
 
        /* Find out which fragments are in front and at the back of us
index e046f55218142d091ba71da87e6af0747bad7277..30aa8e2ee214263c6b1d124f5566eb56c804bf58 100644 (file)
@@ -34,6 +34,7 @@ config IP_NF_CT_ACCT
 
 config IP_NF_CONNTRACK_MARK
        bool  'Connection mark tracking support'
+       depends on IP_NF_CONNTRACK
        help
          This option enables support for connection marks, used by the
          `CONNMARK' target and `connmark' match. Similar to the mark value
@@ -85,6 +86,25 @@ config IP_NF_IRC
 
          To compile it as a module, choose M here.  If unsure, say Y.
 
+config IP_NF_NETBIOS_NS
+       tristate "NetBIOS name service protocol support (EXPERIMENTAL)"
+       depends on IP_NF_CONNTRACK && EXPERIMENTAL
+       help
+         NetBIOS name service requests are sent as broadcast messages from an
+         unprivileged port and responded to with unicast messages to the
+         same port. This make them hard to firewall properly because connection
+         tracking doesn't deal with broadcasts. This helper tracks locally
+         originating NetBIOS name service requests and the corresponding
+         responses. It relies on correct IP address configuration, specifically
+         netmask and broadcast address. When properly configured, the output
+         of "ip address show" should look similar to this:
+
+         $ ip -4 address show eth0
+         4: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
+             inet 172.16.2.252/24 brd 172.16.2.255 scope global eth0
+         
+         To compile it as a module, choose M here.  If unsure, say N.
+
 config IP_NF_TFTP
        tristate "TFTP protocol support"
        depends on IP_NF_CONNTRACK
index a7bd38f5052202c8230e572f27080b39c40db416..1ba0db746817cf2809e80c073899c8a37ba3d50c 100644 (file)
@@ -21,6 +21,7 @@ obj-$(CONFIG_IP_NF_AMANDA) += ip_conntrack_amanda.o
 obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o
 obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o
 obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o
+obj-$(CONFIG_IP_NF_NETBIOS_NS) += ip_conntrack_netbios_ns.o
 
 # NAT helpers 
 obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.o
index be4c9eb3243f94698f35de5af6d11aad219137a7..dc20881004bc57731b4ae348b8272d26622b863e 100644 (file)
@@ -108,6 +108,7 @@ static int help(struct sk_buff **pskb,
                }
 
                exp->expectfn = NULL;
+               exp->flags = 0;
 
                exp->tuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;
                exp->tuple.src.u.tcp.port = 0;
index a0648600190e1b16827e0f363ea138b759f9f656..19cba16e6e1e587c5281a997ac67ec7fa291da8a 100644 (file)
@@ -197,7 +197,7 @@ ip_ct_invert_tuple(struct ip_conntrack_tuple *inverse,
 
 
 /* ip_conntrack_expect helper functions */
-static void unlink_expect(struct ip_conntrack_expect *exp)
+void ip_ct_unlink_expect(struct ip_conntrack_expect *exp)
 {
        ASSERT_WRITE_LOCK(&ip_conntrack_lock);
        IP_NF_ASSERT(!timer_pending(&exp->timeout));
@@ -207,18 +207,12 @@ static void unlink_expect(struct ip_conntrack_expect *exp)
        ip_conntrack_expect_put(exp);
 }
 
-void __ip_ct_expect_unlink_destroy(struct ip_conntrack_expect *exp)
-{
-       unlink_expect(exp);
-       ip_conntrack_expect_put(exp);
-}
-
 static void expectation_timed_out(unsigned long ul_expect)
 {
        struct ip_conntrack_expect *exp = (void *)ul_expect;
 
        write_lock_bh(&ip_conntrack_lock);
-       unlink_expect(exp);
+       ip_ct_unlink_expect(exp);
        write_unlock_bh(&ip_conntrack_lock);
        ip_conntrack_expect_put(exp);
 }
@@ -264,10 +258,14 @@ find_expectation(const struct ip_conntrack_tuple *tuple)
                   master ct never got confirmed, we'd hold a reference to it
                   and weird things would happen to future packets). */
                if (ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)
-                   && is_confirmed(i->master)
-                   && del_timer(&i->timeout)) {
-                       unlink_expect(i);
-                       return i;
+                   && is_confirmed(i->master)) {
+                       if (i->flags & IP_CT_EXPECT_PERMANENT) {
+                               atomic_inc(&i->use);
+                               return i;
+                       } else if (del_timer(&i->timeout)) {
+                               ip_ct_unlink_expect(i);
+                               return i;
+                       }
                }
        }
        return NULL;
@@ -284,7 +282,7 @@ void ip_ct_remove_expectations(struct ip_conntrack *ct)
 
        list_for_each_entry_safe(i, tmp, &ip_conntrack_expect_list, list) {
                if (i->master == ct && del_timer(&i->timeout)) {
-                       unlink_expect(i);
+                       ip_ct_unlink_expect(i);
                        ip_conntrack_expect_put(i);
                }
        }
@@ -925,7 +923,7 @@ void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp)
        /* choose the the oldest expectation to evict */
        list_for_each_entry_reverse(i, &ip_conntrack_expect_list, list) {
                if (expect_matches(i, exp) && del_timer(&i->timeout)) {
-                       unlink_expect(i);
+                       ip_ct_unlink_expect(i);
                        write_unlock_bh(&ip_conntrack_lock);
                        ip_conntrack_expect_put(i);
                        return;
@@ -934,6 +932,9 @@ void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp)
        write_unlock_bh(&ip_conntrack_lock);
 }
 
+/* We don't increase the master conntrack refcount for non-fulfilled
+ * conntracks. During the conntrack destruction, the expectations are 
+ * always killed before the conntrack itself */
 struct ip_conntrack_expect *ip_conntrack_expect_alloc(struct ip_conntrack *me)
 {
        struct ip_conntrack_expect *new;
@@ -944,17 +945,14 @@ struct ip_conntrack_expect *ip_conntrack_expect_alloc(struct ip_conntrack *me)
                return NULL;
        }
        new->master = me;
-       atomic_inc(&new->master->ct_general.use);
        atomic_set(&new->use, 1);
        return new;
 }
 
 void ip_conntrack_expect_put(struct ip_conntrack_expect *exp)
 {
-       if (atomic_dec_and_test(&exp->use)) {
-               ip_conntrack_put(exp->master);
+       if (atomic_dec_and_test(&exp->use))
                kmem_cache_free(ip_conntrack_expect_cachep, exp);
-       }
 }
 
 static void ip_conntrack_expect_insert(struct ip_conntrack_expect *exp)
@@ -982,7 +980,7 @@ static void evict_oldest_expect(struct ip_conntrack *master)
        list_for_each_entry_reverse(i, &ip_conntrack_expect_list, list) {
                if (i->master == master) {
                        if (del_timer(&i->timeout)) {
-                               unlink_expect(i);
+                               ip_ct_unlink_expect(i);
                                ip_conntrack_expect_put(i);
                        }
                        break;
@@ -1099,7 +1097,7 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me)
        /* Get rid of expectations */
        list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list, list) {
                if (exp->master->helper == me && del_timer(&exp->timeout)) {
-                       unlink_expect(exp);
+                       ip_ct_unlink_expect(exp);
                        ip_conntrack_expect_put(exp);
                }
        }
index 3a2627db1729b81ed9002e086a107e8bd0d50595..1b79ec36085ffed8896fdd9882126b24400fd57c 100644 (file)
@@ -421,6 +421,7 @@ static int help(struct sk_buff **pskb,
                  { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
 
        exp->expectfn = NULL;
+       exp->flags = 0;
 
        /* Now, NAT might want to mangle the packet, and register the
         * (possibly changed) expectation itself. */
index 25438eec21a11008c48d607f1c375f34c8ed81f9..d7a8a98c05e1982a9b4b13839ac169a44d00deea 100644 (file)
@@ -221,6 +221,7 @@ static int help(struct sk_buff **pskb,
                                { { 0, { 0 } },
                                  { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }});
                        exp->expectfn = NULL;
+                       exp->flags = 0;
                        if (ip_nat_irc_hook)
                                ret = ip_nat_irc_hook(pskb, ctinfo, 
                                                      addr_beg_p - ib_ptr,
diff --git a/net/ipv4/netfilter/ip_conntrack_netbios_ns.c b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c
new file mode 100644 (file)
index 0000000..2b5cf9c
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ *      NetBIOS name service broadcast connection tracking helper
+ *
+ *      (c) 2005 Patrick McHardy <kaber@trash.net>
+ *
+ *      This program is free software; you can redistribute it and/or
+ *      modify it under the terms of the GNU General Public License
+ *      as published by the Free Software Foundation; either version
+ *      2 of the License, or (at your option) any later version.
+ */
+/*
+ *      This helper tracks locally originating NetBIOS name service
+ *      requests by issuing permanent expectations (valid until
+ *      timing out) matching all reply connections from the
+ *      destination network. The only NetBIOS specific thing is
+ *      actually the port number.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <linux/netdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/udp.h>
+#include <net/route.h>
+
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
+
+MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
+MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper");
+MODULE_LICENSE("GPL");
+
+static unsigned int timeout = 3;
+module_param(timeout, int, 0600);
+MODULE_PARM_DESC(timeout, "timeout for master connection/replies in seconds");
+
+static int help(struct sk_buff **pskb,
+                struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)
+{
+       struct ip_conntrack_expect *exp;
+       struct iphdr *iph = (*pskb)->nh.iph;
+       struct udphdr _uh, *uh;
+       struct rtable *rt = (struct rtable *)(*pskb)->dst;
+       struct in_device *in_dev;
+       u_int32_t mask = 0;
+
+       /* we're only interested in locally generated packets */
+       if ((*pskb)->sk == NULL)
+               goto out;
+       if (rt == NULL || !(rt->rt_flags & RTCF_BROADCAST))
+               goto out;
+       if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL)
+               goto out;
+
+       rcu_read_lock();
+       in_dev = __in_dev_get(rt->u.dst.dev);
+       if (in_dev != NULL) {
+               for_primary_ifa(in_dev) {
+                       if (ifa->ifa_broadcast == iph->daddr) {
+                               mask = ifa->ifa_mask;
+                               break;
+                       }
+               } endfor_ifa(in_dev);
+       }
+       rcu_read_unlock();
+
+       if (mask == 0)
+               goto out;
+
+       uh = skb_header_pointer(*pskb, iph->ihl * 4, sizeof(_uh), &_uh);
+       BUG_ON(uh == NULL);
+
+       exp = ip_conntrack_expect_alloc(ct);
+       if (exp == NULL)
+               goto out;
+       memset(&exp->tuple, 0, sizeof(exp->tuple));
+       exp->tuple.src.ip         = iph->daddr & mask;
+       exp->tuple.dst.ip         = iph->saddr;
+       exp->tuple.dst.u.udp.port = uh->source;
+       exp->tuple.dst.protonum   = IPPROTO_UDP;
+
+       memset(&exp->mask, 0, sizeof(exp->mask));
+       exp->mask.src.ip          = mask;
+       exp->mask.dst.ip          = 0xFFFFFFFF;
+       exp->mask.dst.u.udp.port  = 0xFFFF;
+       exp->mask.dst.protonum    = 0xFF;
+
+       exp->expectfn             = NULL;
+       exp->flags                = IP_CT_EXPECT_PERMANENT;
+
+       ip_conntrack_expect_related(exp);
+       ip_conntrack_expect_put(exp);
+
+       ip_ct_refresh_acct(ct, ctinfo, NULL, timeout * HZ);
+out:
+       return NF_ACCEPT;
+}
+
+static struct ip_conntrack_helper helper = {
+       .name                   = "netbios-ns",
+       .tuple = {
+               .src.u.udp.port = __constant_htons(137),
+               .dst.protonum   = IPPROTO_UDP,
+       },
+       .mask = {
+               .src.u.udp.port = 0xFFFF,
+               .dst.protonum   = 0xFF,
+       },
+       .max_expected           = 1,
+       .me                     = THIS_MODULE,
+       .help                   = help,
+};
+
+static int __init init(void)
+{
+       helper.timeout = timeout;
+       return ip_conntrack_helper_register(&helper);
+}
+
+static void __exit fini(void)
+{
+       ip_conntrack_helper_unregister(&helper);
+}
+
+module_init(init);
+module_exit(fini);
index a4e9278db4eda7d2050e95a2344e504c34b8f396..15aef356474264926ef3449a69751897e51ae8ce 100644 (file)
@@ -1349,8 +1349,10 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list,
                                         list) {
                        if (exp->master->helper == h 
-                           && del_timer(&exp->timeout))
-                               __ip_ct_expect_unlink_destroy(exp);
+                           && del_timer(&exp->timeout)) {
+                               ip_ct_unlink_expect(exp);
+                               ip_conntrack_expect_put(exp);
+                       }
                }
                write_unlock(&ip_conntrack_lock);
        } else {
@@ -1358,8 +1360,10 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
                write_lock_bh(&ip_conntrack_lock);
                list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list,
                                         list) {
-                       if (del_timer(&exp->timeout))
-                               __ip_ct_expect_unlink_destroy(exp);
+                       if (del_timer(&exp->timeout)) {
+                               ip_ct_unlink_expect(exp);
+                               ip_conntrack_expect_put(exp);
+                       }
                }
                write_unlock_bh(&ip_conntrack_lock);
        }
@@ -1413,6 +1417,7 @@ ctnetlink_create_expect(struct nfattr *cda[])
        }
        
        exp->expectfn = NULL;
+       exp->flags = 0;
        exp->master = ct;
        memcpy(&exp->tuple, &tuple, sizeof(struct ip_conntrack_tuple));
        memcpy(&exp->mask, &mask, sizeof(struct ip_conntrack_tuple));
index f23ef1f88c46b40701f956b74f49f3c9d7ef9ceb..1985abc59d2497f13c453750277d71da0bf73946 100644 (file)
@@ -349,6 +349,7 @@ static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa,
        return 0;
 
 nfattr_failure:
+       read_unlock_bh(&tcp_lock);
        return -1;
 }
 #endif
index ee5895afd0c3e8a0bfb932c56bc623f16de0cd05..ae3e3e655db555054c14dd34372e792abb2e25e5 100644 (file)
@@ -998,7 +998,7 @@ EXPORT_SYMBOL(ip_conntrack_expect_related);
 EXPORT_SYMBOL(ip_conntrack_unexpect_related);
 EXPORT_SYMBOL_GPL(ip_conntrack_expect_list);
 EXPORT_SYMBOL_GPL(__ip_conntrack_expect_find);
-EXPORT_SYMBOL_GPL(__ip_ct_expect_unlink_destroy);
+EXPORT_SYMBOL_GPL(ip_ct_unlink_expect);
 
 EXPORT_SYMBOL(ip_conntrack_tuple_taken);
 EXPORT_SYMBOL(ip_ct_gather_frags);
index f8ff170f390a3ad8bd8e5f0100658d7d1908008f..d2b590533452e201d48c8b1bc172a0661828b917 100644 (file)
@@ -75,6 +75,7 @@ static int tftp_help(struct sk_buff **pskb,
                exp->mask.dst.u.udp.port = 0xffff;
                exp->mask.dst.protonum = 0xff;
                exp->expectfn = NULL;
+               exp->flags = 0;
 
                DEBUGP("expect: ");
                DUMP_TUPLE(&exp->tuple);
index 60d70fa41a156a63bd4abb9a04a894297a8fa0d7..cb66b8bddeb3d63eb2ef23ee359a2491c6511c63 100644 (file)
@@ -255,6 +255,27 @@ alloc_null_binding(struct ip_conntrack *conntrack,
        return ip_nat_setup_info(conntrack, &range, hooknum);
 }
 
+unsigned int
+alloc_null_binding_confirmed(struct ip_conntrack *conntrack,
+                             struct ip_nat_info *info,
+                             unsigned int hooknum)
+{
+       u_int32_t ip
+               = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
+                  ? conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip
+                  : conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip);
+       u_int16_t all
+               = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
+                  ? conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.all
+                  : conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.all);
+       struct ip_nat_range range
+               = { IP_NAT_RANGE_MAP_IPS, ip, ip, { all }, { all } };
+
+       DEBUGP("Allocating NULL binding for confirmed %p (%u.%u.%u.%u)\n",
+              conntrack, NIPQUAD(ip));
+       return ip_nat_setup_info(conntrack, &range, hooknum);
+}
+
 int ip_nat_rule_find(struct sk_buff **pskb,
                     unsigned int hooknum,
                     const struct net_device *in,
index 89db052add81e4a61def654f00cc4bcc9d92f889..0ff368b131f6bac3bfd27e8201b519ce700b64bd 100644 (file)
@@ -123,8 +123,12 @@ ip_nat_fn(unsigned int hooknum,
                if (!ip_nat_initialized(ct, maniptype)) {
                        unsigned int ret;
 
-                       /* LOCAL_IN hook doesn't have a chain!  */
-                       if (hooknum == NF_IP_LOCAL_IN)
+                       if (unlikely(is_confirmed(ct)))
+                               /* NAT module was loaded late */
+                               ret = alloc_null_binding_confirmed(ct, info,
+                                                                  hooknum);
+                       else if (hooknum == NF_IP_LOCAL_IN)
+                               /* LOCAL_IN hook doesn't have a chain!  */
                                ret = alloc_null_binding(ct, info, hooknum);
                        else
                                ret = ip_nat_rule_find(pskb, hooknum,
index 249bddb28acd9057bccac1b89960ecc8994041b3..f81fe8c52e99ba2d3d90762cecc9ac4194fbf956 100644 (file)
@@ -371,6 +371,12 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
                break;
        
        case NFQNL_COPY_PACKET:
+               if (entry->skb->ip_summed == CHECKSUM_HW &&
+                   (*errp = skb_checksum_help(entry->skb,
+                                              entry->info->outdev == NULL))) {
+                       spin_unlock_bh(&queue->lock);
+                       return NULL;
+               }
                if (queue->copy_range == 0 
                    || queue->copy_range > entry->skb->len)
                        data_len = entry->skb->len;
@@ -636,7 +642,7 @@ nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e)
        if (!skb_make_writable(&e->skb, data_len))
                return -ENOMEM;
        memcpy(e->skb->data, data, data_len);
-
+       e->skb->ip_summed = CHECKSUM_NONE;
        return 0;
 }
 
index 62435ffc61846396e6a862dd9907319a1a3b8688..a64e1d5ce3ca8f38ae3cb76c41d62d4bd0a8d136 100644 (file)
@@ -398,24 +398,13 @@ static int netlink_create(struct socket *sock, int protocol)
        if (nl_table[protocol].registered &&
            try_module_get(nl_table[protocol].module))
                module = nl_table[protocol].module;
-       else
-               err = -EPROTONOSUPPORT;
        groups = nl_table[protocol].groups;
        netlink_unlock_table();
 
-       if (err || (err = __netlink_create(sock, protocol) < 0))
+       if ((err = __netlink_create(sock, protocol) < 0))
                goto out_module;
 
        nlk = nlk_sk(sock->sk);
-
-       nlk->groups = kmalloc(NLGRPSZ(groups), GFP_KERNEL);
-       if (nlk->groups == NULL) {
-               err = -ENOMEM;
-               goto out_module;
-       }
-       memset(nlk->groups, 0, NLGRPSZ(groups));
-       nlk->ngroups = groups;
-
        nlk->module = module;
 out:
        return err;
@@ -534,6 +523,29 @@ netlink_update_subscriptions(struct sock *sk, unsigned int subscriptions)
        nlk->subscriptions = subscriptions;
 }
 
+static int netlink_alloc_groups(struct sock *sk)
+{
+       struct netlink_sock *nlk = nlk_sk(sk);
+       unsigned int groups;
+       int err = 0;
+
+       netlink_lock_table();
+       groups = nl_table[sk->sk_protocol].groups;
+       if (!nl_table[sk->sk_protocol].registered)
+               err = -ENOENT;
+       netlink_unlock_table();
+
+       if (err)
+               return err;
+
+       nlk->groups = kmalloc(NLGRPSZ(groups), GFP_KERNEL);
+       if (nlk->groups == NULL)
+               return -ENOMEM;
+       memset(nlk->groups, 0, NLGRPSZ(groups));
+       nlk->ngroups = groups;
+       return 0;
+}
+
 static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len)
 {
        struct sock *sk = sock->sk;
@@ -545,8 +557,15 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len
                return -EINVAL;
 
        /* Only superuser is allowed to listen multicasts */
-       if (nladdr->nl_groups && !netlink_capable(sock, NL_NONROOT_RECV))
-               return -EPERM;
+       if (nladdr->nl_groups) {
+               if (!netlink_capable(sock, NL_NONROOT_RECV))
+                       return -EPERM;
+               if (nlk->groups == NULL) {
+                       err = netlink_alloc_groups(sk);
+                       if (err)
+                               return err;
+               }
+       }
 
        if (nlk->pid) {
                if (nladdr->nl_pid != nlk->pid)
@@ -559,7 +578,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len
                        return err;
        }
 
-       if (!nladdr->nl_groups && !(u32)nlk->groups[0])
+       if (!nladdr->nl_groups && (nlk->groups == NULL || !(u32)nlk->groups[0]))
                return 0;
 
        netlink_table_grab();
@@ -620,7 +639,7 @@ static int netlink_getname(struct socket *sock, struct sockaddr *addr, int *addr
                nladdr->nl_groups = netlink_group_mask(nlk->dst_group);
        } else {
                nladdr->nl_pid = nlk->pid;
-               nladdr->nl_groups = nlk->groups[0];
+               nladdr->nl_groups = nlk->groups ? nlk->groups[0] : 0;
        }
        return 0;
 }
@@ -976,6 +995,11 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
 
                if (!netlink_capable(sock, NL_NONROOT_RECV))
                        return -EPERM;
+               if (nlk->groups == NULL) {
+                       err = netlink_alloc_groups(sk);
+                       if (err)
+                               return err;
+               }
                if (!val || val - 1 >= nlk->ngroups)
                        return -EINVAL;
                netlink_table_grab();
@@ -1483,8 +1507,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v)
                           s,
                           s->sk_protocol,
                           nlk->pid,
-                          nlk->flags & NETLINK_KERNEL_SOCKET ?
-                               0 : (unsigned int)nlk->groups[0],
+                          nlk->groups ? (u32)nlk->groups[0] : 0,
                           atomic_read(&s->sk_rmem_alloc),
                           atomic_read(&s->sk_wmem_alloc),
                           nlk->cb,
index 4b53de982114d242706ba632960781190641c85a..f4578c759ffcc3350ebbd708c7f0a2ffef52c587 100644 (file)
@@ -1261,6 +1261,7 @@ static int nr_info_show(struct seq_file *seq, void *v)
        struct net_device *dev;
        struct nr_sock *nr;
        const char *devname;
+       char buf[11];
 
        if (v == SEQ_START_TOKEN)
                seq_puts(seq,
@@ -1276,11 +1277,11 @@ static int nr_info_show(struct seq_file *seq, void *v)
                else
                        devname = dev->name;
 
-               seq_printf(seq, "%-9s ", ax2asc(&nr->user_addr));
-               seq_printf(seq, "%-9s ", ax2asc(&nr->dest_addr));
+               seq_printf(seq, "%-9s ", ax2asc(buf, &nr->user_addr));
+               seq_printf(seq, "%-9s ", ax2asc(buf, &nr->dest_addr));
                seq_printf(seq, 
 "%-9s %-3s  %02X/%02X %02X/%02X %2d %3d %3d %3d %3lu/%03lu %2lu/%02lu %3lu/%03lu %3lu/%03lu %2d/%02d %3d %5d %5d %ld\n",
-                       ax2asc(&nr->source_addr),
+                       ax2asc(buf, &nr->source_addr),
                        devname,
                        nr->my_index,
                        nr->my_id,
index 7a86b36cba505d6547a0a63620e5105858c9955d..b3b9097c87c7df5ae3c9af4a8d5b7115c34a9d10 100644 (file)
@@ -881,6 +881,7 @@ static void nr_node_stop(struct seq_file *seq, void *v)
 
 static int nr_node_show(struct seq_file *seq, void *v)
 {
+       char buf[11];
        int i;
 
        if (v == SEQ_START_TOKEN)
@@ -890,7 +891,7 @@ static int nr_node_show(struct seq_file *seq, void *v)
                struct nr_node *nr_node = v;
                nr_node_lock(nr_node);
                seq_printf(seq, "%-9s %-7s  %d %d",
-                       ax2asc(&nr_node->callsign),
+                       ax2asc(buf, &nr_node->callsign),
                        (nr_node->mnemonic[0] == '\0') ? "*" : nr_node->mnemonic,
                        nr_node->which + 1,
                        nr_node->count);
@@ -964,6 +965,7 @@ static void nr_neigh_stop(struct seq_file *seq, void *v)
 
 static int nr_neigh_show(struct seq_file *seq, void *v)
 {
+       char buf[11];
        int i;
 
        if (v == SEQ_START_TOKEN)
@@ -973,7 +975,7 @@ static int nr_neigh_show(struct seq_file *seq, void *v)
 
                seq_printf(seq, "%05d %-9s %-4s  %3d    %d   %3d    %3d",
                        nr_neigh->number,
-                       ax2asc(&nr_neigh->callsign),
+                       ax2asc(buf, &nr_neigh->callsign),
                        nr_neigh->dev ? nr_neigh->dev->name : "???",
                        nr_neigh->quality,
                        nr_neigh->locked,
@@ -983,7 +985,7 @@ static int nr_neigh_show(struct seq_file *seq, void *v)
                if (nr_neigh->digipeat != NULL) {
                        for (i = 0; i < nr_neigh->digipeat->ndigi; i++)
                                seq_printf(seq, " %s", 
-                                          ax2asc(&nr_neigh->digipeat->calls[i]));
+                                          ax2asc(buf, &nr_neigh->digipeat->calls[i]));
                }
 
                seq_puts(seq, "\n");
index ba997095f08f7ba3c670e0de052a694d39da6a11..8690f171c1ef28136e7e57e160e980955d6b742d 100644 (file)
@@ -1535,8 +1535,7 @@ static unsigned int packet_poll(struct file * file, struct socket *sock,
 static void packet_mm_open(struct vm_area_struct *vma)
 {
        struct file *file = vma->vm_file;
-       struct inode *inode = file->f_dentry->d_inode;
-       struct socket * sock = SOCKET_I(inode);
+       struct socket * sock = file->private_data;
        struct sock *sk = sock->sk;
        
        if (sk)
@@ -1546,8 +1545,7 @@ static void packet_mm_open(struct vm_area_struct *vma)
 static void packet_mm_close(struct vm_area_struct *vma)
 {
        struct file *file = vma->vm_file;
-       struct inode *inode = file->f_dentry->d_inode;
-       struct socket * sock = SOCKET_I(inode);
+       struct socket * sock = file->private_data;
        struct sock *sk = sock->sk;
        
        if (sk)
index c6e59f84c3ae78594dca71aa480a724cae9a00d0..3077878ed4f09fdc1a9a1bcf0b1303084f098641 100644 (file)
@@ -1363,6 +1363,8 @@ static void rose_info_stop(struct seq_file *seq, void *v)
 
 static int rose_info_show(struct seq_file *seq, void *v)
 {
+       char buf[11];
+
        if (v == SEQ_START_TOKEN)
                seq_puts(seq, 
                         "dest_addr  dest_call src_addr   src_call  dev   lci neigh st vs vr va   t  t1  t2  t3  hb    idle Snd-Q Rcv-Q inode\n");
@@ -1380,12 +1382,12 @@ static int rose_info_show(struct seq_file *seq, void *v)
                
                seq_printf(seq, "%-10s %-9s ",
                        rose2asc(&rose->dest_addr),
-                       ax2asc(&rose->dest_call));
+                       ax2asc(buf, &rose->dest_call));
 
                if (ax25cmp(&rose->source_call, &null_ax25_address) == 0)
                        callsign = "??????-?";
                else
-                       callsign = ax2asc(&rose->source_call);
+                       callsign = ax2asc(buf, &rose->source_call);
 
                seq_printf(seq,
                           "%-10s %-9s %-5s %3.3X %05d  %d  %d  %d  %d %3lu %3lu %3lu %3lu %3lu %3lu/%03lu %5d %5d %ld\n",
index 4510cd7613ecd851259bd4d6b43dc7637fd54ebf..e556d92c0bc4d2eb5883acda48b051a608a10d9f 100644 (file)
@@ -851,6 +851,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
        unsigned char cause, diagnostic;
        struct net_device *dev;
        int len, res = 0;
+       char buf[11];
 
 #if 0
        if (call_in_firewall(PF_ROSE, skb->dev, skb->data, NULL, &skb) != FW_ACCEPT)
@@ -876,7 +877,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
 
        if (rose_neigh == NULL) {
                printk("rose_route : unknown neighbour or device %s\n",
-                      ax2asc(&ax25->dest_addr));
+                      ax2asc(buf, &ax25->dest_addr));
                goto out;
        }
 
@@ -1178,6 +1179,7 @@ static void rose_neigh_stop(struct seq_file *seq, void *v)
 
 static int rose_neigh_show(struct seq_file *seq, void *v)
 {
+       char buf[11];
        int i;
 
        if (v == SEQ_START_TOKEN)
@@ -1189,7 +1191,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
                /* if (!rose_neigh->loopback) { */
                seq_printf(seq, "%05d %-9s %-4s   %3d %3d  %3s     %3s %3lu %3lu",
                           rose_neigh->number,
-                          (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(&rose_neigh->callsign),
+                          (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign),
                           rose_neigh->dev ? rose_neigh->dev->name : "???",
                           rose_neigh->count,
                           rose_neigh->use,
@@ -1200,7 +1202,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v)
 
                if (rose_neigh->digipeat != NULL) {
                        for (i = 0; i < rose_neigh->digipeat->ndigi; i++)
-                               seq_printf(seq, " %s", ax2asc(&rose_neigh->digipeat->calls[i]));
+                               seq_printf(seq, " %s", ax2asc(buf, &rose_neigh->digipeat->calls[i]));
                }
 
                seq_puts(seq, "\n");
@@ -1260,6 +1262,8 @@ static void rose_route_stop(struct seq_file *seq, void *v)
 
 static int rose_route_show(struct seq_file *seq, void *v)
 {
+       char buf[11];
+
        if (v == SEQ_START_TOKEN)
                seq_puts(seq, 
                         "lci  address     callsign   neigh  <-> lci  address     callsign   neigh\n");
@@ -1271,7 +1275,7 @@ static int rose_route_show(struct seq_file *seq, void *v)
                                   "%3.3X  %-10s  %-9s  %05d      ",
                                   rose_route->lci1,
                                   rose2asc(&rose_route->src_addr),
-                                  ax2asc(&rose_route->src_call),
+                                  ax2asc(buf, &rose_route->src_call),
                                   rose_route->neigh1->number);
                else 
                        seq_puts(seq, 
@@ -1282,7 +1286,7 @@ static int rose_route_show(struct seq_file *seq, void *v)
                                   "%3.3X  %-10s  %-9s  %05d\n",
                                rose_route->lci2,
                                rose2asc(&rose_route->dest_addr),
-                               ax2asc(&rose_route->dest_call),
+                               ax2asc(buf, &rose_route->dest_call),
                                rose_route->neigh2->number);
                 else 
                         seq_puts(seq,
index a29a3a960fd657efa21c50a13b3936f5ce28e7bb..02891ce2db37b3ee52c118f9fcb4ca876ccc18ff 100644 (file)
@@ -400,6 +400,7 @@ static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose)
 {
        unsigned char *p = buffer + 1;
        char *callsign;
+       char buf[11];
        int len, nb;
 
        /* National Facilities */
@@ -456,7 +457,7 @@ static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose)
 
        *p++ = FAC_CCITT_DEST_NSAP;
 
-       callsign = ax2asc(&rose->dest_call);
+       callsign = ax2asc(buf, &rose->dest_call);
 
        *p++ = strlen(callsign) + 10;
        *p++ = (strlen(callsign) + 9) * 2;              /* ??? */
@@ -471,7 +472,7 @@ static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose)
 
        *p++ = FAC_CCITT_SRC_NSAP;
 
-       callsign = ax2asc(&rose->source_call);
+       callsign = ax2asc(buf, &rose->source_call);
 
        *p++ = strlen(callsign) + 10;
        *p++ = (strlen(callsign) + 9) * 2;              /* ??? */
index 94fe638b4d72b3721cbda637573c7182f5535b32..e1bd5d84d7bf11acce8a2c6b73d0f5ac41809d05 100644 (file)
@@ -667,7 +667,7 @@ static ssize_t sock_aio_read(struct kiocb *iocb, char __user *ubuf,
        }
        iocb->private = x;
        x->kiocb = iocb;
-       sock = SOCKET_I(iocb->ki_filp->f_dentry->d_inode)
+       sock = iocb->ki_filp->private_data
 
        x->async_msg.msg_name = NULL;
        x->async_msg.msg_namelen = 0;
@@ -709,7 +709,7 @@ static ssize_t sock_aio_write(struct kiocb *iocb, const char __user *ubuf,
        }
        iocb->private = x;
        x->kiocb = iocb;
-       sock = SOCKET_I(iocb->ki_filp->f_dentry->d_inode)
+       sock = iocb->ki_filp->private_data
 
        x->async_msg.msg_name = NULL;
        x->async_msg.msg_namelen = 0;
@@ -732,7 +732,7 @@ static ssize_t sock_sendpage(struct file *file, struct page *page,
        struct socket *sock;
        int flags;
 
-       sock = SOCKET_I(file->f_dentry->d_inode);
+       sock = file->private_data;
 
        flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT;
        if (more)
@@ -741,14 +741,14 @@ static ssize_t sock_sendpage(struct file *file, struct page *page,
        return sock->ops->sendpage(sock, page, offset, size, flags);
 }
 
-static int sock_readv_writev(int type, struct inode * inode,
+static int sock_readv_writev(int type,
                             struct file * file, const struct iovec * iov,
                             long count, size_t size)
 {
        struct msghdr msg;
        struct socket *sock;
 
-       sock = SOCKET_I(inode);
+       sock = file->private_data;
 
        msg.msg_name = NULL;
        msg.msg_namelen = 0;
@@ -775,7 +775,7 @@ static ssize_t sock_readv(struct file *file, const struct iovec *vector,
        int i;
         for (i = 0 ; i < count ; i++)
                 tot_len += vector[i].iov_len;
-       return sock_readv_writev(VERIFY_WRITE, file->f_dentry->d_inode,
+       return sock_readv_writev(VERIFY_WRITE,
                                 file, vector, count, tot_len);
 }
        
@@ -786,7 +786,7 @@ static ssize_t sock_writev(struct file *file, const struct iovec *vector,
        int i;
         for (i = 0 ; i < count ; i++)
                 tot_len += vector[i].iov_len;
-       return sock_readv_writev(VERIFY_READ, file->f_dentry->d_inode,
+       return sock_readv_writev(VERIFY_READ,
                                 file, vector, count, tot_len);
 }
 
@@ -840,7 +840,7 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
        void __user *argp = (void __user *)arg;
        int pid, err;
 
-       sock = SOCKET_I(file->f_dentry->d_inode);
+       sock = file->private_data;
        if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
                err = dev_ioctl(cmd, argp);
        } else
@@ -939,13 +939,13 @@ static unsigned int sock_poll(struct file *file, poll_table * wait)
        /*
         *      We can't return errors to poll, so it's either yes or no. 
         */
-       sock = SOCKET_I(file->f_dentry->d_inode);
+       sock = file->private_data;
        return sock->ops->poll(file, sock, wait);
 }
 
 static int sock_mmap(struct file * file, struct vm_area_struct * vma)
 {
-       struct socket *sock = SOCKET_I(file->f_dentry->d_inode);
+       struct socket *sock = file->private_data;
 
        return sock->ops->mmap(file, sock, vma);
 }
@@ -995,7 +995,7 @@ static int sock_fasync(int fd, struct file *filp, int on)
                        return -ENOMEM;
        }
 
-       sock = SOCKET_I(filp->f_dentry->d_inode);
+       sock = filp->private_data;
 
        if ((sk=sock->sk) == NULL) {
                kfree(fna);