diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/arp.c | 2 | ||||
-rw-r--r-- | net/ipv4/fib_semantics.c | 4 | ||||
-rw-r--r-- | net/ipv4/ip_fragment.c | 4 | ||||
-rw-r--r-- | net/ipv4/ip_input.c | 10 | ||||
-rw-r--r-- | net/ipv4/route.c | 56 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 9 | ||||
-rw-r--r-- | net/ipv4/xfrm4_input.c | 4 | ||||
-rw-r--r-- | net/ipv6/ip6_input.c | 13 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 38 | ||||
-rw-r--r-- | net/wanrouter/wanmain.c | 51 |
10 files changed, 115 insertions, 76 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index a0124eb7dbe..77e87aff419 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -827,7 +827,7 @@ static int arp_process(struct sk_buff *skb) | |||
827 | } | 827 | } |
828 | 828 | ||
829 | if (arp->ar_op == htons(ARPOP_REQUEST) && | 829 | if (arp->ar_op == htons(ARPOP_REQUEST) && |
830 | ip_route_input(skb, tip, sip, 0, dev) == 0) { | 830 | ip_route_input_noref(skb, tip, sip, 0, dev) == 0) { |
831 | 831 | ||
832 | rt = skb_rtable(skb); | 832 | rt = skb_rtable(skb); |
833 | addr_type = rt->rt_type; | 833 | addr_type = rt->rt_type; |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index e55171f184f..da0cc2e6b25 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -172,9 +172,9 @@ static void free_fib_info_rcu(struct rcu_head *head) | |||
172 | if (nexthop_nh->nh_exceptions) | 172 | if (nexthop_nh->nh_exceptions) |
173 | free_nh_exceptions(nexthop_nh); | 173 | free_nh_exceptions(nexthop_nh); |
174 | if (nexthop_nh->nh_rth_output) | 174 | if (nexthop_nh->nh_rth_output) |
175 | dst_release(&nexthop_nh->nh_rth_output->dst); | 175 | dst_free(&nexthop_nh->nh_rth_output->dst); |
176 | if (nexthop_nh->nh_rth_input) | 176 | if (nexthop_nh->nh_rth_input) |
177 | dst_release(&nexthop_nh->nh_rth_input->dst); | 177 | dst_free(&nexthop_nh->nh_rth_input->dst); |
178 | } endfor_nexthops(fi); | 178 | } endfor_nexthops(fi); |
179 | 179 | ||
180 | release_net(fi->fib_net); | 180 | release_net(fi->fib_net); |
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 7ad88e5e711..8d07c973409 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -258,8 +258,8 @@ static void ip_expire(unsigned long arg) | |||
258 | /* skb dst is stale, drop it, and perform route lookup again */ | 258 | /* skb dst is stale, drop it, and perform route lookup again */ |
259 | skb_dst_drop(head); | 259 | skb_dst_drop(head); |
260 | iph = ip_hdr(head); | 260 | iph = ip_hdr(head); |
261 | err = ip_route_input(head, iph->daddr, iph->saddr, | 261 | err = ip_route_input_noref(head, iph->daddr, iph->saddr, |
262 | iph->tos, head->dev); | 262 | iph->tos, head->dev); |
263 | if (err) | 263 | if (err) |
264 | goto out_rcu_unlock; | 264 | goto out_rcu_unlock; |
265 | 265 | ||
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 4ebc6feee25..981ff1eef28 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -314,6 +314,7 @@ drop: | |||
314 | } | 314 | } |
315 | 315 | ||
316 | int sysctl_ip_early_demux __read_mostly = 1; | 316 | int sysctl_ip_early_demux __read_mostly = 1; |
317 | EXPORT_SYMBOL(sysctl_ip_early_demux); | ||
317 | 318 | ||
318 | static int ip_rcv_finish(struct sk_buff *skb) | 319 | static int ip_rcv_finish(struct sk_buff *skb) |
319 | { | 320 | { |
@@ -326,8 +327,11 @@ static int ip_rcv_finish(struct sk_buff *skb) | |||
326 | 327 | ||
327 | rcu_read_lock(); | 328 | rcu_read_lock(); |
328 | ipprot = rcu_dereference(inet_protos[protocol]); | 329 | ipprot = rcu_dereference(inet_protos[protocol]); |
329 | if (ipprot && ipprot->early_demux) | 330 | if (ipprot && ipprot->early_demux) { |
330 | ipprot->early_demux(skb); | 331 | ipprot->early_demux(skb); |
332 | /* must reload iph, skb->head might have changed */ | ||
333 | iph = ip_hdr(skb); | ||
334 | } | ||
331 | rcu_read_unlock(); | 335 | rcu_read_unlock(); |
332 | } | 336 | } |
333 | 337 | ||
@@ -336,8 +340,8 @@ static int ip_rcv_finish(struct sk_buff *skb) | |||
336 | * how the packet travels inside Linux networking. | 340 | * how the packet travels inside Linux networking. |
337 | */ | 341 | */ |
338 | if (!skb_dst(skb)) { | 342 | if (!skb_dst(skb)) { |
339 | int err = ip_route_input(skb, iph->daddr, iph->saddr, | 343 | int err = ip_route_input_noref(skb, iph->daddr, iph->saddr, |
340 | iph->tos, skb->dev); | 344 | iph->tos, skb->dev); |
341 | if (unlikely(err)) { | 345 | if (unlikely(err)) { |
342 | if (err == -EXDEV) | 346 | if (err == -EXDEV) |
343 | NET_INC_STATS_BH(dev_net(skb->dev), | 347 | NET_INC_STATS_BH(dev_net(skb->dev), |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 6bcb8fc71cb..fc1a81ca79a 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -444,7 +444,7 @@ static inline int ip_rt_proc_init(void) | |||
444 | } | 444 | } |
445 | #endif /* CONFIG_PROC_FS */ | 445 | #endif /* CONFIG_PROC_FS */ |
446 | 446 | ||
447 | static inline int rt_is_expired(struct rtable *rth) | 447 | static inline bool rt_is_expired(const struct rtable *rth) |
448 | { | 448 | { |
449 | return rth->rt_genid != rt_genid(dev_net(rth->dst.dev)); | 449 | return rth->rt_genid != rt_genid(dev_net(rth->dst.dev)); |
450 | } | 450 | } |
@@ -1199,10 +1199,9 @@ restart: | |||
1199 | fnhe->fnhe_stamp = jiffies; | 1199 | fnhe->fnhe_stamp = jiffies; |
1200 | } | 1200 | } |
1201 | 1201 | ||
1202 | static inline void rt_release_rcu(struct rcu_head *head) | 1202 | static inline void rt_free(struct rtable *rt) |
1203 | { | 1203 | { |
1204 | struct dst_entry *dst = container_of(head, struct dst_entry, rcu_head); | 1204 | call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free); |
1205 | dst_release(dst); | ||
1206 | } | 1205 | } |
1207 | 1206 | ||
1208 | static void rt_cache_route(struct fib_nh *nh, struct rtable *rt) | 1207 | static void rt_cache_route(struct fib_nh *nh, struct rtable *rt) |
@@ -1216,15 +1215,23 @@ static void rt_cache_route(struct fib_nh *nh, struct rtable *rt) | |||
1216 | 1215 | ||
1217 | prev = cmpxchg(p, orig, rt); | 1216 | prev = cmpxchg(p, orig, rt); |
1218 | if (prev == orig) { | 1217 | if (prev == orig) { |
1219 | dst_clone(&rt->dst); | ||
1220 | if (orig) | 1218 | if (orig) |
1221 | call_rcu_bh(&orig->dst.rcu_head, rt_release_rcu); | 1219 | rt_free(orig); |
1220 | } else { | ||
1221 | /* Routes we intend to cache in the FIB nexthop have | ||
1222 | * the DST_NOCACHE bit clear. However, if we are | ||
1223 | * unsuccessful at storing this route into the cache | ||
1224 | * we really need to set it. | ||
1225 | */ | ||
1226 | rt->dst.flags |= DST_NOCACHE; | ||
1222 | } | 1227 | } |
1223 | } | 1228 | } |
1224 | 1229 | ||
1225 | static bool rt_cache_valid(struct rtable *rt) | 1230 | static bool rt_cache_valid(const struct rtable *rt) |
1226 | { | 1231 | { |
1227 | return (rt && rt->dst.obsolete == DST_OBSOLETE_FORCE_CHK); | 1232 | return rt && |
1233 | rt->dst.obsolete == DST_OBSOLETE_FORCE_CHK && | ||
1234 | !rt_is_expired(rt); | ||
1228 | } | 1235 | } |
1229 | 1236 | ||
1230 | static void rt_set_nexthop(struct rtable *rt, __be32 daddr, | 1237 | static void rt_set_nexthop(struct rtable *rt, __be32 daddr, |
@@ -1243,7 +1250,7 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr, | |||
1243 | #ifdef CONFIG_IP_ROUTE_CLASSID | 1250 | #ifdef CONFIG_IP_ROUTE_CLASSID |
1244 | rt->dst.tclassid = nh->nh_tclassid; | 1251 | rt->dst.tclassid = nh->nh_tclassid; |
1245 | #endif | 1252 | #endif |
1246 | if (!(rt->dst.flags & DST_HOST)) | 1253 | if (!(rt->dst.flags & DST_NOCACHE)) |
1247 | rt_cache_route(nh, rt); | 1254 | rt_cache_route(nh, rt); |
1248 | } | 1255 | } |
1249 | 1256 | ||
@@ -1259,7 +1266,7 @@ static struct rtable *rt_dst_alloc(struct net_device *dev, | |||
1259 | bool nopolicy, bool noxfrm, bool will_cache) | 1266 | bool nopolicy, bool noxfrm, bool will_cache) |
1260 | { | 1267 | { |
1261 | return dst_alloc(&ipv4_dst_ops, dev, 1, DST_OBSOLETE_FORCE_CHK, | 1268 | return dst_alloc(&ipv4_dst_ops, dev, 1, DST_OBSOLETE_FORCE_CHK, |
1262 | (will_cache ? 0 : DST_HOST) | DST_NOCACHE | | 1269 | (will_cache ? 0 : (DST_HOST | DST_NOCACHE)) | |
1263 | (nopolicy ? DST_NOPOLICY : 0) | | 1270 | (nopolicy ? DST_NOPOLICY : 0) | |
1264 | (noxfrm ? DST_NOXFRM : 0)); | 1271 | (noxfrm ? DST_NOXFRM : 0)); |
1265 | } | 1272 | } |
@@ -1364,8 +1371,7 @@ static void ip_handle_martian_source(struct net_device *dev, | |||
1364 | static int __mkroute_input(struct sk_buff *skb, | 1371 | static int __mkroute_input(struct sk_buff *skb, |
1365 | const struct fib_result *res, | 1372 | const struct fib_result *res, |
1366 | struct in_device *in_dev, | 1373 | struct in_device *in_dev, |
1367 | __be32 daddr, __be32 saddr, u32 tos, | 1374 | __be32 daddr, __be32 saddr, u32 tos) |
1368 | struct rtable **result) | ||
1369 | { | 1375 | { |
1370 | struct rtable *rth; | 1376 | struct rtable *rth; |
1371 | int err; | 1377 | int err; |
@@ -1416,7 +1422,7 @@ static int __mkroute_input(struct sk_buff *skb, | |||
1416 | if (!itag) { | 1422 | if (!itag) { |
1417 | rth = FIB_RES_NH(*res).nh_rth_input; | 1423 | rth = FIB_RES_NH(*res).nh_rth_input; |
1418 | if (rt_cache_valid(rth)) { | 1424 | if (rt_cache_valid(rth)) { |
1419 | dst_hold(&rth->dst); | 1425 | skb_dst_set_noref(skb, &rth->dst); |
1420 | goto out; | 1426 | goto out; |
1421 | } | 1427 | } |
1422 | do_cache = true; | 1428 | do_cache = true; |
@@ -1443,8 +1449,8 @@ static int __mkroute_input(struct sk_buff *skb, | |||
1443 | rth->dst.output = ip_output; | 1449 | rth->dst.output = ip_output; |
1444 | 1450 | ||
1445 | rt_set_nexthop(rth, daddr, res, NULL, res->fi, res->type, itag); | 1451 | rt_set_nexthop(rth, daddr, res, NULL, res->fi, res->type, itag); |
1452 | skb_dst_set(skb, &rth->dst); | ||
1446 | out: | 1453 | out: |
1447 | *result = rth; | ||
1448 | err = 0; | 1454 | err = 0; |
1449 | cleanup: | 1455 | cleanup: |
1450 | return err; | 1456 | return err; |
@@ -1456,21 +1462,13 @@ static int ip_mkroute_input(struct sk_buff *skb, | |||
1456 | struct in_device *in_dev, | 1462 | struct in_device *in_dev, |
1457 | __be32 daddr, __be32 saddr, u32 tos) | 1463 | __be32 daddr, __be32 saddr, u32 tos) |
1458 | { | 1464 | { |
1459 | struct rtable *rth = NULL; | ||
1460 | int err; | ||
1461 | |||
1462 | #ifdef CONFIG_IP_ROUTE_MULTIPATH | 1465 | #ifdef CONFIG_IP_ROUTE_MULTIPATH |
1463 | if (res->fi && res->fi->fib_nhs > 1) | 1466 | if (res->fi && res->fi->fib_nhs > 1) |
1464 | fib_select_multipath(res); | 1467 | fib_select_multipath(res); |
1465 | #endif | 1468 | #endif |
1466 | 1469 | ||
1467 | /* create a routing cache entry */ | 1470 | /* create a routing cache entry */ |
1468 | err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, &rth); | 1471 | return __mkroute_input(skb, res, in_dev, daddr, saddr, tos); |
1469 | if (err) | ||
1470 | return err; | ||
1471 | |||
1472 | skb_dst_set(skb, &rth->dst); | ||
1473 | return 0; | ||
1474 | } | 1472 | } |
1475 | 1473 | ||
1476 | /* | 1474 | /* |
@@ -1586,8 +1584,9 @@ local_input: | |||
1586 | if (!itag) { | 1584 | if (!itag) { |
1587 | rth = FIB_RES_NH(res).nh_rth_input; | 1585 | rth = FIB_RES_NH(res).nh_rth_input; |
1588 | if (rt_cache_valid(rth)) { | 1586 | if (rt_cache_valid(rth)) { |
1589 | dst_hold(&rth->dst); | 1587 | skb_dst_set_noref(skb, &rth->dst); |
1590 | goto set_and_out; | 1588 | err = 0; |
1589 | goto out; | ||
1591 | } | 1590 | } |
1592 | do_cache = true; | 1591 | do_cache = true; |
1593 | } | 1592 | } |
@@ -1618,7 +1617,6 @@ local_input: | |||
1618 | } | 1617 | } |
1619 | if (do_cache) | 1618 | if (do_cache) |
1620 | rt_cache_route(&FIB_RES_NH(res), rth); | 1619 | rt_cache_route(&FIB_RES_NH(res), rth); |
1621 | set_and_out: | ||
1622 | skb_dst_set(skb, &rth->dst); | 1620 | skb_dst_set(skb, &rth->dst); |
1623 | err = 0; | 1621 | err = 0; |
1624 | goto out; | 1622 | goto out; |
@@ -1656,8 +1654,8 @@ martian_source_keep_err: | |||
1656 | goto out; | 1654 | goto out; |
1657 | } | 1655 | } |
1658 | 1656 | ||
1659 | int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, | 1657 | int ip_route_input_noref(struct sk_buff *skb, __be32 daddr, __be32 saddr, |
1660 | u8 tos, struct net_device *dev) | 1658 | u8 tos, struct net_device *dev) |
1661 | { | 1659 | { |
1662 | int res; | 1660 | int res; |
1663 | 1661 | ||
@@ -1700,7 +1698,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1700 | rcu_read_unlock(); | 1698 | rcu_read_unlock(); |
1701 | return res; | 1699 | return res; |
1702 | } | 1700 | } |
1703 | EXPORT_SYMBOL(ip_route_input); | 1701 | EXPORT_SYMBOL(ip_route_input_noref); |
1704 | 1702 | ||
1705 | /* called with rcu_read_lock() */ | 1703 | /* called with rcu_read_lock() */ |
1706 | static struct rtable *__mkroute_output(const struct fib_result *res, | 1704 | static struct rtable *__mkroute_output(const struct fib_result *res, |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 3e30548ac32..b6b07c93924 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -1686,7 +1686,6 @@ void tcp_v4_early_demux(struct sk_buff *skb) | |||
1686 | struct net *net = dev_net(skb->dev); | 1686 | struct net *net = dev_net(skb->dev); |
1687 | const struct iphdr *iph; | 1687 | const struct iphdr *iph; |
1688 | const struct tcphdr *th; | 1688 | const struct tcphdr *th; |
1689 | struct net_device *dev; | ||
1690 | struct sock *sk; | 1689 | struct sock *sk; |
1691 | 1690 | ||
1692 | if (skb->pkt_type != PACKET_HOST) | 1691 | if (skb->pkt_type != PACKET_HOST) |
@@ -1701,14 +1700,10 @@ void tcp_v4_early_demux(struct sk_buff *skb) | |||
1701 | if (th->doff < sizeof(struct tcphdr) / 4) | 1700 | if (th->doff < sizeof(struct tcphdr) / 4) |
1702 | return; | 1701 | return; |
1703 | 1702 | ||
1704 | if (!pskb_may_pull(skb, ip_hdrlen(skb) + th->doff * 4)) | ||
1705 | return; | ||
1706 | |||
1707 | dev = skb->dev; | ||
1708 | sk = __inet_lookup_established(net, &tcp_hashinfo, | 1703 | sk = __inet_lookup_established(net, &tcp_hashinfo, |
1709 | iph->saddr, th->source, | 1704 | iph->saddr, th->source, |
1710 | iph->daddr, ntohs(th->dest), | 1705 | iph->daddr, ntohs(th->dest), |
1711 | dev->ifindex); | 1706 | skb->skb_iif); |
1712 | if (sk) { | 1707 | if (sk) { |
1713 | skb->sk = sk; | 1708 | skb->sk = sk; |
1714 | skb->destructor = sock_edemux; | 1709 | skb->destructor = sock_edemux; |
@@ -1718,7 +1713,7 @@ void tcp_v4_early_demux(struct sk_buff *skb) | |||
1718 | if (dst) | 1713 | if (dst) |
1719 | dst = dst_check(dst, 0); | 1714 | dst = dst_check(dst, 0); |
1720 | if (dst && | 1715 | if (dst && |
1721 | icsk->rx_dst_ifindex == dev->ifindex) | 1716 | icsk->rx_dst_ifindex == skb->skb_iif) |
1722 | skb_dst_set_noref(skb, dst); | 1717 | skb_dst_set_noref(skb, dst); |
1723 | } | 1718 | } |
1724 | } | 1719 | } |
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index 58d23a57250..06814b6216d 100644 --- a/net/ipv4/xfrm4_input.c +++ b/net/ipv4/xfrm4_input.c | |||
@@ -27,8 +27,8 @@ static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb) | |||
27 | if (skb_dst(skb) == NULL) { | 27 | if (skb_dst(skb) == NULL) { |
28 | const struct iphdr *iph = ip_hdr(skb); | 28 | const struct iphdr *iph = ip_hdr(skb); |
29 | 29 | ||
30 | if (ip_route_input(skb, iph->daddr, iph->saddr, | 30 | if (ip_route_input_noref(skb, iph->daddr, iph->saddr, |
31 | iph->tos, skb->dev)) | 31 | iph->tos, skb->dev)) |
32 | goto drop; | 32 | goto drop; |
33 | } | 33 | } |
34 | return dst_input(skb); | 34 | return dst_input(skb); |
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 5ab923e51af..47975e363fc 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c | |||
@@ -47,9 +47,18 @@ | |||
47 | 47 | ||
48 | 48 | ||
49 | 49 | ||
50 | inline int ip6_rcv_finish( struct sk_buff *skb) | 50 | int ip6_rcv_finish(struct sk_buff *skb) |
51 | { | 51 | { |
52 | if (skb_dst(skb) == NULL) | 52 | if (sysctl_ip_early_demux && !skb_dst(skb)) { |
53 | const struct inet6_protocol *ipprot; | ||
54 | |||
55 | rcu_read_lock(); | ||
56 | ipprot = rcu_dereference(inet6_protos[ipv6_hdr(skb)->nexthdr]); | ||
57 | if (ipprot && ipprot->early_demux) | ||
58 | ipprot->early_demux(skb); | ||
59 | rcu_read_unlock(); | ||
60 | } | ||
61 | if (!skb_dst(skb)) | ||
53 | ip6_route_input(skb); | 62 | ip6_route_input(skb); |
54 | 63 | ||
55 | return dst_input(skb); | 64 | return dst_input(skb); |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index f49476e2d88..221224e7250 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -1674,6 +1674,43 @@ do_time_wait: | |||
1674 | goto discard_it; | 1674 | goto discard_it; |
1675 | } | 1675 | } |
1676 | 1676 | ||
1677 | static void tcp_v6_early_demux(struct sk_buff *skb) | ||
1678 | { | ||
1679 | const struct ipv6hdr *hdr; | ||
1680 | const struct tcphdr *th; | ||
1681 | struct sock *sk; | ||
1682 | |||
1683 | if (skb->pkt_type != PACKET_HOST) | ||
1684 | return; | ||
1685 | |||
1686 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + sizeof(struct tcphdr))) | ||
1687 | return; | ||
1688 | |||
1689 | hdr = ipv6_hdr(skb); | ||
1690 | th = tcp_hdr(skb); | ||
1691 | |||
1692 | if (th->doff < sizeof(struct tcphdr) / 4) | ||
1693 | return; | ||
1694 | |||
1695 | sk = __inet6_lookup_established(dev_net(skb->dev), &tcp_hashinfo, | ||
1696 | &hdr->saddr, th->source, | ||
1697 | &hdr->daddr, ntohs(th->dest), | ||
1698 | inet6_iif(skb)); | ||
1699 | if (sk) { | ||
1700 | skb->sk = sk; | ||
1701 | skb->destructor = sock_edemux; | ||
1702 | if (sk->sk_state != TCP_TIME_WAIT) { | ||
1703 | struct dst_entry *dst = sk->sk_rx_dst; | ||
1704 | struct inet_sock *icsk = inet_sk(sk); | ||
1705 | if (dst) | ||
1706 | dst = dst_check(dst, 0); | ||
1707 | if (dst && | ||
1708 | icsk->rx_dst_ifindex == inet6_iif(skb)) | ||
1709 | skb_dst_set_noref(skb, dst); | ||
1710 | } | ||
1711 | } | ||
1712 | } | ||
1713 | |||
1677 | static struct timewait_sock_ops tcp6_timewait_sock_ops = { | 1714 | static struct timewait_sock_ops tcp6_timewait_sock_ops = { |
1678 | .twsk_obj_size = sizeof(struct tcp6_timewait_sock), | 1715 | .twsk_obj_size = sizeof(struct tcp6_timewait_sock), |
1679 | .twsk_unique = tcp_twsk_unique, | 1716 | .twsk_unique = tcp_twsk_unique, |
@@ -1984,6 +2021,7 @@ struct proto tcpv6_prot = { | |||
1984 | }; | 2021 | }; |
1985 | 2022 | ||
1986 | static const struct inet6_protocol tcpv6_protocol = { | 2023 | static const struct inet6_protocol tcpv6_protocol = { |
2024 | .early_demux = tcp_v6_early_demux, | ||
1987 | .handler = tcp_v6_rcv, | 2025 | .handler = tcp_v6_rcv, |
1988 | .err_handler = tcp_v6_err, | 2026 | .err_handler = tcp_v6_err, |
1989 | .gso_send_check = tcp_v6_gso_send_check, | 2027 | .gso_send_check = tcp_v6_gso_send_check, |
diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c index 788a12c1eb5..2ab785064b7 100644 --- a/net/wanrouter/wanmain.c +++ b/net/wanrouter/wanmain.c | |||
@@ -602,36 +602,31 @@ static int wanrouter_device_new_if(struct wan_device *wandev, | |||
602 | * successfully, add it to the interface list. | 602 | * successfully, add it to the interface list. |
603 | */ | 603 | */ |
604 | 604 | ||
605 | if (dev->name == NULL) { | 605 | #ifdef WANDEBUG |
606 | err = -EINVAL; | 606 | printk(KERN_INFO "%s: registering interface %s...\n", |
607 | } else { | 607 | wanrouter_modname, dev->name); |
608 | #endif | ||
608 | 609 | ||
609 | #ifdef WANDEBUG | 610 | err = register_netdev(dev); |
610 | printk(KERN_INFO "%s: registering interface %s...\n", | 611 | if (!err) { |
611 | wanrouter_modname, dev->name); | 612 | struct net_device *slave = NULL; |
612 | #endif | 613 | unsigned long smp_flags=0; |
613 | 614 | ||
614 | err = register_netdev(dev); | 615 | lock_adapter_irq(&wandev->lock, &smp_flags); |
615 | if (!err) { | 616 | |
616 | struct net_device *slave = NULL; | 617 | if (wandev->dev == NULL) { |
617 | unsigned long smp_flags=0; | 618 | wandev->dev = dev; |
618 | 619 | } else { | |
619 | lock_adapter_irq(&wandev->lock, &smp_flags); | 620 | for (slave=wandev->dev; |
620 | 621 | DEV_TO_SLAVE(slave); | |
621 | if (wandev->dev == NULL) { | 622 | slave = DEV_TO_SLAVE(slave)) |
622 | wandev->dev = dev; | 623 | DEV_TO_SLAVE(slave) = dev; |
623 | } else { | ||
624 | for (slave=wandev->dev; | ||
625 | DEV_TO_SLAVE(slave); | ||
626 | slave = DEV_TO_SLAVE(slave)) | ||
627 | DEV_TO_SLAVE(slave) = dev; | ||
628 | } | ||
629 | ++wandev->ndev; | ||
630 | |||
631 | unlock_adapter_irq(&wandev->lock, &smp_flags); | ||
632 | err = 0; /* done !!! */ | ||
633 | goto out; | ||
634 | } | 624 | } |
625 | ++wandev->ndev; | ||
626 | |||
627 | unlock_adapter_irq(&wandev->lock, &smp_flags); | ||
628 | err = 0; /* done !!! */ | ||
629 | goto out; | ||
635 | } | 630 | } |
636 | if (wandev->del_if) | 631 | if (wandev->del_if) |
637 | wandev->del_if(wandev, dev); | 632 | wandev->del_if(wandev, dev); |