aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/fib_frontend.c8
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_tcp.c29
-rw-r--r--net/ipv4/netfilter/ipt_recent.c1
3 files changed, 27 insertions, 11 deletions
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 882f88f6d13b..19b1b984d687 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -544,12 +544,16 @@ static void nl_fib_input(struct sock *sk, int len)
544 struct sk_buff *skb = NULL; 544 struct sk_buff *skb = NULL;
545 struct nlmsghdr *nlh = NULL; 545 struct nlmsghdr *nlh = NULL;
546 struct fib_result_nl *frn; 546 struct fib_result_nl *frn;
547 int err;
548 u32 pid; 547 u32 pid;
549 struct fib_table *tb; 548 struct fib_table *tb;
550 549
551 skb = skb_recv_datagram(sk, 0, 0, &err); 550 skb = skb_dequeue(&sk->sk_receive_queue);
552 nlh = (struct nlmsghdr *)skb->data; 551 nlh = (struct nlmsghdr *)skb->data;
552 if (skb->len < NLMSG_SPACE(0) || skb->len < nlh->nlmsg_len ||
553 nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*frn))) {
554 kfree_skb(skb);
555 return;
556 }
553 557
554 frn = (struct fib_result_nl *) NLMSG_DATA(nlh); 558 frn = (struct fib_result_nl *) NLMSG_DATA(nlh);
555 tb = fib_get_table(frn->tb_id_in); 559 tb = fib_get_table(frn->tb_id_in);
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index 625981676776..aeb7353d4777 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -272,9 +272,9 @@ static const enum tcp_conntrack tcp_conntracks[2][6][TCP_CONNTRACK_MAX] = {
272 * sCL -> sCL 272 * sCL -> sCL
273 */ 273 */
274/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */ 274/* sNO, sSS, sSR, sES, sFW, sCW, sLA, sTW, sCL, sLI */
275/*ack*/ { sIV, sIV, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV }, 275/*ack*/ { sIV, sIG, sSR, sES, sCW, sCW, sTW, sTW, sCL, sIV },
276/* 276/*
277 * sSS -> sIV Might be a half-open connection. 277 * sSS -> sIG Might be a half-open connection.
278 * sSR -> sSR Might answer late resent SYN. 278 * sSR -> sSR Might answer late resent SYN.
279 * sES -> sES :-) 279 * sES -> sES :-)
280 * sFW -> sCW Normal close request answered by ACK. 280 * sFW -> sCW Normal close request answered by ACK.
@@ -917,8 +917,12 @@ static int tcp_packet(struct ip_conntrack *conntrack,
917 917
918 switch (new_state) { 918 switch (new_state) {
919 case TCP_CONNTRACK_IGNORE: 919 case TCP_CONNTRACK_IGNORE:
920 /* Either SYN in ORIGINAL 920 /* Ignored packets:
921 * or SYN/ACK in REPLY. */ 921 *
922 * a) SYN in ORIGINAL
923 * b) SYN/ACK in REPLY
924 * c) ACK in reply direction after initial SYN in original.
925 */
922 if (index == TCP_SYNACK_SET 926 if (index == TCP_SYNACK_SET
923 && conntrack->proto.tcp.last_index == TCP_SYN_SET 927 && conntrack->proto.tcp.last_index == TCP_SYN_SET
924 && conntrack->proto.tcp.last_dir != dir 928 && conntrack->proto.tcp.last_dir != dir
@@ -985,13 +989,20 @@ static int tcp_packet(struct ip_conntrack *conntrack,
985 } 989 }
986 case TCP_CONNTRACK_CLOSE: 990 case TCP_CONNTRACK_CLOSE:
987 if (index == TCP_RST_SET 991 if (index == TCP_RST_SET
988 && test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status) 992 && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
989 && conntrack->proto.tcp.last_index == TCP_SYN_SET 993 && conntrack->proto.tcp.last_index == TCP_SYN_SET)
994 || (!test_bit(IPS_ASSURED_BIT, &conntrack->status)
995 && conntrack->proto.tcp.last_index == TCP_ACK_SET))
990 && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) { 996 && ntohl(th->ack_seq) == conntrack->proto.tcp.last_end) {
991 /* RST sent to invalid SYN we had let trough 997 /* RST sent to invalid SYN or ACK we had let trough
992 * SYN was in window then, tear down connection. 998 * at a) and c) above:
999 *
1000 * a) SYN was in window then
1001 * c) we hold a half-open connection.
1002 *
1003 * Delete our connection entry.
993 * We skip window checking, because packet might ACK 1004 * We skip window checking, because packet might ACK
994 * segments we ignored in the SYN. */ 1005 * segments we ignored. */
995 goto in_window; 1006 goto in_window;
996 } 1007 }
997 /* Just fall trough */ 1008 /* Just fall trough */
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c
index 2d44b07688af..261cbb4d4c49 100644
--- a/net/ipv4/netfilter/ipt_recent.c
+++ b/net/ipv4/netfilter/ipt_recent.c
@@ -532,6 +532,7 @@ match(const struct sk_buff *skb,
532 } 532 }
533 if(info->seconds && info->hit_count) { 533 if(info->seconds && info->hit_count) {
534 for(pkt_count = 0, hits_found = 0; pkt_count < ip_pkt_list_tot; pkt_count++) { 534 for(pkt_count = 0, hits_found = 0; pkt_count < ip_pkt_list_tot; pkt_count++) {
535 if(r_list[location].last_pkts[pkt_count] == 0) break;
535 if(time_before_eq(now,r_list[location].last_pkts[pkt_count]+info->seconds*HZ)) hits_found++; 536 if(time_before_eq(now,r_list[location].last_pkts[pkt_count]+info->seconds*HZ)) hits_found++;
536 } 537 }
537 if(hits_found >= info->hit_count) ans = !info->invert; else ans = info->invert; 538 if(hits_found >= info->hit_count) ans = !info->invert; else ans = info->invert;