diff options
Diffstat (limited to 'net')
35 files changed, 321 insertions, 273 deletions
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index add69d0fd99d..fbbf1fa00940 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c | |||
@@ -5,7 +5,7 @@ | |||
5 | #include <linux/export.h> | 5 | #include <linux/export.h> |
6 | #include "vlan.h" | 6 | #include "vlan.h" |
7 | 7 | ||
8 | bool vlan_do_receive(struct sk_buff **skbp, bool last_handler) | 8 | bool vlan_do_receive(struct sk_buff **skbp) |
9 | { | 9 | { |
10 | struct sk_buff *skb = *skbp; | 10 | struct sk_buff *skb = *skbp; |
11 | u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK; | 11 | u16 vlan_id = skb->vlan_tci & VLAN_VID_MASK; |
@@ -13,14 +13,8 @@ bool vlan_do_receive(struct sk_buff **skbp, bool last_handler) | |||
13 | struct vlan_pcpu_stats *rx_stats; | 13 | struct vlan_pcpu_stats *rx_stats; |
14 | 14 | ||
15 | vlan_dev = vlan_find_dev(skb->dev, vlan_id); | 15 | vlan_dev = vlan_find_dev(skb->dev, vlan_id); |
16 | if (!vlan_dev) { | 16 | if (!vlan_dev) |
17 | /* Only the last call to vlan_do_receive() should change | ||
18 | * pkt_type to PACKET_OTHERHOST | ||
19 | */ | ||
20 | if (vlan_id && last_handler) | ||
21 | skb->pkt_type = PACKET_OTHERHOST; | ||
22 | return false; | 17 | return false; |
23 | } | ||
24 | 18 | ||
25 | skb = *skbp = skb_share_check(skb, GFP_ATOMIC); | 19 | skb = *skbp = skb_share_check(skb, GFP_ATOMIC); |
26 | if (unlikely(!skb)) | 20 | if (unlikely(!skb)) |
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 505f0ce3f10b..15656b8573f3 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c | |||
@@ -793,30 +793,28 @@ static int p9_fd_open(struct p9_client *client, int rfd, int wfd) | |||
793 | static int p9_socket_open(struct p9_client *client, struct socket *csocket) | 793 | static int p9_socket_open(struct p9_client *client, struct socket *csocket) |
794 | { | 794 | { |
795 | struct p9_trans_fd *p; | 795 | struct p9_trans_fd *p; |
796 | int ret, fd; | 796 | struct file *file; |
797 | int ret; | ||
797 | 798 | ||
798 | p = kmalloc(sizeof(struct p9_trans_fd), GFP_KERNEL); | 799 | p = kmalloc(sizeof(struct p9_trans_fd), GFP_KERNEL); |
799 | if (!p) | 800 | if (!p) |
800 | return -ENOMEM; | 801 | return -ENOMEM; |
801 | 802 | ||
802 | csocket->sk->sk_allocation = GFP_NOIO; | 803 | csocket->sk->sk_allocation = GFP_NOIO; |
803 | fd = sock_map_fd(csocket, 0); | 804 | file = sock_alloc_file(csocket, 0, NULL); |
804 | if (fd < 0) { | 805 | if (IS_ERR(file)) { |
805 | pr_err("%s (%d): failed to map fd\n", | 806 | pr_err("%s (%d): failed to map fd\n", |
806 | __func__, task_pid_nr(current)); | 807 | __func__, task_pid_nr(current)); |
807 | sock_release(csocket); | 808 | sock_release(csocket); |
808 | kfree(p); | 809 | kfree(p); |
809 | return fd; | 810 | return PTR_ERR(file); |
810 | } | 811 | } |
811 | 812 | ||
812 | get_file(csocket->file); | 813 | get_file(file); |
813 | get_file(csocket->file); | 814 | p->wr = p->rd = file; |
814 | p->wr = p->rd = csocket->file; | ||
815 | client->trans = p; | 815 | client->trans = p; |
816 | client->status = Connected; | 816 | client->status = Connected; |
817 | 817 | ||
818 | sys_close(fd); /* still racy */ | ||
819 | |||
820 | p->rd->f_flags |= O_NONBLOCK; | 818 | p->rd->f_flags |= O_NONBLOCK; |
821 | 819 | ||
822 | p->conn = p9_conn_create(client); | 820 | p->conn = p9_conn_create(client); |
diff --git a/net/can/af_can.c b/net/can/af_can.c index 821022a7214f..ddac1ee2ed20 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c | |||
@@ -63,7 +63,7 @@ | |||
63 | 63 | ||
64 | #include "af_can.h" | 64 | #include "af_can.h" |
65 | 65 | ||
66 | static __initdata const char banner[] = KERN_INFO | 66 | static __initconst const char banner[] = KERN_INFO |
67 | "can: controller area network core (" CAN_VERSION_STRING ")\n"; | 67 | "can: controller area network core (" CAN_VERSION_STRING ")\n"; |
68 | 68 | ||
69 | MODULE_DESCRIPTION("Controller Area Network PF_CAN core"); | 69 | MODULE_DESCRIPTION("Controller Area Network PF_CAN core"); |
diff --git a/net/can/bcm.c b/net/can/bcm.c index 151b7730c12c..6f747582718e 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
@@ -77,7 +77,7 @@ | |||
77 | (CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG)) | 77 | (CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG)) |
78 | 78 | ||
79 | #define CAN_BCM_VERSION CAN_VERSION | 79 | #define CAN_BCM_VERSION CAN_VERSION |
80 | static __initdata const char banner[] = KERN_INFO | 80 | static __initconst const char banner[] = KERN_INFO |
81 | "can: broadcast manager protocol (rev " CAN_BCM_VERSION " t)\n"; | 81 | "can: broadcast manager protocol (rev " CAN_BCM_VERSION " t)\n"; |
82 | 82 | ||
83 | MODULE_DESCRIPTION("PF_CAN broadcast manager protocol"); | 83 | MODULE_DESCRIPTION("PF_CAN broadcast manager protocol"); |
diff --git a/net/can/gw.c b/net/can/gw.c index 127879c55fb6..1f5c9785a262 100644 --- a/net/can/gw.c +++ b/net/can/gw.c | |||
@@ -58,7 +58,7 @@ | |||
58 | #include <net/sock.h> | 58 | #include <net/sock.h> |
59 | 59 | ||
60 | #define CAN_GW_VERSION "20101209" | 60 | #define CAN_GW_VERSION "20101209" |
61 | static __initdata const char banner[] = | 61 | static __initconst const char banner[] = |
62 | KERN_INFO "can: netlink gateway (rev " CAN_GW_VERSION ")\n"; | 62 | KERN_INFO "can: netlink gateway (rev " CAN_GW_VERSION ")\n"; |
63 | 63 | ||
64 | MODULE_DESCRIPTION("PF_CAN netlink gateway"); | 64 | MODULE_DESCRIPTION("PF_CAN netlink gateway"); |
diff --git a/net/can/raw.c b/net/can/raw.c index 3e9c89356a93..5b0e3e330d97 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
@@ -55,7 +55,7 @@ | |||
55 | #include <net/net_namespace.h> | 55 | #include <net/net_namespace.h> |
56 | 56 | ||
57 | #define CAN_RAW_VERSION CAN_VERSION | 57 | #define CAN_RAW_VERSION CAN_VERSION |
58 | static __initdata const char banner[] = | 58 | static __initconst const char banner[] = |
59 | KERN_INFO "can: raw protocol (rev " CAN_RAW_VERSION ")\n"; | 59 | KERN_INFO "can: raw protocol (rev " CAN_RAW_VERSION ")\n"; |
60 | 60 | ||
61 | MODULE_DESCRIPTION("PF_CAN raw protocol"); | 61 | MODULE_DESCRIPTION("PF_CAN raw protocol"); |
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c index 900ea0f043fc..812eb3b46c1f 100644 --- a/net/ceph/mon_client.c +++ b/net/ceph/mon_client.c | |||
@@ -637,7 +637,7 @@ bad: | |||
637 | /* | 637 | /* |
638 | * Do a synchronous pool op. | 638 | * Do a synchronous pool op. |
639 | */ | 639 | */ |
640 | int ceph_monc_do_poolop(struct ceph_mon_client *monc, u32 op, | 640 | static int do_poolop(struct ceph_mon_client *monc, u32 op, |
641 | u32 pool, u64 snapid, | 641 | u32 pool, u64 snapid, |
642 | char *buf, int len) | 642 | char *buf, int len) |
643 | { | 643 | { |
@@ -687,7 +687,7 @@ out: | |||
687 | int ceph_monc_create_snapid(struct ceph_mon_client *monc, | 687 | int ceph_monc_create_snapid(struct ceph_mon_client *monc, |
688 | u32 pool, u64 *snapid) | 688 | u32 pool, u64 *snapid) |
689 | { | 689 | { |
690 | return ceph_monc_do_poolop(monc, POOL_OP_CREATE_UNMANAGED_SNAP, | 690 | return do_poolop(monc, POOL_OP_CREATE_UNMANAGED_SNAP, |
691 | pool, 0, (char *)snapid, sizeof(*snapid)); | 691 | pool, 0, (char *)snapid, sizeof(*snapid)); |
692 | 692 | ||
693 | } | 693 | } |
@@ -696,7 +696,7 @@ EXPORT_SYMBOL(ceph_monc_create_snapid); | |||
696 | int ceph_monc_delete_snapid(struct ceph_mon_client *monc, | 696 | int ceph_monc_delete_snapid(struct ceph_mon_client *monc, |
697 | u32 pool, u64 snapid) | 697 | u32 pool, u64 snapid) |
698 | { | 698 | { |
699 | return ceph_monc_do_poolop(monc, POOL_OP_CREATE_UNMANAGED_SNAP, | 699 | return do_poolop(monc, POOL_OP_CREATE_UNMANAGED_SNAP, |
700 | pool, snapid, 0, 0); | 700 | pool, snapid, 0, 0); |
701 | 701 | ||
702 | } | 702 | } |
@@ -769,7 +769,6 @@ static int build_initial_monmap(struct ceph_mon_client *monc) | |||
769 | monc->monmap->mon_inst[i].name.num = cpu_to_le64(i); | 769 | monc->monmap->mon_inst[i].name.num = cpu_to_le64(i); |
770 | } | 770 | } |
771 | monc->monmap->num_mon = num_mon; | 771 | monc->monmap->num_mon = num_mon; |
772 | monc->have_fsid = false; | ||
773 | return 0; | 772 | return 0; |
774 | } | 773 | } |
775 | 774 | ||
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 42119c05e82c..c1d756cc7448 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c | |||
@@ -52,7 +52,7 @@ static int op_has_extent(int op) | |||
52 | op == CEPH_OSD_OP_WRITE); | 52 | op == CEPH_OSD_OP_WRITE); |
53 | } | 53 | } |
54 | 54 | ||
55 | void ceph_calc_raw_layout(struct ceph_osd_client *osdc, | 55 | int ceph_calc_raw_layout(struct ceph_osd_client *osdc, |
56 | struct ceph_file_layout *layout, | 56 | struct ceph_file_layout *layout, |
57 | u64 snapid, | 57 | u64 snapid, |
58 | u64 off, u64 *plen, u64 *bno, | 58 | u64 off, u64 *plen, u64 *bno, |
@@ -62,12 +62,15 @@ void ceph_calc_raw_layout(struct ceph_osd_client *osdc, | |||
62 | struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base; | 62 | struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base; |
63 | u64 orig_len = *plen; | 63 | u64 orig_len = *plen; |
64 | u64 objoff, objlen; /* extent in object */ | 64 | u64 objoff, objlen; /* extent in object */ |
65 | int r; | ||
65 | 66 | ||
66 | reqhead->snapid = cpu_to_le64(snapid); | 67 | reqhead->snapid = cpu_to_le64(snapid); |
67 | 68 | ||
68 | /* object extent? */ | 69 | /* object extent? */ |
69 | ceph_calc_file_object_mapping(layout, off, plen, bno, | 70 | r = ceph_calc_file_object_mapping(layout, off, plen, bno, |
70 | &objoff, &objlen); | 71 | &objoff, &objlen); |
72 | if (r < 0) | ||
73 | return r; | ||
71 | if (*plen < orig_len) | 74 | if (*plen < orig_len) |
72 | dout(" skipping last %llu, final file extent %llu~%llu\n", | 75 | dout(" skipping last %llu, final file extent %llu~%llu\n", |
73 | orig_len - *plen, off, *plen); | 76 | orig_len - *plen, off, *plen); |
@@ -83,7 +86,7 @@ void ceph_calc_raw_layout(struct ceph_osd_client *osdc, | |||
83 | 86 | ||
84 | dout("calc_layout bno=%llx %llu~%llu (%d pages)\n", | 87 | dout("calc_layout bno=%llx %llu~%llu (%d pages)\n", |
85 | *bno, objoff, objlen, req->r_num_pages); | 88 | *bno, objoff, objlen, req->r_num_pages); |
86 | 89 | return 0; | |
87 | } | 90 | } |
88 | EXPORT_SYMBOL(ceph_calc_raw_layout); | 91 | EXPORT_SYMBOL(ceph_calc_raw_layout); |
89 | 92 | ||
@@ -112,20 +115,25 @@ EXPORT_SYMBOL(ceph_calc_raw_layout); | |||
112 | * | 115 | * |
113 | * fill osd op in request message. | 116 | * fill osd op in request message. |
114 | */ | 117 | */ |
115 | static void calc_layout(struct ceph_osd_client *osdc, | 118 | static int calc_layout(struct ceph_osd_client *osdc, |
116 | struct ceph_vino vino, | 119 | struct ceph_vino vino, |
117 | struct ceph_file_layout *layout, | 120 | struct ceph_file_layout *layout, |
118 | u64 off, u64 *plen, | 121 | u64 off, u64 *plen, |
119 | struct ceph_osd_request *req, | 122 | struct ceph_osd_request *req, |
120 | struct ceph_osd_req_op *op) | 123 | struct ceph_osd_req_op *op) |
121 | { | 124 | { |
122 | u64 bno; | 125 | u64 bno; |
126 | int r; | ||
123 | 127 | ||
124 | ceph_calc_raw_layout(osdc, layout, vino.snap, off, | 128 | r = ceph_calc_raw_layout(osdc, layout, vino.snap, off, |
125 | plen, &bno, req, op); | 129 | plen, &bno, req, op); |
130 | if (r < 0) | ||
131 | return r; | ||
126 | 132 | ||
127 | snprintf(req->r_oid, sizeof(req->r_oid), "%llx.%08llx", vino.ino, bno); | 133 | snprintf(req->r_oid, sizeof(req->r_oid), "%llx.%08llx", vino.ino, bno); |
128 | req->r_oid_len = strlen(req->r_oid); | 134 | req->r_oid_len = strlen(req->r_oid); |
135 | |||
136 | return r; | ||
129 | } | 137 | } |
130 | 138 | ||
131 | /* | 139 | /* |
@@ -213,7 +221,6 @@ struct ceph_osd_request *ceph_osdc_alloc_request(struct ceph_osd_client *osdc, | |||
213 | kref_init(&req->r_kref); | 221 | kref_init(&req->r_kref); |
214 | init_completion(&req->r_completion); | 222 | init_completion(&req->r_completion); |
215 | init_completion(&req->r_safe_completion); | 223 | init_completion(&req->r_safe_completion); |
216 | rb_init_node(&req->r_node); | ||
217 | INIT_LIST_HEAD(&req->r_unsafe_item); | 224 | INIT_LIST_HEAD(&req->r_unsafe_item); |
218 | INIT_LIST_HEAD(&req->r_linger_item); | 225 | INIT_LIST_HEAD(&req->r_linger_item); |
219 | INIT_LIST_HEAD(&req->r_linger_osd); | 226 | INIT_LIST_HEAD(&req->r_linger_osd); |
@@ -456,6 +463,7 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, | |||
456 | { | 463 | { |
457 | struct ceph_osd_req_op ops[3]; | 464 | struct ceph_osd_req_op ops[3]; |
458 | struct ceph_osd_request *req; | 465 | struct ceph_osd_request *req; |
466 | int r; | ||
459 | 467 | ||
460 | ops[0].op = opcode; | 468 | ops[0].op = opcode; |
461 | ops[0].extent.truncate_seq = truncate_seq; | 469 | ops[0].extent.truncate_seq = truncate_seq; |
@@ -474,10 +482,12 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, | |||
474 | use_mempool, | 482 | use_mempool, |
475 | GFP_NOFS, NULL, NULL); | 483 | GFP_NOFS, NULL, NULL); |
476 | if (!req) | 484 | if (!req) |
477 | return NULL; | 485 | return ERR_PTR(-ENOMEM); |
478 | 486 | ||
479 | /* calculate max write size */ | 487 | /* calculate max write size */ |
480 | calc_layout(osdc, vino, layout, off, plen, req, ops); | 488 | r = calc_layout(osdc, vino, layout, off, plen, req, ops); |
489 | if (r < 0) | ||
490 | return ERR_PTR(r); | ||
481 | req->r_file_layout = *layout; /* keep a copy */ | 491 | req->r_file_layout = *layout; /* keep a copy */ |
482 | 492 | ||
483 | /* in case it differs from natural (file) alignment that | 493 | /* in case it differs from natural (file) alignment that |
@@ -1920,8 +1930,8 @@ int ceph_osdc_readpages(struct ceph_osd_client *osdc, | |||
1920 | CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ, | 1930 | CEPH_OSD_OP_READ, CEPH_OSD_FLAG_READ, |
1921 | NULL, 0, truncate_seq, truncate_size, NULL, | 1931 | NULL, 0, truncate_seq, truncate_size, NULL, |
1922 | false, 1, page_align); | 1932 | false, 1, page_align); |
1923 | if (!req) | 1933 | if (IS_ERR(req)) |
1924 | return -ENOMEM; | 1934 | return PTR_ERR(req); |
1925 | 1935 | ||
1926 | /* it may be a short read due to an object boundary */ | 1936 | /* it may be a short read due to an object boundary */ |
1927 | req->r_pages = pages; | 1937 | req->r_pages = pages; |
@@ -1963,8 +1973,8 @@ int ceph_osdc_writepages(struct ceph_osd_client *osdc, struct ceph_vino vino, | |||
1963 | snapc, do_sync, | 1973 | snapc, do_sync, |
1964 | truncate_seq, truncate_size, mtime, | 1974 | truncate_seq, truncate_size, mtime, |
1965 | nofail, 1, page_align); | 1975 | nofail, 1, page_align); |
1966 | if (!req) | 1976 | if (IS_ERR(req)) |
1967 | return -ENOMEM; | 1977 | return PTR_ERR(req); |
1968 | 1978 | ||
1969 | /* it may be a short write due to an object boundary */ | 1979 | /* it may be a short write due to an object boundary */ |
1970 | req->r_pages = pages; | 1980 | req->r_pages = pages; |
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index 3124b71a8883..5433fb0eb3c6 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c | |||
@@ -984,7 +984,7 @@ bad: | |||
984 | * for now, we write only a single su, until we can | 984 | * for now, we write only a single su, until we can |
985 | * pass a stride back to the caller. | 985 | * pass a stride back to the caller. |
986 | */ | 986 | */ |
987 | void ceph_calc_file_object_mapping(struct ceph_file_layout *layout, | 987 | int ceph_calc_file_object_mapping(struct ceph_file_layout *layout, |
988 | u64 off, u64 *plen, | 988 | u64 off, u64 *plen, |
989 | u64 *ono, | 989 | u64 *ono, |
990 | u64 *oxoff, u64 *oxlen) | 990 | u64 *oxoff, u64 *oxlen) |
@@ -998,11 +998,17 @@ void ceph_calc_file_object_mapping(struct ceph_file_layout *layout, | |||
998 | 998 | ||
999 | dout("mapping %llu~%llu osize %u fl_su %u\n", off, *plen, | 999 | dout("mapping %llu~%llu osize %u fl_su %u\n", off, *plen, |
1000 | osize, su); | 1000 | osize, su); |
1001 | if (su == 0 || sc == 0) | ||
1002 | goto invalid; | ||
1001 | su_per_object = osize / su; | 1003 | su_per_object = osize / su; |
1004 | if (su_per_object == 0) | ||
1005 | goto invalid; | ||
1002 | dout("osize %u / su %u = su_per_object %u\n", osize, su, | 1006 | dout("osize %u / su %u = su_per_object %u\n", osize, su, |
1003 | su_per_object); | 1007 | su_per_object); |
1004 | 1008 | ||
1005 | BUG_ON((su & ~PAGE_MASK) != 0); | 1009 | if ((su & ~PAGE_MASK) != 0) |
1010 | goto invalid; | ||
1011 | |||
1006 | /* bl = *off / su; */ | 1012 | /* bl = *off / su; */ |
1007 | t = off; | 1013 | t = off; |
1008 | do_div(t, su); | 1014 | do_div(t, su); |
@@ -1030,6 +1036,14 @@ void ceph_calc_file_object_mapping(struct ceph_file_layout *layout, | |||
1030 | *plen = *oxlen; | 1036 | *plen = *oxlen; |
1031 | 1037 | ||
1032 | dout(" obj extent %llu~%llu\n", *oxoff, *oxlen); | 1038 | dout(" obj extent %llu~%llu\n", *oxoff, *oxlen); |
1039 | return 0; | ||
1040 | |||
1041 | invalid: | ||
1042 | dout(" invalid layout\n"); | ||
1043 | *ono = 0; | ||
1044 | *oxoff = 0; | ||
1045 | *oxlen = 0; | ||
1046 | return -EINVAL; | ||
1033 | } | 1047 | } |
1034 | EXPORT_SYMBOL(ceph_calc_file_object_mapping); | 1048 | EXPORT_SYMBOL(ceph_calc_file_object_mapping); |
1035 | 1049 | ||
diff --git a/net/ceph/pagelist.c b/net/ceph/pagelist.c index 665cd23020ff..92866bebb65f 100644 --- a/net/ceph/pagelist.c +++ b/net/ceph/pagelist.c | |||
@@ -1,4 +1,3 @@ | |||
1 | |||
2 | #include <linux/module.h> | 1 | #include <linux/module.h> |
3 | #include <linux/gfp.h> | 2 | #include <linux/gfp.h> |
4 | #include <linux/pagemap.h> | 3 | #include <linux/pagemap.h> |
@@ -134,8 +133,8 @@ int ceph_pagelist_truncate(struct ceph_pagelist *pl, | |||
134 | ceph_pagelist_unmap_tail(pl); | 133 | ceph_pagelist_unmap_tail(pl); |
135 | while (pl->head.prev != c->page_lru) { | 134 | while (pl->head.prev != c->page_lru) { |
136 | page = list_entry(pl->head.prev, struct page, lru); | 135 | page = list_entry(pl->head.prev, struct page, lru); |
137 | list_del(&page->lru); /* remove from pagelist */ | 136 | /* move from pagelist to reserve */ |
138 | list_add_tail(&page->lru, &pl->free_list); /* add to reserve */ | 137 | list_move_tail(&page->lru, &pl->free_list); |
139 | ++pl->num_pages_free; | 138 | ++pl->num_pages_free; |
140 | } | 139 | } |
141 | pl->room = c->room; | 140 | pl->room = c->room; |
diff --git a/net/compat.c b/net/compat.c index 74ed1d7a84a2..79ae88485001 100644 --- a/net/compat.c +++ b/net/compat.c | |||
@@ -301,8 +301,7 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm) | |||
301 | break; | 301 | break; |
302 | } | 302 | } |
303 | /* Bump the usage count and install the file. */ | 303 | /* Bump the usage count and install the file. */ |
304 | get_file(fp[i]); | 304 | fd_install(new_fd, get_file(fp[i])); |
305 | fd_install(new_fd, fp[i]); | ||
306 | } | 305 | } |
307 | 306 | ||
308 | if (i > 0) { | 307 | if (i > 0) { |
diff --git a/net/core/dev.c b/net/core/dev.c index 1e0a1847c3bb..09cb3f6dc40c 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -3300,18 +3300,18 @@ ncls: | |||
3300 | && !skb_pfmemalloc_protocol(skb)) | 3300 | && !skb_pfmemalloc_protocol(skb)) |
3301 | goto drop; | 3301 | goto drop; |
3302 | 3302 | ||
3303 | rx_handler = rcu_dereference(skb->dev->rx_handler); | ||
3304 | if (vlan_tx_tag_present(skb)) { | 3303 | if (vlan_tx_tag_present(skb)) { |
3305 | if (pt_prev) { | 3304 | if (pt_prev) { |
3306 | ret = deliver_skb(skb, pt_prev, orig_dev); | 3305 | ret = deliver_skb(skb, pt_prev, orig_dev); |
3307 | pt_prev = NULL; | 3306 | pt_prev = NULL; |
3308 | } | 3307 | } |
3309 | if (vlan_do_receive(&skb, !rx_handler)) | 3308 | if (vlan_do_receive(&skb)) |
3310 | goto another_round; | 3309 | goto another_round; |
3311 | else if (unlikely(!skb)) | 3310 | else if (unlikely(!skb)) |
3312 | goto unlock; | 3311 | goto unlock; |
3313 | } | 3312 | } |
3314 | 3313 | ||
3314 | rx_handler = rcu_dereference(skb->dev->rx_handler); | ||
3315 | if (rx_handler) { | 3315 | if (rx_handler) { |
3316 | if (pt_prev) { | 3316 | if (pt_prev) { |
3317 | ret = deliver_skb(skb, pt_prev, orig_dev); | 3317 | ret = deliver_skb(skb, pt_prev, orig_dev); |
@@ -3331,6 +3331,9 @@ ncls: | |||
3331 | } | 3331 | } |
3332 | } | 3332 | } |
3333 | 3333 | ||
3334 | if (vlan_tx_nonzero_tag_present(skb)) | ||
3335 | skb->pkt_type = PACKET_OTHERHOST; | ||
3336 | |||
3334 | /* deliver only exact match when indicated */ | 3337 | /* deliver only exact match when indicated */ |
3335 | null_or_dev = deliver_exact ? skb->dev : NULL; | 3338 | null_or_dev = deliver_exact ? skb->dev : NULL; |
3336 | 3339 | ||
@@ -3471,17 +3474,31 @@ out: | |||
3471 | return netif_receive_skb(skb); | 3474 | return netif_receive_skb(skb); |
3472 | } | 3475 | } |
3473 | 3476 | ||
3474 | inline void napi_gro_flush(struct napi_struct *napi) | 3477 | /* napi->gro_list contains packets ordered by age. |
3478 | * youngest packets at the head of it. | ||
3479 | * Complete skbs in reverse order to reduce latencies. | ||
3480 | */ | ||
3481 | void napi_gro_flush(struct napi_struct *napi, bool flush_old) | ||
3475 | { | 3482 | { |
3476 | struct sk_buff *skb, *next; | 3483 | struct sk_buff *skb, *prev = NULL; |
3477 | 3484 | ||
3478 | for (skb = napi->gro_list; skb; skb = next) { | 3485 | /* scan list and build reverse chain */ |
3479 | next = skb->next; | 3486 | for (skb = napi->gro_list; skb != NULL; skb = skb->next) { |
3487 | skb->prev = prev; | ||
3488 | prev = skb; | ||
3489 | } | ||
3490 | |||
3491 | for (skb = prev; skb; skb = prev) { | ||
3480 | skb->next = NULL; | 3492 | skb->next = NULL; |
3493 | |||
3494 | if (flush_old && NAPI_GRO_CB(skb)->age == jiffies) | ||
3495 | return; | ||
3496 | |||
3497 | prev = skb->prev; | ||
3481 | napi_gro_complete(skb); | 3498 | napi_gro_complete(skb); |
3499 | napi->gro_count--; | ||
3482 | } | 3500 | } |
3483 | 3501 | ||
3484 | napi->gro_count = 0; | ||
3485 | napi->gro_list = NULL; | 3502 | napi->gro_list = NULL; |
3486 | } | 3503 | } |
3487 | EXPORT_SYMBOL(napi_gro_flush); | 3504 | EXPORT_SYMBOL(napi_gro_flush); |
@@ -3542,6 +3559,7 @@ enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | |||
3542 | 3559 | ||
3543 | napi->gro_count++; | 3560 | napi->gro_count++; |
3544 | NAPI_GRO_CB(skb)->count = 1; | 3561 | NAPI_GRO_CB(skb)->count = 1; |
3562 | NAPI_GRO_CB(skb)->age = jiffies; | ||
3545 | skb_shinfo(skb)->gso_size = skb_gro_len(skb); | 3563 | skb_shinfo(skb)->gso_size = skb_gro_len(skb); |
3546 | skb->next = napi->gro_list; | 3564 | skb->next = napi->gro_list; |
3547 | napi->gro_list = skb; | 3565 | napi->gro_list = skb; |
@@ -3631,20 +3649,22 @@ gro_result_t napi_skb_finish(gro_result_t ret, struct sk_buff *skb) | |||
3631 | } | 3649 | } |
3632 | EXPORT_SYMBOL(napi_skb_finish); | 3650 | EXPORT_SYMBOL(napi_skb_finish); |
3633 | 3651 | ||
3634 | void skb_gro_reset_offset(struct sk_buff *skb) | 3652 | static void skb_gro_reset_offset(struct sk_buff *skb) |
3635 | { | 3653 | { |
3654 | const struct skb_shared_info *pinfo = skb_shinfo(skb); | ||
3655 | const skb_frag_t *frag0 = &pinfo->frags[0]; | ||
3656 | |||
3636 | NAPI_GRO_CB(skb)->data_offset = 0; | 3657 | NAPI_GRO_CB(skb)->data_offset = 0; |
3637 | NAPI_GRO_CB(skb)->frag0 = NULL; | 3658 | NAPI_GRO_CB(skb)->frag0 = NULL; |
3638 | NAPI_GRO_CB(skb)->frag0_len = 0; | 3659 | NAPI_GRO_CB(skb)->frag0_len = 0; |
3639 | 3660 | ||
3640 | if (skb->mac_header == skb->tail && | 3661 | if (skb->mac_header == skb->tail && |
3641 | !PageHighMem(skb_frag_page(&skb_shinfo(skb)->frags[0]))) { | 3662 | pinfo->nr_frags && |
3642 | NAPI_GRO_CB(skb)->frag0 = | 3663 | !PageHighMem(skb_frag_page(frag0))) { |
3643 | skb_frag_address(&skb_shinfo(skb)->frags[0]); | 3664 | NAPI_GRO_CB(skb)->frag0 = skb_frag_address(frag0); |
3644 | NAPI_GRO_CB(skb)->frag0_len = skb_frag_size(&skb_shinfo(skb)->frags[0]); | 3665 | NAPI_GRO_CB(skb)->frag0_len = skb_frag_size(frag0); |
3645 | } | 3666 | } |
3646 | } | 3667 | } |
3647 | EXPORT_SYMBOL(skb_gro_reset_offset); | ||
3648 | 3668 | ||
3649 | gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) | 3669 | gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb) |
3650 | { | 3670 | { |
@@ -3876,7 +3896,7 @@ void napi_complete(struct napi_struct *n) | |||
3876 | if (unlikely(test_bit(NAPI_STATE_NPSVC, &n->state))) | 3896 | if (unlikely(test_bit(NAPI_STATE_NPSVC, &n->state))) |
3877 | return; | 3897 | return; |
3878 | 3898 | ||
3879 | napi_gro_flush(n); | 3899 | napi_gro_flush(n, false); |
3880 | local_irq_save(flags); | 3900 | local_irq_save(flags); |
3881 | __napi_complete(n); | 3901 | __napi_complete(n); |
3882 | local_irq_restore(flags); | 3902 | local_irq_restore(flags); |
@@ -3981,8 +4001,17 @@ static void net_rx_action(struct softirq_action *h) | |||
3981 | local_irq_enable(); | 4001 | local_irq_enable(); |
3982 | napi_complete(n); | 4002 | napi_complete(n); |
3983 | local_irq_disable(); | 4003 | local_irq_disable(); |
3984 | } else | 4004 | } else { |
4005 | if (n->gro_list) { | ||
4006 | /* flush too old packets | ||
4007 | * If HZ < 1000, flush all packets. | ||
4008 | */ | ||
4009 | local_irq_enable(); | ||
4010 | napi_gro_flush(n, HZ >= 1000); | ||
4011 | local_irq_disable(); | ||
4012 | } | ||
3985 | list_move_tail(&n->poll_list, &sd->poll_list); | 4013 | list_move_tail(&n->poll_list, &sd->poll_list); |
4014 | } | ||
3986 | } | 4015 | } |
3987 | 4016 | ||
3988 | netpoll_poll_unlock(have); | 4017 | netpoll_poll_unlock(have); |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index baca771caae2..22571488730a 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -1301,8 +1301,6 @@ int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb) | |||
1301 | if (!dst) | 1301 | if (!dst) |
1302 | goto discard; | 1302 | goto discard; |
1303 | 1303 | ||
1304 | __skb_pull(skb, skb_network_offset(skb)); | ||
1305 | |||
1306 | if (!neigh_event_send(neigh, skb)) { | 1304 | if (!neigh_event_send(neigh, skb)) { |
1307 | int err; | 1305 | int err; |
1308 | struct net_device *dev = neigh->dev; | 1306 | struct net_device *dev = neigh->dev; |
@@ -1312,6 +1310,7 @@ int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb) | |||
1312 | neigh_hh_init(neigh, dst); | 1310 | neigh_hh_init(neigh, dst); |
1313 | 1311 | ||
1314 | do { | 1312 | do { |
1313 | __skb_pull(skb, skb_network_offset(skb)); | ||
1315 | seq = read_seqbegin(&neigh->ha_lock); | 1314 | seq = read_seqbegin(&neigh->ha_lock); |
1316 | err = dev_hard_header(skb, dev, ntohs(skb->protocol), | 1315 | err = dev_hard_header(skb, dev, ntohs(skb->protocol), |
1317 | neigh->ha, NULL, skb->len); | 1316 | neigh->ha, NULL, skb->len); |
@@ -1342,9 +1341,8 @@ int neigh_connected_output(struct neighbour *neigh, struct sk_buff *skb) | |||
1342 | unsigned int seq; | 1341 | unsigned int seq; |
1343 | int err; | 1342 | int err; |
1344 | 1343 | ||
1345 | __skb_pull(skb, skb_network_offset(skb)); | ||
1346 | |||
1347 | do { | 1344 | do { |
1345 | __skb_pull(skb, skb_network_offset(skb)); | ||
1348 | seq = read_seqbegin(&neigh->ha_lock); | 1346 | seq = read_seqbegin(&neigh->ha_lock); |
1349 | err = dev_hard_header(skb, dev, ntohs(skb->protocol), | 1347 | err = dev_hard_header(skb, dev, ntohs(skb->protocol), |
1350 | neigh->ha, NULL, skb->len); | 1348 | neigh->ha, NULL, skb->len); |
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c index 4a83fb3c8e87..79285a36035f 100644 --- a/net/core/netprio_cgroup.c +++ b/net/core/netprio_cgroup.c | |||
@@ -239,38 +239,24 @@ out_free_devname: | |||
239 | return ret; | 239 | return ret; |
240 | } | 240 | } |
241 | 241 | ||
242 | static int update_netprio(const void *v, struct file *file, unsigned n) | ||
243 | { | ||
244 | int err; | ||
245 | struct socket *sock = sock_from_file(file, &err); | ||
246 | if (sock) | ||
247 | sock->sk->sk_cgrp_prioidx = (u32)(unsigned long)v; | ||
248 | return 0; | ||
249 | } | ||
250 | |||
242 | void net_prio_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) | 251 | void net_prio_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) |
243 | { | 252 | { |
244 | struct task_struct *p; | 253 | struct task_struct *p; |
254 | void *v; | ||
245 | 255 | ||
246 | cgroup_taskset_for_each(p, cgrp, tset) { | 256 | cgroup_taskset_for_each(p, cgrp, tset) { |
247 | unsigned int fd; | ||
248 | struct fdtable *fdt; | ||
249 | struct files_struct *files; | ||
250 | |||
251 | task_lock(p); | 257 | task_lock(p); |
252 | files = p->files; | 258 | v = (void *)(unsigned long)task_netprioidx(p); |
253 | if (!files) { | 259 | iterate_fd(p->files, 0, update_netprio, v); |
254 | task_unlock(p); | ||
255 | continue; | ||
256 | } | ||
257 | |||
258 | spin_lock(&files->file_lock); | ||
259 | fdt = files_fdtable(files); | ||
260 | for (fd = 0; fd < fdt->max_fds; fd++) { | ||
261 | struct file *file; | ||
262 | struct socket *sock; | ||
263 | int err; | ||
264 | |||
265 | file = fcheck_files(files, fd); | ||
266 | if (!file) | ||
267 | continue; | ||
268 | |||
269 | sock = sock_from_file(file, &err); | ||
270 | if (sock) | ||
271 | sock_update_netprioidx(sock->sk, p); | ||
272 | } | ||
273 | spin_unlock(&files->file_lock); | ||
274 | task_unlock(p); | 260 | task_unlock(p); |
275 | } | 261 | } |
276 | } | 262 | } |
diff --git a/net/core/scm.c b/net/core/scm.c index 9c1c63da3ca8..ab570841a532 100644 --- a/net/core/scm.c +++ b/net/core/scm.c | |||
@@ -301,11 +301,10 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) | |||
301 | break; | 301 | break; |
302 | } | 302 | } |
303 | /* Bump the usage count and install the file. */ | 303 | /* Bump the usage count and install the file. */ |
304 | get_file(fp[i]); | ||
305 | sock = sock_from_file(fp[i], &err); | 304 | sock = sock_from_file(fp[i], &err); |
306 | if (sock) | 305 | if (sock) |
307 | sock_update_netprioidx(sock->sk, current); | 306 | sock_update_netprioidx(sock->sk, current); |
308 | fd_install(new_fd, fp[i]); | 307 | fd_install(new_fd, get_file(fp[i])); |
309 | } | 308 | } |
310 | 309 | ||
311 | if (i > 0) | 310 | if (i > 0) |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index cdc28598f4ef..6e04b1fa11f2 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -655,53 +655,6 @@ void consume_skb(struct sk_buff *skb) | |||
655 | } | 655 | } |
656 | EXPORT_SYMBOL(consume_skb); | 656 | EXPORT_SYMBOL(consume_skb); |
657 | 657 | ||
658 | /** | ||
659 | * skb_recycle - clean up an skb for reuse | ||
660 | * @skb: buffer | ||
661 | * | ||
662 | * Recycles the skb to be reused as a receive buffer. This | ||
663 | * function does any necessary reference count dropping, and | ||
664 | * cleans up the skbuff as if it just came from __alloc_skb(). | ||
665 | */ | ||
666 | void skb_recycle(struct sk_buff *skb) | ||
667 | { | ||
668 | struct skb_shared_info *shinfo; | ||
669 | |||
670 | skb_release_head_state(skb); | ||
671 | |||
672 | shinfo = skb_shinfo(skb); | ||
673 | memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); | ||
674 | atomic_set(&shinfo->dataref, 1); | ||
675 | |||
676 | memset(skb, 0, offsetof(struct sk_buff, tail)); | ||
677 | skb->data = skb->head + NET_SKB_PAD; | ||
678 | skb_reset_tail_pointer(skb); | ||
679 | } | ||
680 | EXPORT_SYMBOL(skb_recycle); | ||
681 | |||
682 | /** | ||
683 | * skb_recycle_check - check if skb can be reused for receive | ||
684 | * @skb: buffer | ||
685 | * @skb_size: minimum receive buffer size | ||
686 | * | ||
687 | * Checks that the skb passed in is not shared or cloned, and | ||
688 | * that it is linear and its head portion at least as large as | ||
689 | * skb_size so that it can be recycled as a receive buffer. | ||
690 | * If these conditions are met, this function does any necessary | ||
691 | * reference count dropping and cleans up the skbuff as if it | ||
692 | * just came from __alloc_skb(). | ||
693 | */ | ||
694 | bool skb_recycle_check(struct sk_buff *skb, int skb_size) | ||
695 | { | ||
696 | if (!skb_is_recycleable(skb, skb_size)) | ||
697 | return false; | ||
698 | |||
699 | skb_recycle(skb); | ||
700 | |||
701 | return true; | ||
702 | } | ||
703 | EXPORT_SYMBOL(skb_recycle_check); | ||
704 | |||
705 | static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | 658 | static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) |
706 | { | 659 | { |
707 | new->tstamp = old->tstamp; | 660 | new->tstamp = old->tstamp; |
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index e65f2c856e06..faf7cc3483fe 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c | |||
@@ -220,7 +220,7 @@ static void dn_fib_rule_flush_cache(struct fib_rules_ops *ops) | |||
220 | dn_rt_cache_flush(-1); | 220 | dn_rt_cache_flush(-1); |
221 | } | 221 | } |
222 | 222 | ||
223 | static const struct fib_rules_ops __net_initdata dn_fib_rules_ops_template = { | 223 | static const struct fib_rules_ops __net_initconst dn_fib_rules_ops_template = { |
224 | .family = AF_DECnet, | 224 | .family = AF_DECnet, |
225 | .rule_size = sizeof(struct dn_fib_rule), | 225 | .rule_size = sizeof(struct dn_fib_rule), |
226 | .addr_size = sizeof(u16), | 226 | .addr_size = sizeof(u16), |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 68c93d1bb03a..825c608826de 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -322,7 +322,8 @@ int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, | |||
322 | { | 322 | { |
323 | int r = secpath_exists(skb) ? 0 : IN_DEV_RPFILTER(idev); | 323 | int r = secpath_exists(skb) ? 0 : IN_DEV_RPFILTER(idev); |
324 | 324 | ||
325 | if (!r && !fib_num_tclassid_users(dev_net(dev))) { | 325 | if (!r && !fib_num_tclassid_users(dev_net(dev)) && |
326 | (dev->ifindex != oif || !IN_DEV_TX_REDIRECTS(idev))) { | ||
326 | *itag = 0; | 327 | *itag = 0; |
327 | return 0; | 328 | return 0; |
328 | } | 329 | } |
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index 274309d3aded..26aa65d1fce4 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c | |||
@@ -262,7 +262,7 @@ static void fib4_rule_flush_cache(struct fib_rules_ops *ops) | |||
262 | rt_cache_flush(ops->fro_net); | 262 | rt_cache_flush(ops->fro_net); |
263 | } | 263 | } |
264 | 264 | ||
265 | static const struct fib_rules_ops __net_initdata fib4_rules_ops_template = { | 265 | static const struct fib_rules_ops __net_initconst fib4_rules_ops_template = { |
266 | .family = AF_INET, | 266 | .family = AF_INET, |
267 | .rule_size = sizeof(struct fib4_rule), | 267 | .rule_size = sizeof(struct fib4_rule), |
268 | .addr_size = sizeof(u32), | 268 | .addr_size = sizeof(u32), |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index 267753060ffc..71b125cd5db1 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -840,6 +840,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg) | |||
840 | change_nexthops(fi) { | 840 | change_nexthops(fi) { |
841 | nexthop_nh->nh_parent = fi; | 841 | nexthop_nh->nh_parent = fi; |
842 | nexthop_nh->nh_pcpu_rth_output = alloc_percpu(struct rtable __rcu *); | 842 | nexthop_nh->nh_pcpu_rth_output = alloc_percpu(struct rtable __rcu *); |
843 | if (!nexthop_nh->nh_pcpu_rth_output) | ||
844 | goto failure; | ||
843 | } endfor_nexthops(fi) | 845 | } endfor_nexthops(fi) |
844 | 846 | ||
845 | if (cfg->fc_mx) { | 847 | if (cfg->fc_mx) { |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index f0c5b9c1a957..d34ce2972c8f 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -406,7 +406,7 @@ struct dst_entry *inet_csk_route_req(struct sock *sk, | |||
406 | rt = ip_route_output_flow(net, fl4, sk); | 406 | rt = ip_route_output_flow(net, fl4, sk); |
407 | if (IS_ERR(rt)) | 407 | if (IS_ERR(rt)) |
408 | goto no_route; | 408 | goto no_route; |
409 | if (opt && opt->opt.is_strictroute && rt->rt_gateway) | 409 | if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway) |
410 | goto route_err; | 410 | goto route_err; |
411 | return &rt->dst; | 411 | return &rt->dst; |
412 | 412 | ||
@@ -442,7 +442,7 @@ struct dst_entry *inet_csk_route_child_sock(struct sock *sk, | |||
442 | rt = ip_route_output_flow(net, fl4, sk); | 442 | rt = ip_route_output_flow(net, fl4, sk); |
443 | if (IS_ERR(rt)) | 443 | if (IS_ERR(rt)) |
444 | goto no_route; | 444 | goto no_route; |
445 | if (opt && opt->opt.is_strictroute && rt->rt_gateway) | 445 | if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway) |
446 | goto route_err; | 446 | goto route_err; |
447 | rcu_read_unlock(); | 447 | rcu_read_unlock(); |
448 | return &rt->dst; | 448 | return &rt->dst; |
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index ab09b126423c..694de3b7aebf 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c | |||
@@ -85,7 +85,7 @@ int ip_forward(struct sk_buff *skb) | |||
85 | 85 | ||
86 | rt = skb_rtable(skb); | 86 | rt = skb_rtable(skb); |
87 | 87 | ||
88 | if (opt->is_strictroute && opt->nexthop != rt->rt_gateway) | 88 | if (opt->is_strictroute && rt->rt_uses_gateway) |
89 | goto sr_failed; | 89 | goto sr_failed; |
90 | 90 | ||
91 | if (unlikely(skb->len > dst_mtu(&rt->dst) && !skb_is_gso(skb) && | 91 | if (unlikely(skb->len > dst_mtu(&rt->dst) && !skb_is_gso(skb) && |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 24a29a39e9a8..6537a408a4fb 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -193,7 +193,7 @@ static inline int ip_finish_output2(struct sk_buff *skb) | |||
193 | } | 193 | } |
194 | 194 | ||
195 | rcu_read_lock_bh(); | 195 | rcu_read_lock_bh(); |
196 | nexthop = rt->rt_gateway ? rt->rt_gateway : ip_hdr(skb)->daddr; | 196 | nexthop = (__force u32) rt_nexthop(rt, ip_hdr(skb)->daddr); |
197 | neigh = __ipv4_neigh_lookup_noref(dev, nexthop); | 197 | neigh = __ipv4_neigh_lookup_noref(dev, nexthop); |
198 | if (unlikely(!neigh)) | 198 | if (unlikely(!neigh)) |
199 | neigh = __neigh_create(&arp_tbl, &nexthop, dev, false); | 199 | neigh = __neigh_create(&arp_tbl, &nexthop, dev, false); |
@@ -371,7 +371,7 @@ int ip_queue_xmit(struct sk_buff *skb, struct flowi *fl) | |||
371 | skb_dst_set_noref(skb, &rt->dst); | 371 | skb_dst_set_noref(skb, &rt->dst); |
372 | 372 | ||
373 | packet_routed: | 373 | packet_routed: |
374 | if (inet_opt && inet_opt->opt.is_strictroute && rt->rt_gateway) | 374 | if (inet_opt && inet_opt->opt.is_strictroute && rt->rt_uses_gateway) |
375 | goto no_route; | 375 | goto no_route; |
376 | 376 | ||
377 | /* OK, we know where to send it, allocate and build IP header. */ | 377 | /* OK, we know where to send it, allocate and build IP header. */ |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 1daa95c2a0ba..6168c4dc58b1 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -221,7 +221,7 @@ static int ipmr_rule_fill(struct fib_rule *rule, struct sk_buff *skb, | |||
221 | return 0; | 221 | return 0; |
222 | } | 222 | } |
223 | 223 | ||
224 | static const struct fib_rules_ops __net_initdata ipmr_rules_ops_template = { | 224 | static const struct fib_rules_ops __net_initconst ipmr_rules_ops_template = { |
225 | .family = RTNL_FAMILY_IPMR, | 225 | .family = RTNL_FAMILY_IPMR, |
226 | .rule_size = sizeof(struct ipmr_rule), | 226 | .rule_size = sizeof(struct ipmr_rule), |
227 | .addr_size = sizeof(u32), | 227 | .addr_size = sizeof(u32), |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index ff622069fcef..1a0da8dc8180 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -802,7 +802,8 @@ void ip_rt_send_redirect(struct sk_buff *skb) | |||
802 | net = dev_net(rt->dst.dev); | 802 | net = dev_net(rt->dst.dev); |
803 | peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr, 1); | 803 | peer = inet_getpeer_v4(net->ipv4.peers, ip_hdr(skb)->saddr, 1); |
804 | if (!peer) { | 804 | if (!peer) { |
805 | icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway); | 805 | icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, |
806 | rt_nexthop(rt, ip_hdr(skb)->daddr)); | ||
806 | return; | 807 | return; |
807 | } | 808 | } |
808 | 809 | ||
@@ -827,7 +828,9 @@ void ip_rt_send_redirect(struct sk_buff *skb) | |||
827 | time_after(jiffies, | 828 | time_after(jiffies, |
828 | (peer->rate_last + | 829 | (peer->rate_last + |
829 | (ip_rt_redirect_load << peer->rate_tokens)))) { | 830 | (ip_rt_redirect_load << peer->rate_tokens)))) { |
830 | icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway); | 831 | __be32 gw = rt_nexthop(rt, ip_hdr(skb)->daddr); |
832 | |||
833 | icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, gw); | ||
831 | peer->rate_last = jiffies; | 834 | peer->rate_last = jiffies; |
832 | ++peer->rate_tokens; | 835 | ++peer->rate_tokens; |
833 | #ifdef CONFIG_IP_ROUTE_VERBOSE | 836 | #ifdef CONFIG_IP_ROUTE_VERBOSE |
@@ -835,7 +838,7 @@ void ip_rt_send_redirect(struct sk_buff *skb) | |||
835 | peer->rate_tokens == ip_rt_redirect_number) | 838 | peer->rate_tokens == ip_rt_redirect_number) |
836 | net_warn_ratelimited("host %pI4/if%d ignores redirects for %pI4 to %pI4\n", | 839 | net_warn_ratelimited("host %pI4/if%d ignores redirects for %pI4 to %pI4\n", |
837 | &ip_hdr(skb)->saddr, inet_iif(skb), | 840 | &ip_hdr(skb)->saddr, inet_iif(skb), |
838 | &ip_hdr(skb)->daddr, &rt->rt_gateway); | 841 | &ip_hdr(skb)->daddr, &gw); |
839 | #endif | 842 | #endif |
840 | } | 843 | } |
841 | out_put_peer: | 844 | out_put_peer: |
@@ -904,22 +907,32 @@ out: kfree_skb(skb); | |||
904 | return 0; | 907 | return 0; |
905 | } | 908 | } |
906 | 909 | ||
907 | static u32 __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) | 910 | static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) |
908 | { | 911 | { |
912 | struct dst_entry *dst = &rt->dst; | ||
909 | struct fib_result res; | 913 | struct fib_result res; |
910 | 914 | ||
915 | if (dst->dev->mtu < mtu) | ||
916 | return; | ||
917 | |||
911 | if (mtu < ip_rt_min_pmtu) | 918 | if (mtu < ip_rt_min_pmtu) |
912 | mtu = ip_rt_min_pmtu; | 919 | mtu = ip_rt_min_pmtu; |
913 | 920 | ||
921 | if (!rt->rt_pmtu) { | ||
922 | dst->obsolete = DST_OBSOLETE_KILL; | ||
923 | } else { | ||
924 | rt->rt_pmtu = mtu; | ||
925 | dst->expires = max(1UL, jiffies + ip_rt_mtu_expires); | ||
926 | } | ||
927 | |||
914 | rcu_read_lock(); | 928 | rcu_read_lock(); |
915 | if (fib_lookup(dev_net(rt->dst.dev), fl4, &res) == 0) { | 929 | if (fib_lookup(dev_net(dst->dev), fl4, &res) == 0) { |
916 | struct fib_nh *nh = &FIB_RES_NH(res); | 930 | struct fib_nh *nh = &FIB_RES_NH(res); |
917 | 931 | ||
918 | update_or_create_fnhe(nh, fl4->daddr, 0, mtu, | 932 | update_or_create_fnhe(nh, fl4->daddr, 0, mtu, |
919 | jiffies + ip_rt_mtu_expires); | 933 | jiffies + ip_rt_mtu_expires); |
920 | } | 934 | } |
921 | rcu_read_unlock(); | 935 | rcu_read_unlock(); |
922 | return mtu; | ||
923 | } | 936 | } |
924 | 937 | ||
925 | static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, | 938 | static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, |
@@ -929,14 +942,7 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk, | |||
929 | struct flowi4 fl4; | 942 | struct flowi4 fl4; |
930 | 943 | ||
931 | ip_rt_build_flow_key(&fl4, sk, skb); | 944 | ip_rt_build_flow_key(&fl4, sk, skb); |
932 | mtu = __ip_rt_update_pmtu(rt, &fl4, mtu); | 945 | __ip_rt_update_pmtu(rt, &fl4, mtu); |
933 | |||
934 | if (!rt->rt_pmtu) { | ||
935 | dst->obsolete = DST_OBSOLETE_KILL; | ||
936 | } else { | ||
937 | rt->rt_pmtu = mtu; | ||
938 | rt->dst.expires = max(1UL, jiffies + ip_rt_mtu_expires); | ||
939 | } | ||
940 | } | 946 | } |
941 | 947 | ||
942 | void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, | 948 | void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu, |
@@ -1120,7 +1126,7 @@ static unsigned int ipv4_mtu(const struct dst_entry *dst) | |||
1120 | mtu = dst->dev->mtu; | 1126 | mtu = dst->dev->mtu; |
1121 | 1127 | ||
1122 | if (unlikely(dst_metric_locked(dst, RTAX_MTU))) { | 1128 | if (unlikely(dst_metric_locked(dst, RTAX_MTU))) { |
1123 | if (rt->rt_gateway && mtu > 576) | 1129 | if (rt->rt_uses_gateway && mtu > 576) |
1124 | mtu = 576; | 1130 | mtu = 576; |
1125 | } | 1131 | } |
1126 | 1132 | ||
@@ -1171,7 +1177,9 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe, | |||
1171 | if (fnhe->fnhe_gw) { | 1177 | if (fnhe->fnhe_gw) { |
1172 | rt->rt_flags |= RTCF_REDIRECTED; | 1178 | rt->rt_flags |= RTCF_REDIRECTED; |
1173 | rt->rt_gateway = fnhe->fnhe_gw; | 1179 | rt->rt_gateway = fnhe->fnhe_gw; |
1174 | } | 1180 | rt->rt_uses_gateway = 1; |
1181 | } else if (!rt->rt_gateway) | ||
1182 | rt->rt_gateway = daddr; | ||
1175 | 1183 | ||
1176 | orig = rcu_dereference(fnhe->fnhe_rth); | 1184 | orig = rcu_dereference(fnhe->fnhe_rth); |
1177 | rcu_assign_pointer(fnhe->fnhe_rth, rt); | 1185 | rcu_assign_pointer(fnhe->fnhe_rth, rt); |
@@ -1180,13 +1188,6 @@ static bool rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe, | |||
1180 | 1188 | ||
1181 | fnhe->fnhe_stamp = jiffies; | 1189 | fnhe->fnhe_stamp = jiffies; |
1182 | ret = true; | 1190 | ret = true; |
1183 | } else { | ||
1184 | /* Routes we intend to cache in nexthop exception have | ||
1185 | * the DST_NOCACHE bit clear. However, if we are | ||
1186 | * unsuccessful at storing this route into the cache | ||
1187 | * we really need to set it. | ||
1188 | */ | ||
1189 | rt->dst.flags |= DST_NOCACHE; | ||
1190 | } | 1191 | } |
1191 | spin_unlock_bh(&fnhe_lock); | 1192 | spin_unlock_bh(&fnhe_lock); |
1192 | 1193 | ||
@@ -1201,8 +1202,6 @@ static bool rt_cache_route(struct fib_nh *nh, struct rtable *rt) | |||
1201 | if (rt_is_input_route(rt)) { | 1202 | if (rt_is_input_route(rt)) { |
1202 | p = (struct rtable **)&nh->nh_rth_input; | 1203 | p = (struct rtable **)&nh->nh_rth_input; |
1203 | } else { | 1204 | } else { |
1204 | if (!nh->nh_pcpu_rth_output) | ||
1205 | goto nocache; | ||
1206 | p = (struct rtable **)__this_cpu_ptr(nh->nh_pcpu_rth_output); | 1205 | p = (struct rtable **)__this_cpu_ptr(nh->nh_pcpu_rth_output); |
1207 | } | 1206 | } |
1208 | orig = *p; | 1207 | orig = *p; |
@@ -1211,16 +1210,8 @@ static bool rt_cache_route(struct fib_nh *nh, struct rtable *rt) | |||
1211 | if (prev == orig) { | 1210 | if (prev == orig) { |
1212 | if (orig) | 1211 | if (orig) |
1213 | rt_free(orig); | 1212 | rt_free(orig); |
1214 | } else { | 1213 | } else |
1215 | /* Routes we intend to cache in the FIB nexthop have | ||
1216 | * the DST_NOCACHE bit clear. However, if we are | ||
1217 | * unsuccessful at storing this route into the cache | ||
1218 | * we really need to set it. | ||
1219 | */ | ||
1220 | nocache: | ||
1221 | rt->dst.flags |= DST_NOCACHE; | ||
1222 | ret = false; | 1214 | ret = false; |
1223 | } | ||
1224 | 1215 | ||
1225 | return ret; | 1216 | return ret; |
1226 | } | 1217 | } |
@@ -1281,8 +1272,10 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr, | |||
1281 | if (fi) { | 1272 | if (fi) { |
1282 | struct fib_nh *nh = &FIB_RES_NH(*res); | 1273 | struct fib_nh *nh = &FIB_RES_NH(*res); |
1283 | 1274 | ||
1284 | if (nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK) | 1275 | if (nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK) { |
1285 | rt->rt_gateway = nh->nh_gw; | 1276 | rt->rt_gateway = nh->nh_gw; |
1277 | rt->rt_uses_gateway = 1; | ||
1278 | } | ||
1286 | dst_init_metrics(&rt->dst, fi->fib_metrics, true); | 1279 | dst_init_metrics(&rt->dst, fi->fib_metrics, true); |
1287 | #ifdef CONFIG_IP_ROUTE_CLASSID | 1280 | #ifdef CONFIG_IP_ROUTE_CLASSID |
1288 | rt->dst.tclassid = nh->nh_tclassid; | 1281 | rt->dst.tclassid = nh->nh_tclassid; |
@@ -1291,8 +1284,18 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr, | |||
1291 | cached = rt_bind_exception(rt, fnhe, daddr); | 1284 | cached = rt_bind_exception(rt, fnhe, daddr); |
1292 | else if (!(rt->dst.flags & DST_NOCACHE)) | 1285 | else if (!(rt->dst.flags & DST_NOCACHE)) |
1293 | cached = rt_cache_route(nh, rt); | 1286 | cached = rt_cache_route(nh, rt); |
1294 | } | 1287 | if (unlikely(!cached)) { |
1295 | if (unlikely(!cached)) | 1288 | /* Routes we intend to cache in nexthop exception or |
1289 | * FIB nexthop have the DST_NOCACHE bit clear. | ||
1290 | * However, if we are unsuccessful at storing this | ||
1291 | * route into the cache we really need to set it. | ||
1292 | */ | ||
1293 | rt->dst.flags |= DST_NOCACHE; | ||
1294 | if (!rt->rt_gateway) | ||
1295 | rt->rt_gateway = daddr; | ||
1296 | rt_add_uncached_list(rt); | ||
1297 | } | ||
1298 | } else | ||
1296 | rt_add_uncached_list(rt); | 1299 | rt_add_uncached_list(rt); |
1297 | 1300 | ||
1298 | #ifdef CONFIG_IP_ROUTE_CLASSID | 1301 | #ifdef CONFIG_IP_ROUTE_CLASSID |
@@ -1360,6 +1363,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1360 | rth->rt_iif = 0; | 1363 | rth->rt_iif = 0; |
1361 | rth->rt_pmtu = 0; | 1364 | rth->rt_pmtu = 0; |
1362 | rth->rt_gateway = 0; | 1365 | rth->rt_gateway = 0; |
1366 | rth->rt_uses_gateway = 0; | ||
1363 | INIT_LIST_HEAD(&rth->rt_uncached); | 1367 | INIT_LIST_HEAD(&rth->rt_uncached); |
1364 | if (our) { | 1368 | if (our) { |
1365 | rth->dst.input= ip_local_deliver; | 1369 | rth->dst.input= ip_local_deliver; |
@@ -1429,7 +1433,6 @@ static int __mkroute_input(struct sk_buff *skb, | |||
1429 | return -EINVAL; | 1433 | return -EINVAL; |
1430 | } | 1434 | } |
1431 | 1435 | ||
1432 | |||
1433 | err = fib_validate_source(skb, saddr, daddr, tos, FIB_RES_OIF(*res), | 1436 | err = fib_validate_source(skb, saddr, daddr, tos, FIB_RES_OIF(*res), |
1434 | in_dev->dev, in_dev, &itag); | 1437 | in_dev->dev, in_dev, &itag); |
1435 | if (err < 0) { | 1438 | if (err < 0) { |
@@ -1439,10 +1442,13 @@ static int __mkroute_input(struct sk_buff *skb, | |||
1439 | goto cleanup; | 1442 | goto cleanup; |
1440 | } | 1443 | } |
1441 | 1444 | ||
1442 | if (out_dev == in_dev && err && | 1445 | do_cache = res->fi && !itag; |
1446 | if (out_dev == in_dev && err && IN_DEV_TX_REDIRECTS(out_dev) && | ||
1443 | (IN_DEV_SHARED_MEDIA(out_dev) || | 1447 | (IN_DEV_SHARED_MEDIA(out_dev) || |
1444 | inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) | 1448 | inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) { |
1445 | flags |= RTCF_DOREDIRECT; | 1449 | flags |= RTCF_DOREDIRECT; |
1450 | do_cache = false; | ||
1451 | } | ||
1446 | 1452 | ||
1447 | if (skb->protocol != htons(ETH_P_IP)) { | 1453 | if (skb->protocol != htons(ETH_P_IP)) { |
1448 | /* Not IP (i.e. ARP). Do not create route, if it is | 1454 | /* Not IP (i.e. ARP). Do not create route, if it is |
@@ -1459,15 +1465,11 @@ static int __mkroute_input(struct sk_buff *skb, | |||
1459 | } | 1465 | } |
1460 | } | 1466 | } |
1461 | 1467 | ||
1462 | do_cache = false; | 1468 | if (do_cache) { |
1463 | if (res->fi) { | 1469 | rth = rcu_dereference(FIB_RES_NH(*res).nh_rth_input); |
1464 | if (!itag) { | 1470 | if (rt_cache_valid(rth)) { |
1465 | rth = rcu_dereference(FIB_RES_NH(*res).nh_rth_input); | 1471 | skb_dst_set_noref(skb, &rth->dst); |
1466 | if (rt_cache_valid(rth)) { | 1472 | goto out; |
1467 | skb_dst_set_noref(skb, &rth->dst); | ||
1468 | goto out; | ||
1469 | } | ||
1470 | do_cache = true; | ||
1471 | } | 1473 | } |
1472 | } | 1474 | } |
1473 | 1475 | ||
@@ -1486,6 +1488,7 @@ static int __mkroute_input(struct sk_buff *skb, | |||
1486 | rth->rt_iif = 0; | 1488 | rth->rt_iif = 0; |
1487 | rth->rt_pmtu = 0; | 1489 | rth->rt_pmtu = 0; |
1488 | rth->rt_gateway = 0; | 1490 | rth->rt_gateway = 0; |
1491 | rth->rt_uses_gateway = 0; | ||
1489 | INIT_LIST_HEAD(&rth->rt_uncached); | 1492 | INIT_LIST_HEAD(&rth->rt_uncached); |
1490 | 1493 | ||
1491 | rth->dst.input = ip_forward; | 1494 | rth->dst.input = ip_forward; |
@@ -1656,6 +1659,7 @@ local_input: | |||
1656 | rth->rt_iif = 0; | 1659 | rth->rt_iif = 0; |
1657 | rth->rt_pmtu = 0; | 1660 | rth->rt_pmtu = 0; |
1658 | rth->rt_gateway = 0; | 1661 | rth->rt_gateway = 0; |
1662 | rth->rt_uses_gateway = 0; | ||
1659 | INIT_LIST_HEAD(&rth->rt_uncached); | 1663 | INIT_LIST_HEAD(&rth->rt_uncached); |
1660 | if (res.type == RTN_UNREACHABLE) { | 1664 | if (res.type == RTN_UNREACHABLE) { |
1661 | rth->dst.input= ip_error; | 1665 | rth->dst.input= ip_error; |
@@ -1758,6 +1762,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
1758 | struct in_device *in_dev; | 1762 | struct in_device *in_dev; |
1759 | u16 type = res->type; | 1763 | u16 type = res->type; |
1760 | struct rtable *rth; | 1764 | struct rtable *rth; |
1765 | bool do_cache; | ||
1761 | 1766 | ||
1762 | in_dev = __in_dev_get_rcu(dev_out); | 1767 | in_dev = __in_dev_get_rcu(dev_out); |
1763 | if (!in_dev) | 1768 | if (!in_dev) |
@@ -1794,24 +1799,36 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
1794 | } | 1799 | } |
1795 | 1800 | ||
1796 | fnhe = NULL; | 1801 | fnhe = NULL; |
1802 | do_cache = fi != NULL; | ||
1797 | if (fi) { | 1803 | if (fi) { |
1798 | struct rtable __rcu **prth; | 1804 | struct rtable __rcu **prth; |
1805 | struct fib_nh *nh = &FIB_RES_NH(*res); | ||
1799 | 1806 | ||
1800 | fnhe = find_exception(&FIB_RES_NH(*res), fl4->daddr); | 1807 | fnhe = find_exception(nh, fl4->daddr); |
1801 | if (fnhe) | 1808 | if (fnhe) |
1802 | prth = &fnhe->fnhe_rth; | 1809 | prth = &fnhe->fnhe_rth; |
1803 | else | 1810 | else { |
1804 | prth = __this_cpu_ptr(FIB_RES_NH(*res).nh_pcpu_rth_output); | 1811 | if (unlikely(fl4->flowi4_flags & |
1812 | FLOWI_FLAG_KNOWN_NH && | ||
1813 | !(nh->nh_gw && | ||
1814 | nh->nh_scope == RT_SCOPE_LINK))) { | ||
1815 | do_cache = false; | ||
1816 | goto add; | ||
1817 | } | ||
1818 | prth = __this_cpu_ptr(nh->nh_pcpu_rth_output); | ||
1819 | } | ||
1805 | rth = rcu_dereference(*prth); | 1820 | rth = rcu_dereference(*prth); |
1806 | if (rt_cache_valid(rth)) { | 1821 | if (rt_cache_valid(rth)) { |
1807 | dst_hold(&rth->dst); | 1822 | dst_hold(&rth->dst); |
1808 | return rth; | 1823 | return rth; |
1809 | } | 1824 | } |
1810 | } | 1825 | } |
1826 | |||
1827 | add: | ||
1811 | rth = rt_dst_alloc(dev_out, | 1828 | rth = rt_dst_alloc(dev_out, |
1812 | IN_DEV_CONF_GET(in_dev, NOPOLICY), | 1829 | IN_DEV_CONF_GET(in_dev, NOPOLICY), |
1813 | IN_DEV_CONF_GET(in_dev, NOXFRM), | 1830 | IN_DEV_CONF_GET(in_dev, NOXFRM), |
1814 | fi); | 1831 | do_cache); |
1815 | if (!rth) | 1832 | if (!rth) |
1816 | return ERR_PTR(-ENOBUFS); | 1833 | return ERR_PTR(-ENOBUFS); |
1817 | 1834 | ||
@@ -1824,6 +1841,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res, | |||
1824 | rth->rt_iif = orig_oif ? : 0; | 1841 | rth->rt_iif = orig_oif ? : 0; |
1825 | rth->rt_pmtu = 0; | 1842 | rth->rt_pmtu = 0; |
1826 | rth->rt_gateway = 0; | 1843 | rth->rt_gateway = 0; |
1844 | rth->rt_uses_gateway = 0; | ||
1827 | INIT_LIST_HEAD(&rth->rt_uncached); | 1845 | INIT_LIST_HEAD(&rth->rt_uncached); |
1828 | 1846 | ||
1829 | RT_CACHE_STAT_INC(out_slow_tot); | 1847 | RT_CACHE_STAT_INC(out_slow_tot); |
@@ -2102,6 +2120,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or | |||
2102 | rt->rt_flags = ort->rt_flags; | 2120 | rt->rt_flags = ort->rt_flags; |
2103 | rt->rt_type = ort->rt_type; | 2121 | rt->rt_type = ort->rt_type; |
2104 | rt->rt_gateway = ort->rt_gateway; | 2122 | rt->rt_gateway = ort->rt_gateway; |
2123 | rt->rt_uses_gateway = ort->rt_uses_gateway; | ||
2105 | 2124 | ||
2106 | INIT_LIST_HEAD(&rt->rt_uncached); | 2125 | INIT_LIST_HEAD(&rt->rt_uncached); |
2107 | 2126 | ||
@@ -2180,12 +2199,22 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src, | |||
2180 | if (nla_put_be32(skb, RTA_PREFSRC, fl4->saddr)) | 2199 | if (nla_put_be32(skb, RTA_PREFSRC, fl4->saddr)) |
2181 | goto nla_put_failure; | 2200 | goto nla_put_failure; |
2182 | } | 2201 | } |
2183 | if (rt->rt_gateway && | 2202 | if (rt->rt_uses_gateway && |
2184 | nla_put_be32(skb, RTA_GATEWAY, rt->rt_gateway)) | 2203 | nla_put_be32(skb, RTA_GATEWAY, rt->rt_gateway)) |
2185 | goto nla_put_failure; | 2204 | goto nla_put_failure; |
2186 | 2205 | ||
2206 | expires = rt->dst.expires; | ||
2207 | if (expires) { | ||
2208 | unsigned long now = jiffies; | ||
2209 | |||
2210 | if (time_before(now, expires)) | ||
2211 | expires -= now; | ||
2212 | else | ||
2213 | expires = 0; | ||
2214 | } | ||
2215 | |||
2187 | memcpy(metrics, dst_metrics_ptr(&rt->dst), sizeof(metrics)); | 2216 | memcpy(metrics, dst_metrics_ptr(&rt->dst), sizeof(metrics)); |
2188 | if (rt->rt_pmtu) | 2217 | if (rt->rt_pmtu && expires) |
2189 | metrics[RTAX_MTU - 1] = rt->rt_pmtu; | 2218 | metrics[RTAX_MTU - 1] = rt->rt_pmtu; |
2190 | if (rtnetlink_put_metrics(skb, metrics) < 0) | 2219 | if (rtnetlink_put_metrics(skb, metrics) < 0) |
2191 | goto nla_put_failure; | 2220 | goto nla_put_failure; |
@@ -2195,13 +2224,6 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src, | |||
2195 | goto nla_put_failure; | 2224 | goto nla_put_failure; |
2196 | 2225 | ||
2197 | error = rt->dst.error; | 2226 | error = rt->dst.error; |
2198 | expires = rt->dst.expires; | ||
2199 | if (expires) { | ||
2200 | if (time_before(jiffies, expires)) | ||
2201 | expires -= jiffies; | ||
2202 | else | ||
2203 | expires = 0; | ||
2204 | } | ||
2205 | 2227 | ||
2206 | if (rt_is_input_route(rt)) { | 2228 | if (rt_is_input_route(rt)) { |
2207 | if (nla_put_u32(skb, RTA_IIF, rt->rt_iif)) | 2229 | if (nla_put_u32(skb, RTA_IIF, rt->rt_iif)) |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 681ea2f413e2..05c5ab8d983c 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
@@ -91,6 +91,7 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev, | |||
91 | RTCF_LOCAL); | 91 | RTCF_LOCAL); |
92 | xdst->u.rt.rt_type = rt->rt_type; | 92 | xdst->u.rt.rt_type = rt->rt_type; |
93 | xdst->u.rt.rt_gateway = rt->rt_gateway; | 93 | xdst->u.rt.rt_gateway = rt->rt_gateway; |
94 | xdst->u.rt.rt_uses_gateway = rt->rt_uses_gateway; | ||
94 | xdst->u.rt.rt_pmtu = rt->rt_pmtu; | 95 | xdst->u.rt.rt_pmtu = rt->rt_pmtu; |
95 | INIT_LIST_HEAD(&xdst->u.rt.rt_uncached); | 96 | INIT_LIST_HEAD(&xdst->u.rt.rt_uncached); |
96 | 97 | ||
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c index 4be23da32b89..ff76eecfd622 100644 --- a/net/ipv6/addrlabel.c +++ b/net/ipv6/addrlabel.c | |||
@@ -79,7 +79,7 @@ struct net *ip6addrlbl_net(const struct ip6addrlbl_entry *lbl) | |||
79 | 79 | ||
80 | #define IPV6_ADDR_LABEL_DEFAULT 0xffffffffUL | 80 | #define IPV6_ADDR_LABEL_DEFAULT 0xffffffffUL |
81 | 81 | ||
82 | static const __net_initdata struct ip6addrlbl_init_table | 82 | static const __net_initconst struct ip6addrlbl_init_table |
83 | { | 83 | { |
84 | const struct in6_addr *prefix; | 84 | const struct in6_addr *prefix; |
85 | int prefixlen; | 85 | int prefixlen; |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index e22e6d88bac6..a974247a9ae4 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -822,13 +822,6 @@ out: | |||
822 | return segs; | 822 | return segs; |
823 | } | 823 | } |
824 | 824 | ||
825 | struct ipv6_gro_cb { | ||
826 | struct napi_gro_cb napi; | ||
827 | int proto; | ||
828 | }; | ||
829 | |||
830 | #define IPV6_GRO_CB(skb) ((struct ipv6_gro_cb *)(skb)->cb) | ||
831 | |||
832 | static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, | 825 | static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, |
833 | struct sk_buff *skb) | 826 | struct sk_buff *skb) |
834 | { | 827 | { |
@@ -874,28 +867,31 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head, | |||
874 | iph = ipv6_hdr(skb); | 867 | iph = ipv6_hdr(skb); |
875 | } | 868 | } |
876 | 869 | ||
877 | IPV6_GRO_CB(skb)->proto = proto; | 870 | NAPI_GRO_CB(skb)->proto = proto; |
878 | 871 | ||
879 | flush--; | 872 | flush--; |
880 | nlen = skb_network_header_len(skb); | 873 | nlen = skb_network_header_len(skb); |
881 | 874 | ||
882 | for (p = *head; p; p = p->next) { | 875 | for (p = *head; p; p = p->next) { |
883 | struct ipv6hdr *iph2; | 876 | const struct ipv6hdr *iph2; |
877 | __be32 first_word; /* <Version:4><Traffic_Class:8><Flow_Label:20> */ | ||
884 | 878 | ||
885 | if (!NAPI_GRO_CB(p)->same_flow) | 879 | if (!NAPI_GRO_CB(p)->same_flow) |
886 | continue; | 880 | continue; |
887 | 881 | ||
888 | iph2 = ipv6_hdr(p); | 882 | iph2 = ipv6_hdr(p); |
883 | first_word = *(__be32 *)iph ^ *(__be32 *)iph2 ; | ||
889 | 884 | ||
890 | /* All fields must match except length. */ | 885 | /* All fields must match except length and Traffic Class. */ |
891 | if (nlen != skb_network_header_len(p) || | 886 | if (nlen != skb_network_header_len(p) || |
892 | memcmp(iph, iph2, offsetof(struct ipv6hdr, payload_len)) || | 887 | (first_word & htonl(0xF00FFFFF)) || |
893 | memcmp(&iph->nexthdr, &iph2->nexthdr, | 888 | memcmp(&iph->nexthdr, &iph2->nexthdr, |
894 | nlen - offsetof(struct ipv6hdr, nexthdr))) { | 889 | nlen - offsetof(struct ipv6hdr, nexthdr))) { |
895 | NAPI_GRO_CB(p)->same_flow = 0; | 890 | NAPI_GRO_CB(p)->same_flow = 0; |
896 | continue; | 891 | continue; |
897 | } | 892 | } |
898 | 893 | /* flush if Traffic Class fields are different */ | |
894 | NAPI_GRO_CB(p)->flush |= !!(first_word & htonl(0x0FF00000)); | ||
899 | NAPI_GRO_CB(p)->flush |= flush; | 895 | NAPI_GRO_CB(p)->flush |= flush; |
900 | } | 896 | } |
901 | 897 | ||
@@ -927,7 +923,7 @@ static int ipv6_gro_complete(struct sk_buff *skb) | |||
927 | sizeof(*iph)); | 923 | sizeof(*iph)); |
928 | 924 | ||
929 | rcu_read_lock(); | 925 | rcu_read_lock(); |
930 | ops = rcu_dereference(inet6_protos[IPV6_GRO_CB(skb)->proto]); | 926 | ops = rcu_dereference(inet6_protos[NAPI_GRO_CB(skb)->proto]); |
931 | if (WARN_ON(!ops || !ops->gro_complete)) | 927 | if (WARN_ON(!ops || !ops->gro_complete)) |
932 | goto out_unlock; | 928 | goto out_unlock; |
933 | 929 | ||
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index 0ff1cfd55bc4..d9fb9110f607 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -238,7 +238,7 @@ static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule) | |||
238 | + nla_total_size(16); /* src */ | 238 | + nla_total_size(16); /* src */ |
239 | } | 239 | } |
240 | 240 | ||
241 | static const struct fib_rules_ops __net_initdata fib6_rules_ops_template = { | 241 | static const struct fib_rules_ops __net_initconst fib6_rules_ops_template = { |
242 | .family = AF_INET6, | 242 | .family = AF_INET6, |
243 | .rule_size = sizeof(struct fib6_rule), | 243 | .rule_size = sizeof(struct fib6_rule), |
244 | .addr_size = sizeof(struct in6_addr), | 244 | .addr_size = sizeof(struct in6_addr), |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 08ea3f0b6e55..f7c7c6319720 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -205,7 +205,7 @@ static int ip6mr_rule_fill(struct fib_rule *rule, struct sk_buff *skb, | |||
205 | return 0; | 205 | return 0; |
206 | } | 206 | } |
207 | 207 | ||
208 | static const struct fib_rules_ops __net_initdata ip6mr_rules_ops_template = { | 208 | static const struct fib_rules_ops __net_initconst ip6mr_rules_ops_template = { |
209 | .family = RTNL_FAMILY_IP6MR, | 209 | .family = RTNL_FAMILY_IP6MR, |
210 | .rule_size = sizeof(struct ip6mr_rule), | 210 | .rule_size = sizeof(struct ip6mr_rule), |
211 | .addr_size = sizeof(struct in6_addr), | 211 | .addr_size = sizeof(struct in6_addr), |
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c index 56f6d5d81a77..cc4c8095681a 100644 --- a/net/netfilter/ipvs/ip_vs_xmit.c +++ b/net/netfilter/ipvs/ip_vs_xmit.c | |||
@@ -50,6 +50,7 @@ enum { | |||
50 | * local | 50 | * local |
51 | */ | 51 | */ |
52 | IP_VS_RT_MODE_CONNECT = 8, /* Always bind route to saddr */ | 52 | IP_VS_RT_MODE_CONNECT = 8, /* Always bind route to saddr */ |
53 | IP_VS_RT_MODE_KNOWN_NH = 16,/* Route via remote addr */ | ||
53 | }; | 54 | }; |
54 | 55 | ||
55 | /* | 56 | /* |
@@ -113,6 +114,8 @@ static struct rtable *do_output_route4(struct net *net, __be32 daddr, | |||
113 | fl4.daddr = daddr; | 114 | fl4.daddr = daddr; |
114 | fl4.saddr = (rt_mode & IP_VS_RT_MODE_CONNECT) ? *saddr : 0; | 115 | fl4.saddr = (rt_mode & IP_VS_RT_MODE_CONNECT) ? *saddr : 0; |
115 | fl4.flowi4_tos = rtos; | 116 | fl4.flowi4_tos = rtos; |
117 | fl4.flowi4_flags = (rt_mode & IP_VS_RT_MODE_KNOWN_NH) ? | ||
118 | FLOWI_FLAG_KNOWN_NH : 0; | ||
116 | 119 | ||
117 | retry: | 120 | retry: |
118 | rt = ip_route_output_key(net, &fl4); | 121 | rt = ip_route_output_key(net, &fl4); |
@@ -1061,7 +1064,8 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
1061 | if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip, | 1064 | if (!(rt = __ip_vs_get_out_rt(skb, cp->dest, cp->daddr.ip, |
1062 | RT_TOS(iph->tos), | 1065 | RT_TOS(iph->tos), |
1063 | IP_VS_RT_MODE_LOCAL | | 1066 | IP_VS_RT_MODE_LOCAL | |
1064 | IP_VS_RT_MODE_NON_LOCAL, NULL))) | 1067 | IP_VS_RT_MODE_NON_LOCAL | |
1068 | IP_VS_RT_MODE_KNOWN_NH, NULL))) | ||
1065 | goto tx_error_icmp; | 1069 | goto tx_error_icmp; |
1066 | if (rt->rt_flags & RTCF_LOCAL) { | 1070 | if (rt->rt_flags & RTCF_LOCAL) { |
1067 | ip_rt_put(rt); | 1071 | ip_rt_put(rt); |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 0f2e3ad69c47..01e944a017a4 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -169,6 +169,8 @@ static void netlink_sock_destruct(struct sock *sk) | |||
169 | if (nlk->cb) { | 169 | if (nlk->cb) { |
170 | if (nlk->cb->done) | 170 | if (nlk->cb->done) |
171 | nlk->cb->done(nlk->cb); | 171 | nlk->cb->done(nlk->cb); |
172 | |||
173 | module_put(nlk->cb->module); | ||
172 | netlink_destroy_callback(nlk->cb); | 174 | netlink_destroy_callback(nlk->cb); |
173 | } | 175 | } |
174 | 176 | ||
@@ -1758,6 +1760,7 @@ static int netlink_dump(struct sock *sk) | |||
1758 | nlk->cb = NULL; | 1760 | nlk->cb = NULL; |
1759 | mutex_unlock(nlk->cb_mutex); | 1761 | mutex_unlock(nlk->cb_mutex); |
1760 | 1762 | ||
1763 | module_put(cb->module); | ||
1761 | netlink_consume_callback(cb); | 1764 | netlink_consume_callback(cb); |
1762 | return 0; | 1765 | return 0; |
1763 | 1766 | ||
@@ -1767,9 +1770,9 @@ errout_skb: | |||
1767 | return err; | 1770 | return err; |
1768 | } | 1771 | } |
1769 | 1772 | ||
1770 | int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, | 1773 | int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, |
1771 | const struct nlmsghdr *nlh, | 1774 | const struct nlmsghdr *nlh, |
1772 | struct netlink_dump_control *control) | 1775 | struct netlink_dump_control *control) |
1773 | { | 1776 | { |
1774 | struct netlink_callback *cb; | 1777 | struct netlink_callback *cb; |
1775 | struct sock *sk; | 1778 | struct sock *sk; |
@@ -1784,6 +1787,7 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, | |||
1784 | cb->done = control->done; | 1787 | cb->done = control->done; |
1785 | cb->nlh = nlh; | 1788 | cb->nlh = nlh; |
1786 | cb->data = control->data; | 1789 | cb->data = control->data; |
1790 | cb->module = control->module; | ||
1787 | cb->min_dump_alloc = control->min_dump_alloc; | 1791 | cb->min_dump_alloc = control->min_dump_alloc; |
1788 | atomic_inc(&skb->users); | 1792 | atomic_inc(&skb->users); |
1789 | cb->skb = skb; | 1793 | cb->skb = skb; |
@@ -1794,19 +1798,28 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, | |||
1794 | return -ECONNREFUSED; | 1798 | return -ECONNREFUSED; |
1795 | } | 1799 | } |
1796 | nlk = nlk_sk(sk); | 1800 | nlk = nlk_sk(sk); |
1797 | /* A dump is in progress... */ | 1801 | |
1798 | mutex_lock(nlk->cb_mutex); | 1802 | mutex_lock(nlk->cb_mutex); |
1803 | /* A dump is in progress... */ | ||
1799 | if (nlk->cb) { | 1804 | if (nlk->cb) { |
1800 | mutex_unlock(nlk->cb_mutex); | 1805 | mutex_unlock(nlk->cb_mutex); |
1801 | netlink_destroy_callback(cb); | 1806 | netlink_destroy_callback(cb); |
1802 | sock_put(sk); | 1807 | ret = -EBUSY; |
1803 | return -EBUSY; | 1808 | goto out; |
1804 | } | 1809 | } |
1810 | /* add reference of module which cb->dump belongs to */ | ||
1811 | if (!try_module_get(cb->module)) { | ||
1812 | mutex_unlock(nlk->cb_mutex); | ||
1813 | netlink_destroy_callback(cb); | ||
1814 | ret = -EPROTONOSUPPORT; | ||
1815 | goto out; | ||
1816 | } | ||
1817 | |||
1805 | nlk->cb = cb; | 1818 | nlk->cb = cb; |
1806 | mutex_unlock(nlk->cb_mutex); | 1819 | mutex_unlock(nlk->cb_mutex); |
1807 | 1820 | ||
1808 | ret = netlink_dump(sk); | 1821 | ret = netlink_dump(sk); |
1809 | 1822 | out: | |
1810 | sock_put(sk); | 1823 | sock_put(sk); |
1811 | 1824 | ||
1812 | if (ret) | 1825 | if (ret) |
@@ -1817,7 +1830,7 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb, | |||
1817 | */ | 1830 | */ |
1818 | return -EINTR; | 1831 | return -EINTR; |
1819 | } | 1832 | } |
1820 | EXPORT_SYMBOL(netlink_dump_start); | 1833 | EXPORT_SYMBOL(__netlink_dump_start); |
1821 | 1834 | ||
1822 | void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) | 1835 | void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err) |
1823 | { | 1836 | { |
diff --git a/net/rds/send.c b/net/rds/send.c index 96531d4033a2..88eace57dd6b 100644 --- a/net/rds/send.c +++ b/net/rds/send.c | |||
@@ -1122,7 +1122,7 @@ rds_send_pong(struct rds_connection *conn, __be16 dport) | |||
1122 | rds_stats_inc(s_send_pong); | 1122 | rds_stats_inc(s_send_pong); |
1123 | 1123 | ||
1124 | if (!test_bit(RDS_LL_SEND_FULL, &conn->c_flags)) | 1124 | if (!test_bit(RDS_LL_SEND_FULL, &conn->c_flags)) |
1125 | rds_send_xmit(conn); | 1125 | queue_delayed_work(rds_wq, &conn->c_send_w, 0); |
1126 | 1126 | ||
1127 | rds_message_put(rm); | 1127 | rds_message_put(rm); |
1128 | return 0; | 1128 | return 0; |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index d37d24ff197f..59d16ea927f0 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -70,6 +70,7 @@ | |||
70 | #include <linux/init.h> | 70 | #include <linux/init.h> |
71 | #include <linux/crypto.h> | 71 | #include <linux/crypto.h> |
72 | #include <linux/slab.h> | 72 | #include <linux/slab.h> |
73 | #include <linux/file.h> | ||
73 | 74 | ||
74 | #include <net/ip.h> | 75 | #include <net/ip.h> |
75 | #include <net/icmp.h> | 76 | #include <net/icmp.h> |
@@ -4292,6 +4293,7 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval | |||
4292 | { | 4293 | { |
4293 | sctp_peeloff_arg_t peeloff; | 4294 | sctp_peeloff_arg_t peeloff; |
4294 | struct socket *newsock; | 4295 | struct socket *newsock; |
4296 | struct file *newfile; | ||
4295 | int retval = 0; | 4297 | int retval = 0; |
4296 | 4298 | ||
4297 | if (len < sizeof(sctp_peeloff_arg_t)) | 4299 | if (len < sizeof(sctp_peeloff_arg_t)) |
@@ -4305,22 +4307,35 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval | |||
4305 | goto out; | 4307 | goto out; |
4306 | 4308 | ||
4307 | /* Map the socket to an unused fd that can be returned to the user. */ | 4309 | /* Map the socket to an unused fd that can be returned to the user. */ |
4308 | retval = sock_map_fd(newsock, 0); | 4310 | retval = get_unused_fd(); |
4309 | if (retval < 0) { | 4311 | if (retval < 0) { |
4310 | sock_release(newsock); | 4312 | sock_release(newsock); |
4311 | goto out; | 4313 | goto out; |
4312 | } | 4314 | } |
4313 | 4315 | ||
4316 | newfile = sock_alloc_file(newsock, 0, NULL); | ||
4317 | if (unlikely(IS_ERR(newfile))) { | ||
4318 | put_unused_fd(retval); | ||
4319 | sock_release(newsock); | ||
4320 | return PTR_ERR(newfile); | ||
4321 | } | ||
4322 | |||
4314 | SCTP_DEBUG_PRINTK("%s: sk: %p newsk: %p sd: %d\n", | 4323 | SCTP_DEBUG_PRINTK("%s: sk: %p newsk: %p sd: %d\n", |
4315 | __func__, sk, newsock->sk, retval); | 4324 | __func__, sk, newsock->sk, retval); |
4316 | 4325 | ||
4317 | /* Return the fd mapped to the new socket. */ | 4326 | /* Return the fd mapped to the new socket. */ |
4327 | if (put_user(len, optlen)) { | ||
4328 | fput(newfile); | ||
4329 | put_unused_fd(retval); | ||
4330 | return -EFAULT; | ||
4331 | } | ||
4318 | peeloff.sd = retval; | 4332 | peeloff.sd = retval; |
4319 | if (put_user(len, optlen)) | 4333 | if (copy_to_user(optval, &peeloff, len)) { |
4334 | fput(newfile); | ||
4335 | put_unused_fd(retval); | ||
4320 | return -EFAULT; | 4336 | return -EFAULT; |
4321 | if (copy_to_user(optval, &peeloff, len)) | 4337 | } |
4322 | retval = -EFAULT; | 4338 | fd_install(retval, newfile); |
4323 | |||
4324 | out: | 4339 | out: |
4325 | return retval; | 4340 | return retval; |
4326 | } | 4341 | } |
diff --git a/net/socket.c b/net/socket.c index 80dc7e84b046..d92c490e66fa 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -347,17 +347,11 @@ static struct file_system_type sock_fs_type = { | |||
347 | * but we take care of internal coherence yet. | 347 | * but we take care of internal coherence yet. |
348 | */ | 348 | */ |
349 | 349 | ||
350 | static int sock_alloc_file(struct socket *sock, struct file **f, int flags, | 350 | struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname) |
351 | const char *dname) | ||
352 | { | 351 | { |
353 | struct qstr name = { .name = "" }; | 352 | struct qstr name = { .name = "" }; |
354 | struct path path; | 353 | struct path path; |
355 | struct file *file; | 354 | struct file *file; |
356 | int fd; | ||
357 | |||
358 | fd = get_unused_fd_flags(flags); | ||
359 | if (unlikely(fd < 0)) | ||
360 | return fd; | ||
361 | 355 | ||
362 | if (dname) { | 356 | if (dname) { |
363 | name.name = dname; | 357 | name.name = dname; |
@@ -367,10 +361,8 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags, | |||
367 | name.len = strlen(name.name); | 361 | name.len = strlen(name.name); |
368 | } | 362 | } |
369 | path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name); | 363 | path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name); |
370 | if (unlikely(!path.dentry)) { | 364 | if (unlikely(!path.dentry)) |
371 | put_unused_fd(fd); | 365 | return ERR_PTR(-ENOMEM); |
372 | return -ENOMEM; | ||
373 | } | ||
374 | path.mnt = mntget(sock_mnt); | 366 | path.mnt = mntget(sock_mnt); |
375 | 367 | ||
376 | d_instantiate(path.dentry, SOCK_INODE(sock)); | 368 | d_instantiate(path.dentry, SOCK_INODE(sock)); |
@@ -382,30 +374,33 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags, | |||
382 | /* drop dentry, keep inode */ | 374 | /* drop dentry, keep inode */ |
383 | ihold(path.dentry->d_inode); | 375 | ihold(path.dentry->d_inode); |
384 | path_put(&path); | 376 | path_put(&path); |
385 | put_unused_fd(fd); | 377 | return ERR_PTR(-ENFILE); |
386 | return -ENFILE; | ||
387 | } | 378 | } |
388 | 379 | ||
389 | sock->file = file; | 380 | sock->file = file; |
390 | file->f_flags = O_RDWR | (flags & O_NONBLOCK); | 381 | file->f_flags = O_RDWR | (flags & O_NONBLOCK); |
391 | file->f_pos = 0; | 382 | file->f_pos = 0; |
392 | file->private_data = sock; | 383 | file->private_data = sock; |
393 | 384 | return file; | |
394 | *f = file; | ||
395 | return fd; | ||
396 | } | 385 | } |
386 | EXPORT_SYMBOL(sock_alloc_file); | ||
397 | 387 | ||
398 | int sock_map_fd(struct socket *sock, int flags) | 388 | static int sock_map_fd(struct socket *sock, int flags) |
399 | { | 389 | { |
400 | struct file *newfile; | 390 | struct file *newfile; |
401 | int fd = sock_alloc_file(sock, &newfile, flags, NULL); | 391 | int fd = get_unused_fd_flags(flags); |
392 | if (unlikely(fd < 0)) | ||
393 | return fd; | ||
402 | 394 | ||
403 | if (likely(fd >= 0)) | 395 | newfile = sock_alloc_file(sock, flags, NULL); |
396 | if (likely(!IS_ERR(newfile))) { | ||
404 | fd_install(fd, newfile); | 397 | fd_install(fd, newfile); |
398 | return fd; | ||
399 | } | ||
405 | 400 | ||
406 | return fd; | 401 | put_unused_fd(fd); |
402 | return PTR_ERR(newfile); | ||
407 | } | 403 | } |
408 | EXPORT_SYMBOL(sock_map_fd); | ||
409 | 404 | ||
410 | struct socket *sock_from_file(struct file *file, int *err) | 405 | struct socket *sock_from_file(struct file *file, int *err) |
411 | { | 406 | { |
@@ -1466,17 +1461,32 @@ SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol, | |||
1466 | if (err < 0) | 1461 | if (err < 0) |
1467 | goto out_release_both; | 1462 | goto out_release_both; |
1468 | 1463 | ||
1469 | fd1 = sock_alloc_file(sock1, &newfile1, flags, NULL); | 1464 | fd1 = get_unused_fd_flags(flags); |
1470 | if (unlikely(fd1 < 0)) { | 1465 | if (unlikely(fd1 < 0)) { |
1471 | err = fd1; | 1466 | err = fd1; |
1472 | goto out_release_both; | 1467 | goto out_release_both; |
1473 | } | 1468 | } |
1474 | 1469 | fd2 = get_unused_fd_flags(flags); | |
1475 | fd2 = sock_alloc_file(sock2, &newfile2, flags, NULL); | ||
1476 | if (unlikely(fd2 < 0)) { | 1470 | if (unlikely(fd2 < 0)) { |
1477 | err = fd2; | 1471 | err = fd2; |
1472 | put_unused_fd(fd1); | ||
1473 | goto out_release_both; | ||
1474 | } | ||
1475 | |||
1476 | newfile1 = sock_alloc_file(sock1, flags, NULL); | ||
1477 | if (unlikely(IS_ERR(newfile1))) { | ||
1478 | err = PTR_ERR(newfile1); | ||
1479 | put_unused_fd(fd1); | ||
1480 | put_unused_fd(fd2); | ||
1481 | goto out_release_both; | ||
1482 | } | ||
1483 | |||
1484 | newfile2 = sock_alloc_file(sock2, flags, NULL); | ||
1485 | if (IS_ERR(newfile2)) { | ||
1486 | err = PTR_ERR(newfile2); | ||
1478 | fput(newfile1); | 1487 | fput(newfile1); |
1479 | put_unused_fd(fd1); | 1488 | put_unused_fd(fd1); |
1489 | put_unused_fd(fd2); | ||
1480 | sock_release(sock2); | 1490 | sock_release(sock2); |
1481 | goto out; | 1491 | goto out; |
1482 | } | 1492 | } |
@@ -1608,13 +1618,19 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr, | |||
1608 | */ | 1618 | */ |
1609 | __module_get(newsock->ops->owner); | 1619 | __module_get(newsock->ops->owner); |
1610 | 1620 | ||
1611 | newfd = sock_alloc_file(newsock, &newfile, flags, | 1621 | newfd = get_unused_fd_flags(flags); |
1612 | sock->sk->sk_prot_creator->name); | ||
1613 | if (unlikely(newfd < 0)) { | 1622 | if (unlikely(newfd < 0)) { |
1614 | err = newfd; | 1623 | err = newfd; |
1615 | sock_release(newsock); | 1624 | sock_release(newsock); |
1616 | goto out_put; | 1625 | goto out_put; |
1617 | } | 1626 | } |
1627 | newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name); | ||
1628 | if (unlikely(IS_ERR(newfile))) { | ||
1629 | err = PTR_ERR(newfile); | ||
1630 | put_unused_fd(newfd); | ||
1631 | sock_release(newsock); | ||
1632 | goto out_put; | ||
1633 | } | ||
1618 | 1634 | ||
1619 | err = security_socket_accept(sock, newsock); | 1635 | err = security_socket_accept(sock, newsock); |
1620 | if (err) | 1636 | if (err) |