]> err.no Git - linux-2.6/blobdiff - net/ipv6/addrlabel.c
[NETNS][IPV6] fib6_rules - handle several network namespaces
[linux-2.6] / net / ipv6 / addrlabel.c
index 38674121ae5f930a08e5a24076d298935fe2c57b..3a8b3f52da35f16ca9422f02a0d7f65155ed4007 100644 (file)
@@ -58,6 +58,7 @@ static struct ip6addrlbl_table
  * ::ffff:0:0/96       V4MAPPED        4
  * fc00::/7            N/A             5               ULA (RFC 4193)
  * 2001::/32           N/A             6               Teredo (RFC 4380)
+ * 2001:10::/28                N/A             7               ORCHID (RFC 4843)
  *
  * Note: 0xffffffff is used if we do not have any policies.
  */
@@ -85,6 +86,10 @@ static const __initdata struct ip6addrlbl_init_table
                .prefix = &(struct in6_addr){{{ 0x20, 0x01 }}},
                .prefixlen = 32,
                .label = 6,
+       },{     /* 2001:10::/28 */
+               .prefix = &(struct in6_addr){{{ 0x20, 0x01, 0x00, 0x10 }}},
+               .prefixlen = 28,
+               .label = 7,
        },{     /* ::ffff:0:0 */
                .prefix = &(struct in6_addr){{{ [10] = 0xff, [11] = 0xff }}},
                .prefixlen = 96,
@@ -106,6 +111,11 @@ static inline void ip6addrlbl_free(struct ip6addrlbl_entry *p)
        kfree(p);
 }
 
+static void ip6addrlbl_free_rcu(struct rcu_head *h)
+{
+       ip6addrlbl_free(container_of(h, struct ip6addrlbl_entry, rcu));
+}
+
 static inline int ip6addrlbl_hold(struct ip6addrlbl_entry *p)
 {
        return atomic_inc_not_zero(&p->refcnt);
@@ -114,12 +124,7 @@ static inline int ip6addrlbl_hold(struct ip6addrlbl_entry *p)
 static inline void ip6addrlbl_put(struct ip6addrlbl_entry *p)
 {
        if (atomic_dec_and_test(&p->refcnt))
-               ip6addrlbl_free(p);
-}
-
-static void ip6addrlbl_free_rcu(struct rcu_head *h)
-{
-       ip6addrlbl_free(container_of(h, struct ip6addrlbl_entry, rcu));
+               call_rcu(&p->rcu, ip6addrlbl_free_rcu);
 }
 
 /* Find label */
@@ -240,7 +245,6 @@ static int __ip6addrlbl_add(struct ip6addrlbl_entry *newp, int replace)
                                }
                                hlist_replace_rcu(&p->list, &newp->list);
                                ip6addrlbl_put(p);
-                               call_rcu(&p->rcu, ip6addrlbl_free_rcu);
                                goto out;
                        } else if ((p->prefixlen == newp->prefixlen && !p->ifindex) ||
                                   (p->prefixlen < newp->prefixlen)) {
@@ -300,7 +304,6 @@ static int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
                    ipv6_addr_equal(&p->prefix, prefix)) {
                        hlist_del_rcu(&p->list);
                        ip6addrlbl_put(p);
-                       call_rcu(&p->rcu, ip6addrlbl_free_rcu);
                        ret = 0;
                        break;
                }