diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-03-26 17:51:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-03-26 17:51:24 -0400 |
commit | 703071b5b93d88d5acb0edd5b9dd86c69ad970f2 (patch) | |
tree | 3da99cded2e42f65450bfe849615d56c845263ac /net | |
parent | 6288c338661cc26ea66e7818b0d3862ee163fd1d (diff) | |
parent | 09c72ec8ed8f7499d115309a6e19cd5e66808d88 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
[SUNGEM]: Fix MAC address setting when interface is up.
[IPV4] fib_trie: Document locking.
[NET]: Correct accept(2) recovery after sock_attach_fd()
[PPP]: Don't leak an sk_buff on interface destruction.
[NET_SCHED]: Fix ingress locking
[NET_SCHED]: cls_basic: fix NULL pointer dereference
[DCCP]: make dccp_write_xmit_timer() static again
[TG3]: Update version and reldate.
[TG3]: Exit irq handler during chip reset.
[TG3]: Eliminate the unused TG3_FLAG_SPLIT_MODE flag.
[IPV6]: Fix routing round-robin locking.
[DECNet] fib: Fix out of bound access of dn_fib_props[]
[IPv4] fib: Fix out of bound access of fib_props[]
[NET] AX.25 Kconfig and docs updates and fixes
[NET]: Fix neighbour destructor handling.
[NET]: Fix fib_rules compatibility breakage
[SCTP]: Update SCTP Maintainers entry
[NET]: remove unused header file: drivers/net/wan/lmc/lmc_media.h
Diffstat (limited to 'net')
-rw-r--r-- | net/atm/clip.c | 9 | ||||
-rw-r--r-- | net/ax25/Kconfig | 61 | ||||
-rw-r--r-- | net/core/dev.c | 4 | ||||
-rw-r--r-- | net/core/fib_rules.c | 30 | ||||
-rw-r--r-- | net/core/neighbour.c | 14 | ||||
-rw-r--r-- | net/dccp/dccp.h | 1 | ||||
-rw-r--r-- | net/dccp/timer.c | 2 | ||||
-rw-r--r-- | net/decnet/dn_fib.c | 5 | ||||
-rw-r--r-- | net/decnet/dn_rules.c | 13 | ||||
-rw-r--r-- | net/ipv4/fib_frontend.c | 5 | ||||
-rw-r--r-- | net/ipv4/fib_rules.c | 14 | ||||
-rw-r--r-- | net/ipv4/fib_semantics.c | 2 | ||||
-rw-r--r-- | net/ipv4/fib_trie.c | 9 | ||||
-rw-r--r-- | net/ipv6/fib6_rules.c | 14 | ||||
-rw-r--r-- | net/ipv6/ip6_fib.c | 8 | ||||
-rw-r--r-- | net/ipv6/route.c | 97 | ||||
-rw-r--r-- | net/sched/cls_basic.c | 16 | ||||
-rw-r--r-- | net/socket.c | 7 |
18 files changed, 195 insertions, 116 deletions
diff --git a/net/atm/clip.c b/net/atm/clip.c index ebb5d0ce8b6f..8c3825816085 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c | |||
@@ -261,14 +261,6 @@ static void clip_pop(struct atm_vcc *vcc, struct sk_buff *skb) | |||
261 | spin_unlock_irqrestore(&PRIV(dev)->xoff_lock, flags); | 261 | spin_unlock_irqrestore(&PRIV(dev)->xoff_lock, flags); |
262 | } | 262 | } |
263 | 263 | ||
264 | static void clip_neigh_destroy(struct neighbour *neigh) | ||
265 | { | ||
266 | DPRINTK("clip_neigh_destroy (neigh %p)\n", neigh); | ||
267 | if (NEIGH2ENTRY(neigh)->vccs) | ||
268 | printk(KERN_CRIT "clip_neigh_destroy: vccs != NULL !!!\n"); | ||
269 | NEIGH2ENTRY(neigh)->vccs = (void *) NEIGHBOR_DEAD; | ||
270 | } | ||
271 | |||
272 | static void clip_neigh_solicit(struct neighbour *neigh, struct sk_buff *skb) | 264 | static void clip_neigh_solicit(struct neighbour *neigh, struct sk_buff *skb) |
273 | { | 265 | { |
274 | DPRINTK("clip_neigh_solicit (neigh %p, skb %p)\n", neigh, skb); | 266 | DPRINTK("clip_neigh_solicit (neigh %p, skb %p)\n", neigh, skb); |
@@ -342,7 +334,6 @@ static struct neigh_table clip_tbl = { | |||
342 | /* parameters are copied from ARP ... */ | 334 | /* parameters are copied from ARP ... */ |
343 | .parms = { | 335 | .parms = { |
344 | .tbl = &clip_tbl, | 336 | .tbl = &clip_tbl, |
345 | .neigh_destructor = clip_neigh_destroy, | ||
346 | .base_reachable_time = 30 * HZ, | 337 | .base_reachable_time = 30 * HZ, |
347 | .retrans_time = 1 * HZ, | 338 | .retrans_time = 1 * HZ, |
348 | .gc_staletime = 60 * HZ, | 339 | .gc_staletime = 60 * HZ, |
diff --git a/net/ax25/Kconfig b/net/ax25/Kconfig index a8993a041724..43dd86fca4d3 100644 --- a/net/ax25/Kconfig +++ b/net/ax25/Kconfig | |||
@@ -1,30 +1,27 @@ | |||
1 | # | 1 | # |
2 | # Amateur Radio protocols and AX.25 device configuration | 2 | # Amateur Radio protocols and AX.25 device configuration |
3 | # | 3 | # |
4 | # 19971130 Now in an own category to make correct compilation of the | ||
5 | # AX.25 stuff easier... | ||
6 | # Joerg Reuter DL1BKE <jreuter@yaina.de> | ||
7 | # 19980129 Moved to net/ax25/Config.in, sourcing device drivers. | ||
8 | 4 | ||
9 | menuconfig HAMRADIO | 5 | menuconfig HAMRADIO |
10 | depends on NET | 6 | depends on NET |
11 | bool "Amateur Radio support" | 7 | bool "Amateur Radio support" |
12 | help | 8 | help |
13 | If you want to connect your Linux box to an amateur radio, answer Y | 9 | If you want to connect your Linux box to an amateur radio, answer Y |
14 | here. You want to read <http://www.tapr.org/tapr/html/pkthome.html> and | 10 | here. You want to read <http://www.tapr.org/tapr/html/pkthome.html> |
15 | the AX25-HOWTO, available from <http://www.tldp.org/docs.html#howto>. | 11 | and more specifically about AX.25 on Linux |
12 | <http://www.linux-ax25.org/>. | ||
16 | 13 | ||
17 | Note that the answer to this question won't directly affect the | 14 | Note that the answer to this question won't directly affect the |
18 | kernel: saying N will just cause the configurator to skip all | 15 | kernel: saying N will just cause the configurator to skip all |
19 | the questions about amateur radio. | 16 | the questions about amateur radio. |
20 | 17 | ||
21 | comment "Packet Radio protocols" | 18 | comment "Packet Radio protocols" |
22 | depends on HAMRADIO && NET | 19 | depends on HAMRADIO |
23 | 20 | ||
24 | config AX25 | 21 | config AX25 |
25 | tristate "Amateur Radio AX.25 Level 2 protocol" | 22 | tristate "Amateur Radio AX.25 Level 2 protocol" |
26 | depends on HAMRADIO && NET | 23 | depends on HAMRADIO |
27 | ---help--- | 24 | help |
28 | This is the protocol used for computer communication over amateur | 25 | This is the protocol used for computer communication over amateur |
29 | radio. It is either used by itself for point-to-point links, or to | 26 | radio. It is either used by itself for point-to-point links, or to |
30 | carry other protocols such as tcp/ip. To use it, you need a device | 27 | carry other protocols such as tcp/ip. To use it, you need a device |
@@ -52,6 +49,7 @@ config AX25 | |||
52 | 49 | ||
53 | config AX25_DAMA_SLAVE | 50 | config AX25_DAMA_SLAVE |
54 | bool "AX.25 DAMA Slave support" | 51 | bool "AX.25 DAMA Slave support" |
52 | default y | ||
55 | depends on AX25 | 53 | depends on AX25 |
56 | help | 54 | help |
57 | DAMA is a mechanism to prevent collisions when doing AX.25 | 55 | DAMA is a mechanism to prevent collisions when doing AX.25 |
@@ -59,23 +57,38 @@ config AX25_DAMA_SLAVE | |||
59 | from clients (called "slaves") and redistributes it to other slaves. | 57 | from clients (called "slaves") and redistributes it to other slaves. |
60 | If you say Y here, your Linux box will act as a DAMA slave; this is | 58 | If you say Y here, your Linux box will act as a DAMA slave; this is |
61 | transparent in that you don't have to do any special DAMA | 59 | transparent in that you don't have to do any special DAMA |
62 | configuration. (Linux cannot yet act as a DAMA server.) If unsure, | 60 | configuration. Linux cannot yet act as a DAMA server. This option |
63 | say N. | 61 | only compiles DAMA slave support into the kernel. It still needs to |
62 | be enabled at runtime. For more about DAMA see | ||
63 | <http://www.linux-ax25.org>. If unsure, say Y. | ||
64 | |||
65 | # placeholder until implemented | ||
66 | config AX25_DAMA_MASTER | ||
67 | bool 'AX.25 DAMA Master support' | ||
68 | depends on AX25_DAMA_SLAVE && BROKEN | ||
69 | help | ||
70 | DAMA is a mechanism to prevent collisions when doing AX.25 | ||
71 | networking. A DAMA server (called "master") accepts incoming traffic | ||
72 | from clients (called "slaves") and redistributes it to other slaves. | ||
73 | If you say Y here, your Linux box will act as a DAMA master; this is | ||
74 | transparent in that you don't have to do any special DAMA | ||
75 | configuration. Linux cannot yet act as a DAMA server. This option | ||
76 | only compiles DAMA slave support into the kernel. It still needs to | ||
77 | be explicitly enabled, so if unsure, say Y. | ||
64 | 78 | ||
65 | # bool ' AX.25 DAMA Master support' CONFIG_AX25_DAMA_MASTER | ||
66 | config NETROM | 79 | config NETROM |
67 | tristate "Amateur Radio NET/ROM protocol" | 80 | tristate "Amateur Radio NET/ROM protocol" |
68 | depends on AX25 | 81 | depends on AX25 |
69 | ---help--- | 82 | help |
70 | NET/ROM is a network layer protocol on top of AX.25 useful for | 83 | NET/ROM is a network layer protocol on top of AX.25 useful for |
71 | routing. | 84 | routing. |
72 | 85 | ||
73 | A comprehensive listing of all the software for Linux amateur radio | 86 | A comprehensive listing of all the software for Linux amateur radio |
74 | users as well as information about how to configure an AX.25 port is | 87 | users as well as information about how to configure an AX.25 port is |
75 | contained in the AX25-HOWTO, available from | 88 | contained in the Linux Ham Wiki, available from |
76 | <http://www.tldp.org/docs.html#howto>. You also might want to | 89 | <http://www.linux-ax25.org>. You also might want to check out the |
77 | check out the file <file:Documentation/networking/ax25.txt>. More | 90 | file <file:Documentation/networking/ax25.txt>. More information about |
78 | information about digital amateur radio in general is on the WWW at | 91 | digital amateur radio in general is on the WWW at |
79 | <http://www.tapr.org/tapr/html/pkthome.html>. | 92 | <http://www.tapr.org/tapr/html/pkthome.html>. |
80 | 93 | ||
81 | To compile this driver as a module, choose M here: the | 94 | To compile this driver as a module, choose M here: the |
@@ -84,27 +97,25 @@ config NETROM | |||
84 | config ROSE | 97 | config ROSE |
85 | tristate "Amateur Radio X.25 PLP (Rose)" | 98 | tristate "Amateur Radio X.25 PLP (Rose)" |
86 | depends on AX25 | 99 | depends on AX25 |
87 | ---help--- | 100 | help |
88 | The Packet Layer Protocol (PLP) is a way to route packets over X.25 | 101 | The Packet Layer Protocol (PLP) is a way to route packets over X.25 |
89 | connections in general and amateur radio AX.25 connections in | 102 | connections in general and amateur radio AX.25 connections in |
90 | particular, essentially an alternative to NET/ROM. | 103 | particular, essentially an alternative to NET/ROM. |
91 | 104 | ||
92 | A comprehensive listing of all the software for Linux amateur radio | 105 | A comprehensive listing of all the software for Linux amateur radio |
93 | users as well as information about how to configure an AX.25 port is | 106 | users as well as information about how to configure an AX.25 port is |
94 | contained in the AX25-HOWTO, available from | 107 | contained in the Linux Ham Wiki, available from |
95 | <http://www.tldp.org/docs.html#howto>. You also might want to | 108 | <http://www.linux-ax25.org>. You also might want to check out the |
96 | check out the file <file:Documentation/networking/ax25.txt>. More | 109 | file <file:Documentation/networking/ax25.txt>. More information about |
97 | information about digital amateur radio in general is on the WWW at | 110 | digital amateur radio in general is on the WWW at |
98 | <http://www.tapr.org/tapr/html/pkthome.html>. | 111 | <http://www.tapr.org/tapr/html/pkthome.html>. |
99 | 112 | ||
100 | To compile this driver as a module, choose M here: the | 113 | To compile this driver as a module, choose M here: the |
101 | module will be called rose. | 114 | module will be called rose. |
102 | 115 | ||
103 | |||
104 | menu "AX.25 network device drivers" | 116 | menu "AX.25 network device drivers" |
105 | depends on HAMRADIO && NET && AX25!=n | 117 | depends on HAMRADIO && AX25 |
106 | 118 | ||
107 | source "drivers/net/hamradio/Kconfig" | 119 | source "drivers/net/hamradio/Kconfig" |
108 | 120 | ||
109 | endmenu | 121 | endmenu |
110 | |||
diff --git a/net/core/dev.c b/net/core/dev.c index cf71614dae93..5984b55311a1 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1750,10 +1750,10 @@ static int ing_filter(struct sk_buff *skb) | |||
1750 | 1750 | ||
1751 | skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_INGRESS); | 1751 | skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_INGRESS); |
1752 | 1752 | ||
1753 | spin_lock(&dev->ingress_lock); | 1753 | spin_lock(&dev->queue_lock); |
1754 | if ((q = dev->qdisc_ingress) != NULL) | 1754 | if ((q = dev->qdisc_ingress) != NULL) |
1755 | result = q->enqueue(skb, q); | 1755 | result = q->enqueue(skb, q); |
1756 | spin_unlock(&dev->ingress_lock); | 1756 | spin_unlock(&dev->queue_lock); |
1757 | 1757 | ||
1758 | } | 1758 | } |
1759 | 1759 | ||
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 3aea4e87d3d7..d011819a8058 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
@@ -152,6 +152,28 @@ out: | |||
152 | 152 | ||
153 | EXPORT_SYMBOL_GPL(fib_rules_lookup); | 153 | EXPORT_SYMBOL_GPL(fib_rules_lookup); |
154 | 154 | ||
155 | static int validate_rulemsg(struct fib_rule_hdr *frh, struct nlattr **tb, | ||
156 | struct fib_rules_ops *ops) | ||
157 | { | ||
158 | int err = -EINVAL; | ||
159 | |||
160 | if (frh->src_len) | ||
161 | if (tb[FRA_SRC] == NULL || | ||
162 | frh->src_len > (ops->addr_size * 8) || | ||
163 | nla_len(tb[FRA_SRC]) != ops->addr_size) | ||
164 | goto errout; | ||
165 | |||
166 | if (frh->dst_len) | ||
167 | if (tb[FRA_DST] == NULL || | ||
168 | frh->dst_len > (ops->addr_size * 8) || | ||
169 | nla_len(tb[FRA_DST]) != ops->addr_size) | ||
170 | goto errout; | ||
171 | |||
172 | err = 0; | ||
173 | errout: | ||
174 | return err; | ||
175 | } | ||
176 | |||
155 | int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | 177 | int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) |
156 | { | 178 | { |
157 | struct fib_rule_hdr *frh = nlmsg_data(nlh); | 179 | struct fib_rule_hdr *frh = nlmsg_data(nlh); |
@@ -173,6 +195,10 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
173 | if (err < 0) | 195 | if (err < 0) |
174 | goto errout; | 196 | goto errout; |
175 | 197 | ||
198 | err = validate_rulemsg(frh, tb, ops); | ||
199 | if (err < 0) | ||
200 | goto errout; | ||
201 | |||
176 | rule = kzalloc(ops->rule_size, GFP_KERNEL); | 202 | rule = kzalloc(ops->rule_size, GFP_KERNEL); |
177 | if (rule == NULL) { | 203 | if (rule == NULL) { |
178 | err = -ENOMEM; | 204 | err = -ENOMEM; |
@@ -260,6 +286,10 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) | |||
260 | if (err < 0) | 286 | if (err < 0) |
261 | goto errout; | 287 | goto errout; |
262 | 288 | ||
289 | err = validate_rulemsg(frh, tb, ops); | ||
290 | if (err < 0) | ||
291 | goto errout; | ||
292 | |||
263 | list_for_each_entry(rule, ops->rules_list, list) { | 293 | list_for_each_entry(rule, ops->rules_list, list) { |
264 | if (frh->action && (frh->action != rule->action)) | 294 | if (frh->action && (frh->action != rule->action)) |
265 | continue; | 295 | continue; |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 3183142c6044..cfc60019cf92 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -140,6 +140,8 @@ static int neigh_forced_gc(struct neigh_table *tbl) | |||
140 | n->dead = 1; | 140 | n->dead = 1; |
141 | shrunk = 1; | 141 | shrunk = 1; |
142 | write_unlock(&n->lock); | 142 | write_unlock(&n->lock); |
143 | if (n->parms->neigh_cleanup) | ||
144 | n->parms->neigh_cleanup(n); | ||
143 | neigh_release(n); | 145 | neigh_release(n); |
144 | continue; | 146 | continue; |
145 | } | 147 | } |
@@ -211,6 +213,8 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev) | |||
211 | NEIGH_PRINTK2("neigh %p is stray.\n", n); | 213 | NEIGH_PRINTK2("neigh %p is stray.\n", n); |
212 | } | 214 | } |
213 | write_unlock(&n->lock); | 215 | write_unlock(&n->lock); |
216 | if (n->parms->neigh_cleanup) | ||
217 | n->parms->neigh_cleanup(n); | ||
214 | neigh_release(n); | 218 | neigh_release(n); |
215 | } | 219 | } |
216 | } | 220 | } |
@@ -582,9 +586,6 @@ void neigh_destroy(struct neighbour *neigh) | |||
582 | kfree(hh); | 586 | kfree(hh); |
583 | } | 587 | } |
584 | 588 | ||
585 | if (neigh->parms->neigh_destructor) | ||
586 | (neigh->parms->neigh_destructor)(neigh); | ||
587 | |||
588 | skb_queue_purge(&neigh->arp_queue); | 589 | skb_queue_purge(&neigh->arp_queue); |
589 | 590 | ||
590 | dev_put(neigh->dev); | 591 | dev_put(neigh->dev); |
@@ -675,6 +676,8 @@ static void neigh_periodic_timer(unsigned long arg) | |||
675 | *np = n->next; | 676 | *np = n->next; |
676 | n->dead = 1; | 677 | n->dead = 1; |
677 | write_unlock(&n->lock); | 678 | write_unlock(&n->lock); |
679 | if (n->parms->neigh_cleanup) | ||
680 | n->parms->neigh_cleanup(n); | ||
678 | neigh_release(n); | 681 | neigh_release(n); |
679 | continue; | 682 | continue; |
680 | } | 683 | } |
@@ -2088,8 +2091,11 @@ void __neigh_for_each_release(struct neigh_table *tbl, | |||
2088 | } else | 2091 | } else |
2089 | np = &n->next; | 2092 | np = &n->next; |
2090 | write_unlock(&n->lock); | 2093 | write_unlock(&n->lock); |
2091 | if (release) | 2094 | if (release) { |
2095 | if (n->parms->neigh_cleanup) | ||
2096 | n->parms->neigh_cleanup(n); | ||
2092 | neigh_release(n); | 2097 | neigh_release(n); |
2098 | } | ||
2093 | } | 2099 | } |
2094 | } | 2100 | } |
2095 | } | 2101 | } |
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h index a0e7cd183a5d..e33a9edb4036 100644 --- a/net/dccp/dccp.h +++ b/net/dccp/dccp.h | |||
@@ -191,7 +191,6 @@ extern void dccp_send_sync(struct sock *sk, const u64 seq, | |||
191 | const enum dccp_pkt_type pkt_type); | 191 | const enum dccp_pkt_type pkt_type); |
192 | 192 | ||
193 | extern void dccp_write_xmit(struct sock *sk, int block); | 193 | extern void dccp_write_xmit(struct sock *sk, int block); |
194 | extern void dccp_write_xmit_timer(unsigned long data); | ||
195 | extern void dccp_write_space(struct sock *sk); | 194 | extern void dccp_write_space(struct sock *sk); |
196 | 195 | ||
197 | extern void dccp_init_xmit_timers(struct sock *sk); | 196 | extern void dccp_init_xmit_timers(struct sock *sk); |
diff --git a/net/dccp/timer.c b/net/dccp/timer.c index b038a0a3ad40..0197a41c256a 100644 --- a/net/dccp/timer.c +++ b/net/dccp/timer.c | |||
@@ -262,7 +262,7 @@ out: | |||
262 | } | 262 | } |
263 | 263 | ||
264 | /* Transmit-delay timer: used by the CCIDs to delay actual send time */ | 264 | /* Transmit-delay timer: used by the CCIDs to delay actual send time */ |
265 | void dccp_write_xmit_timer(unsigned long data) | 265 | static void dccp_write_xmit_timer(unsigned long data) |
266 | { | 266 | { |
267 | struct sock *sk = (struct sock *)data; | 267 | struct sock *sk = (struct sock *)data; |
268 | struct dccp_sock *dp = dccp_sk(sk); | 268 | struct dccp_sock *dp = dccp_sk(sk); |
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index 3cbfddc98430..82d58a977e6f 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c | |||
@@ -63,7 +63,7 @@ static struct | |||
63 | { | 63 | { |
64 | int error; | 64 | int error; |
65 | u8 scope; | 65 | u8 scope; |
66 | } dn_fib_props[RTA_MAX+1] = { | 66 | } dn_fib_props[RTN_MAX+1] = { |
67 | [RTN_UNSPEC] = { .error = 0, .scope = RT_SCOPE_NOWHERE }, | 67 | [RTN_UNSPEC] = { .error = 0, .scope = RT_SCOPE_NOWHERE }, |
68 | [RTN_UNICAST] = { .error = 0, .scope = RT_SCOPE_UNIVERSE }, | 68 | [RTN_UNICAST] = { .error = 0, .scope = RT_SCOPE_UNIVERSE }, |
69 | [RTN_LOCAL] = { .error = 0, .scope = RT_SCOPE_HOST }, | 69 | [RTN_LOCAL] = { .error = 0, .scope = RT_SCOPE_HOST }, |
@@ -276,6 +276,9 @@ struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r, struct dn_kern_rta | |||
276 | struct dn_fib_info *ofi; | 276 | struct dn_fib_info *ofi; |
277 | int nhs = 1; | 277 | int nhs = 1; |
278 | 278 | ||
279 | if (r->rtm_type > RTN_MAX) | ||
280 | goto err_inval; | ||
281 | |||
279 | if (dn_fib_props[r->rtm_type].scope > r->rtm_scope) | 282 | if (dn_fib_props[r->rtm_type].scope > r->rtm_scope) |
280 | goto err_inval; | 283 | goto err_inval; |
281 | 284 | ||
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index b6c98ac93dc8..5e86dd542302 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c | |||
@@ -109,8 +109,6 @@ errout: | |||
109 | 109 | ||
110 | static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = { | 110 | static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = { |
111 | FRA_GENERIC_POLICY, | 111 | FRA_GENERIC_POLICY, |
112 | [FRA_SRC] = { .type = NLA_U16 }, | ||
113 | [FRA_DST] = { .type = NLA_U16 }, | ||
114 | }; | 112 | }; |
115 | 113 | ||
116 | static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) | 114 | static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) |
@@ -133,7 +131,7 @@ static int dn_fib_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | |||
133 | int err = -EINVAL; | 131 | int err = -EINVAL; |
134 | struct dn_fib_rule *r = (struct dn_fib_rule *)rule; | 132 | struct dn_fib_rule *r = (struct dn_fib_rule *)rule; |
135 | 133 | ||
136 | if (frh->src_len > 16 || frh->dst_len > 16 || frh->tos) | 134 | if (frh->tos) |
137 | goto errout; | 135 | goto errout; |
138 | 136 | ||
139 | if (rule->table == RT_TABLE_UNSPEC) { | 137 | if (rule->table == RT_TABLE_UNSPEC) { |
@@ -150,10 +148,10 @@ static int dn_fib_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | |||
150 | } | 148 | } |
151 | } | 149 | } |
152 | 150 | ||
153 | if (tb[FRA_SRC]) | 151 | if (frh->src_len) |
154 | r->src = nla_get_le16(tb[FRA_SRC]); | 152 | r->src = nla_get_le16(tb[FRA_SRC]); |
155 | 153 | ||
156 | if (tb[FRA_DST]) | 154 | if (frh->dst_len) |
157 | r->dst = nla_get_le16(tb[FRA_DST]); | 155 | r->dst = nla_get_le16(tb[FRA_DST]); |
158 | 156 | ||
159 | r->src_len = frh->src_len; | 157 | r->src_len = frh->src_len; |
@@ -176,10 +174,10 @@ static int dn_fib_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, | |||
176 | if (frh->dst_len && (r->dst_len != frh->dst_len)) | 174 | if (frh->dst_len && (r->dst_len != frh->dst_len)) |
177 | return 0; | 175 | return 0; |
178 | 176 | ||
179 | if (tb[FRA_SRC] && (r->src != nla_get_le16(tb[FRA_SRC]))) | 177 | if (frh->src_len && (r->src != nla_get_le16(tb[FRA_SRC]))) |
180 | return 0; | 178 | return 0; |
181 | 179 | ||
182 | if (tb[FRA_DST] && (r->dst != nla_get_le16(tb[FRA_DST]))) | 180 | if (frh->dst_len && (r->dst != nla_get_le16(tb[FRA_DST]))) |
183 | return 0; | 181 | return 0; |
184 | 182 | ||
185 | return 1; | 183 | return 1; |
@@ -249,6 +247,7 @@ int dn_fib_dump_rules(struct sk_buff *skb, struct netlink_callback *cb) | |||
249 | static struct fib_rules_ops dn_fib_rules_ops = { | 247 | static struct fib_rules_ops dn_fib_rules_ops = { |
250 | .family = AF_DECnet, | 248 | .family = AF_DECnet, |
251 | .rule_size = sizeof(struct dn_fib_rule), | 249 | .rule_size = sizeof(struct dn_fib_rule), |
250 | .addr_size = sizeof(u16), | ||
252 | .action = dn_fib_rule_action, | 251 | .action = dn_fib_rule_action, |
253 | .match = dn_fib_rule_match, | 252 | .match = dn_fib_rule_match, |
254 | .configure = dn_fib_rule_configure, | 253 | .configure = dn_fib_rule_configure, |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 1fba6439fc57..fc920f63452b 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -493,6 +493,11 @@ static int rtm_to_fib_config(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
493 | cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid; | 493 | cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid; |
494 | cfg->fc_nlinfo.nlh = nlh; | 494 | cfg->fc_nlinfo.nlh = nlh; |
495 | 495 | ||
496 | if (cfg->fc_type > RTN_MAX) { | ||
497 | err = -EINVAL; | ||
498 | goto errout; | ||
499 | } | ||
500 | |||
496 | nlmsg_for_each_attr(attr, nlh, sizeof(struct rtmsg), remaining) { | 501 | nlmsg_for_each_attr(attr, nlh, sizeof(struct rtmsg), remaining) { |
497 | switch (attr->nla_type) { | 502 | switch (attr->nla_type) { |
498 | case RTA_DST: | 503 | case RTA_DST: |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index b837c33e0404..c660c074c76c 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -171,8 +171,6 @@ static struct fib_table *fib_empty_table(void) | |||
171 | 171 | ||
172 | static struct nla_policy fib4_rule_policy[FRA_MAX+1] __read_mostly = { | 172 | static struct nla_policy fib4_rule_policy[FRA_MAX+1] __read_mostly = { |
173 | FRA_GENERIC_POLICY, | 173 | FRA_GENERIC_POLICY, |
174 | [FRA_SRC] = { .type = NLA_U32 }, | ||
175 | [FRA_DST] = { .type = NLA_U32 }, | ||
176 | [FRA_FLOW] = { .type = NLA_U32 }, | 174 | [FRA_FLOW] = { .type = NLA_U32 }, |
177 | }; | 175 | }; |
178 | 176 | ||
@@ -183,8 +181,7 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | |||
183 | int err = -EINVAL; | 181 | int err = -EINVAL; |
184 | struct fib4_rule *rule4 = (struct fib4_rule *) rule; | 182 | struct fib4_rule *rule4 = (struct fib4_rule *) rule; |
185 | 183 | ||
186 | if (frh->src_len > 32 || frh->dst_len > 32 || | 184 | if (frh->tos & ~IPTOS_TOS_MASK) |
187 | (frh->tos & ~IPTOS_TOS_MASK)) | ||
188 | goto errout; | 185 | goto errout; |
189 | 186 | ||
190 | if (rule->table == RT_TABLE_UNSPEC) { | 187 | if (rule->table == RT_TABLE_UNSPEC) { |
@@ -201,10 +198,10 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | |||
201 | } | 198 | } |
202 | } | 199 | } |
203 | 200 | ||
204 | if (tb[FRA_SRC]) | 201 | if (frh->src_len) |
205 | rule4->src = nla_get_be32(tb[FRA_SRC]); | 202 | rule4->src = nla_get_be32(tb[FRA_SRC]); |
206 | 203 | ||
207 | if (tb[FRA_DST]) | 204 | if (frh->dst_len) |
208 | rule4->dst = nla_get_be32(tb[FRA_DST]); | 205 | rule4->dst = nla_get_be32(tb[FRA_DST]); |
209 | 206 | ||
210 | #ifdef CONFIG_NET_CLS_ROUTE | 207 | #ifdef CONFIG_NET_CLS_ROUTE |
@@ -242,10 +239,10 @@ static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, | |||
242 | return 0; | 239 | return 0; |
243 | #endif | 240 | #endif |
244 | 241 | ||
245 | if (tb[FRA_SRC] && (rule4->src != nla_get_be32(tb[FRA_SRC]))) | 242 | if (frh->src_len && (rule4->src != nla_get_be32(tb[FRA_SRC]))) |
246 | return 0; | 243 | return 0; |
247 | 244 | ||
248 | if (tb[FRA_DST] && (rule4->dst != nla_get_be32(tb[FRA_DST]))) | 245 | if (frh->dst_len && (rule4->dst != nla_get_be32(tb[FRA_DST]))) |
249 | return 0; | 246 | return 0; |
250 | 247 | ||
251 | return 1; | 248 | return 1; |
@@ -309,6 +306,7 @@ static size_t fib4_rule_nlmsg_payload(struct fib_rule *rule) | |||
309 | static struct fib_rules_ops fib4_rules_ops = { | 306 | static struct fib_rules_ops fib4_rules_ops = { |
310 | .family = AF_INET, | 307 | .family = AF_INET, |
311 | .rule_size = sizeof(struct fib4_rule), | 308 | .rule_size = sizeof(struct fib4_rule), |
309 | .addr_size = sizeof(u32), | ||
312 | .action = fib4_rule_action, | 310 | .action = fib4_rule_action, |
313 | .match = fib4_rule_match, | 311 | .match = fib4_rule_match, |
314 | .configure = fib4_rule_configure, | 312 | .configure = fib4_rule_configure, |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 2f1fdae6efa6..3dad12ee76c3 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -89,7 +89,7 @@ static const struct | |||
89 | { | 89 | { |
90 | int error; | 90 | int error; |
91 | u8 scope; | 91 | u8 scope; |
92 | } fib_props[RTA_MAX + 1] = { | 92 | } fib_props[RTN_MAX + 1] = { |
93 | { | 93 | { |
94 | .error = 0, | 94 | .error = 0, |
95 | .scope = RT_SCOPE_NOWHERE, | 95 | .scope = RT_SCOPE_NOWHERE, |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index ada9b3db507d..214c34732e84 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -1123,6 +1123,9 @@ err: | |||
1123 | return fa_head; | 1123 | return fa_head; |
1124 | } | 1124 | } |
1125 | 1125 | ||
1126 | /* | ||
1127 | * Caller must hold RTNL. | ||
1128 | */ | ||
1126 | static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) | 1129 | static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg) |
1127 | { | 1130 | { |
1128 | struct trie *t = (struct trie *) tb->tb_data; | 1131 | struct trie *t = (struct trie *) tb->tb_data; |
@@ -1540,6 +1543,9 @@ static int trie_leaf_remove(struct trie *t, t_key key) | |||
1540 | return 1; | 1543 | return 1; |
1541 | } | 1544 | } |
1542 | 1545 | ||
1546 | /* | ||
1547 | * Caller must hold RTNL. | ||
1548 | */ | ||
1543 | static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg) | 1549 | static int fn_trie_delete(struct fib_table *tb, struct fib_config *cfg) |
1544 | { | 1550 | { |
1545 | struct trie *t = (struct trie *) tb->tb_data; | 1551 | struct trie *t = (struct trie *) tb->tb_data; |
@@ -1718,6 +1724,9 @@ up: | |||
1718 | return NULL; /* Ready. Root of trie */ | 1724 | return NULL; /* Ready. Root of trie */ |
1719 | } | 1725 | } |
1720 | 1726 | ||
1727 | /* | ||
1728 | * Caller must hold RTNL. | ||
1729 | */ | ||
1721 | static int fn_trie_flush(struct fib_table *tb) | 1730 | static int fn_trie_flush(struct fib_table *tb) |
1722 | { | 1731 | { |
1723 | struct trie *t = (struct trie *) tb->tb_data; | 1732 | struct trie *t = (struct trie *) tb->tb_data; |
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 0862809ffcf7..ea3035b4e3e8 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -131,8 +131,6 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) | |||
131 | 131 | ||
132 | static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = { | 132 | static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = { |
133 | FRA_GENERIC_POLICY, | 133 | FRA_GENERIC_POLICY, |
134 | [FRA_SRC] = { .len = sizeof(struct in6_addr) }, | ||
135 | [FRA_DST] = { .len = sizeof(struct in6_addr) }, | ||
136 | }; | 134 | }; |
137 | 135 | ||
138 | static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | 136 | static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, |
@@ -142,9 +140,6 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | |||
142 | int err = -EINVAL; | 140 | int err = -EINVAL; |
143 | struct fib6_rule *rule6 = (struct fib6_rule *) rule; | 141 | struct fib6_rule *rule6 = (struct fib6_rule *) rule; |
144 | 142 | ||
145 | if (frh->src_len > 128 || frh->dst_len > 128) | ||
146 | goto errout; | ||
147 | |||
148 | if (rule->action == FR_ACT_TO_TBL) { | 143 | if (rule->action == FR_ACT_TO_TBL) { |
149 | if (rule->table == RT6_TABLE_UNSPEC) | 144 | if (rule->table == RT6_TABLE_UNSPEC) |
150 | goto errout; | 145 | goto errout; |
@@ -155,11 +150,11 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | |||
155 | } | 150 | } |
156 | } | 151 | } |
157 | 152 | ||
158 | if (tb[FRA_SRC]) | 153 | if (frh->src_len) |
159 | nla_memcpy(&rule6->src.addr, tb[FRA_SRC], | 154 | nla_memcpy(&rule6->src.addr, tb[FRA_SRC], |
160 | sizeof(struct in6_addr)); | 155 | sizeof(struct in6_addr)); |
161 | 156 | ||
162 | if (tb[FRA_DST]) | 157 | if (frh->dst_len) |
163 | nla_memcpy(&rule6->dst.addr, tb[FRA_DST], | 158 | nla_memcpy(&rule6->dst.addr, tb[FRA_DST], |
164 | sizeof(struct in6_addr)); | 159 | sizeof(struct in6_addr)); |
165 | 160 | ||
@@ -186,11 +181,11 @@ static int fib6_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh, | |||
186 | if (frh->tos && (rule6->tclass != frh->tos)) | 181 | if (frh->tos && (rule6->tclass != frh->tos)) |
187 | return 0; | 182 | return 0; |
188 | 183 | ||
189 | if (tb[FRA_SRC] && | 184 | if (frh->src_len && |
190 | nla_memcmp(tb[FRA_SRC], &rule6->src.addr, sizeof(struct in6_addr))) | 185 | nla_memcmp(tb[FRA_SRC], &rule6->src.addr, sizeof(struct in6_addr))) |
191 | return 0; | 186 | return 0; |
192 | 187 | ||
193 | if (tb[FRA_DST] && | 188 | if (frh->dst_len && |
194 | nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr))) | 189 | nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr))) |
195 | return 0; | 190 | return 0; |
196 | 191 | ||
@@ -240,6 +235,7 @@ static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule) | |||
240 | static struct fib_rules_ops fib6_rules_ops = { | 235 | static struct fib_rules_ops fib6_rules_ops = { |
241 | .family = AF_INET6, | 236 | .family = AF_INET6, |
242 | .rule_size = sizeof(struct fib6_rule), | 237 | .rule_size = sizeof(struct fib6_rule), |
238 | .addr_size = sizeof(struct in6_addr), | ||
243 | .action = fib6_rule_action, | 239 | .action = fib6_rule_action, |
244 | .match = fib6_rule_match, | 240 | .match = fib6_rule_match, |
245 | .configure = fib6_rule_configure, | 241 | .configure = fib6_rule_configure, |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index f4d7be77eb0f..268f476ef3db 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -658,6 +658,10 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt, | |||
658 | ins = &iter->u.dst.rt6_next; | 658 | ins = &iter->u.dst.rt6_next; |
659 | } | 659 | } |
660 | 660 | ||
661 | /* Reset round-robin state, if necessary */ | ||
662 | if (ins == &fn->leaf) | ||
663 | fn->rr_ptr = NULL; | ||
664 | |||
661 | /* | 665 | /* |
662 | * insert node | 666 | * insert node |
663 | */ | 667 | */ |
@@ -1109,6 +1113,10 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, | |||
1109 | rt6_stats.fib_rt_entries--; | 1113 | rt6_stats.fib_rt_entries--; |
1110 | rt6_stats.fib_discarded_routes++; | 1114 | rt6_stats.fib_discarded_routes++; |
1111 | 1115 | ||
1116 | /* Reset round-robin state, if necessary */ | ||
1117 | if (fn->rr_ptr == rt) | ||
1118 | fn->rr_ptr = NULL; | ||
1119 | |||
1112 | /* Adjust walkers */ | 1120 | /* Adjust walkers */ |
1113 | read_lock(&fib6_walker_lock); | 1121 | read_lock(&fib6_walker_lock); |
1114 | FOR_WALKERS(w) { | 1122 | FOR_WALKERS(w) { |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index a6b3117df546..3931b33b25e8 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -363,55 +363,76 @@ static int rt6_score_route(struct rt6_info *rt, int oif, | |||
363 | return m; | 363 | return m; |
364 | } | 364 | } |
365 | 365 | ||
366 | static struct rt6_info *rt6_select(struct rt6_info **head, int oif, | 366 | static struct rt6_info *find_match(struct rt6_info *rt, int oif, int strict, |
367 | int strict) | 367 | int *mpri, struct rt6_info *match) |
368 | { | 368 | { |
369 | struct rt6_info *match = NULL, *last = NULL; | 369 | int m; |
370 | struct rt6_info *rt, *rt0 = *head; | 370 | |
371 | u32 metric; | 371 | if (rt6_check_expired(rt)) |
372 | goto out; | ||
373 | |||
374 | m = rt6_score_route(rt, oif, strict); | ||
375 | if (m < 0) | ||
376 | goto out; | ||
377 | |||
378 | if (m > *mpri) { | ||
379 | if (strict & RT6_LOOKUP_F_REACHABLE) | ||
380 | rt6_probe(match); | ||
381 | *mpri = m; | ||
382 | match = rt; | ||
383 | } else if (strict & RT6_LOOKUP_F_REACHABLE) { | ||
384 | rt6_probe(rt); | ||
385 | } | ||
386 | |||
387 | out: | ||
388 | return match; | ||
389 | } | ||
390 | |||
391 | static struct rt6_info *find_rr_leaf(struct fib6_node *fn, | ||
392 | struct rt6_info *rr_head, | ||
393 | u32 metric, int oif, int strict) | ||
394 | { | ||
395 | struct rt6_info *rt, *match; | ||
372 | int mpri = -1; | 396 | int mpri = -1; |
373 | 397 | ||
374 | RT6_TRACE("%s(head=%p(*head=%p), oif=%d)\n", | 398 | match = NULL; |
375 | __FUNCTION__, head, head ? *head : NULL, oif); | 399 | for (rt = rr_head; rt && rt->rt6i_metric == metric; |
400 | rt = rt->u.dst.rt6_next) | ||
401 | match = find_match(rt, oif, strict, &mpri, match); | ||
402 | for (rt = fn->leaf; rt && rt != rr_head && rt->rt6i_metric == metric; | ||
403 | rt = rt->u.dst.rt6_next) | ||
404 | match = find_match(rt, oif, strict, &mpri, match); | ||
376 | 405 | ||
377 | for (rt = rt0, metric = rt0->rt6i_metric; | 406 | return match; |
378 | rt && rt->rt6i_metric == metric && (!last || rt != rt0); | 407 | } |
379 | rt = rt->u.dst.rt6_next) { | ||
380 | int m; | ||
381 | 408 | ||
382 | if (rt6_check_expired(rt)) | 409 | static struct rt6_info *rt6_select(struct fib6_node *fn, int oif, int strict) |
383 | continue; | 410 | { |
411 | struct rt6_info *match, *rt0; | ||
384 | 412 | ||
385 | last = rt; | 413 | RT6_TRACE("%s(fn->leaf=%p, oif=%d)\n", |
414 | __FUNCTION__, fn->leaf, oif); | ||
386 | 415 | ||
387 | m = rt6_score_route(rt, oif, strict); | 416 | rt0 = fn->rr_ptr; |
388 | if (m < 0) | 417 | if (!rt0) |
389 | continue; | 418 | fn->rr_ptr = rt0 = fn->leaf; |
390 | 419 | ||
391 | if (m > mpri) { | 420 | match = find_rr_leaf(fn, rt0, rt0->rt6i_metric, oif, strict); |
392 | if (strict & RT6_LOOKUP_F_REACHABLE) | ||
393 | rt6_probe(match); | ||
394 | match = rt; | ||
395 | mpri = m; | ||
396 | } else if (strict & RT6_LOOKUP_F_REACHABLE) { | ||
397 | rt6_probe(rt); | ||
398 | } | ||
399 | } | ||
400 | 421 | ||
401 | if (!match && | 422 | if (!match && |
402 | (strict & RT6_LOOKUP_F_REACHABLE) && | 423 | (strict & RT6_LOOKUP_F_REACHABLE)) { |
403 | last && last != rt0) { | 424 | struct rt6_info *next = rt0->u.dst.rt6_next; |
425 | |||
404 | /* no entries matched; do round-robin */ | 426 | /* no entries matched; do round-robin */ |
405 | static DEFINE_SPINLOCK(lock); | 427 | if (!next || next->rt6i_metric != rt0->rt6i_metric) |
406 | spin_lock(&lock); | 428 | next = fn->leaf; |
407 | *head = rt0->u.dst.rt6_next; | 429 | |
408 | rt0->u.dst.rt6_next = last->u.dst.rt6_next; | 430 | if (next != rt0) |
409 | last->u.dst.rt6_next = rt0; | 431 | fn->rr_ptr = next; |
410 | spin_unlock(&lock); | ||
411 | } | 432 | } |
412 | 433 | ||
413 | RT6_TRACE("%s() => %p, score=%d\n", | 434 | RT6_TRACE("%s() => %p\n", |
414 | __FUNCTION__, match, mpri); | 435 | __FUNCTION__, match); |
415 | 436 | ||
416 | return (match ? match : &ip6_null_entry); | 437 | return (match ? match : &ip6_null_entry); |
417 | } | 438 | } |
@@ -657,7 +678,7 @@ restart_2: | |||
657 | fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); | 678 | fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); |
658 | 679 | ||
659 | restart: | 680 | restart: |
660 | rt = rt6_select(&fn->leaf, fl->iif, strict | reachable); | 681 | rt = rt6_select(fn, fl->iif, strict | reachable); |
661 | BACKTRACK(&fl->fl6_src); | 682 | BACKTRACK(&fl->fl6_src); |
662 | if (rt == &ip6_null_entry || | 683 | if (rt == &ip6_null_entry || |
663 | rt->rt6i_flags & RTF_CACHE) | 684 | rt->rt6i_flags & RTF_CACHE) |
@@ -752,7 +773,7 @@ restart_2: | |||
752 | fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); | 773 | fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src); |
753 | 774 | ||
754 | restart: | 775 | restart: |
755 | rt = rt6_select(&fn->leaf, fl->oif, strict | reachable); | 776 | rt = rt6_select(fn, fl->oif, strict | reachable); |
756 | BACKTRACK(&fl->fl6_src); | 777 | BACKTRACK(&fl->fl6_src); |
757 | if (rt == &ip6_null_entry || | 778 | if (rt == &ip6_null_entry || |
758 | rt->rt6i_flags & RTF_CACHE) | 779 | rt->rt6i_flags & RTF_CACHE) |
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index fad08e521c24..70fe36eb66a2 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c | |||
@@ -81,6 +81,13 @@ static void basic_put(struct tcf_proto *tp, unsigned long f) | |||
81 | 81 | ||
82 | static int basic_init(struct tcf_proto *tp) | 82 | static int basic_init(struct tcf_proto *tp) |
83 | { | 83 | { |
84 | struct basic_head *head; | ||
85 | |||
86 | head = kzalloc(sizeof(*head), GFP_KERNEL); | ||
87 | if (head == NULL) | ||
88 | return -ENOBUFS; | ||
89 | INIT_LIST_HEAD(&head->flist); | ||
90 | tp->root = head; | ||
84 | return 0; | 91 | return 0; |
85 | } | 92 | } |
86 | 93 | ||
@@ -176,15 +183,6 @@ static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle, | |||
176 | } | 183 | } |
177 | 184 | ||
178 | err = -ENOBUFS; | 185 | err = -ENOBUFS; |
179 | if (head == NULL) { | ||
180 | head = kzalloc(sizeof(*head), GFP_KERNEL); | ||
181 | if (head == NULL) | ||
182 | goto errout; | ||
183 | |||
184 | INIT_LIST_HEAD(&head->flist); | ||
185 | tp->root = head; | ||
186 | } | ||
187 | |||
188 | f = kzalloc(sizeof(*f), GFP_KERNEL); | 186 | f = kzalloc(sizeof(*f), GFP_KERNEL); |
189 | if (f == NULL) | 187 | if (f == NULL) |
190 | goto errout; | 188 | goto errout; |
diff --git a/net/socket.c b/net/socket.c index 9566e57ac7f5..ea8f81abc45c 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -1381,7 +1381,7 @@ asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, | |||
1381 | 1381 | ||
1382 | err = sock_attach_fd(newsock, newfile); | 1382 | err = sock_attach_fd(newsock, newfile); |
1383 | if (err < 0) | 1383 | if (err < 0) |
1384 | goto out_fd; | 1384 | goto out_fd_simple; |
1385 | 1385 | ||
1386 | err = security_socket_accept(sock, newsock); | 1386 | err = security_socket_accept(sock, newsock); |
1387 | if (err) | 1387 | if (err) |
@@ -1414,6 +1414,11 @@ out_put: | |||
1414 | fput_light(sock->file, fput_needed); | 1414 | fput_light(sock->file, fput_needed); |
1415 | out: | 1415 | out: |
1416 | return err; | 1416 | return err; |
1417 | out_fd_simple: | ||
1418 | sock_release(newsock); | ||
1419 | put_filp(newfile); | ||
1420 | put_unused_fd(newfd); | ||
1421 | goto out_put; | ||
1417 | out_fd: | 1422 | out_fd: |
1418 | fput(newfile); | 1423 | fput(newfile); |
1419 | put_unused_fd(newfd); | 1424 | put_unused_fd(newfd); |