diff options
author | David S. Miller <davem@davemloft.net> | 2011-02-04 17:28:58 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-02-04 17:28:58 -0500 |
commit | bd4a6974cc9090ef3851e5b0a2071e5383565c7c (patch) | |
tree | e96ef46426d293b730a305b5185ba5412c9172d4 /net | |
parent | 2b7bcebf958c74124220ee8103024def8597b36c (diff) | |
parent | 1e6d93e45b231b3ae87c01902ede2315aacfe976 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Diffstat (limited to 'net')
-rw-r--r-- | net/bridge/br_fdb.c | 4 | ||||
-rw-r--r-- | net/core/dev.c | 4 | ||||
-rw-r--r-- | net/ipv4/ipmr.c | 32 | ||||
-rw-r--r-- | net/ipv4/netfilter/arpt_mangle.c | 6 | ||||
-rw-r--r-- | net/ipv4/route.c | 6 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 75 | ||||
-rw-r--r-- | net/ipv6/raw.c | 19 | ||||
-rw-r--r-- | net/ipv6/route.c | 6 | ||||
-rw-r--r-- | net/ipv6/sysctl_net_ipv6.c | 9 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_ecache.c | 3 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_netlink.c | 1 | ||||
-rw-r--r-- | net/netfilter/xt_iprange.c | 16 |
12 files changed, 164 insertions, 17 deletions
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 2872393b2939..88485cc74dc3 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c | |||
@@ -328,12 +328,12 @@ static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head, | |||
328 | fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC); | 328 | fdb = kmem_cache_alloc(br_fdb_cache, GFP_ATOMIC); |
329 | if (fdb) { | 329 | if (fdb) { |
330 | memcpy(fdb->addr.addr, addr, ETH_ALEN); | 330 | memcpy(fdb->addr.addr, addr, ETH_ALEN); |
331 | hlist_add_head_rcu(&fdb->hlist, head); | ||
332 | |||
333 | fdb->dst = source; | 331 | fdb->dst = source; |
334 | fdb->is_local = is_local; | 332 | fdb->is_local = is_local; |
335 | fdb->is_static = is_local; | 333 | fdb->is_static = is_local; |
336 | fdb->ageing_timer = jiffies; | 334 | fdb->ageing_timer = jiffies; |
335 | |||
336 | hlist_add_head_rcu(&fdb->hlist, head); | ||
337 | } | 337 | } |
338 | return fdb; | 338 | return fdb; |
339 | } | 339 | } |
diff --git a/net/core/dev.c b/net/core/dev.c index 9109e2648d4d..f46ee357ff2e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2666,7 +2666,8 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb, | |||
2666 | 2666 | ||
2667 | map = rcu_dereference(rxqueue->rps_map); | 2667 | map = rcu_dereference(rxqueue->rps_map); |
2668 | if (map) { | 2668 | if (map) { |
2669 | if (map->len == 1) { | 2669 | if (map->len == 1 && |
2670 | !rcu_dereference_raw(rxqueue->rps_flow_table)) { | ||
2670 | tcpu = map->cpus[0]; | 2671 | tcpu = map->cpus[0]; |
2671 | if (cpu_online(tcpu)) | 2672 | if (cpu_online(tcpu)) |
2672 | cpu = tcpu; | 2673 | cpu = tcpu; |
@@ -3565,6 +3566,7 @@ static void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb) | |||
3565 | skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); | 3566 | skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb)); |
3566 | skb->vlan_tci = 0; | 3567 | skb->vlan_tci = 0; |
3567 | skb->dev = napi->dev; | 3568 | skb->dev = napi->dev; |
3569 | skb->skb_iif = 0; | ||
3568 | 3570 | ||
3569 | napi->skb = skb; | 3571 | napi->skb = skb; |
3570 | } | 3572 | } |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 7e41ac0b9260..8b65a12654e7 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -1444,9 +1444,19 @@ struct compat_sioc_sg_req { | |||
1444 | compat_ulong_t wrong_if; | 1444 | compat_ulong_t wrong_if; |
1445 | }; | 1445 | }; |
1446 | 1446 | ||
1447 | struct compat_sioc_vif_req { | ||
1448 | vifi_t vifi; /* Which iface */ | ||
1449 | compat_ulong_t icount; | ||
1450 | compat_ulong_t ocount; | ||
1451 | compat_ulong_t ibytes; | ||
1452 | compat_ulong_t obytes; | ||
1453 | }; | ||
1454 | |||
1447 | int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) | 1455 | int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) |
1448 | { | 1456 | { |
1449 | struct sioc_sg_req sr; | 1457 | struct compat_sioc_sg_req sr; |
1458 | struct compat_sioc_vif_req vr; | ||
1459 | struct vif_device *vif; | ||
1450 | struct mfc_cache *c; | 1460 | struct mfc_cache *c; |
1451 | struct net *net = sock_net(sk); | 1461 | struct net *net = sock_net(sk); |
1452 | struct mr_table *mrt; | 1462 | struct mr_table *mrt; |
@@ -1456,6 +1466,26 @@ int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) | |||
1456 | return -ENOENT; | 1466 | return -ENOENT; |
1457 | 1467 | ||
1458 | switch (cmd) { | 1468 | switch (cmd) { |
1469 | case SIOCGETVIFCNT: | ||
1470 | if (copy_from_user(&vr, arg, sizeof(vr))) | ||
1471 | return -EFAULT; | ||
1472 | if (vr.vifi >= mrt->maxvif) | ||
1473 | return -EINVAL; | ||
1474 | read_lock(&mrt_lock); | ||
1475 | vif = &mrt->vif_table[vr.vifi]; | ||
1476 | if (VIF_EXISTS(mrt, vr.vifi)) { | ||
1477 | vr.icount = vif->pkt_in; | ||
1478 | vr.ocount = vif->pkt_out; | ||
1479 | vr.ibytes = vif->bytes_in; | ||
1480 | vr.obytes = vif->bytes_out; | ||
1481 | read_unlock(&mrt_lock); | ||
1482 | |||
1483 | if (copy_to_user(arg, &vr, sizeof(vr))) | ||
1484 | return -EFAULT; | ||
1485 | return 0; | ||
1486 | } | ||
1487 | read_unlock(&mrt_lock); | ||
1488 | return -EADDRNOTAVAIL; | ||
1459 | case SIOCGETSGCNT: | 1489 | case SIOCGETSGCNT: |
1460 | if (copy_from_user(&sr, arg, sizeof(sr))) | 1490 | if (copy_from_user(&sr, arg, sizeof(sr))) |
1461 | return -EFAULT; | 1491 | return -EFAULT; |
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c index b8ddcc480ed9..a5e52a9f0a12 100644 --- a/net/ipv4/netfilter/arpt_mangle.c +++ b/net/ipv4/netfilter/arpt_mangle.c | |||
@@ -60,12 +60,12 @@ static int checkentry(const struct xt_tgchk_param *par) | |||
60 | 60 | ||
61 | if (mangle->flags & ~ARPT_MANGLE_MASK || | 61 | if (mangle->flags & ~ARPT_MANGLE_MASK || |
62 | !(mangle->flags & ARPT_MANGLE_MASK)) | 62 | !(mangle->flags & ARPT_MANGLE_MASK)) |
63 | return false; | 63 | return -EINVAL; |
64 | 64 | ||
65 | if (mangle->target != NF_DROP && mangle->target != NF_ACCEPT && | 65 | if (mangle->target != NF_DROP && mangle->target != NF_ACCEPT && |
66 | mangle->target != XT_CONTINUE) | 66 | mangle->target != XT_CONTINUE) |
67 | return false; | 67 | return -EINVAL; |
68 | return true; | 68 | return 0; |
69 | } | 69 | } |
70 | 70 | ||
71 | static struct xt_target arpt_mangle_reg __read_mostly = { | 71 | static struct xt_target arpt_mangle_reg __read_mostly = { |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 242a3de83fbb..e4c81652f17d 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -2773,6 +2773,11 @@ static struct dst_entry *ipv4_blackhole_dst_check(struct dst_entry *dst, u32 coo | |||
2773 | return NULL; | 2773 | return NULL; |
2774 | } | 2774 | } |
2775 | 2775 | ||
2776 | static unsigned int ipv4_blackhole_default_mtu(const struct dst_entry *dst) | ||
2777 | { | ||
2778 | return 0; | ||
2779 | } | ||
2780 | |||
2776 | static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) | 2781 | static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) |
2777 | { | 2782 | { |
2778 | } | 2783 | } |
@@ -2782,6 +2787,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = { | |||
2782 | .protocol = cpu_to_be16(ETH_P_IP), | 2787 | .protocol = cpu_to_be16(ETH_P_IP), |
2783 | .destroy = ipv4_dst_destroy, | 2788 | .destroy = ipv4_dst_destroy, |
2784 | .check = ipv4_blackhole_dst_check, | 2789 | .check = ipv4_blackhole_dst_check, |
2790 | .default_mtu = ipv4_blackhole_default_mtu, | ||
2785 | .update_pmtu = ipv4_rt_blackhole_update_pmtu, | 2791 | .update_pmtu = ipv4_rt_blackhole_update_pmtu, |
2786 | }; | 2792 | }; |
2787 | 2793 | ||
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 9fab274019c0..0e1d53bcf1e0 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/seq_file.h> | 34 | #include <linux/seq_file.h> |
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
37 | #include <linux/compat.h> | ||
37 | #include <net/protocol.h> | 38 | #include <net/protocol.h> |
38 | #include <linux/skbuff.h> | 39 | #include <linux/skbuff.h> |
39 | #include <net/sock.h> | 40 | #include <net/sock.h> |
@@ -1804,6 +1805,80 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg) | |||
1804 | } | 1805 | } |
1805 | } | 1806 | } |
1806 | 1807 | ||
1808 | #ifdef CONFIG_COMPAT | ||
1809 | struct compat_sioc_sg_req6 { | ||
1810 | struct sockaddr_in6 src; | ||
1811 | struct sockaddr_in6 grp; | ||
1812 | compat_ulong_t pktcnt; | ||
1813 | compat_ulong_t bytecnt; | ||
1814 | compat_ulong_t wrong_if; | ||
1815 | }; | ||
1816 | |||
1817 | struct compat_sioc_mif_req6 { | ||
1818 | mifi_t mifi; | ||
1819 | compat_ulong_t icount; | ||
1820 | compat_ulong_t ocount; | ||
1821 | compat_ulong_t ibytes; | ||
1822 | compat_ulong_t obytes; | ||
1823 | }; | ||
1824 | |||
1825 | int ip6mr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) | ||
1826 | { | ||
1827 | struct compat_sioc_sg_req6 sr; | ||
1828 | struct compat_sioc_mif_req6 vr; | ||
1829 | struct mif_device *vif; | ||
1830 | struct mfc6_cache *c; | ||
1831 | struct net *net = sock_net(sk); | ||
1832 | struct mr6_table *mrt; | ||
1833 | |||
1834 | mrt = ip6mr_get_table(net, raw6_sk(sk)->ip6mr_table ? : RT6_TABLE_DFLT); | ||
1835 | if (mrt == NULL) | ||
1836 | return -ENOENT; | ||
1837 | |||
1838 | switch (cmd) { | ||
1839 | case SIOCGETMIFCNT_IN6: | ||
1840 | if (copy_from_user(&vr, arg, sizeof(vr))) | ||
1841 | return -EFAULT; | ||
1842 | if (vr.mifi >= mrt->maxvif) | ||
1843 | return -EINVAL; | ||
1844 | read_lock(&mrt_lock); | ||
1845 | vif = &mrt->vif6_table[vr.mifi]; | ||
1846 | if (MIF_EXISTS(mrt, vr.mifi)) { | ||
1847 | vr.icount = vif->pkt_in; | ||
1848 | vr.ocount = vif->pkt_out; | ||
1849 | vr.ibytes = vif->bytes_in; | ||
1850 | vr.obytes = vif->bytes_out; | ||
1851 | read_unlock(&mrt_lock); | ||
1852 | |||
1853 | if (copy_to_user(arg, &vr, sizeof(vr))) | ||
1854 | return -EFAULT; | ||
1855 | return 0; | ||
1856 | } | ||
1857 | read_unlock(&mrt_lock); | ||
1858 | return -EADDRNOTAVAIL; | ||
1859 | case SIOCGETSGCNT_IN6: | ||
1860 | if (copy_from_user(&sr, arg, sizeof(sr))) | ||
1861 | return -EFAULT; | ||
1862 | |||
1863 | read_lock(&mrt_lock); | ||
1864 | c = ip6mr_cache_find(mrt, &sr.src.sin6_addr, &sr.grp.sin6_addr); | ||
1865 | if (c) { | ||
1866 | sr.pktcnt = c->mfc_un.res.pkt; | ||
1867 | sr.bytecnt = c->mfc_un.res.bytes; | ||
1868 | sr.wrong_if = c->mfc_un.res.wrong_if; | ||
1869 | read_unlock(&mrt_lock); | ||
1870 | |||
1871 | if (copy_to_user(arg, &sr, sizeof(sr))) | ||
1872 | return -EFAULT; | ||
1873 | return 0; | ||
1874 | } | ||
1875 | read_unlock(&mrt_lock); | ||
1876 | return -EADDRNOTAVAIL; | ||
1877 | default: | ||
1878 | return -ENOIOCTLCMD; | ||
1879 | } | ||
1880 | } | ||
1881 | #endif | ||
1807 | 1882 | ||
1808 | static inline int ip6mr_forward2_finish(struct sk_buff *skb) | 1883 | static inline int ip6mr_forward2_finish(struct sk_buff *skb) |
1809 | { | 1884 | { |
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 2bc6cd7bb8ec..364e86683388 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/netfilter.h> | 31 | #include <linux/netfilter.h> |
32 | #include <linux/netfilter_ipv6.h> | 32 | #include <linux/netfilter_ipv6.h> |
33 | #include <linux/skbuff.h> | 33 | #include <linux/skbuff.h> |
34 | #include <linux/compat.h> | ||
34 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
35 | #include <asm/ioctls.h> | 36 | #include <asm/ioctls.h> |
36 | 37 | ||
@@ -1157,6 +1158,23 @@ static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
1157 | } | 1158 | } |
1158 | } | 1159 | } |
1159 | 1160 | ||
1161 | #ifdef CONFIG_COMPAT | ||
1162 | static int compat_rawv6_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg) | ||
1163 | { | ||
1164 | switch (cmd) { | ||
1165 | case SIOCOUTQ: | ||
1166 | case SIOCINQ: | ||
1167 | return -ENOIOCTLCMD; | ||
1168 | default: | ||
1169 | #ifdef CONFIG_IPV6_MROUTE | ||
1170 | return ip6mr_compat_ioctl(sk, cmd, compat_ptr(arg)); | ||
1171 | #else | ||
1172 | return -ENOIOCTLCMD; | ||
1173 | #endif | ||
1174 | } | ||
1175 | } | ||
1176 | #endif | ||
1177 | |||
1160 | static void rawv6_close(struct sock *sk, long timeout) | 1178 | static void rawv6_close(struct sock *sk, long timeout) |
1161 | { | 1179 | { |
1162 | if (inet_sk(sk)->inet_num == IPPROTO_RAW) | 1180 | if (inet_sk(sk)->inet_num == IPPROTO_RAW) |
@@ -1215,6 +1233,7 @@ struct proto rawv6_prot = { | |||
1215 | #ifdef CONFIG_COMPAT | 1233 | #ifdef CONFIG_COMPAT |
1216 | .compat_setsockopt = compat_rawv6_setsockopt, | 1234 | .compat_setsockopt = compat_rawv6_setsockopt, |
1217 | .compat_getsockopt = compat_rawv6_getsockopt, | 1235 | .compat_getsockopt = compat_rawv6_getsockopt, |
1236 | .compat_ioctl = compat_rawv6_ioctl, | ||
1218 | #endif | 1237 | #endif |
1219 | }; | 1238 | }; |
1220 | 1239 | ||
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 72609f1c6158..0a63d44e6f48 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -144,6 +144,11 @@ static struct dst_ops ip6_dst_ops_template = { | |||
144 | .local_out = __ip6_local_out, | 144 | .local_out = __ip6_local_out, |
145 | }; | 145 | }; |
146 | 146 | ||
147 | static unsigned int ip6_blackhole_default_mtu(const struct dst_entry *dst) | ||
148 | { | ||
149 | return 0; | ||
150 | } | ||
151 | |||
147 | static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) | 152 | static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu) |
148 | { | 153 | { |
149 | } | 154 | } |
@@ -153,6 +158,7 @@ static struct dst_ops ip6_dst_blackhole_ops = { | |||
153 | .protocol = cpu_to_be16(ETH_P_IPV6), | 158 | .protocol = cpu_to_be16(ETH_P_IPV6), |
154 | .destroy = ip6_dst_destroy, | 159 | .destroy = ip6_dst_destroy, |
155 | .check = ip6_dst_check, | 160 | .check = ip6_dst_check, |
161 | .default_mtu = ip6_blackhole_default_mtu, | ||
156 | .update_pmtu = ip6_rt_blackhole_update_pmtu, | 162 | .update_pmtu = ip6_rt_blackhole_update_pmtu, |
157 | }; | 163 | }; |
158 | 164 | ||
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index fa1d8f4e0051..7cb65ef79f9c 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c | |||
@@ -15,6 +15,8 @@ | |||
15 | #include <net/addrconf.h> | 15 | #include <net/addrconf.h> |
16 | #include <net/inet_frag.h> | 16 | #include <net/inet_frag.h> |
17 | 17 | ||
18 | static struct ctl_table empty[1]; | ||
19 | |||
18 | static ctl_table ipv6_table_template[] = { | 20 | static ctl_table ipv6_table_template[] = { |
19 | { | 21 | { |
20 | .procname = "route", | 22 | .procname = "route", |
@@ -35,6 +37,12 @@ static ctl_table ipv6_table_template[] = { | |||
35 | .mode = 0644, | 37 | .mode = 0644, |
36 | .proc_handler = proc_dointvec | 38 | .proc_handler = proc_dointvec |
37 | }, | 39 | }, |
40 | { | ||
41 | .procname = "neigh", | ||
42 | .maxlen = 0, | ||
43 | .mode = 0555, | ||
44 | .child = empty, | ||
45 | }, | ||
38 | { } | 46 | { } |
39 | }; | 47 | }; |
40 | 48 | ||
@@ -152,7 +160,6 @@ static struct ctl_table_header *ip6_base; | |||
152 | 160 | ||
153 | int ipv6_static_sysctl_register(void) | 161 | int ipv6_static_sysctl_register(void) |
154 | { | 162 | { |
155 | static struct ctl_table empty[1]; | ||
156 | ip6_base = register_sysctl_paths(net_ipv6_ctl_path, empty); | 163 | ip6_base = register_sysctl_paths(net_ipv6_ctl_path, empty); |
157 | if (ip6_base == NULL) | 164 | if (ip6_base == NULL) |
158 | return -ENOMEM; | 165 | return -ENOMEM; |
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c index 5702de35e2bb..63a1b915a7e4 100644 --- a/net/netfilter/nf_conntrack_ecache.c +++ b/net/netfilter/nf_conntrack_ecache.c | |||
@@ -63,6 +63,9 @@ void nf_ct_deliver_cached_events(struct nf_conn *ct) | |||
63 | * this does not harm and it happens very rarely. */ | 63 | * this does not harm and it happens very rarely. */ |
64 | unsigned long missed = e->missed; | 64 | unsigned long missed = e->missed; |
65 | 65 | ||
66 | if (!((events | missed) & e->ctmask)) | ||
67 | goto out_unlock; | ||
68 | |||
66 | ret = notify->fcn(events | missed, &item); | 69 | ret = notify->fcn(events | missed, &item); |
67 | if (unlikely(ret < 0 || missed)) { | 70 | if (unlikely(ret < 0 || missed)) { |
68 | spin_lock_bh(&ct->lock); | 71 | spin_lock_bh(&ct->lock); |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index b4df3eff4240..30bf8a167fc8 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -710,6 +710,7 @@ restart: | |||
710 | if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid, | 710 | if (ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).pid, |
711 | cb->nlh->nlmsg_seq, | 711 | cb->nlh->nlmsg_seq, |
712 | IPCTNL_MSG_CT_NEW, ct) < 0) { | 712 | IPCTNL_MSG_CT_NEW, ct) < 0) { |
713 | nf_conntrack_get(&ct->ct_general); | ||
713 | cb->args[1] = (unsigned long)ct; | 714 | cb->args[1] = (unsigned long)ct; |
714 | goto out; | 715 | goto out; |
715 | } | 716 | } |
diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c index d3eb5ed1892f..b46626cddd93 100644 --- a/net/netfilter/xt_iprange.c +++ b/net/netfilter/xt_iprange.c | |||
@@ -53,15 +53,13 @@ iprange_mt4(const struct sk_buff *skb, struct xt_action_param *par) | |||
53 | } | 53 | } |
54 | 54 | ||
55 | static inline int | 55 | static inline int |
56 | iprange_ipv6_sub(const struct in6_addr *a, const struct in6_addr *b) | 56 | iprange_ipv6_lt(const struct in6_addr *a, const struct in6_addr *b) |
57 | { | 57 | { |
58 | unsigned int i; | 58 | unsigned int i; |
59 | int r; | ||
60 | 59 | ||
61 | for (i = 0; i < 4; ++i) { | 60 | for (i = 0; i < 4; ++i) { |
62 | r = ntohl(a->s6_addr32[i]) - ntohl(b->s6_addr32[i]); | 61 | if (a->s6_addr32[i] != b->s6_addr32[i]) |
63 | if (r != 0) | 62 | return ntohl(a->s6_addr32[i]) < ntohl(b->s6_addr32[i]); |
64 | return r; | ||
65 | } | 63 | } |
66 | 64 | ||
67 | return 0; | 65 | return 0; |
@@ -75,8 +73,8 @@ iprange_mt6(const struct sk_buff *skb, struct xt_action_param *par) | |||
75 | bool m; | 73 | bool m; |
76 | 74 | ||
77 | if (info->flags & IPRANGE_SRC) { | 75 | if (info->flags & IPRANGE_SRC) { |
78 | m = iprange_ipv6_sub(&iph->saddr, &info->src_min.in6) < 0; | 76 | m = iprange_ipv6_lt(&iph->saddr, &info->src_min.in6); |
79 | m |= iprange_ipv6_sub(&iph->saddr, &info->src_max.in6) > 0; | 77 | m |= iprange_ipv6_lt(&info->src_max.in6, &iph->saddr); |
80 | m ^= !!(info->flags & IPRANGE_SRC_INV); | 78 | m ^= !!(info->flags & IPRANGE_SRC_INV); |
81 | if (m) { | 79 | if (m) { |
82 | pr_debug("src IP %pI6 NOT in range %s%pI6-%pI6\n", | 80 | pr_debug("src IP %pI6 NOT in range %s%pI6-%pI6\n", |
@@ -88,8 +86,8 @@ iprange_mt6(const struct sk_buff *skb, struct xt_action_param *par) | |||
88 | } | 86 | } |
89 | } | 87 | } |
90 | if (info->flags & IPRANGE_DST) { | 88 | if (info->flags & IPRANGE_DST) { |
91 | m = iprange_ipv6_sub(&iph->daddr, &info->dst_min.in6) < 0; | 89 | m = iprange_ipv6_lt(&iph->daddr, &info->dst_min.in6); |
92 | m |= iprange_ipv6_sub(&iph->daddr, &info->dst_max.in6) > 0; | 90 | m |= iprange_ipv6_lt(&info->dst_max.in6, &iph->daddr); |
93 | m ^= !!(info->flags & IPRANGE_DST_INV); | 91 | m ^= !!(info->flags & IPRANGE_DST_INV); |
94 | if (m) { | 92 | if (m) { |
95 | pr_debug("dst IP %pI6 NOT in range %s%pI6-%pI6\n", | 93 | pr_debug("dst IP %pI6 NOT in range %s%pI6-%pI6\n", |