diff options
35 files changed, 356 insertions, 105 deletions
diff --git a/crypto/cipher.c b/crypto/cipher.c index 3df47f93c9db..dfd4bcfc5975 100644 --- a/crypto/cipher.c +++ b/crypto/cipher.c | |||
| @@ -191,6 +191,8 @@ static unsigned int cbc_process_encrypt(const struct cipher_desc *desc, | |||
| 191 | u8 *iv = desc->info; | 191 | u8 *iv = desc->info; |
| 192 | unsigned int done = 0; | 192 | unsigned int done = 0; |
| 193 | 193 | ||
| 194 | nbytes -= bsize; | ||
| 195 | |||
| 194 | do { | 196 | do { |
| 195 | xor(iv, src); | 197 | xor(iv, src); |
| 196 | fn(crypto_tfm_ctx(tfm), dst, iv); | 198 | fn(crypto_tfm_ctx(tfm), dst, iv); |
| @@ -198,7 +200,7 @@ static unsigned int cbc_process_encrypt(const struct cipher_desc *desc, | |||
| 198 | 200 | ||
| 199 | src += bsize; | 201 | src += bsize; |
| 200 | dst += bsize; | 202 | dst += bsize; |
| 201 | } while ((done += bsize) < nbytes); | 203 | } while ((done += bsize) <= nbytes); |
| 202 | 204 | ||
| 203 | return done; | 205 | return done; |
| 204 | } | 206 | } |
| @@ -219,6 +221,8 @@ static unsigned int cbc_process_decrypt(const struct cipher_desc *desc, | |||
| 219 | u8 *iv = desc->info; | 221 | u8 *iv = desc->info; |
| 220 | unsigned int done = 0; | 222 | unsigned int done = 0; |
| 221 | 223 | ||
| 224 | nbytes -= bsize; | ||
| 225 | |||
| 222 | do { | 226 | do { |
| 223 | u8 *tmp_dst = *dst_p; | 227 | u8 *tmp_dst = *dst_p; |
| 224 | 228 | ||
| @@ -230,7 +234,7 @@ static unsigned int cbc_process_decrypt(const struct cipher_desc *desc, | |||
| 230 | 234 | ||
| 231 | src += bsize; | 235 | src += bsize; |
| 232 | dst += bsize; | 236 | dst += bsize; |
| 233 | } while ((done += bsize) < nbytes); | 237 | } while ((done += bsize) <= nbytes); |
| 234 | 238 | ||
| 235 | return done; | 239 | return done; |
| 236 | } | 240 | } |
| @@ -243,12 +247,14 @@ static unsigned int ecb_process(const struct cipher_desc *desc, u8 *dst, | |||
| 243 | void (*fn)(void *, u8 *, const u8 *) = desc->crfn; | 247 | void (*fn)(void *, u8 *, const u8 *) = desc->crfn; |
| 244 | unsigned int done = 0; | 248 | unsigned int done = 0; |
| 245 | 249 | ||
| 250 | nbytes -= bsize; | ||
| 251 | |||
| 246 | do { | 252 | do { |
| 247 | fn(crypto_tfm_ctx(tfm), dst, src); | 253 | fn(crypto_tfm_ctx(tfm), dst, src); |
| 248 | 254 | ||
| 249 | src += bsize; | 255 | src += bsize; |
| 250 | dst += bsize; | 256 | dst += bsize; |
| 251 | } while ((done += bsize) < nbytes); | 257 | } while ((done += bsize) <= nbytes); |
| 252 | 258 | ||
| 253 | return done; | 259 | return done; |
| 254 | } | 260 | } |
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index 4f9f69e22c1b..12ef52c193a3 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c | |||
| @@ -597,7 +597,7 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
| 597 | struct ArcProto *proto; | 597 | struct ArcProto *proto; |
| 598 | int txbuf; | 598 | int txbuf; |
| 599 | unsigned long flags; | 599 | unsigned long flags; |
| 600 | int freeskb = 0; | 600 | int freeskb, retval; |
| 601 | 601 | ||
| 602 | BUGMSG(D_DURING, | 602 | BUGMSG(D_DURING, |
| 603 | "transmit requested (status=%Xh, txbufs=%d/%d, len=%d, protocol %x)\n", | 603 | "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) | |||
| 615 | if (skb->len - ARC_HDR_SIZE > XMTU && !proto->continue_tx) { | 615 | if (skb->len - ARC_HDR_SIZE > XMTU && !proto->continue_tx) { |
| 616 | BUGMSG(D_NORMAL, "fixme: packet too large: compensating badly!\n"); | 616 | BUGMSG(D_NORMAL, "fixme: packet too large: compensating badly!\n"); |
| 617 | dev_kfree_skb(skb); | 617 | dev_kfree_skb(skb); |
| 618 | return 0; /* don't try again */ | 618 | return NETDEV_TX_OK; /* don't try again */ |
| 619 | } | 619 | } |
| 620 | 620 | ||
| 621 | /* We're busy transmitting a packet... */ | 621 | /* We're busy transmitting a packet... */ |
| @@ -623,8 +623,11 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
| 623 | 623 | ||
| 624 | spin_lock_irqsave(&lp->lock, flags); | 624 | spin_lock_irqsave(&lp->lock, flags); |
| 625 | AINTMASK(0); | 625 | AINTMASK(0); |
| 626 | 626 | if(lp->next_tx == -1) | |
| 627 | txbuf = get_arcbuf(dev); | 627 | txbuf = get_arcbuf(dev); |
| 628 | else { | ||
| 629 | txbuf = -1; | ||
| 630 | } | ||
| 628 | if (txbuf != -1) { | 631 | if (txbuf != -1) { |
| 629 | if (proto->prepare_tx(dev, pkt, skb->len, txbuf) && | 632 | if (proto->prepare_tx(dev, pkt, skb->len, txbuf) && |
| 630 | !proto->ack_tx) { | 633 | !proto->ack_tx) { |
| @@ -638,6 +641,8 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
| 638 | lp->outgoing.skb = skb; | 641 | lp->outgoing.skb = skb; |
| 639 | lp->outgoing.pkt = pkt; | 642 | lp->outgoing.pkt = pkt; |
| 640 | 643 | ||
| 644 | freeskb = 0; | ||
| 645 | |||
| 641 | if (proto->continue_tx && | 646 | if (proto->continue_tx && |
| 642 | proto->continue_tx(dev, txbuf)) { | 647 | proto->continue_tx(dev, txbuf)) { |
| 643 | BUGMSG(D_NORMAL, | 648 | BUGMSG(D_NORMAL, |
| @@ -645,10 +650,12 @@ static int arcnet_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
| 645 | "(proto='%c')\n", proto->suffix); | 650 | "(proto='%c')\n", proto->suffix); |
| 646 | } | 651 | } |
| 647 | } | 652 | } |
| 648 | 653 | retval = NETDEV_TX_OK; | |
| 654 | dev->trans_start = jiffies; | ||
| 649 | lp->next_tx = txbuf; | 655 | lp->next_tx = txbuf; |
| 650 | } else { | 656 | } else { |
| 651 | freeskb = 1; | 657 | retval = NETDEV_TX_BUSY; |
| 658 | freeskb = 0; | ||
| 652 | } | 659 | } |
| 653 | 660 | ||
| 654 | BUGMSG(D_DEBUG, "%s: %d: %s, status: %x\n",__FILE__,__LINE__,__FUNCTION__,ASTATUS()); | 661 | 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) | |||
| 664 | if (freeskb) { | 671 | if (freeskb) { |
| 665 | dev_kfree_skb(skb); | 672 | dev_kfree_skb(skb); |
| 666 | } | 673 | } |
| 667 | return 0; /* no need to try again */ | 674 | return retval; /* no need to try again */ |
| 668 | } | 675 | } |
| 669 | 676 | ||
| 670 | 677 | ||
| @@ -690,7 +697,6 @@ static int go_tx(struct net_device *dev) | |||
| 690 | /* start sending */ | 697 | /* start sending */ |
| 691 | ACOMMAND(TXcmd | (lp->cur_tx << 3)); | 698 | ACOMMAND(TXcmd | (lp->cur_tx << 3)); |
| 692 | 699 | ||
| 693 | dev->trans_start = jiffies; | ||
| 694 | lp->stats.tx_packets++; | 700 | lp->stats.tx_packets++; |
| 695 | lp->lasttrans_dest = lp->lastload_dest; | 701 | lp->lasttrans_dest = lp->lastload_dest; |
| 696 | lp->lastload_dest = 0; | 702 | lp->lastload_dest = 0; |
| @@ -917,6 +923,9 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
| 917 | 923 | ||
| 918 | BUGMSG(D_RECON, "Network reconfiguration detected (status=%Xh)\n", | 924 | BUGMSG(D_RECON, "Network reconfiguration detected (status=%Xh)\n", |
| 919 | status); | 925 | status); |
| 926 | /* MYRECON bit is at bit 7 of diagstatus */ | ||
| 927 | if(diagstatus & 0x80) | ||
| 928 | BUGMSG(D_RECON,"Put out that recon myself\n"); | ||
| 920 | 929 | ||
| 921 | /* is the RECON info empty or old? */ | 930 | /* is the RECON info empty or old? */ |
| 922 | if (!lp->first_recon || !lp->last_recon || | 931 | if (!lp->first_recon || !lp->last_recon || |
diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h index 088742befe49..7e033e9271a8 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack.h +++ b/include/linux/netfilter_ipv4/ip_conntrack.h | |||
| @@ -263,6 +263,9 @@ struct ip_conntrack_expect | |||
| 263 | /* Unique ID */ | 263 | /* Unique ID */ |
| 264 | unsigned int id; | 264 | unsigned int id; |
| 265 | 265 | ||
| 266 | /* Flags */ | ||
| 267 | unsigned int flags; | ||
| 268 | |||
| 266 | #ifdef CONFIG_IP_NF_NAT_NEEDED | 269 | #ifdef CONFIG_IP_NF_NAT_NEEDED |
| 267 | /* This is the original per-proto part, used to map the | 270 | /* This is the original per-proto part, used to map the |
| 268 | * expected connection the way the recipient expects. */ | 271 | * expected connection the way the recipient expects. */ |
| @@ -272,6 +275,8 @@ struct ip_conntrack_expect | |||
| 272 | #endif | 275 | #endif |
| 273 | }; | 276 | }; |
| 274 | 277 | ||
| 278 | #define IP_CT_EXPECT_PERMANENT 0x1 | ||
| 279 | |||
| 275 | static inline struct ip_conntrack * | 280 | static inline struct ip_conntrack * |
| 276 | tuplehash_to_ctrack(const struct ip_conntrack_tuple_hash *hash) | 281 | tuplehash_to_ctrack(const struct ip_conntrack_tuple_hash *hash) |
| 277 | { | 282 | { |
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_core.h b/include/linux/netfilter_ipv4/ip_conntrack_core.h index dc4d2a0575de..907d4f5ca5dc 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack_core.h +++ b/include/linux/netfilter_ipv4/ip_conntrack_core.h | |||
| @@ -52,7 +52,7 @@ static inline int ip_conntrack_confirm(struct sk_buff **pskb) | |||
| 52 | return ret; | 52 | return ret; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | extern void __ip_ct_expect_unlink_destroy(struct ip_conntrack_expect *exp); | 55 | extern void ip_ct_unlink_expect(struct ip_conntrack_expect *exp); |
| 56 | 56 | ||
| 57 | extern struct list_head *ip_conntrack_hash; | 57 | extern struct list_head *ip_conntrack_hash; |
| 58 | extern struct list_head ip_conntrack_expect_list; | 58 | extern struct list_head ip_conntrack_expect_list; |
diff --git a/include/linux/netfilter_ipv4/ip_nat_rule.h b/include/linux/netfilter_ipv4/ip_nat_rule.h index fecd2a06dcd8..73b9552e6a89 100644 --- a/include/linux/netfilter_ipv4/ip_nat_rule.h +++ b/include/linux/netfilter_ipv4/ip_nat_rule.h | |||
| @@ -19,5 +19,10 @@ extern unsigned int | |||
| 19 | alloc_null_binding(struct ip_conntrack *conntrack, | 19 | alloc_null_binding(struct ip_conntrack *conntrack, |
| 20 | struct ip_nat_info *info, | 20 | struct ip_nat_info *info, |
| 21 | unsigned int hooknum); | 21 | unsigned int hooknum); |
| 22 | |||
| 23 | extern unsigned int | ||
| 24 | alloc_null_binding_confirmed(struct ip_conntrack *conntrack, | ||
| 25 | struct ip_nat_info *info, | ||
| 26 | unsigned int hooknum); | ||
| 22 | #endif | 27 | #endif |
| 23 | #endif /* _IP_NAT_RULE_H */ | 28 | #endif /* _IP_NAT_RULE_H */ |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 42edce6abe23..da7da9c0ed1b 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
| @@ -1251,7 +1251,7 @@ extern void skb_add_mtu(int mtu); | |||
| 1251 | * This function converts the offset back to a struct timeval and stores | 1251 | * This function converts the offset back to a struct timeval and stores |
| 1252 | * it in stamp. | 1252 | * it in stamp. |
| 1253 | */ | 1253 | */ |
| 1254 | static inline void skb_get_timestamp(struct sk_buff *skb, struct timeval *stamp) | 1254 | static inline void skb_get_timestamp(const struct sk_buff *skb, struct timeval *stamp) |
| 1255 | { | 1255 | { |
| 1256 | stamp->tv_sec = skb->tstamp.off_sec; | 1256 | stamp->tv_sec = skb->tstamp.off_sec; |
| 1257 | stamp->tv_usec = skb->tstamp.off_usec; | 1257 | stamp->tv_usec = skb->tstamp.off_usec; |
| @@ -1270,7 +1270,7 @@ static inline void skb_get_timestamp(struct sk_buff *skb, struct timeval *stamp) | |||
| 1270 | * This function converts a struct timeval to an offset and stores | 1270 | * This function converts a struct timeval to an offset and stores |
| 1271 | * it in the skb. | 1271 | * it in the skb. |
| 1272 | */ | 1272 | */ |
| 1273 | static inline void skb_set_timestamp(struct sk_buff *skb, struct timeval *stamp) | 1273 | static inline void skb_set_timestamp(struct sk_buff *skb, const struct timeval *stamp) |
| 1274 | { | 1274 | { |
| 1275 | skb->tstamp.off_sec = stamp->tv_sec - skb_tv_base.tv_sec; | 1275 | skb->tstamp.off_sec = stamp->tv_sec - skb_tv_base.tv_sec; |
| 1276 | skb->tstamp.off_usec = stamp->tv_usec - skb_tv_base.tv_usec; | 1276 | skb->tstamp.off_usec = stamp->tv_usec - skb_tv_base.tv_usec; |
diff --git a/include/net/ax25.h b/include/net/ax25.h index 926eed543023..364b046e9f47 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h | |||
| @@ -257,7 +257,7 @@ extern struct sock *ax25_make_new(struct sock *, struct ax25_dev *); | |||
| 257 | 257 | ||
| 258 | /* ax25_addr.c */ | 258 | /* ax25_addr.c */ |
| 259 | extern ax25_address null_ax25_address; | 259 | extern ax25_address null_ax25_address; |
| 260 | extern char *ax2asc(ax25_address *); | 260 | extern char *ax2asc(char *buf, ax25_address *); |
| 261 | extern ax25_address *asc2ax(char *); | 261 | extern ax25_address *asc2ax(char *); |
| 262 | extern int ax25cmp(ax25_address *, ax25_address *); | 262 | extern int ax25cmp(ax25_address *, ax25_address *); |
| 263 | extern int ax25digicmp(ax25_digi *, ax25_digi *); | 263 | extern int ax25digicmp(ax25_digi *, ax25_digi *); |
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index ea43dfb774e2..ed705ddad56b 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
| @@ -1874,6 +1874,7 @@ static void ax25_info_stop(struct seq_file *seq, void *v) | |||
| 1874 | static int ax25_info_show(struct seq_file *seq, void *v) | 1874 | static int ax25_info_show(struct seq_file *seq, void *v) |
| 1875 | { | 1875 | { |
| 1876 | ax25_cb *ax25 = v; | 1876 | ax25_cb *ax25 = v; |
| 1877 | char buf[11]; | ||
| 1877 | int k; | 1878 | int k; |
| 1878 | 1879 | ||
| 1879 | 1880 | ||
| @@ -1885,13 +1886,13 @@ static int ax25_info_show(struct seq_file *seq, void *v) | |||
| 1885 | seq_printf(seq, "%8.8lx %s %s%s ", | 1886 | seq_printf(seq, "%8.8lx %s %s%s ", |
| 1886 | (long) ax25, | 1887 | (long) ax25, |
| 1887 | ax25->ax25_dev == NULL? "???" : ax25->ax25_dev->dev->name, | 1888 | ax25->ax25_dev == NULL? "???" : ax25->ax25_dev->dev->name, |
| 1888 | ax2asc(&ax25->source_addr), | 1889 | ax2asc(buf, &ax25->source_addr), |
| 1889 | ax25->iamdigi? "*":""); | 1890 | ax25->iamdigi? "*":""); |
| 1890 | seq_printf(seq, "%s", ax2asc(&ax25->dest_addr)); | 1891 | seq_printf(seq, "%s", ax2asc(buf, &ax25->dest_addr)); |
| 1891 | 1892 | ||
| 1892 | for (k=0; (ax25->digipeat != NULL) && (k < ax25->digipeat->ndigi); k++) { | 1893 | for (k=0; (ax25->digipeat != NULL) && (k < ax25->digipeat->ndigi); k++) { |
| 1893 | seq_printf(seq, ",%s%s", | 1894 | seq_printf(seq, ",%s%s", |
| 1894 | ax2asc(&ax25->digipeat->calls[k]), | 1895 | ax2asc(buf, &ax25->digipeat->calls[k]), |
| 1895 | ax25->digipeat->repeated[k]? "*":""); | 1896 | ax25->digipeat->repeated[k]? "*":""); |
| 1896 | } | 1897 | } |
| 1897 | 1898 | ||
diff --git a/net/ax25/ax25_addr.c b/net/ax25/ax25_addr.c index f4fa6dfb846e..dca179daf415 100644 --- a/net/ax25/ax25_addr.c +++ b/net/ax25/ax25_addr.c | |||
| @@ -36,9 +36,8 @@ ax25_address null_ax25_address = {{0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00}}; | |||
| 36 | /* | 36 | /* |
| 37 | * ax25 -> ascii conversion | 37 | * ax25 -> ascii conversion |
| 38 | */ | 38 | */ |
| 39 | char *ax2asc(ax25_address *a) | 39 | char *ax2asc(char *buf, ax25_address *a) |
| 40 | { | 40 | { |
| 41 | static char buf[11]; | ||
| 42 | char c, *s; | 41 | char c, *s; |
| 43 | int n; | 42 | int n; |
| 44 | 43 | ||
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c index c288526da4ce..26b77d972220 100644 --- a/net/ax25/ax25_route.c +++ b/net/ax25/ax25_route.c | |||
| @@ -298,6 +298,8 @@ static void ax25_rt_seq_stop(struct seq_file *seq, void *v) | |||
| 298 | 298 | ||
| 299 | static int ax25_rt_seq_show(struct seq_file *seq, void *v) | 299 | static int ax25_rt_seq_show(struct seq_file *seq, void *v) |
| 300 | { | 300 | { |
| 301 | char buf[11]; | ||
| 302 | |||
| 301 | if (v == SEQ_START_TOKEN) | 303 | if (v == SEQ_START_TOKEN) |
| 302 | seq_puts(seq, "callsign dev mode digipeaters\n"); | 304 | seq_puts(seq, "callsign dev mode digipeaters\n"); |
| 303 | else { | 305 | else { |
| @@ -308,7 +310,7 @@ static int ax25_rt_seq_show(struct seq_file *seq, void *v) | |||
| 308 | if (ax25cmp(&ax25_rt->callsign, &null_ax25_address) == 0) | 310 | if (ax25cmp(&ax25_rt->callsign, &null_ax25_address) == 0) |
| 309 | callsign = "default"; | 311 | callsign = "default"; |
| 310 | else | 312 | else |
| 311 | callsign = ax2asc(&ax25_rt->callsign); | 313 | callsign = ax2asc(buf, &ax25_rt->callsign); |
| 312 | 314 | ||
| 313 | seq_printf(seq, "%-9s %-4s", | 315 | seq_printf(seq, "%-9s %-4s", |
| 314 | callsign, | 316 | callsign, |
| @@ -328,7 +330,8 @@ static int ax25_rt_seq_show(struct seq_file *seq, void *v) | |||
| 328 | 330 | ||
| 329 | if (ax25_rt->digipeat != NULL) | 331 | if (ax25_rt->digipeat != NULL) |
| 330 | for (i = 0; i < ax25_rt->digipeat->ndigi; i++) | 332 | for (i = 0; i < ax25_rt->digipeat->ndigi; i++) |
| 331 | seq_printf(seq, " %s", ax2asc(&ax25_rt->digipeat->calls[i])); | 333 | seq_printf(seq, " %s", |
| 334 | ax2asc(buf, &ax25_rt->digipeat->calls[i])); | ||
| 332 | 335 | ||
| 333 | seq_puts(seq, "\n"); | 336 | seq_puts(seq, "\n"); |
| 334 | } | 337 | } |
diff --git a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c index a8b3822f3ee4..d53cc8615865 100644 --- a/net/ax25/ax25_uid.c +++ b/net/ax25/ax25_uid.c | |||
| @@ -168,12 +168,14 @@ static void ax25_uid_seq_stop(struct seq_file *seq, void *v) | |||
| 168 | 168 | ||
| 169 | static int ax25_uid_seq_show(struct seq_file *seq, void *v) | 169 | static int ax25_uid_seq_show(struct seq_file *seq, void *v) |
| 170 | { | 170 | { |
| 171 | char buf[11]; | ||
| 172 | |||
| 171 | if (v == SEQ_START_TOKEN) | 173 | if (v == SEQ_START_TOKEN) |
| 172 | seq_printf(seq, "Policy: %d\n", ax25_uid_policy); | 174 | seq_printf(seq, "Policy: %d\n", ax25_uid_policy); |
| 173 | else { | 175 | else { |
| 174 | struct ax25_uid_assoc *pt = v; | 176 | struct ax25_uid_assoc *pt = v; |
| 175 | 177 | ||
| 176 | seq_printf(seq, "%6d %s\n", pt->uid, ax2asc(&pt->call)); | 178 | seq_printf(seq, "%6d %s\n", pt->uid, ax2asc(buf, &pt->call)); |
| 177 | } | 179 | } |
| 178 | return 0; | 180 | return 0; |
| 179 | } | 181 | } |
diff --git a/net/core/sock.c b/net/core/sock.c index c13594579bfb..ac63b56e23b2 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -341,11 +341,11 @@ set_rcvbuf: | |||
| 341 | sock_reset_flag(sk, SOCK_LINGER); | 341 | sock_reset_flag(sk, SOCK_LINGER); |
| 342 | else { | 342 | else { |
| 343 | #if (BITS_PER_LONG == 32) | 343 | #if (BITS_PER_LONG == 32) |
| 344 | if (ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ) | 344 | if ((unsigned int)ling.l_linger >= MAX_SCHEDULE_TIMEOUT/HZ) |
| 345 | sk->sk_lingertime = MAX_SCHEDULE_TIMEOUT; | 345 | sk->sk_lingertime = MAX_SCHEDULE_TIMEOUT; |
| 346 | else | 346 | else |
| 347 | #endif | 347 | #endif |
| 348 | sk->sk_lingertime = ling.l_linger * HZ; | 348 | sk->sk_lingertime = (unsigned int)ling.l_linger * HZ; |
| 349 | sock_set_flag(sk, SOCK_LINGER); | 349 | sock_set_flag(sk, SOCK_LINGER); |
| 350 | } | 350 | } |
| 351 | break; | 351 | break; |
| @@ -1529,6 +1529,8 @@ EXPORT_SYMBOL(proto_register); | |||
| 1529 | void proto_unregister(struct proto *prot) | 1529 | void proto_unregister(struct proto *prot) |
| 1530 | { | 1530 | { |
| 1531 | write_lock(&proto_list_lock); | 1531 | write_lock(&proto_list_lock); |
| 1532 | list_del(&prot->node); | ||
| 1533 | write_unlock(&proto_list_lock); | ||
| 1532 | 1534 | ||
| 1533 | if (prot->slab != NULL) { | 1535 | if (prot->slab != NULL) { |
| 1534 | kmem_cache_destroy(prot->slab); | 1536 | kmem_cache_destroy(prot->slab); |
| @@ -1550,9 +1552,6 @@ void proto_unregister(struct proto *prot) | |||
| 1550 | kfree(name); | 1552 | kfree(name); |
| 1551 | prot->twsk_slab = NULL; | 1553 | prot->twsk_slab = NULL; |
| 1552 | } | 1554 | } |
| 1553 | |||
| 1554 | list_del(&prot->node); | ||
| 1555 | write_unlock(&proto_list_lock); | ||
| 1556 | } | 1555 | } |
| 1557 | 1556 | ||
| 1558 | EXPORT_SYMBOL(proto_unregister); | 1557 | EXPORT_SYMBOL(proto_unregister); |
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 9e6e683cc34d..e7d26d9943c2 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
| @@ -457,7 +457,7 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb) | |||
| 457 | 457 | ||
| 458 | if (pskb_pull(skb, ihl) == NULL) | 458 | if (pskb_pull(skb, ihl) == NULL) |
| 459 | goto err; | 459 | goto err; |
| 460 | if (pskb_trim(skb, end-offset)) | 460 | if (pskb_trim_rcsum(skb, end-offset)) |
| 461 | goto err; | 461 | goto err; |
| 462 | 462 | ||
| 463 | /* Find out which fragments are in front and at the back of us | 463 | /* Find out which fragments are in front and at the back of us |
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index e046f5521814..30aa8e2ee214 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
| @@ -34,6 +34,7 @@ config IP_NF_CT_ACCT | |||
| 34 | 34 | ||
| 35 | config IP_NF_CONNTRACK_MARK | 35 | config IP_NF_CONNTRACK_MARK |
| 36 | bool 'Connection mark tracking support' | 36 | bool 'Connection mark tracking support' |
| 37 | depends on IP_NF_CONNTRACK | ||
| 37 | help | 38 | help |
| 38 | This option enables support for connection marks, used by the | 39 | This option enables support for connection marks, used by the |
| 39 | `CONNMARK' target and `connmark' match. Similar to the mark value | 40 | `CONNMARK' target and `connmark' match. Similar to the mark value |
| @@ -85,6 +86,25 @@ config IP_NF_IRC | |||
| 85 | 86 | ||
| 86 | To compile it as a module, choose M here. If unsure, say Y. | 87 | To compile it as a module, choose M here. If unsure, say Y. |
| 87 | 88 | ||
| 89 | config IP_NF_NETBIOS_NS | ||
| 90 | tristate "NetBIOS name service protocol support (EXPERIMENTAL)" | ||
| 91 | depends on IP_NF_CONNTRACK && EXPERIMENTAL | ||
| 92 | help | ||
| 93 | NetBIOS name service requests are sent as broadcast messages from an | ||
| 94 | unprivileged port and responded to with unicast messages to the | ||
| 95 | same port. This make them hard to firewall properly because connection | ||
| 96 | tracking doesn't deal with broadcasts. This helper tracks locally | ||
| 97 | originating NetBIOS name service requests and the corresponding | ||
| 98 | responses. It relies on correct IP address configuration, specifically | ||
| 99 | netmask and broadcast address. When properly configured, the output | ||
| 100 | of "ip address show" should look similar to this: | ||
| 101 | |||
| 102 | $ ip -4 address show eth0 | ||
| 103 | 4: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000 | ||
| 104 | inet 172.16.2.252/24 brd 172.16.2.255 scope global eth0 | ||
| 105 | |||
| 106 | To compile it as a module, choose M here. If unsure, say N. | ||
| 107 | |||
| 88 | config IP_NF_TFTP | 108 | config IP_NF_TFTP |
| 89 | tristate "TFTP protocol support" | 109 | tristate "TFTP protocol support" |
| 90 | depends on IP_NF_CONNTRACK | 110 | depends on IP_NF_CONNTRACK |
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index a7bd38f50522..1ba0db746817 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile | |||
| @@ -21,6 +21,7 @@ obj-$(CONFIG_IP_NF_AMANDA) += ip_conntrack_amanda.o | |||
| 21 | obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o | 21 | obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o |
| 22 | obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o | 22 | obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o |
| 23 | obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o | 23 | obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o |
| 24 | obj-$(CONFIG_IP_NF_NETBIOS_NS) += ip_conntrack_netbios_ns.o | ||
| 24 | 25 | ||
| 25 | # NAT helpers | 26 | # NAT helpers |
| 26 | obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.o | 27 | obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.o |
diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c index be4c9eb3243f..dc20881004bc 100644 --- a/net/ipv4/netfilter/ip_conntrack_amanda.c +++ b/net/ipv4/netfilter/ip_conntrack_amanda.c | |||
| @@ -108,6 +108,7 @@ static int help(struct sk_buff **pskb, | |||
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | exp->expectfn = NULL; | 110 | exp->expectfn = NULL; |
| 111 | exp->flags = 0; | ||
| 111 | 112 | ||
| 112 | exp->tuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; | 113 | exp->tuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; |
| 113 | exp->tuple.src.u.tcp.port = 0; | 114 | exp->tuple.src.u.tcp.port = 0; |
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index a0648600190e..19cba16e6e1e 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c | |||
| @@ -197,7 +197,7 @@ ip_ct_invert_tuple(struct ip_conntrack_tuple *inverse, | |||
| 197 | 197 | ||
| 198 | 198 | ||
| 199 | /* ip_conntrack_expect helper functions */ | 199 | /* ip_conntrack_expect helper functions */ |
| 200 | static void unlink_expect(struct ip_conntrack_expect *exp) | 200 | void ip_ct_unlink_expect(struct ip_conntrack_expect *exp) |
| 201 | { | 201 | { |
| 202 | ASSERT_WRITE_LOCK(&ip_conntrack_lock); | 202 | ASSERT_WRITE_LOCK(&ip_conntrack_lock); |
| 203 | IP_NF_ASSERT(!timer_pending(&exp->timeout)); | 203 | IP_NF_ASSERT(!timer_pending(&exp->timeout)); |
| @@ -207,18 +207,12 @@ static void unlink_expect(struct ip_conntrack_expect *exp) | |||
| 207 | ip_conntrack_expect_put(exp); | 207 | ip_conntrack_expect_put(exp); |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | void __ip_ct_expect_unlink_destroy(struct ip_conntrack_expect *exp) | ||
| 211 | { | ||
| 212 | unlink_expect(exp); | ||
| 213 | ip_conntrack_expect_put(exp); | ||
| 214 | } | ||
| 215 | |||
| 216 | static void expectation_timed_out(unsigned long ul_expect) | 210 | static void expectation_timed_out(unsigned long ul_expect) |
| 217 | { | 211 | { |
| 218 | struct ip_conntrack_expect *exp = (void *)ul_expect; | 212 | struct ip_conntrack_expect *exp = (void *)ul_expect; |
| 219 | 213 | ||
| 220 | write_lock_bh(&ip_conntrack_lock); | 214 | write_lock_bh(&ip_conntrack_lock); |
| 221 | unlink_expect(exp); | 215 | ip_ct_unlink_expect(exp); |
| 222 | write_unlock_bh(&ip_conntrack_lock); | 216 | write_unlock_bh(&ip_conntrack_lock); |
| 223 | ip_conntrack_expect_put(exp); | 217 | ip_conntrack_expect_put(exp); |
| 224 | } | 218 | } |
| @@ -264,10 +258,14 @@ find_expectation(const struct ip_conntrack_tuple *tuple) | |||
| 264 | master ct never got confirmed, we'd hold a reference to it | 258 | master ct never got confirmed, we'd hold a reference to it |
| 265 | and weird things would happen to future packets). */ | 259 | and weird things would happen to future packets). */ |
| 266 | if (ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask) | 260 | if (ip_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask) |
| 267 | && is_confirmed(i->master) | 261 | && is_confirmed(i->master)) { |
| 268 | && del_timer(&i->timeout)) { | 262 | if (i->flags & IP_CT_EXPECT_PERMANENT) { |
| 269 | unlink_expect(i); | 263 | atomic_inc(&i->use); |
| 270 | return i; | 264 | return i; |
| 265 | } else if (del_timer(&i->timeout)) { | ||
| 266 | ip_ct_unlink_expect(i); | ||
| 267 | return i; | ||
| 268 | } | ||
| 271 | } | 269 | } |
| 272 | } | 270 | } |
| 273 | return NULL; | 271 | return NULL; |
| @@ -284,7 +282,7 @@ void ip_ct_remove_expectations(struct ip_conntrack *ct) | |||
| 284 | 282 | ||
| 285 | list_for_each_entry_safe(i, tmp, &ip_conntrack_expect_list, list) { | 283 | list_for_each_entry_safe(i, tmp, &ip_conntrack_expect_list, list) { |
| 286 | if (i->master == ct && del_timer(&i->timeout)) { | 284 | if (i->master == ct && del_timer(&i->timeout)) { |
| 287 | unlink_expect(i); | 285 | ip_ct_unlink_expect(i); |
| 288 | ip_conntrack_expect_put(i); | 286 | ip_conntrack_expect_put(i); |
| 289 | } | 287 | } |
| 290 | } | 288 | } |
| @@ -925,7 +923,7 @@ void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp) | |||
| 925 | /* choose the the oldest expectation to evict */ | 923 | /* choose the the oldest expectation to evict */ |
| 926 | list_for_each_entry_reverse(i, &ip_conntrack_expect_list, list) { | 924 | list_for_each_entry_reverse(i, &ip_conntrack_expect_list, list) { |
| 927 | if (expect_matches(i, exp) && del_timer(&i->timeout)) { | 925 | if (expect_matches(i, exp) && del_timer(&i->timeout)) { |
| 928 | unlink_expect(i); | 926 | ip_ct_unlink_expect(i); |
| 929 | write_unlock_bh(&ip_conntrack_lock); | 927 | write_unlock_bh(&ip_conntrack_lock); |
| 930 | ip_conntrack_expect_put(i); | 928 | ip_conntrack_expect_put(i); |
| 931 | return; | 929 | return; |
| @@ -934,6 +932,9 @@ void ip_conntrack_unexpect_related(struct ip_conntrack_expect *exp) | |||
| 934 | write_unlock_bh(&ip_conntrack_lock); | 932 | write_unlock_bh(&ip_conntrack_lock); |
| 935 | } | 933 | } |
| 936 | 934 | ||
| 935 | /* We don't increase the master conntrack refcount for non-fulfilled | ||
| 936 | * conntracks. During the conntrack destruction, the expectations are | ||
| 937 | * always killed before the conntrack itself */ | ||
| 937 | struct ip_conntrack_expect *ip_conntrack_expect_alloc(struct ip_conntrack *me) | 938 | struct ip_conntrack_expect *ip_conntrack_expect_alloc(struct ip_conntrack *me) |
| 938 | { | 939 | { |
| 939 | struct ip_conntrack_expect *new; | 940 | struct ip_conntrack_expect *new; |
| @@ -944,17 +945,14 @@ struct ip_conntrack_expect *ip_conntrack_expect_alloc(struct ip_conntrack *me) | |||
| 944 | return NULL; | 945 | return NULL; |
| 945 | } | 946 | } |
| 946 | new->master = me; | 947 | new->master = me; |
| 947 | atomic_inc(&new->master->ct_general.use); | ||
| 948 | atomic_set(&new->use, 1); | 948 | atomic_set(&new->use, 1); |
| 949 | return new; | 949 | return new; |
| 950 | } | 950 | } |
| 951 | 951 | ||
| 952 | void ip_conntrack_expect_put(struct ip_conntrack_expect *exp) | 952 | void ip_conntrack_expect_put(struct ip_conntrack_expect *exp) |
| 953 | { | 953 | { |
| 954 | if (atomic_dec_and_test(&exp->use)) { | 954 | if (atomic_dec_and_test(&exp->use)) |
| 955 | ip_conntrack_put(exp->master); | ||
| 956 | kmem_cache_free(ip_conntrack_expect_cachep, exp); | 955 | kmem_cache_free(ip_conntrack_expect_cachep, exp); |
| 957 | } | ||
| 958 | } | 956 | } |
| 959 | 957 | ||
| 960 | static void ip_conntrack_expect_insert(struct ip_conntrack_expect *exp) | 958 | static void ip_conntrack_expect_insert(struct ip_conntrack_expect *exp) |
| @@ -982,7 +980,7 @@ static void evict_oldest_expect(struct ip_conntrack *master) | |||
| 982 | list_for_each_entry_reverse(i, &ip_conntrack_expect_list, list) { | 980 | list_for_each_entry_reverse(i, &ip_conntrack_expect_list, list) { |
| 983 | if (i->master == master) { | 981 | if (i->master == master) { |
| 984 | if (del_timer(&i->timeout)) { | 982 | if (del_timer(&i->timeout)) { |
| 985 | unlink_expect(i); | 983 | ip_ct_unlink_expect(i); |
| 986 | ip_conntrack_expect_put(i); | 984 | ip_conntrack_expect_put(i); |
| 987 | } | 985 | } |
| 988 | break; | 986 | break; |
| @@ -1099,7 +1097,7 @@ void ip_conntrack_helper_unregister(struct ip_conntrack_helper *me) | |||
| 1099 | /* Get rid of expectations */ | 1097 | /* Get rid of expectations */ |
| 1100 | list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list, list) { | 1098 | list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list, list) { |
| 1101 | if (exp->master->helper == me && del_timer(&exp->timeout)) { | 1099 | if (exp->master->helper == me && del_timer(&exp->timeout)) { |
| 1102 | unlink_expect(exp); | 1100 | ip_ct_unlink_expect(exp); |
| 1103 | ip_conntrack_expect_put(exp); | 1101 | ip_conntrack_expect_put(exp); |
| 1104 | } | 1102 | } |
| 1105 | } | 1103 | } |
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c index 3a2627db1729..1b79ec36085f 100644 --- a/net/ipv4/netfilter/ip_conntrack_ftp.c +++ b/net/ipv4/netfilter/ip_conntrack_ftp.c | |||
| @@ -421,6 +421,7 @@ static int help(struct sk_buff **pskb, | |||
| 421 | { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }}); | 421 | { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }}); |
| 422 | 422 | ||
| 423 | exp->expectfn = NULL; | 423 | exp->expectfn = NULL; |
| 424 | exp->flags = 0; | ||
| 424 | 425 | ||
| 425 | /* Now, NAT might want to mangle the packet, and register the | 426 | /* Now, NAT might want to mangle the packet, and register the |
| 426 | * (possibly changed) expectation itself. */ | 427 | * (possibly changed) expectation itself. */ |
diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c index 25438eec21a1..d7a8a98c05e1 100644 --- a/net/ipv4/netfilter/ip_conntrack_irc.c +++ b/net/ipv4/netfilter/ip_conntrack_irc.c | |||
| @@ -221,6 +221,7 @@ static int help(struct sk_buff **pskb, | |||
| 221 | { { 0, { 0 } }, | 221 | { { 0, { 0 } }, |
| 222 | { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }}); | 222 | { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFF }}); |
| 223 | exp->expectfn = NULL; | 223 | exp->expectfn = NULL; |
| 224 | exp->flags = 0; | ||
| 224 | if (ip_nat_irc_hook) | 225 | if (ip_nat_irc_hook) |
| 225 | ret = ip_nat_irc_hook(pskb, ctinfo, | 226 | ret = ip_nat_irc_hook(pskb, ctinfo, |
| 226 | addr_beg_p - ib_ptr, | 227 | 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 index 000000000000..2b5cf9c51309 --- /dev/null +++ b/net/ipv4/netfilter/ip_conntrack_netbios_ns.c | |||
| @@ -0,0 +1,131 @@ | |||
| 1 | /* | ||
| 2 | * NetBIOS name service broadcast connection tracking helper | ||
| 3 | * | ||
| 4 | * (c) 2005 Patrick McHardy <kaber@trash.net> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or | ||
| 7 | * modify it under the terms of the GNU General Public License | ||
| 8 | * as published by the Free Software Foundation; either version | ||
| 9 | * 2 of the License, or (at your option) any later version. | ||
| 10 | */ | ||
| 11 | /* | ||
| 12 | * This helper tracks locally originating NetBIOS name service | ||
| 13 | * requests by issuing permanent expectations (valid until | ||
| 14 | * timing out) matching all reply connections from the | ||
| 15 | * destination network. The only NetBIOS specific thing is | ||
| 16 | * actually the port number. | ||
| 17 | */ | ||
| 18 | #include <linux/kernel.h> | ||
| 19 | #include <linux/module.h> | ||
| 20 | #include <linux/init.h> | ||
| 21 | #include <linux/skbuff.h> | ||
| 22 | #include <linux/netdevice.h> | ||
| 23 | #include <linux/inetdevice.h> | ||
| 24 | #include <linux/in.h> | ||
| 25 | #include <linux/ip.h> | ||
| 26 | #include <linux/udp.h> | ||
| 27 | #include <net/route.h> | ||
| 28 | |||
| 29 | #include <linux/netfilter.h> | ||
| 30 | #include <linux/netfilter_ipv4.h> | ||
| 31 | #include <linux/netfilter_ipv4/ip_conntrack.h> | ||
| 32 | #include <linux/netfilter_ipv4/ip_conntrack_helper.h> | ||
| 33 | |||
| 34 | MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); | ||
| 35 | MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper"); | ||
| 36 | MODULE_LICENSE("GPL"); | ||
| 37 | |||
| 38 | static unsigned int timeout = 3; | ||
| 39 | module_param(timeout, int, 0600); | ||
| 40 | MODULE_PARM_DESC(timeout, "timeout for master connection/replies in seconds"); | ||
| 41 | |||
| 42 | static int help(struct sk_buff **pskb, | ||
| 43 | struct ip_conntrack *ct, enum ip_conntrack_info ctinfo) | ||
| 44 | { | ||
| 45 | struct ip_conntrack_expect *exp; | ||
| 46 | struct iphdr *iph = (*pskb)->nh.iph; | ||
| 47 | struct udphdr _uh, *uh; | ||
| 48 | struct rtable *rt = (struct rtable *)(*pskb)->dst; | ||
| 49 | struct in_device *in_dev; | ||
| 50 | u_int32_t mask = 0; | ||
| 51 | |||
| 52 | /* we're only interested in locally generated packets */ | ||
| 53 | if ((*pskb)->sk == NULL) | ||
| 54 | goto out; | ||
| 55 | if (rt == NULL || !(rt->rt_flags & RTCF_BROADCAST)) | ||
| 56 | goto out; | ||
| 57 | if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) | ||
| 58 | goto out; | ||
| 59 | |||
| 60 | rcu_read_lock(); | ||
| 61 | in_dev = __in_dev_get(rt->u.dst.dev); | ||
| 62 | if (in_dev != NULL) { | ||
| 63 | for_primary_ifa(in_dev) { | ||
| 64 | if (ifa->ifa_broadcast == iph->daddr) { | ||
| 65 | mask = ifa->ifa_mask; | ||
| 66 | break; | ||
| 67 | } | ||
| 68 | } endfor_ifa(in_dev); | ||
| 69 | } | ||
| 70 | rcu_read_unlock(); | ||
| 71 | |||
| 72 | if (mask == 0) | ||
| 73 | goto out; | ||
| 74 | |||
| 75 | uh = skb_header_pointer(*pskb, iph->ihl * 4, sizeof(_uh), &_uh); | ||
| 76 | BUG_ON(uh == NULL); | ||
| 77 | |||
| 78 | exp = ip_conntrack_expect_alloc(ct); | ||
| 79 | if (exp == NULL) | ||
| 80 | goto out; | ||
| 81 | memset(&exp->tuple, 0, sizeof(exp->tuple)); | ||
| 82 | exp->tuple.src.ip = iph->daddr & mask; | ||
| 83 | exp->tuple.dst.ip = iph->saddr; | ||
| 84 | exp->tuple.dst.u.udp.port = uh->source; | ||
| 85 | exp->tuple.dst.protonum = IPPROTO_UDP; | ||
| 86 | |||
| 87 | memset(&exp->mask, 0, sizeof(exp->mask)); | ||
| 88 | exp->mask.src.ip = mask; | ||
| 89 | exp->mask.dst.ip = 0xFFFFFFFF; | ||
| 90 | exp->mask.dst.u.udp.port = 0xFFFF; | ||
| 91 | exp->mask.dst.protonum = 0xFF; | ||
| 92 | |||
| 93 | exp->expectfn = NULL; | ||
| 94 | exp->flags = IP_CT_EXPECT_PERMANENT; | ||
| 95 | |||
| 96 | ip_conntrack_expect_related(exp); | ||
| 97 | ip_conntrack_expect_put(exp); | ||
| 98 | |||
| 99 | ip_ct_refresh_acct(ct, ctinfo, NULL, timeout * HZ); | ||
| 100 | out: | ||
| 101 | return NF_ACCEPT; | ||
| 102 | } | ||
| 103 | |||
| 104 | static struct ip_conntrack_helper helper = { | ||
| 105 | .name = "netbios-ns", | ||
| 106 | .tuple = { | ||
| 107 | .src.u.udp.port = __constant_htons(137), | ||
| 108 | .dst.protonum = IPPROTO_UDP, | ||
| 109 | }, | ||
| 110 | .mask = { | ||
| 111 | .src.u.udp.port = 0xFFFF, | ||
| 112 | .dst.protonum = 0xFF, | ||
| 113 | }, | ||
| 114 | .max_expected = 1, | ||
| 115 | .me = THIS_MODULE, | ||
| 116 | .help = help, | ||
| 117 | }; | ||
| 118 | |||
| 119 | static int __init init(void) | ||
| 120 | { | ||
| 121 | helper.timeout = timeout; | ||
| 122 | return ip_conntrack_helper_register(&helper); | ||
| 123 | } | ||
| 124 | |||
| 125 | static void __exit fini(void) | ||
| 126 | { | ||
| 127 | ip_conntrack_helper_unregister(&helper); | ||
| 128 | } | ||
| 129 | |||
| 130 | module_init(init); | ||
| 131 | module_exit(fini); | ||
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c index a4e9278db4ed..15aef3564742 100644 --- a/net/ipv4/netfilter/ip_conntrack_netlink.c +++ b/net/ipv4/netfilter/ip_conntrack_netlink.c | |||
| @@ -1349,8 +1349,10 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, | |||
| 1349 | list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list, | 1349 | list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list, |
| 1350 | list) { | 1350 | list) { |
| 1351 | if (exp->master->helper == h | 1351 | if (exp->master->helper == h |
| 1352 | && del_timer(&exp->timeout)) | 1352 | && del_timer(&exp->timeout)) { |
| 1353 | __ip_ct_expect_unlink_destroy(exp); | 1353 | ip_ct_unlink_expect(exp); |
| 1354 | ip_conntrack_expect_put(exp); | ||
| 1355 | } | ||
| 1354 | } | 1356 | } |
| 1355 | write_unlock(&ip_conntrack_lock); | 1357 | write_unlock(&ip_conntrack_lock); |
| 1356 | } else { | 1358 | } else { |
| @@ -1358,8 +1360,10 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb, | |||
| 1358 | write_lock_bh(&ip_conntrack_lock); | 1360 | write_lock_bh(&ip_conntrack_lock); |
| 1359 | list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list, | 1361 | list_for_each_entry_safe(exp, tmp, &ip_conntrack_expect_list, |
| 1360 | list) { | 1362 | list) { |
| 1361 | if (del_timer(&exp->timeout)) | 1363 | if (del_timer(&exp->timeout)) { |
| 1362 | __ip_ct_expect_unlink_destroy(exp); | 1364 | ip_ct_unlink_expect(exp); |
| 1365 | ip_conntrack_expect_put(exp); | ||
| 1366 | } | ||
| 1363 | } | 1367 | } |
| 1364 | write_unlock_bh(&ip_conntrack_lock); | 1368 | write_unlock_bh(&ip_conntrack_lock); |
| 1365 | } | 1369 | } |
| @@ -1413,6 +1417,7 @@ ctnetlink_create_expect(struct nfattr *cda[]) | |||
| 1413 | } | 1417 | } |
| 1414 | 1418 | ||
| 1415 | exp->expectfn = NULL; | 1419 | exp->expectfn = NULL; |
| 1420 | exp->flags = 0; | ||
| 1416 | exp->master = ct; | 1421 | exp->master = ct; |
| 1417 | memcpy(&exp->tuple, &tuple, sizeof(struct ip_conntrack_tuple)); | 1422 | memcpy(&exp->tuple, &tuple, sizeof(struct ip_conntrack_tuple)); |
| 1418 | memcpy(&exp->mask, &mask, sizeof(struct ip_conntrack_tuple)); | 1423 | memcpy(&exp->mask, &mask, sizeof(struct ip_conntrack_tuple)); |
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c index f23ef1f88c46..1985abc59d24 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c | |||
| @@ -349,6 +349,7 @@ static int tcp_to_nfattr(struct sk_buff *skb, struct nfattr *nfa, | |||
| 349 | return 0; | 349 | return 0; |
| 350 | 350 | ||
| 351 | nfattr_failure: | 351 | nfattr_failure: |
| 352 | read_unlock_bh(&tcp_lock); | ||
| 352 | return -1; | 353 | return -1; |
| 353 | } | 354 | } |
| 354 | #endif | 355 | #endif |
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index ee5895afd0c3..ae3e3e655db5 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c | |||
| @@ -998,7 +998,7 @@ EXPORT_SYMBOL(ip_conntrack_expect_related); | |||
| 998 | EXPORT_SYMBOL(ip_conntrack_unexpect_related); | 998 | EXPORT_SYMBOL(ip_conntrack_unexpect_related); |
| 999 | EXPORT_SYMBOL_GPL(ip_conntrack_expect_list); | 999 | EXPORT_SYMBOL_GPL(ip_conntrack_expect_list); |
| 1000 | EXPORT_SYMBOL_GPL(__ip_conntrack_expect_find); | 1000 | EXPORT_SYMBOL_GPL(__ip_conntrack_expect_find); |
| 1001 | EXPORT_SYMBOL_GPL(__ip_ct_expect_unlink_destroy); | 1001 | EXPORT_SYMBOL_GPL(ip_ct_unlink_expect); |
| 1002 | 1002 | ||
| 1003 | EXPORT_SYMBOL(ip_conntrack_tuple_taken); | 1003 | EXPORT_SYMBOL(ip_conntrack_tuple_taken); |
| 1004 | EXPORT_SYMBOL(ip_ct_gather_frags); | 1004 | EXPORT_SYMBOL(ip_ct_gather_frags); |
diff --git a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c index f8ff170f390a..d2b590533452 100644 --- a/net/ipv4/netfilter/ip_conntrack_tftp.c +++ b/net/ipv4/netfilter/ip_conntrack_tftp.c | |||
| @@ -75,6 +75,7 @@ static int tftp_help(struct sk_buff **pskb, | |||
| 75 | exp->mask.dst.u.udp.port = 0xffff; | 75 | exp->mask.dst.u.udp.port = 0xffff; |
| 76 | exp->mask.dst.protonum = 0xff; | 76 | exp->mask.dst.protonum = 0xff; |
| 77 | exp->expectfn = NULL; | 77 | exp->expectfn = NULL; |
| 78 | exp->flags = 0; | ||
| 78 | 79 | ||
| 79 | DEBUGP("expect: "); | 80 | DEBUGP("expect: "); |
| 80 | DUMP_TUPLE(&exp->tuple); | 81 | DUMP_TUPLE(&exp->tuple); |
diff --git a/net/ipv4/netfilter/ip_nat_rule.c b/net/ipv4/netfilter/ip_nat_rule.c index 60d70fa41a15..cb66b8bddeb3 100644 --- a/net/ipv4/netfilter/ip_nat_rule.c +++ b/net/ipv4/netfilter/ip_nat_rule.c | |||
| @@ -255,6 +255,27 @@ alloc_null_binding(struct ip_conntrack *conntrack, | |||
| 255 | return ip_nat_setup_info(conntrack, &range, hooknum); | 255 | return ip_nat_setup_info(conntrack, &range, hooknum); |
| 256 | } | 256 | } |
| 257 | 257 | ||
| 258 | unsigned int | ||
| 259 | alloc_null_binding_confirmed(struct ip_conntrack *conntrack, | ||
| 260 | struct ip_nat_info *info, | ||
| 261 | unsigned int hooknum) | ||
| 262 | { | ||
| 263 | u_int32_t ip | ||
| 264 | = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC | ||
| 265 | ? conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip | ||
| 266 | : conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip); | ||
| 267 | u_int16_t all | ||
| 268 | = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC | ||
| 269 | ? conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.all | ||
| 270 | : conntrack->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.all); | ||
| 271 | struct ip_nat_range range | ||
| 272 | = { IP_NAT_RANGE_MAP_IPS, ip, ip, { all }, { all } }; | ||
| 273 | |||
| 274 | DEBUGP("Allocating NULL binding for confirmed %p (%u.%u.%u.%u)\n", | ||
| 275 | conntrack, NIPQUAD(ip)); | ||
| 276 | return ip_nat_setup_info(conntrack, &range, hooknum); | ||
| 277 | } | ||
| 278 | |||
| 258 | int ip_nat_rule_find(struct sk_buff **pskb, | 279 | int ip_nat_rule_find(struct sk_buff **pskb, |
| 259 | unsigned int hooknum, | 280 | unsigned int hooknum, |
| 260 | const struct net_device *in, | 281 | const struct net_device *in, |
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index 89db052add81..0ff368b131f6 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c | |||
| @@ -123,8 +123,12 @@ ip_nat_fn(unsigned int hooknum, | |||
| 123 | if (!ip_nat_initialized(ct, maniptype)) { | 123 | if (!ip_nat_initialized(ct, maniptype)) { |
| 124 | unsigned int ret; | 124 | unsigned int ret; |
| 125 | 125 | ||
| 126 | /* LOCAL_IN hook doesn't have a chain! */ | 126 | if (unlikely(is_confirmed(ct))) |
| 127 | if (hooknum == NF_IP_LOCAL_IN) | 127 | /* NAT module was loaded late */ |
| 128 | ret = alloc_null_binding_confirmed(ct, info, | ||
| 129 | hooknum); | ||
| 130 | else if (hooknum == NF_IP_LOCAL_IN) | ||
| 131 | /* LOCAL_IN hook doesn't have a chain! */ | ||
| 128 | ret = alloc_null_binding(ct, info, hooknum); | 132 | ret = alloc_null_binding(ct, info, hooknum); |
| 129 | else | 133 | else |
| 130 | ret = ip_nat_rule_find(pskb, hooknum, | 134 | ret = ip_nat_rule_find(pskb, hooknum, |
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 249bddb28acd..f81fe8c52e99 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
| @@ -371,6 +371,12 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue, | |||
| 371 | break; | 371 | break; |
| 372 | 372 | ||
| 373 | case NFQNL_COPY_PACKET: | 373 | case NFQNL_COPY_PACKET: |
| 374 | if (entry->skb->ip_summed == CHECKSUM_HW && | ||
| 375 | (*errp = skb_checksum_help(entry->skb, | ||
| 376 | entry->info->outdev == NULL))) { | ||
| 377 | spin_unlock_bh(&queue->lock); | ||
| 378 | return NULL; | ||
| 379 | } | ||
| 374 | if (queue->copy_range == 0 | 380 | if (queue->copy_range == 0 |
| 375 | || queue->copy_range > entry->skb->len) | 381 | || queue->copy_range > entry->skb->len) |
| 376 | data_len = entry->skb->len; | 382 | data_len = entry->skb->len; |
| @@ -636,7 +642,7 @@ nfqnl_mangle(void *data, int data_len, struct nfqnl_queue_entry *e) | |||
| 636 | if (!skb_make_writable(&e->skb, data_len)) | 642 | if (!skb_make_writable(&e->skb, data_len)) |
| 637 | return -ENOMEM; | 643 | return -ENOMEM; |
| 638 | memcpy(e->skb->data, data, data_len); | 644 | memcpy(e->skb->data, data, data_len); |
| 639 | 645 | e->skb->ip_summed = CHECKSUM_NONE; | |
| 640 | return 0; | 646 | return 0; |
| 641 | } | 647 | } |
| 642 | 648 | ||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 62435ffc6184..a64e1d5ce3ca 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -398,24 +398,13 @@ static int netlink_create(struct socket *sock, int protocol) | |||
| 398 | if (nl_table[protocol].registered && | 398 | if (nl_table[protocol].registered && |
| 399 | try_module_get(nl_table[protocol].module)) | 399 | try_module_get(nl_table[protocol].module)) |
| 400 | module = nl_table[protocol].module; | 400 | module = nl_table[protocol].module; |
| 401 | else | ||
| 402 | err = -EPROTONOSUPPORT; | ||
| 403 | groups = nl_table[protocol].groups; | 401 | groups = nl_table[protocol].groups; |
| 404 | netlink_unlock_table(); | 402 | netlink_unlock_table(); |
| 405 | 403 | ||
| 406 | if (err || (err = __netlink_create(sock, protocol) < 0)) | 404 | if ((err = __netlink_create(sock, protocol) < 0)) |
| 407 | goto out_module; | 405 | goto out_module; |
| 408 | 406 | ||
| 409 | nlk = nlk_sk(sock->sk); | 407 | nlk = nlk_sk(sock->sk); |
| 410 | |||
| 411 | nlk->groups = kmalloc(NLGRPSZ(groups), GFP_KERNEL); | ||
| 412 | if (nlk->groups == NULL) { | ||
| 413 | err = -ENOMEM; | ||
| 414 | goto out_module; | ||
| 415 | } | ||
| 416 | memset(nlk->groups, 0, NLGRPSZ(groups)); | ||
| 417 | nlk->ngroups = groups; | ||
| 418 | |||
| 419 | nlk->module = module; | 408 | nlk->module = module; |
| 420 | out: | 409 | out: |
| 421 | return err; | 410 | return err; |
| @@ -534,6 +523,29 @@ netlink_update_subscriptions(struct sock *sk, unsigned int subscriptions) | |||
| 534 | nlk->subscriptions = subscriptions; | 523 | nlk->subscriptions = subscriptions; |
| 535 | } | 524 | } |
| 536 | 525 | ||
| 526 | static int netlink_alloc_groups(struct sock *sk) | ||
| 527 | { | ||
| 528 | struct netlink_sock *nlk = nlk_sk(sk); | ||
| 529 | unsigned int groups; | ||
| 530 | int err = 0; | ||
| 531 | |||
| 532 | netlink_lock_table(); | ||
| 533 | groups = nl_table[sk->sk_protocol].groups; | ||
| 534 | if (!nl_table[sk->sk_protocol].registered) | ||
| 535 | err = -ENOENT; | ||
| 536 | netlink_unlock_table(); | ||
| 537 | |||
| 538 | if (err) | ||
| 539 | return err; | ||
| 540 | |||
| 541 | nlk->groups = kmalloc(NLGRPSZ(groups), GFP_KERNEL); | ||
| 542 | if (nlk->groups == NULL) | ||
| 543 | return -ENOMEM; | ||
| 544 | memset(nlk->groups, 0, NLGRPSZ(groups)); | ||
| 545 | nlk->ngroups = groups; | ||
| 546 | return 0; | ||
| 547 | } | ||
| 548 | |||
| 537 | static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len) | 549 | static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len) |
| 538 | { | 550 | { |
| 539 | struct sock *sk = sock->sk; | 551 | struct sock *sk = sock->sk; |
| @@ -545,8 +557,15 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len | |||
| 545 | return -EINVAL; | 557 | return -EINVAL; |
| 546 | 558 | ||
| 547 | /* Only superuser is allowed to listen multicasts */ | 559 | /* Only superuser is allowed to listen multicasts */ |
| 548 | if (nladdr->nl_groups && !netlink_capable(sock, NL_NONROOT_RECV)) | 560 | if (nladdr->nl_groups) { |
| 549 | return -EPERM; | 561 | if (!netlink_capable(sock, NL_NONROOT_RECV)) |
| 562 | return -EPERM; | ||
| 563 | if (nlk->groups == NULL) { | ||
| 564 | err = netlink_alloc_groups(sk); | ||
| 565 | if (err) | ||
| 566 | return err; | ||
| 567 | } | ||
| 568 | } | ||
| 550 | 569 | ||
| 551 | if (nlk->pid) { | 570 | if (nlk->pid) { |
| 552 | if (nladdr->nl_pid != nlk->pid) | 571 | if (nladdr->nl_pid != nlk->pid) |
| @@ -559,7 +578,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, int addr_len | |||
| 559 | return err; | 578 | return err; |
| 560 | } | 579 | } |
| 561 | 580 | ||
| 562 | if (!nladdr->nl_groups && !(u32)nlk->groups[0]) | 581 | if (!nladdr->nl_groups && (nlk->groups == NULL || !(u32)nlk->groups[0])) |
| 563 | return 0; | 582 | return 0; |
| 564 | 583 | ||
| 565 | netlink_table_grab(); | 584 | netlink_table_grab(); |
| @@ -620,7 +639,7 @@ static int netlink_getname(struct socket *sock, struct sockaddr *addr, int *addr | |||
| 620 | nladdr->nl_groups = netlink_group_mask(nlk->dst_group); | 639 | nladdr->nl_groups = netlink_group_mask(nlk->dst_group); |
| 621 | } else { | 640 | } else { |
| 622 | nladdr->nl_pid = nlk->pid; | 641 | nladdr->nl_pid = nlk->pid; |
| 623 | nladdr->nl_groups = nlk->groups[0]; | 642 | nladdr->nl_groups = nlk->groups ? nlk->groups[0] : 0; |
| 624 | } | 643 | } |
| 625 | return 0; | 644 | return 0; |
| 626 | } | 645 | } |
| @@ -976,6 +995,11 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname, | |||
| 976 | 995 | ||
| 977 | if (!netlink_capable(sock, NL_NONROOT_RECV)) | 996 | if (!netlink_capable(sock, NL_NONROOT_RECV)) |
| 978 | return -EPERM; | 997 | return -EPERM; |
| 998 | if (nlk->groups == NULL) { | ||
| 999 | err = netlink_alloc_groups(sk); | ||
| 1000 | if (err) | ||
| 1001 | return err; | ||
| 1002 | } | ||
| 979 | if (!val || val - 1 >= nlk->ngroups) | 1003 | if (!val || val - 1 >= nlk->ngroups) |
| 980 | return -EINVAL; | 1004 | return -EINVAL; |
| 981 | netlink_table_grab(); | 1005 | netlink_table_grab(); |
| @@ -1483,8 +1507,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v) | |||
| 1483 | s, | 1507 | s, |
| 1484 | s->sk_protocol, | 1508 | s->sk_protocol, |
| 1485 | nlk->pid, | 1509 | nlk->pid, |
| 1486 | nlk->flags & NETLINK_KERNEL_SOCKET ? | 1510 | nlk->groups ? (u32)nlk->groups[0] : 0, |
| 1487 | 0 : (unsigned int)nlk->groups[0], | ||
| 1488 | atomic_read(&s->sk_rmem_alloc), | 1511 | atomic_read(&s->sk_rmem_alloc), |
| 1489 | atomic_read(&s->sk_wmem_alloc), | 1512 | atomic_read(&s->sk_wmem_alloc), |
| 1490 | nlk->cb, | 1513 | nlk->cb, |
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 4b53de982114..f4578c759ffc 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
| @@ -1261,6 +1261,7 @@ static int nr_info_show(struct seq_file *seq, void *v) | |||
| 1261 | struct net_device *dev; | 1261 | struct net_device *dev; |
| 1262 | struct nr_sock *nr; | 1262 | struct nr_sock *nr; |
| 1263 | const char *devname; | 1263 | const char *devname; |
| 1264 | char buf[11]; | ||
| 1264 | 1265 | ||
| 1265 | if (v == SEQ_START_TOKEN) | 1266 | if (v == SEQ_START_TOKEN) |
| 1266 | seq_puts(seq, | 1267 | seq_puts(seq, |
| @@ -1276,11 +1277,11 @@ static int nr_info_show(struct seq_file *seq, void *v) | |||
| 1276 | else | 1277 | else |
| 1277 | devname = dev->name; | 1278 | devname = dev->name; |
| 1278 | 1279 | ||
| 1279 | seq_printf(seq, "%-9s ", ax2asc(&nr->user_addr)); | 1280 | seq_printf(seq, "%-9s ", ax2asc(buf, &nr->user_addr)); |
| 1280 | seq_printf(seq, "%-9s ", ax2asc(&nr->dest_addr)); | 1281 | seq_printf(seq, "%-9s ", ax2asc(buf, &nr->dest_addr)); |
| 1281 | seq_printf(seq, | 1282 | seq_printf(seq, |
| 1282 | "%-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", | 1283 | "%-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", |
| 1283 | ax2asc(&nr->source_addr), | 1284 | ax2asc(buf, &nr->source_addr), |
| 1284 | devname, | 1285 | devname, |
| 1285 | nr->my_index, | 1286 | nr->my_index, |
| 1286 | nr->my_id, | 1287 | nr->my_id, |
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c index 7a86b36cba50..b3b9097c87c7 100644 --- a/net/netrom/nr_route.c +++ b/net/netrom/nr_route.c | |||
| @@ -881,6 +881,7 @@ static void nr_node_stop(struct seq_file *seq, void *v) | |||
| 881 | 881 | ||
| 882 | static int nr_node_show(struct seq_file *seq, void *v) | 882 | static int nr_node_show(struct seq_file *seq, void *v) |
| 883 | { | 883 | { |
| 884 | char buf[11]; | ||
| 884 | int i; | 885 | int i; |
| 885 | 886 | ||
| 886 | if (v == SEQ_START_TOKEN) | 887 | if (v == SEQ_START_TOKEN) |
| @@ -890,7 +891,7 @@ static int nr_node_show(struct seq_file *seq, void *v) | |||
| 890 | struct nr_node *nr_node = v; | 891 | struct nr_node *nr_node = v; |
| 891 | nr_node_lock(nr_node); | 892 | nr_node_lock(nr_node); |
| 892 | seq_printf(seq, "%-9s %-7s %d %d", | 893 | seq_printf(seq, "%-9s %-7s %d %d", |
| 893 | ax2asc(&nr_node->callsign), | 894 | ax2asc(buf, &nr_node->callsign), |
| 894 | (nr_node->mnemonic[0] == '\0') ? "*" : nr_node->mnemonic, | 895 | (nr_node->mnemonic[0] == '\0') ? "*" : nr_node->mnemonic, |
| 895 | nr_node->which + 1, | 896 | nr_node->which + 1, |
| 896 | nr_node->count); | 897 | nr_node->count); |
| @@ -964,6 +965,7 @@ static void nr_neigh_stop(struct seq_file *seq, void *v) | |||
| 964 | 965 | ||
| 965 | static int nr_neigh_show(struct seq_file *seq, void *v) | 966 | static int nr_neigh_show(struct seq_file *seq, void *v) |
| 966 | { | 967 | { |
| 968 | char buf[11]; | ||
| 967 | int i; | 969 | int i; |
| 968 | 970 | ||
| 969 | if (v == SEQ_START_TOKEN) | 971 | if (v == SEQ_START_TOKEN) |
| @@ -973,7 +975,7 @@ static int nr_neigh_show(struct seq_file *seq, void *v) | |||
| 973 | 975 | ||
| 974 | seq_printf(seq, "%05d %-9s %-4s %3d %d %3d %3d", | 976 | seq_printf(seq, "%05d %-9s %-4s %3d %d %3d %3d", |
| 975 | nr_neigh->number, | 977 | nr_neigh->number, |
| 976 | ax2asc(&nr_neigh->callsign), | 978 | ax2asc(buf, &nr_neigh->callsign), |
| 977 | nr_neigh->dev ? nr_neigh->dev->name : "???", | 979 | nr_neigh->dev ? nr_neigh->dev->name : "???", |
| 978 | nr_neigh->quality, | 980 | nr_neigh->quality, |
| 979 | nr_neigh->locked, | 981 | nr_neigh->locked, |
| @@ -983,7 +985,7 @@ static int nr_neigh_show(struct seq_file *seq, void *v) | |||
| 983 | if (nr_neigh->digipeat != NULL) { | 985 | if (nr_neigh->digipeat != NULL) { |
| 984 | for (i = 0; i < nr_neigh->digipeat->ndigi; i++) | 986 | for (i = 0; i < nr_neigh->digipeat->ndigi; i++) |
| 985 | seq_printf(seq, " %s", | 987 | seq_printf(seq, " %s", |
| 986 | ax2asc(&nr_neigh->digipeat->calls[i])); | 988 | ax2asc(buf, &nr_neigh->digipeat->calls[i])); |
| 987 | } | 989 | } |
| 988 | 990 | ||
| 989 | seq_puts(seq, "\n"); | 991 | seq_puts(seq, "\n"); |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index ba997095f08f..8690f171c1ef 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
| @@ -1535,8 +1535,7 @@ static unsigned int packet_poll(struct file * file, struct socket *sock, | |||
| 1535 | static void packet_mm_open(struct vm_area_struct *vma) | 1535 | static void packet_mm_open(struct vm_area_struct *vma) |
| 1536 | { | 1536 | { |
| 1537 | struct file *file = vma->vm_file; | 1537 | struct file *file = vma->vm_file; |
| 1538 | struct inode *inode = file->f_dentry->d_inode; | 1538 | struct socket * sock = file->private_data; |
| 1539 | struct socket * sock = SOCKET_I(inode); | ||
| 1540 | struct sock *sk = sock->sk; | 1539 | struct sock *sk = sock->sk; |
| 1541 | 1540 | ||
| 1542 | if (sk) | 1541 | if (sk) |
| @@ -1546,8 +1545,7 @@ static void packet_mm_open(struct vm_area_struct *vma) | |||
| 1546 | static void packet_mm_close(struct vm_area_struct *vma) | 1545 | static void packet_mm_close(struct vm_area_struct *vma) |
| 1547 | { | 1546 | { |
| 1548 | struct file *file = vma->vm_file; | 1547 | struct file *file = vma->vm_file; |
| 1549 | struct inode *inode = file->f_dentry->d_inode; | 1548 | struct socket * sock = file->private_data; |
| 1550 | struct socket * sock = SOCKET_I(inode); | ||
| 1551 | struct sock *sk = sock->sk; | 1549 | struct sock *sk = sock->sk; |
| 1552 | 1550 | ||
| 1553 | if (sk) | 1551 | if (sk) |
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index c6e59f84c3ae..3077878ed4f0 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
| @@ -1363,6 +1363,8 @@ static void rose_info_stop(struct seq_file *seq, void *v) | |||
| 1363 | 1363 | ||
| 1364 | static int rose_info_show(struct seq_file *seq, void *v) | 1364 | static int rose_info_show(struct seq_file *seq, void *v) |
| 1365 | { | 1365 | { |
| 1366 | char buf[11]; | ||
| 1367 | |||
| 1366 | if (v == SEQ_START_TOKEN) | 1368 | if (v == SEQ_START_TOKEN) |
| 1367 | seq_puts(seq, | 1369 | seq_puts(seq, |
| 1368 | "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"); | 1370 | "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) | |||
| 1380 | 1382 | ||
| 1381 | seq_printf(seq, "%-10s %-9s ", | 1383 | seq_printf(seq, "%-10s %-9s ", |
| 1382 | rose2asc(&rose->dest_addr), | 1384 | rose2asc(&rose->dest_addr), |
| 1383 | ax2asc(&rose->dest_call)); | 1385 | ax2asc(buf, &rose->dest_call)); |
| 1384 | 1386 | ||
| 1385 | if (ax25cmp(&rose->source_call, &null_ax25_address) == 0) | 1387 | if (ax25cmp(&rose->source_call, &null_ax25_address) == 0) |
| 1386 | callsign = "??????-?"; | 1388 | callsign = "??????-?"; |
| 1387 | else | 1389 | else |
| 1388 | callsign = ax2asc(&rose->source_call); | 1390 | callsign = ax2asc(buf, &rose->source_call); |
| 1389 | 1391 | ||
| 1390 | seq_printf(seq, | 1392 | seq_printf(seq, |
| 1391 | "%-10s %-9s %-5s %3.3X %05d %d %d %d %d %3lu %3lu %3lu %3lu %3lu %3lu/%03lu %5d %5d %ld\n", | 1393 | "%-10s %-9s %-5s %3.3X %05d %d %d %d %d %3lu %3lu %3lu %3lu %3lu %3lu/%03lu %5d %5d %ld\n", |
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index 4510cd7613ec..e556d92c0bc4 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c | |||
| @@ -851,6 +851,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) | |||
| 851 | unsigned char cause, diagnostic; | 851 | unsigned char cause, diagnostic; |
| 852 | struct net_device *dev; | 852 | struct net_device *dev; |
| 853 | int len, res = 0; | 853 | int len, res = 0; |
| 854 | char buf[11]; | ||
| 854 | 855 | ||
| 855 | #if 0 | 856 | #if 0 |
| 856 | if (call_in_firewall(PF_ROSE, skb->dev, skb->data, NULL, &skb) != FW_ACCEPT) | 857 | 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) | |||
| 876 | 877 | ||
| 877 | if (rose_neigh == NULL) { | 878 | if (rose_neigh == NULL) { |
| 878 | printk("rose_route : unknown neighbour or device %s\n", | 879 | printk("rose_route : unknown neighbour or device %s\n", |
| 879 | ax2asc(&ax25->dest_addr)); | 880 | ax2asc(buf, &ax25->dest_addr)); |
| 880 | goto out; | 881 | goto out; |
| 881 | } | 882 | } |
| 882 | 883 | ||
| @@ -1178,6 +1179,7 @@ static void rose_neigh_stop(struct seq_file *seq, void *v) | |||
| 1178 | 1179 | ||
| 1179 | static int rose_neigh_show(struct seq_file *seq, void *v) | 1180 | static int rose_neigh_show(struct seq_file *seq, void *v) |
| 1180 | { | 1181 | { |
| 1182 | char buf[11]; | ||
| 1181 | int i; | 1183 | int i; |
| 1182 | 1184 | ||
| 1183 | if (v == SEQ_START_TOKEN) | 1185 | if (v == SEQ_START_TOKEN) |
| @@ -1189,7 +1191,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v) | |||
| 1189 | /* if (!rose_neigh->loopback) { */ | 1191 | /* if (!rose_neigh->loopback) { */ |
| 1190 | seq_printf(seq, "%05d %-9s %-4s %3d %3d %3s %3s %3lu %3lu", | 1192 | seq_printf(seq, "%05d %-9s %-4s %3d %3d %3s %3s %3lu %3lu", |
| 1191 | rose_neigh->number, | 1193 | rose_neigh->number, |
| 1192 | (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(&rose_neigh->callsign), | 1194 | (rose_neigh->loopback) ? "RSLOOP-0" : ax2asc(buf, &rose_neigh->callsign), |
| 1193 | rose_neigh->dev ? rose_neigh->dev->name : "???", | 1195 | rose_neigh->dev ? rose_neigh->dev->name : "???", |
| 1194 | rose_neigh->count, | 1196 | rose_neigh->count, |
| 1195 | rose_neigh->use, | 1197 | rose_neigh->use, |
| @@ -1200,7 +1202,7 @@ static int rose_neigh_show(struct seq_file *seq, void *v) | |||
| 1200 | 1202 | ||
| 1201 | if (rose_neigh->digipeat != NULL) { | 1203 | if (rose_neigh->digipeat != NULL) { |
| 1202 | for (i = 0; i < rose_neigh->digipeat->ndigi; i++) | 1204 | for (i = 0; i < rose_neigh->digipeat->ndigi; i++) |
| 1203 | seq_printf(seq, " %s", ax2asc(&rose_neigh->digipeat->calls[i])); | 1205 | seq_printf(seq, " %s", ax2asc(buf, &rose_neigh->digipeat->calls[i])); |
| 1204 | } | 1206 | } |
| 1205 | 1207 | ||
| 1206 | seq_puts(seq, "\n"); | 1208 | seq_puts(seq, "\n"); |
| @@ -1260,6 +1262,8 @@ static void rose_route_stop(struct seq_file *seq, void *v) | |||
| 1260 | 1262 | ||
| 1261 | static int rose_route_show(struct seq_file *seq, void *v) | 1263 | static int rose_route_show(struct seq_file *seq, void *v) |
| 1262 | { | 1264 | { |
| 1265 | char buf[11]; | ||
| 1266 | |||
| 1263 | if (v == SEQ_START_TOKEN) | 1267 | if (v == SEQ_START_TOKEN) |
| 1264 | seq_puts(seq, | 1268 | seq_puts(seq, |
| 1265 | "lci address callsign neigh <-> lci address callsign neigh\n"); | 1269 | "lci address callsign neigh <-> lci address callsign neigh\n"); |
| @@ -1271,7 +1275,7 @@ static int rose_route_show(struct seq_file *seq, void *v) | |||
| 1271 | "%3.3X %-10s %-9s %05d ", | 1275 | "%3.3X %-10s %-9s %05d ", |
| 1272 | rose_route->lci1, | 1276 | rose_route->lci1, |
| 1273 | rose2asc(&rose_route->src_addr), | 1277 | rose2asc(&rose_route->src_addr), |
| 1274 | ax2asc(&rose_route->src_call), | 1278 | ax2asc(buf, &rose_route->src_call), |
| 1275 | rose_route->neigh1->number); | 1279 | rose_route->neigh1->number); |
| 1276 | else | 1280 | else |
| 1277 | seq_puts(seq, | 1281 | seq_puts(seq, |
| @@ -1282,7 +1286,7 @@ static int rose_route_show(struct seq_file *seq, void *v) | |||
| 1282 | "%3.3X %-10s %-9s %05d\n", | 1286 | "%3.3X %-10s %-9s %05d\n", |
| 1283 | rose_route->lci2, | 1287 | rose_route->lci2, |
| 1284 | rose2asc(&rose_route->dest_addr), | 1288 | rose2asc(&rose_route->dest_addr), |
| 1285 | ax2asc(&rose_route->dest_call), | 1289 | ax2asc(buf, &rose_route->dest_call), |
| 1286 | rose_route->neigh2->number); | 1290 | rose_route->neigh2->number); |
| 1287 | else | 1291 | else |
| 1288 | seq_puts(seq, | 1292 | seq_puts(seq, |
diff --git a/net/rose/rose_subr.c b/net/rose/rose_subr.c index a29a3a960fd6..02891ce2db37 100644 --- a/net/rose/rose_subr.c +++ b/net/rose/rose_subr.c | |||
| @@ -400,6 +400,7 @@ static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose) | |||
| 400 | { | 400 | { |
| 401 | unsigned char *p = buffer + 1; | 401 | unsigned char *p = buffer + 1; |
| 402 | char *callsign; | 402 | char *callsign; |
| 403 | char buf[11]; | ||
| 403 | int len, nb; | 404 | int len, nb; |
| 404 | 405 | ||
| 405 | /* National Facilities */ | 406 | /* National Facilities */ |
| @@ -456,7 +457,7 @@ static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose) | |||
| 456 | 457 | ||
| 457 | *p++ = FAC_CCITT_DEST_NSAP; | 458 | *p++ = FAC_CCITT_DEST_NSAP; |
| 458 | 459 | ||
| 459 | callsign = ax2asc(&rose->dest_call); | 460 | callsign = ax2asc(buf, &rose->dest_call); |
| 460 | 461 | ||
| 461 | *p++ = strlen(callsign) + 10; | 462 | *p++ = strlen(callsign) + 10; |
| 462 | *p++ = (strlen(callsign) + 9) * 2; /* ??? */ | 463 | *p++ = (strlen(callsign) + 9) * 2; /* ??? */ |
| @@ -471,7 +472,7 @@ static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose) | |||
| 471 | 472 | ||
| 472 | *p++ = FAC_CCITT_SRC_NSAP; | 473 | *p++ = FAC_CCITT_SRC_NSAP; |
| 473 | 474 | ||
| 474 | callsign = ax2asc(&rose->source_call); | 475 | callsign = ax2asc(buf, &rose->source_call); |
| 475 | 476 | ||
| 476 | *p++ = strlen(callsign) + 10; | 477 | *p++ = strlen(callsign) + 10; |
| 477 | *p++ = (strlen(callsign) + 9) * 2; /* ??? */ | 478 | *p++ = (strlen(callsign) + 9) * 2; /* ??? */ |
diff --git a/net/socket.c b/net/socket.c index 94fe638b4d72..e1bd5d84d7bf 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -667,7 +667,7 @@ static ssize_t sock_aio_read(struct kiocb *iocb, char __user *ubuf, | |||
| 667 | } | 667 | } |
| 668 | iocb->private = x; | 668 | iocb->private = x; |
| 669 | x->kiocb = iocb; | 669 | x->kiocb = iocb; |
| 670 | sock = SOCKET_I(iocb->ki_filp->f_dentry->d_inode); | 670 | sock = iocb->ki_filp->private_data; |
| 671 | 671 | ||
| 672 | x->async_msg.msg_name = NULL; | 672 | x->async_msg.msg_name = NULL; |
| 673 | x->async_msg.msg_namelen = 0; | 673 | x->async_msg.msg_namelen = 0; |
| @@ -709,7 +709,7 @@ static ssize_t sock_aio_write(struct kiocb *iocb, const char __user *ubuf, | |||
| 709 | } | 709 | } |
| 710 | iocb->private = x; | 710 | iocb->private = x; |
| 711 | x->kiocb = iocb; | 711 | x->kiocb = iocb; |
| 712 | sock = SOCKET_I(iocb->ki_filp->f_dentry->d_inode); | 712 | sock = iocb->ki_filp->private_data; |
| 713 | 713 | ||
| 714 | x->async_msg.msg_name = NULL; | 714 | x->async_msg.msg_name = NULL; |
| 715 | x->async_msg.msg_namelen = 0; | 715 | x->async_msg.msg_namelen = 0; |
| @@ -732,7 +732,7 @@ static ssize_t sock_sendpage(struct file *file, struct page *page, | |||
| 732 | struct socket *sock; | 732 | struct socket *sock; |
| 733 | int flags; | 733 | int flags; |
| 734 | 734 | ||
| 735 | sock = SOCKET_I(file->f_dentry->d_inode); | 735 | sock = file->private_data; |
| 736 | 736 | ||
| 737 | flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT; | 737 | flags = !(file->f_flags & O_NONBLOCK) ? 0 : MSG_DONTWAIT; |
| 738 | if (more) | 738 | if (more) |
| @@ -741,14 +741,14 @@ static ssize_t sock_sendpage(struct file *file, struct page *page, | |||
| 741 | return sock->ops->sendpage(sock, page, offset, size, flags); | 741 | return sock->ops->sendpage(sock, page, offset, size, flags); |
| 742 | } | 742 | } |
| 743 | 743 | ||
| 744 | static int sock_readv_writev(int type, struct inode * inode, | 744 | static int sock_readv_writev(int type, |
| 745 | struct file * file, const struct iovec * iov, | 745 | struct file * file, const struct iovec * iov, |
| 746 | long count, size_t size) | 746 | long count, size_t size) |
| 747 | { | 747 | { |
| 748 | struct msghdr msg; | 748 | struct msghdr msg; |
| 749 | struct socket *sock; | 749 | struct socket *sock; |
| 750 | 750 | ||
| 751 | sock = SOCKET_I(inode); | 751 | sock = file->private_data; |
| 752 | 752 | ||
| 753 | msg.msg_name = NULL; | 753 | msg.msg_name = NULL; |
| 754 | msg.msg_namelen = 0; | 754 | msg.msg_namelen = 0; |
| @@ -775,7 +775,7 @@ static ssize_t sock_readv(struct file *file, const struct iovec *vector, | |||
| 775 | int i; | 775 | int i; |
| 776 | for (i = 0 ; i < count ; i++) | 776 | for (i = 0 ; i < count ; i++) |
| 777 | tot_len += vector[i].iov_len; | 777 | tot_len += vector[i].iov_len; |
| 778 | return sock_readv_writev(VERIFY_WRITE, file->f_dentry->d_inode, | 778 | return sock_readv_writev(VERIFY_WRITE, |
| 779 | file, vector, count, tot_len); | 779 | file, vector, count, tot_len); |
| 780 | } | 780 | } |
| 781 | 781 | ||
| @@ -786,7 +786,7 @@ static ssize_t sock_writev(struct file *file, const struct iovec *vector, | |||
| 786 | int i; | 786 | int i; |
| 787 | for (i = 0 ; i < count ; i++) | 787 | for (i = 0 ; i < count ; i++) |
| 788 | tot_len += vector[i].iov_len; | 788 | tot_len += vector[i].iov_len; |
| 789 | return sock_readv_writev(VERIFY_READ, file->f_dentry->d_inode, | 789 | return sock_readv_writev(VERIFY_READ, |
| 790 | file, vector, count, tot_len); | 790 | file, vector, count, tot_len); |
| 791 | } | 791 | } |
| 792 | 792 | ||
| @@ -840,7 +840,7 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) | |||
| 840 | void __user *argp = (void __user *)arg; | 840 | void __user *argp = (void __user *)arg; |
| 841 | int pid, err; | 841 | int pid, err; |
| 842 | 842 | ||
| 843 | sock = SOCKET_I(file->f_dentry->d_inode); | 843 | sock = file->private_data; |
| 844 | if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { | 844 | if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { |
| 845 | err = dev_ioctl(cmd, argp); | 845 | err = dev_ioctl(cmd, argp); |
| 846 | } else | 846 | } else |
| @@ -939,13 +939,13 @@ static unsigned int sock_poll(struct file *file, poll_table * wait) | |||
| 939 | /* | 939 | /* |
| 940 | * We can't return errors to poll, so it's either yes or no. | 940 | * We can't return errors to poll, so it's either yes or no. |
| 941 | */ | 941 | */ |
| 942 | sock = SOCKET_I(file->f_dentry->d_inode); | 942 | sock = file->private_data; |
| 943 | return sock->ops->poll(file, sock, wait); | 943 | return sock->ops->poll(file, sock, wait); |
| 944 | } | 944 | } |
| 945 | 945 | ||
| 946 | static int sock_mmap(struct file * file, struct vm_area_struct * vma) | 946 | static int sock_mmap(struct file * file, struct vm_area_struct * vma) |
| 947 | { | 947 | { |
| 948 | struct socket *sock = SOCKET_I(file->f_dentry->d_inode); | 948 | struct socket *sock = file->private_data; |
| 949 | 949 | ||
| 950 | return sock->ops->mmap(file, sock, vma); | 950 | return sock->ops->mmap(file, sock, vma); |
| 951 | } | 951 | } |
| @@ -995,7 +995,7 @@ static int sock_fasync(int fd, struct file *filp, int on) | |||
| 995 | return -ENOMEM; | 995 | return -ENOMEM; |
| 996 | } | 996 | } |
| 997 | 997 | ||
| 998 | sock = SOCKET_I(filp->f_dentry->d_inode); | 998 | sock = filp->private_data; |
| 999 | 999 | ||
| 1000 | if ((sk=sock->sk) == NULL) { | 1000 | if ((sk=sock->sk) == NULL) { |
| 1001 | kfree(fna); | 1001 | kfree(fna); |
