diff options
| author | Andi Kleen <andi@basil.nowhere.org> | 2006-11-21 04:22:09 -0500 |
|---|---|---|
| committer | Andi Kleen <andi@basil.nowhere.org> | 2006-11-21 04:22:09 -0500 |
| commit | 1b7f6a626f0ff511c3840678466cbfe1d62c0b29 (patch) | |
| tree | 415e8c838c0067bff384afb8a2c91e5f7c6d11d3 /net/ipv6 | |
| parent | b3edc9cec07ade41aaf1804f7c9e876afa90c862 (diff) | |
| parent | 3f5a6ca31c334011fd929501a078424c0d3f71be (diff) | |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'net/ipv6')
| -rw-r--r-- | net/ipv6/ip6_fib.c | 9 | ||||
| -rw-r--r-- | net/ipv6/ip6_flowlabel.c | 24 | ||||
| -rw-r--r-- | net/ipv6/ndisc.c | 1 | ||||
| -rw-r--r-- | net/ipv6/netfilter/Kconfig | 2 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6_queue.c | 7 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 47 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6t_ah.c | 7 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6t_frag.c | 7 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6t_hbh.c | 7 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6t_rt.c | 7 | ||||
| -rw-r--r-- | net/ipv6/raw.c | 17 | ||||
| -rw-r--r-- | net/ipv6/sit.c | 1 | ||||
| -rw-r--r-- | net/ipv6/xfrm6_tunnel.c | 4 |
13 files changed, 91 insertions, 49 deletions
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 8fcae7a6510b..f98ca30d7c1f 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
| @@ -169,7 +169,6 @@ static __inline__ void rt6_release(struct rt6_info *rt) | |||
| 169 | 169 | ||
| 170 | static struct fib6_table fib6_main_tbl = { | 170 | static struct fib6_table fib6_main_tbl = { |
| 171 | .tb6_id = RT6_TABLE_MAIN, | 171 | .tb6_id = RT6_TABLE_MAIN, |
| 172 | .tb6_lock = RW_LOCK_UNLOCKED, | ||
| 173 | .tb6_root = { | 172 | .tb6_root = { |
| 174 | .leaf = &ip6_null_entry, | 173 | .leaf = &ip6_null_entry, |
| 175 | .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO, | 174 | .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO, |
| @@ -187,6 +186,12 @@ static void fib6_link_table(struct fib6_table *tb) | |||
| 187 | { | 186 | { |
| 188 | unsigned int h; | 187 | unsigned int h; |
| 189 | 188 | ||
| 189 | /* | ||
| 190 | * Initialize table lock at a single place to give lockdep a key, | ||
| 191 | * tables aren't visible prior to being linked to the list. | ||
| 192 | */ | ||
| 193 | rwlock_init(&tb->tb6_lock); | ||
| 194 | |||
| 190 | h = tb->tb6_id & (FIB_TABLE_HASHSZ - 1); | 195 | h = tb->tb6_id & (FIB_TABLE_HASHSZ - 1); |
| 191 | 196 | ||
| 192 | /* | 197 | /* |
| @@ -199,7 +204,6 @@ static void fib6_link_table(struct fib6_table *tb) | |||
| 199 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES | 204 | #ifdef CONFIG_IPV6_MULTIPLE_TABLES |
| 200 | static struct fib6_table fib6_local_tbl = { | 205 | static struct fib6_table fib6_local_tbl = { |
| 201 | .tb6_id = RT6_TABLE_LOCAL, | 206 | .tb6_id = RT6_TABLE_LOCAL, |
| 202 | .tb6_lock = RW_LOCK_UNLOCKED, | ||
| 203 | .tb6_root = { | 207 | .tb6_root = { |
| 204 | .leaf = &ip6_null_entry, | 208 | .leaf = &ip6_null_entry, |
| 205 | .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO, | 209 | .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO, |
| @@ -213,7 +217,6 @@ static struct fib6_table *fib6_alloc_table(u32 id) | |||
| 213 | table = kzalloc(sizeof(*table), GFP_ATOMIC); | 217 | table = kzalloc(sizeof(*table), GFP_ATOMIC); |
| 214 | if (table != NULL) { | 218 | if (table != NULL) { |
| 215 | table->tb6_id = id; | 219 | table->tb6_id = id; |
| 216 | table->tb6_lock = RW_LOCK_UNLOCKED; | ||
| 217 | table->tb6_root.leaf = &ip6_null_entry; | 220 | table->tb6_root.leaf = &ip6_null_entry; |
| 218 | table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; | 221 | table->tb6_root.fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO; |
| 219 | } | 222 | } |
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 1d672b0547f2..6d4533b58dca 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c | |||
| @@ -330,8 +330,10 @@ fl_create(struct in6_flowlabel_req *freq, char __user *optval, int optlen, int * | |||
| 330 | fl->share = freq->flr_share; | 330 | fl->share = freq->flr_share; |
| 331 | addr_type = ipv6_addr_type(&freq->flr_dst); | 331 | addr_type = ipv6_addr_type(&freq->flr_dst); |
| 332 | if ((addr_type&IPV6_ADDR_MAPPED) | 332 | if ((addr_type&IPV6_ADDR_MAPPED) |
| 333 | || addr_type == IPV6_ADDR_ANY) | 333 | || addr_type == IPV6_ADDR_ANY) { |
| 334 | err = -EINVAL; | ||
| 334 | goto done; | 335 | goto done; |
| 336 | } | ||
| 335 | ipv6_addr_copy(&fl->dst, &freq->flr_dst); | 337 | ipv6_addr_copy(&fl->dst, &freq->flr_dst); |
| 336 | atomic_set(&fl->users, 1); | 338 | atomic_set(&fl->users, 1); |
| 337 | switch (fl->share) { | 339 | switch (fl->share) { |
| @@ -587,6 +589,8 @@ static struct ip6_flowlabel *ip6fl_get_next(struct seq_file *seq, struct ip6_flo | |||
| 587 | while (!fl) { | 589 | while (!fl) { |
| 588 | if (++state->bucket <= FL_HASH_MASK) | 590 | if (++state->bucket <= FL_HASH_MASK) |
| 589 | fl = fl_ht[state->bucket]; | 591 | fl = fl_ht[state->bucket]; |
| 592 | else | ||
| 593 | break; | ||
| 590 | } | 594 | } |
| 591 | return fl; | 595 | return fl; |
| 592 | } | 596 | } |
| @@ -623,9 +627,13 @@ static void ip6fl_seq_stop(struct seq_file *seq, void *v) | |||
| 623 | read_unlock_bh(&ip6_fl_lock); | 627 | read_unlock_bh(&ip6_fl_lock); |
| 624 | } | 628 | } |
| 625 | 629 | ||
| 626 | static void ip6fl_fl_seq_show(struct seq_file *seq, struct ip6_flowlabel *fl) | 630 | static int ip6fl_seq_show(struct seq_file *seq, void *v) |
| 627 | { | 631 | { |
| 628 | while(fl) { | 632 | if (v == SEQ_START_TOKEN) |
| 633 | seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", | ||
| 634 | "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); | ||
| 635 | else { | ||
| 636 | struct ip6_flowlabel *fl = v; | ||
| 629 | seq_printf(seq, | 637 | seq_printf(seq, |
| 630 | "%05X %-1d %-6d %-6d %-6ld %-8ld " NIP6_SEQFMT " %-4d\n", | 638 | "%05X %-1d %-6d %-6d %-6ld %-8ld " NIP6_SEQFMT " %-4d\n", |
| 631 | (unsigned)ntohl(fl->label), | 639 | (unsigned)ntohl(fl->label), |
| @@ -636,17 +644,7 @@ static void ip6fl_fl_seq_show(struct seq_file *seq, struct ip6_flowlabel *fl) | |||
| 636 | (long)(fl->expires - jiffies)/HZ, | 644 | (long)(fl->expires - jiffies)/HZ, |
| 637 | NIP6(fl->dst), | 645 | NIP6(fl->dst), |
| 638 | fl->opt ? fl->opt->opt_nflen : 0); | 646 | fl->opt ? fl->opt->opt_nflen : 0); |
| 639 | fl = fl->next; | ||
| 640 | } | 647 | } |
| 641 | } | ||
| 642 | |||
| 643 | static int ip6fl_seq_show(struct seq_file *seq, void *v) | ||
| 644 | { | ||
| 645 | if (v == SEQ_START_TOKEN) | ||
| 646 | seq_printf(seq, "%-5s %-1s %-6s %-6s %-6s %-8s %-32s %s\n", | ||
| 647 | "Label", "S", "Owner", "Users", "Linger", "Expires", "Dst", "Opt"); | ||
| 648 | else | ||
| 649 | ip6fl_fl_seq_show(seq, v); | ||
| 650 | return 0; | 648 | return 0; |
| 651 | } | 649 | } |
| 652 | 650 | ||
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 41a8a5f06602..73eb8c33e9f0 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
| @@ -1742,6 +1742,7 @@ int __init ndisc_init(struct net_proto_family *ops) | |||
| 1742 | 1742 | ||
| 1743 | void ndisc_cleanup(void) | 1743 | void ndisc_cleanup(void) |
| 1744 | { | 1744 | { |
| 1745 | unregister_netdevice_notifier(&ndisc_netdev_notifier); | ||
| 1745 | #ifdef CONFIG_SYSCTL | 1746 | #ifdef CONFIG_SYSCTL |
| 1746 | neigh_sysctl_unregister(&nd_tbl.parms); | 1747 | neigh_sysctl_unregister(&nd_tbl.parms); |
| 1747 | #endif | 1748 | #endif |
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig index 4bc4e5b33794..d7c45a9c15fe 100644 --- a/net/ipv6/netfilter/Kconfig +++ b/net/ipv6/netfilter/Kconfig | |||
| @@ -40,7 +40,7 @@ config IP6_NF_QUEUE | |||
| 40 | To compile it as a module, choose M here. If unsure, say N. | 40 | To compile it as a module, choose M here. If unsure, say N. |
| 41 | 41 | ||
| 42 | config IP6_NF_IPTABLES | 42 | config IP6_NF_IPTABLES |
| 43 | tristate "IP6 tables support (required for filtering/masq/NAT)" | 43 | tristate "IP6 tables support (required for filtering)" |
| 44 | depends on NETFILTER_XTABLES | 44 | depends on NETFILTER_XTABLES |
| 45 | help | 45 | help |
| 46 | ip6tables is a general, extensible packet identification framework. | 46 | ip6tables is a general, extensible packet identification framework. |
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 9510c24ca8d2..9fec832ee08b 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c | |||
| @@ -349,9 +349,10 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e) | |||
| 349 | if (v->data_len < sizeof(*user_iph)) | 349 | if (v->data_len < sizeof(*user_iph)) |
| 350 | return 0; | 350 | return 0; |
| 351 | diff = v->data_len - e->skb->len; | 351 | diff = v->data_len - e->skb->len; |
| 352 | if (diff < 0) | 352 | if (diff < 0) { |
| 353 | skb_trim(e->skb, v->data_len); | 353 | if (pskb_trim(e->skb, v->data_len)) |
| 354 | else if (diff > 0) { | 354 | return -ENOMEM; |
| 355 | } else if (diff > 0) { | ||
| 355 | if (v->data_len > 0xFFFF) | 356 | if (v->data_len > 0xFFFF) |
| 356 | return -EINVAL; | 357 | return -EINVAL; |
| 357 | if (diff > skb_tailroom(e->skb)) { | 358 | if (diff > skb_tailroom(e->skb)) { |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 4ab368fa0b8f..204e02162d49 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
| @@ -111,7 +111,7 @@ ip6_packet_match(const struct sk_buff *skb, | |||
| 111 | const char *outdev, | 111 | const char *outdev, |
| 112 | const struct ip6t_ip6 *ip6info, | 112 | const struct ip6t_ip6 *ip6info, |
| 113 | unsigned int *protoff, | 113 | unsigned int *protoff, |
| 114 | int *fragoff) | 114 | int *fragoff, int *hotdrop) |
| 115 | { | 115 | { |
| 116 | size_t i; | 116 | size_t i; |
| 117 | unsigned long ret; | 117 | unsigned long ret; |
| @@ -169,9 +169,11 @@ ip6_packet_match(const struct sk_buff *skb, | |||
| 169 | unsigned short _frag_off; | 169 | unsigned short _frag_off; |
| 170 | 170 | ||
| 171 | protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off); | 171 | protohdr = ipv6_find_hdr(skb, protoff, -1, &_frag_off); |
| 172 | if (protohdr < 0) | 172 | if (protohdr < 0) { |
| 173 | if (_frag_off == 0) | ||
| 174 | *hotdrop = 1; | ||
| 173 | return 0; | 175 | return 0; |
| 174 | 176 | } | |
| 175 | *fragoff = _frag_off; | 177 | *fragoff = _frag_off; |
| 176 | 178 | ||
| 177 | dprintf("Packet protocol %hi ?= %s%hi.\n", | 179 | dprintf("Packet protocol %hi ?= %s%hi.\n", |
| @@ -290,7 +292,7 @@ ip6t_do_table(struct sk_buff **pskb, | |||
| 290 | IP_NF_ASSERT(e); | 292 | IP_NF_ASSERT(e); |
| 291 | IP_NF_ASSERT(back); | 293 | IP_NF_ASSERT(back); |
| 292 | if (ip6_packet_match(*pskb, indev, outdev, &e->ipv6, | 294 | if (ip6_packet_match(*pskb, indev, outdev, &e->ipv6, |
| 293 | &protoff, &offset)) { | 295 | &protoff, &offset, &hotdrop)) { |
| 294 | struct ip6t_entry_target *t; | 296 | struct ip6t_entry_target *t; |
| 295 | 297 | ||
| 296 | if (IP6T_MATCH_ITERATE(e, do_match, | 298 | if (IP6T_MATCH_ITERATE(e, do_match, |
| @@ -584,12 +586,19 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size, | |||
| 584 | return -EINVAL; | 586 | return -EINVAL; |
| 585 | } | 587 | } |
| 586 | 588 | ||
| 589 | if (e->target_offset + sizeof(struct ip6t_entry_target) > | ||
| 590 | e->next_offset) | ||
| 591 | return -EINVAL; | ||
| 592 | |||
| 587 | j = 0; | 593 | j = 0; |
| 588 | ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, e->comefrom, &j); | 594 | ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, e->comefrom, &j); |
| 589 | if (ret != 0) | 595 | if (ret != 0) |
| 590 | goto cleanup_matches; | 596 | goto cleanup_matches; |
| 591 | 597 | ||
| 592 | t = ip6t_get_target(e); | 598 | t = ip6t_get_target(e); |
| 599 | ret = -EINVAL; | ||
| 600 | if (e->target_offset + t->u.target_size > e->next_offset) | ||
| 601 | goto cleanup_matches; | ||
| 593 | target = try_then_request_module(xt_find_target(AF_INET6, | 602 | target = try_then_request_module(xt_find_target(AF_INET6, |
| 594 | t->u.user.name, | 603 | t->u.user.name, |
| 595 | t->u.user.revision), | 604 | t->u.user.revision), |
| @@ -749,19 +758,17 @@ translate_table(const char *name, | |||
| 749 | } | 758 | } |
| 750 | } | 759 | } |
| 751 | 760 | ||
| 752 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) | ||
| 753 | return -ELOOP; | ||
| 754 | |||
| 755 | /* Finally, each sanity check must pass */ | 761 | /* Finally, each sanity check must pass */ |
| 756 | i = 0; | 762 | i = 0; |
| 757 | ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, | 763 | ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, |
| 758 | check_entry, name, size, &i); | 764 | check_entry, name, size, &i); |
| 759 | 765 | ||
| 760 | if (ret != 0) { | 766 | if (ret != 0) |
| 761 | IP6T_ENTRY_ITERATE(entry0, newinfo->size, | 767 | goto cleanup; |
| 762 | cleanup_entry, &i); | 768 | |
| 763 | return ret; | 769 | ret = -ELOOP; |
| 764 | } | 770 | if (!mark_source_chains(newinfo, valid_hooks, entry0)) |
| 771 | goto cleanup; | ||
| 765 | 772 | ||
| 766 | /* And one copy for every other CPU */ | 773 | /* And one copy for every other CPU */ |
| 767 | for_each_possible_cpu(i) { | 774 | for_each_possible_cpu(i) { |
| @@ -769,6 +776,9 @@ translate_table(const char *name, | |||
| 769 | memcpy(newinfo->entries[i], entry0, newinfo->size); | 776 | memcpy(newinfo->entries[i], entry0, newinfo->size); |
| 770 | } | 777 | } |
| 771 | 778 | ||
| 779 | return 0; | ||
| 780 | cleanup: | ||
| 781 | IP6T_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i); | ||
| 772 | return ret; | 782 | return ret; |
| 773 | } | 783 | } |
| 774 | 784 | ||
| @@ -1438,6 +1448,9 @@ static void __exit ip6_tables_fini(void) | |||
| 1438 | * If target header is found, its offset is set in *offset and return protocol | 1448 | * If target header is found, its offset is set in *offset and return protocol |
| 1439 | * number. Otherwise, return -1. | 1449 | * number. Otherwise, return -1. |
| 1440 | * | 1450 | * |
| 1451 | * If the first fragment doesn't contain the final protocol header or | ||
| 1452 | * NEXTHDR_NONE it is considered invalid. | ||
| 1453 | * | ||
| 1441 | * Note that non-1st fragment is special case that "the protocol number | 1454 | * Note that non-1st fragment is special case that "the protocol number |
| 1442 | * of last header" is "next header" field in Fragment header. In this case, | 1455 | * of last header" is "next header" field in Fragment header. In this case, |
| 1443 | * *offset is meaningless and fragment offset is stored in *fragoff if fragoff | 1456 | * *offset is meaningless and fragment offset is stored in *fragoff if fragoff |
| @@ -1461,12 +1474,12 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, | |||
| 1461 | if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) { | 1474 | if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) { |
| 1462 | if (target < 0) | 1475 | if (target < 0) |
| 1463 | break; | 1476 | break; |
| 1464 | return -1; | 1477 | return -ENOENT; |
| 1465 | } | 1478 | } |
| 1466 | 1479 | ||
| 1467 | hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr); | 1480 | hp = skb_header_pointer(skb, start, sizeof(_hdr), &_hdr); |
| 1468 | if (hp == NULL) | 1481 | if (hp == NULL) |
| 1469 | return -1; | 1482 | return -EBADMSG; |
| 1470 | if (nexthdr == NEXTHDR_FRAGMENT) { | 1483 | if (nexthdr == NEXTHDR_FRAGMENT) { |
| 1471 | unsigned short _frag_off, *fp; | 1484 | unsigned short _frag_off, *fp; |
| 1472 | fp = skb_header_pointer(skb, | 1485 | fp = skb_header_pointer(skb, |
| @@ -1475,18 +1488,18 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, | |||
| 1475 | sizeof(_frag_off), | 1488 | sizeof(_frag_off), |
| 1476 | &_frag_off); | 1489 | &_frag_off); |
| 1477 | if (fp == NULL) | 1490 | if (fp == NULL) |
| 1478 | return -1; | 1491 | return -EBADMSG; |
| 1479 | 1492 | ||
| 1480 | _frag_off = ntohs(*fp) & ~0x7; | 1493 | _frag_off = ntohs(*fp) & ~0x7; |
| 1481 | if (_frag_off) { | 1494 | if (_frag_off) { |
| 1482 | if (target < 0 && | 1495 | if (target < 0 && |
| 1483 | ((!ipv6_ext_hdr(hp->nexthdr)) || | 1496 | ((!ipv6_ext_hdr(hp->nexthdr)) || |
| 1484 | nexthdr == NEXTHDR_NONE)) { | 1497 | hp->nexthdr == NEXTHDR_NONE)) { |
| 1485 | if (fragoff) | 1498 | if (fragoff) |
| 1486 | *fragoff = _frag_off; | 1499 | *fragoff = _frag_off; |
| 1487 | return hp->nexthdr; | 1500 | return hp->nexthdr; |
| 1488 | } | 1501 | } |
| 1489 | return -1; | 1502 | return -ENOENT; |
| 1490 | } | 1503 | } |
| 1491 | hdrlen = 8; | 1504 | hdrlen = 8; |
| 1492 | } else if (nexthdr == NEXTHDR_AUTH) | 1505 | } else if (nexthdr == NEXTHDR_AUTH) |
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c index ec1b1608156c..46486645eb75 100644 --- a/net/ipv6/netfilter/ip6t_ah.c +++ b/net/ipv6/netfilter/ip6t_ah.c | |||
| @@ -54,9 +54,14 @@ match(const struct sk_buff *skb, | |||
| 54 | const struct ip6t_ah *ahinfo = matchinfo; | 54 | const struct ip6t_ah *ahinfo = matchinfo; |
| 55 | unsigned int ptr; | 55 | unsigned int ptr; |
| 56 | unsigned int hdrlen = 0; | 56 | unsigned int hdrlen = 0; |
| 57 | int err; | ||
| 57 | 58 | ||
| 58 | if (ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL) < 0) | 59 | err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL); |
| 60 | if (err < 0) { | ||
| 61 | if (err != -ENOENT) | ||
| 62 | *hotdrop = 1; | ||
| 59 | return 0; | 63 | return 0; |
| 64 | } | ||
| 60 | 65 | ||
| 61 | ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah); | 66 | ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah); |
| 62 | if (ah == NULL) { | 67 | if (ah == NULL) { |
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c index 78d9c8b9e28a..cd22eaaccdca 100644 --- a/net/ipv6/netfilter/ip6t_frag.c +++ b/net/ipv6/netfilter/ip6t_frag.c | |||
| @@ -52,9 +52,14 @@ match(const struct sk_buff *skb, | |||
| 52 | struct frag_hdr _frag, *fh; | 52 | struct frag_hdr _frag, *fh; |
| 53 | const struct ip6t_frag *fraginfo = matchinfo; | 53 | const struct ip6t_frag *fraginfo = matchinfo; |
| 54 | unsigned int ptr; | 54 | unsigned int ptr; |
| 55 | int err; | ||
| 55 | 56 | ||
| 56 | if (ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL) < 0) | 57 | err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL); |
| 58 | if (err < 0) { | ||
| 59 | if (err != -ENOENT) | ||
| 60 | *hotdrop = 1; | ||
| 57 | return 0; | 61 | return 0; |
| 62 | } | ||
| 58 | 63 | ||
| 59 | fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag); | 64 | fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag); |
| 60 | if (fh == NULL) { | 65 | if (fh == NULL) { |
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c index d32a205e3af2..3f25babe0440 100644 --- a/net/ipv6/netfilter/ip6t_hbh.c +++ b/net/ipv6/netfilter/ip6t_hbh.c | |||
| @@ -65,9 +65,14 @@ match(const struct sk_buff *skb, | |||
| 65 | u8 _opttype, *tp = NULL; | 65 | u8 _opttype, *tp = NULL; |
| 66 | u8 _optlen, *lp = NULL; | 66 | u8 _optlen, *lp = NULL; |
| 67 | unsigned int optlen; | 67 | unsigned int optlen; |
| 68 | int err; | ||
| 68 | 69 | ||
| 69 | if (ipv6_find_hdr(skb, &ptr, match->data, NULL) < 0) | 70 | err = ipv6_find_hdr(skb, &ptr, match->data, NULL); |
| 71 | if (err < 0) { | ||
| 72 | if (err != -ENOENT) | ||
| 73 | *hotdrop = 1; | ||
| 70 | return 0; | 74 | return 0; |
| 75 | } | ||
| 71 | 76 | ||
| 72 | oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh); | 77 | oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh); |
| 73 | if (oh == NULL) { | 78 | if (oh == NULL) { |
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c index bcb2e168a5bc..54d7d14134fd 100644 --- a/net/ipv6/netfilter/ip6t_rt.c +++ b/net/ipv6/netfilter/ip6t_rt.c | |||
| @@ -58,9 +58,14 @@ match(const struct sk_buff *skb, | |||
| 58 | unsigned int hdrlen = 0; | 58 | unsigned int hdrlen = 0; |
| 59 | unsigned int ret = 0; | 59 | unsigned int ret = 0; |
| 60 | struct in6_addr *ap, _addr; | 60 | struct in6_addr *ap, _addr; |
| 61 | int err; | ||
| 61 | 62 | ||
| 62 | if (ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL) < 0) | 63 | err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL); |
| 64 | if (err < 0) { | ||
| 65 | if (err != -ENOENT) | ||
| 66 | *hotdrop = 1; | ||
| 63 | return 0; | 67 | return 0; |
| 68 | } | ||
| 64 | 69 | ||
| 65 | rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route); | 70 | rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route); |
| 66 | if (rh == NULL) { | 71 | if (rh == NULL) { |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index d09329ca3267..d6dedc4aec77 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
| @@ -604,7 +604,7 @@ error: | |||
| 604 | return err; | 604 | return err; |
| 605 | } | 605 | } |
| 606 | 606 | ||
| 607 | static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | 607 | static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) |
| 608 | { | 608 | { |
| 609 | struct iovec *iov; | 609 | struct iovec *iov; |
| 610 | u8 __user *type = NULL; | 610 | u8 __user *type = NULL; |
| @@ -616,7 +616,7 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
| 616 | int i; | 616 | int i; |
| 617 | 617 | ||
| 618 | if (!msg->msg_iov) | 618 | if (!msg->msg_iov) |
| 619 | return; | 619 | return 0; |
| 620 | 620 | ||
| 621 | for (i = 0; i < msg->msg_iovlen; i++) { | 621 | for (i = 0; i < msg->msg_iovlen; i++) { |
| 622 | iov = &msg->msg_iov[i]; | 622 | iov = &msg->msg_iov[i]; |
| @@ -638,8 +638,9 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
| 638 | code = iov->iov_base; | 638 | code = iov->iov_base; |
| 639 | 639 | ||
| 640 | if (type && code) { | 640 | if (type && code) { |
| 641 | get_user(fl->fl_icmp_type, type); | 641 | if (get_user(fl->fl_icmp_type, type) || |
| 642 | get_user(fl->fl_icmp_code, code); | 642 | get_user(fl->fl_icmp_code, code)) |
| 643 | return -EFAULT; | ||
| 643 | probed = 1; | 644 | probed = 1; |
| 644 | } | 645 | } |
| 645 | break; | 646 | break; |
| @@ -650,7 +651,8 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
| 650 | /* check if type field is readable or not. */ | 651 | /* check if type field is readable or not. */ |
| 651 | if (iov->iov_len > 2 - len) { | 652 | if (iov->iov_len > 2 - len) { |
| 652 | u8 __user *p = iov->iov_base; | 653 | u8 __user *p = iov->iov_base; |
| 653 | get_user(fl->fl_mh_type, &p[2 - len]); | 654 | if (get_user(fl->fl_mh_type, &p[2 - len])) |
| 655 | return -EFAULT; | ||
| 654 | probed = 1; | 656 | probed = 1; |
| 655 | } else | 657 | } else |
| 656 | len += iov->iov_len; | 658 | len += iov->iov_len; |
| @@ -664,6 +666,7 @@ static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
| 664 | if (probed) | 666 | if (probed) |
| 665 | break; | 667 | break; |
| 666 | } | 668 | } |
| 669 | return 0; | ||
| 667 | } | 670 | } |
| 668 | 671 | ||
| 669 | static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | 672 | static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, |
| @@ -787,7 +790,9 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
| 787 | opt = ipv6_fixup_options(&opt_space, opt); | 790 | opt = ipv6_fixup_options(&opt_space, opt); |
| 788 | 791 | ||
| 789 | fl.proto = proto; | 792 | fl.proto = proto; |
| 790 | rawv6_probe_proto_opt(&fl, msg); | 793 | err = rawv6_probe_proto_opt(&fl, msg); |
| 794 | if (err) | ||
| 795 | goto out; | ||
| 791 | 796 | ||
| 792 | ipv6_addr_copy(&fl.fl6_dst, daddr); | 797 | ipv6_addr_copy(&fl.fl6_dst, daddr); |
| 793 | if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) | 798 | if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index b481a4d780c2..be699f85b2c7 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
| @@ -854,3 +854,4 @@ int __init sit_init(void) | |||
| 854 | module_init(sit_init); | 854 | module_init(sit_init); |
| 855 | module_exit(sit_cleanup); | 855 | module_exit(sit_cleanup); |
| 856 | MODULE_LICENSE("GPL"); | 856 | MODULE_LICENSE("GPL"); |
| 857 | MODULE_ALIAS("sit0"); | ||
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index 7af227bb1551..7931e4f898d4 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c | |||
| @@ -135,7 +135,7 @@ u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr) | |||
| 135 | x6spi = __xfrm6_tunnel_spi_lookup(saddr); | 135 | x6spi = __xfrm6_tunnel_spi_lookup(saddr); |
| 136 | spi = x6spi ? x6spi->spi : 0; | 136 | spi = x6spi ? x6spi->spi : 0; |
| 137 | read_unlock_bh(&xfrm6_tunnel_spi_lock); | 137 | read_unlock_bh(&xfrm6_tunnel_spi_lock); |
| 138 | return spi; | 138 | return htonl(spi); |
| 139 | } | 139 | } |
| 140 | 140 | ||
| 141 | EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup); | 141 | EXPORT_SYMBOL(xfrm6_tunnel_spi_lookup); |
| @@ -210,7 +210,7 @@ u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) | |||
| 210 | spi = __xfrm6_tunnel_alloc_spi(saddr); | 210 | spi = __xfrm6_tunnel_alloc_spi(saddr); |
| 211 | write_unlock_bh(&xfrm6_tunnel_spi_lock); | 211 | write_unlock_bh(&xfrm6_tunnel_spi_lock); |
| 212 | 212 | ||
| 213 | return spi; | 213 | return htonl(spi); |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | EXPORT_SYMBOL(xfrm6_tunnel_alloc_spi); | 216 | EXPORT_SYMBOL(xfrm6_tunnel_alloc_spi); |
