diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/devinet.c | 21 | ||||
-rw-r--r-- | net/ipv4/ip_output.c | 1 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_proto_tcp.c | 1 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_queue.c | 20 | ||||
-rw-r--r-- | net/ipv4/netfilter/iptable_raw.c | 6 | ||||
-rw-r--r-- | net/ipv4/tcp_diag.c | 3 | ||||
-rw-r--r-- | net/ipv4/tcp_ipv4.c | 7 | ||||
-rw-r--r-- | net/ipv4/xfrm4_policy.c | 42 |
8 files changed, 75 insertions, 26 deletions
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index eea7ef01077..abbc6d5c183 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -1107,17 +1107,18 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa) } } -static struct rtnetlink_link inet_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = { - [4] = { .doit = inet_rtm_newaddr, }, - [5] = { .doit = inet_rtm_deladdr, }, - [6] = { .dumpit = inet_dump_ifaddr, }, - [8] = { .doit = inet_rtm_newroute, }, - [9] = { .doit = inet_rtm_delroute, }, - [10] = { .doit = inet_rtm_getroute, .dumpit = inet_dump_fib, }, +static struct rtnetlink_link inet_rtnetlink_table[RTM_NR_MSGTYPES] = { + [RTM_NEWADDR - RTM_BASE] = { .doit = inet_rtm_newaddr, }, + [RTM_DELADDR - RTM_BASE] = { .doit = inet_rtm_deladdr, }, + [RTM_GETADDR - RTM_BASE] = { .dumpit = inet_dump_ifaddr, }, + [RTM_NEWROUTE - RTM_BASE] = { .doit = inet_rtm_newroute, }, + [RTM_DELROUTE - RTM_BASE] = { .doit = inet_rtm_delroute, }, + [RTM_GETROUTE - RTM_BASE] = { .doit = inet_rtm_getroute, + .dumpit = inet_dump_fib, }, #ifdef CONFIG_IP_MULTIPLE_TABLES - [16] = { .doit = inet_rtm_newrule, }, - [17] = { .doit = inet_rtm_delrule, }, - [18] = { .dumpit = inet_dump_rules, }, + [RTM_NEWRULE - RTM_BASE] = { .doit = inet_rtm_newrule, }, + [RTM_DELRULE - RTM_BASE] = { .doit = inet_rtm_delrule, }, + [RTM_GETRULE - RTM_BASE] = { .dumpit = inet_dump_rules, }, #endif }; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 38f69532a02..24fe3e00b42 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -111,6 +111,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb) #ifdef CONFIG_NETFILTER_DEBUG nf_debug_ip_loopback_xmit(newskb); #endif + nf_reset(newskb); netif_rx(newskb); return 0; } diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c index 2b87c1974be..721ddbf522b 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c @@ -819,6 +819,7 @@ static int tcp_error(struct sk_buff *skb, */ /* FIXME: Source route IP option packets --RR */ if (hooknum == NF_IP_PRE_ROUTING + && skb->ip_summed != CHECKSUM_UNNECESSARY && csum_tcpudp_magic(iph->saddr, iph->daddr, tcplen, IPPROTO_TCP, skb->ip_summed == CHECKSUM_HW ? skb->csum : skb_checksum(skb, iph->ihl*4, tcplen, 0))) { diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 9e40dffc204..e5746b67441 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c @@ -546,20 +546,18 @@ ipq_rcv_skb(struct sk_buff *skb) static void ipq_rcv_sk(struct sock *sk, int len) { - do { - struct sk_buff *skb; + struct sk_buff *skb; + unsigned int qlen; - if (down_trylock(&ipqnl_sem)) - return; + down(&ipqnl_sem); - while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { - ipq_rcv_skb(skb); - kfree_skb(skb); - } + for (qlen = skb_queue_len(&sk->sk_receive_queue); qlen; qlen--) { + skb = skb_dequeue(&sk->sk_receive_queue); + ipq_rcv_skb(skb); + kfree_skb(skb); + } - up(&ipqnl_sem); - - } while (ipqnl && ipqnl->sk_receive_queue.qlen); + up(&ipqnl_sem); } static int diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c index 01b4a3c814d..47449ba83eb 100644 --- a/net/ipv4/netfilter/iptable_raw.c +++ b/net/ipv4/netfilter/iptable_raw.c @@ -103,13 +103,15 @@ static struct nf_hook_ops ipt_ops[] = { .hook = ipt_hook, .pf = PF_INET, .hooknum = NF_IP_PRE_ROUTING, - .priority = NF_IP_PRI_RAW + .priority = NF_IP_PRI_RAW, + .owner = THIS_MODULE, }, { .hook = ipt_hook, .pf = PF_INET, .hooknum = NF_IP_LOCAL_OUT, - .priority = NF_IP_PRI_RAW + .priority = NF_IP_PRI_RAW, + .owner = THIS_MODULE, }, }; diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c index 313c1408da3..8faa8948f75 100644 --- a/net/ipv4/tcp_diag.c +++ b/net/ipv4/tcp_diag.c @@ -777,8 +777,9 @@ static inline void tcpdiag_rcv_skb(struct sk_buff *skb) static void tcpdiag_rcv(struct sock *sk, int len) { struct sk_buff *skb; + unsigned int qlen = skb_queue_len(&sk->sk_receive_queue); - while ((skb = skb_dequeue(&sk->sk_receive_queue)) != NULL) { + while (qlen-- && (skb = skb_dequeue(&sk->sk_receive_queue))) { tcpdiag_rcv_skb(skb); kfree_skb(skb); } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 3ac6659869c..dad98e4a504 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -222,10 +222,13 @@ static int tcp_v4_get_port(struct sock *sk, unsigned short snum) int rover; spin_lock(&tcp_portalloc_lock); - rover = tcp_port_rover; + if (tcp_port_rover < low) + rover = low; + else + rover = tcp_port_rover; do { rover++; - if (rover < low || rover > high) + if (rover > high) rover = low; head = &tcp_bhash[tcp_bhashfn(rover)]; spin_lock(&head->lock); diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 7fe2afd2e66..b2b60f3e9cd 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -8,7 +8,10 @@ * */ +#include <asm/bug.h> +#include <linux/compiler.h> #include <linux/config.h> +#include <linux/inetdevice.h> #include <net/xfrm.h> #include <net/ip.h> @@ -152,6 +155,8 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int x->u.rt.rt_dst = rt0->rt_dst; x->u.rt.rt_gateway = rt->rt_gateway; x->u.rt.rt_spec_dst = rt0->rt_spec_dst; + x->u.rt.idev = rt0->idev; + in_dev_hold(rt0->idev); header_len -= x->u.dst.xfrm->props.header_len; trailer_len -= x->u.dst.xfrm->props.trailer_len; } @@ -243,11 +248,48 @@ static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu) path->ops->update_pmtu(path, mtu); } +static void xfrm4_dst_destroy(struct dst_entry *dst) +{ + struct xfrm_dst *xdst = (struct xfrm_dst *)dst; + + if (likely(xdst->u.rt.idev)) + in_dev_put(xdst->u.rt.idev); + xfrm_dst_destroy(xdst); +} + +static void xfrm4_dst_ifdown(struct dst_entry *dst, struct net_device *dev, + int unregister) +{ + struct xfrm_dst *xdst; + + if (!unregister) + return; + + xdst = (struct xfrm_dst *)dst; + if (xdst->u.rt.idev->dev == dev) { + struct in_device *loopback_idev = in_dev_get(&loopback_dev); + BUG_ON(!loopback_idev); + + do { + in_dev_put(xdst->u.rt.idev); + xdst->u.rt.idev = loopback_idev; + in_dev_hold(loopback_idev); + xdst = (struct xfrm_dst *)xdst->u.dst.child; + } while (xdst->u.dst.xfrm); + + __in_dev_put(loopback_idev); + } + + xfrm_dst_ifdown(dst, dev); +} + static struct dst_ops xfrm4_dst_ops = { .family = AF_INET, .protocol = __constant_htons(ETH_P_IP), .gc = xfrm4_garbage_collect, .update_pmtu = xfrm4_update_pmtu, + .destroy = xfrm4_dst_destroy, + .ifdown = xfrm4_dst_ifdown, .gc_thresh = 1024, .entry_size = sizeof(struct xfrm_dst), }; |