diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-07 20:20:11 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-07 20:20:11 -0400 |
commit | f7402dc44d617be807e7184c6c624611b2d35b4e (patch) | |
tree | 1df6e5877ee3083838c7956285a5966d78d0646f | |
parent | e72225d160a2529d6ce6d5898a267f7dae02aa6e (diff) | |
parent | 832079d29a781ddf89467662ab4b540f0c1e668a (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
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); |