]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
netlabel: correctly list all the static label mappings
authorPaul Moore <pmoore@redhat.com>
Wed, 6 Mar 2013 11:45:24 +0000 (11:45 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 20 Mar 2013 20:10:58 +0000 (13:10 -0700)
[ Upstream commits 0c1233aba1e948c37f6dc7620cb7c253fcd71ce9 and
  a6a8fe950e1b8596bb06f2c89c3a1a4bf2011ba9 ]

When we have a large number of static label mappings that spill across
the netlink message boundary we fail to properly save our state in the
netlink_callback struct which causes us to repeat the same listings.
This patch fixes this problem by saving the state correctly between
calls to the NetLabel static label netlink "dumpit" routines.

Signed-off-by: Paul Moore <pmoore@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/netlabel/netlabel_unlabeled.c

index 847d495cd4de0bee797f994fcaf491ed6efb30ce..8a6c6ea466d874dd34afd2013bef4f777a47db42 100644 (file)
@@ -1189,8 +1189,6 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
        struct netlbl_unlhsh_walk_arg cb_arg;
        u32 skip_bkt = cb->args[0];
        u32 skip_chain = cb->args[1];
-       u32 skip_addr4 = cb->args[2];
-       u32 skip_addr6 = cb->args[3];
        u32 iter_bkt;
        u32 iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0;
        struct netlbl_unlhsh_iface *iface;
@@ -1215,7 +1213,7 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
                                continue;
                        netlbl_af4list_foreach_rcu(addr4,
                                                   &iface->addr4_list) {
-                               if (iter_addr4++ < skip_addr4)
+                               if (iter_addr4++ < cb->args[2])
                                        continue;
                                if (netlbl_unlabel_staticlist_gen(
                                              NLBL_UNLABEL_C_STATICLIST,
@@ -1231,7 +1229,7 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
 #if IS_ENABLED(CONFIG_IPV6)
                        netlbl_af6list_foreach_rcu(addr6,
                                                   &iface->addr6_list) {
-                               if (iter_addr6++ < skip_addr6)
+                               if (iter_addr6++ < cb->args[3])
                                        continue;
                                if (netlbl_unlabel_staticlist_gen(
                                              NLBL_UNLABEL_C_STATICLIST,
@@ -1250,10 +1248,10 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
 
 unlabel_staticlist_return:
        rcu_read_unlock();
-       cb->args[0] = skip_bkt;
-       cb->args[1] = skip_chain;
-       cb->args[2] = skip_addr4;
-       cb->args[3] = skip_addr6;
+       cb->args[0] = iter_bkt;
+       cb->args[1] = iter_chain;
+       cb->args[2] = iter_addr4;
+       cb->args[3] = iter_addr6;
        return skb->len;
 }
 
@@ -1273,12 +1271,9 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
 {
        struct netlbl_unlhsh_walk_arg cb_arg;
        struct netlbl_unlhsh_iface *iface;
-       u32 skip_addr4 = cb->args[0];
-       u32 skip_addr6 = cb->args[1];
-       u32 iter_addr4 = 0;
+       u32 iter_addr4 = 0, iter_addr6 = 0;
        struct netlbl_af4list *addr4;
 #if IS_ENABLED(CONFIG_IPV6)
-       u32 iter_addr6 = 0;
        struct netlbl_af6list *addr6;
 #endif
 
@@ -1292,7 +1287,7 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
                goto unlabel_staticlistdef_return;
 
        netlbl_af4list_foreach_rcu(addr4, &iface->addr4_list) {
-               if (iter_addr4++ < skip_addr4)
+               if (iter_addr4++ < cb->args[0])
                        continue;
                if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
                                              iface,
@@ -1305,7 +1300,7 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
        }
 #if IS_ENABLED(CONFIG_IPV6)
        netlbl_af6list_foreach_rcu(addr6, &iface->addr6_list) {
-               if (iter_addr6++ < skip_addr6)
+               if (iter_addr6++ < cb->args[1])
                        continue;
                if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
                                              iface,
@@ -1320,8 +1315,8 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
 
 unlabel_staticlistdef_return:
        rcu_read_unlock();
-       cb->args[0] = skip_addr4;
-       cb->args[1] = skip_addr6;
+       cb->args[0] = iter_addr4;
+       cb->args[1] = iter_addr6;
        return skb->len;
 }