* ::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.
*/
.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,
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);
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 */
rcu_read_unlock();
ADDRLABEL(KERN_DEBUG "%s(addr=" NIP6_FMT ", type=%d, ifindex=%d) => %08x\n",
- __FUNCTION__,
+ __func__,
NIP6(*addr), type, ifindex,
label);
}
/* allocate one entry */
-struct ip6addrlbl_entry *ip6addrlbl_alloc(const struct in6_addr *prefix,
- int prefixlen, int ifindex,
- u32 label)
+static struct ip6addrlbl_entry *ip6addrlbl_alloc(const struct in6_addr *prefix,
+ int prefixlen, int ifindex,
+ u32 label)
{
struct ip6addrlbl_entry *newp;
int addrtype;
ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d, label=%u)\n",
- __FUNCTION__,
+ __func__,
NIP6(*prefix), prefixlen,
ifindex,
(unsigned int)label);
}
/* add a label */
-int __ip6addrlbl_add(struct ip6addrlbl_entry *newp, int replace)
+static int __ip6addrlbl_add(struct ip6addrlbl_entry *newp, int replace)
{
int ret = 0;
ADDRLABEL(KERN_DEBUG "%s(newp=%p, replace=%d)\n",
- __FUNCTION__,
+ __func__,
newp, replace);
if (hlist_empty(&ip6addrlbl_table.head)) {
}
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)) {
}
/* add a label */
-int ip6addrlbl_add(const struct in6_addr *prefix, int prefixlen,
- int ifindex, u32 label, int replace)
+static int ip6addrlbl_add(const struct in6_addr *prefix, int prefixlen,
+ int ifindex, u32 label, int replace)
{
struct ip6addrlbl_entry *newp;
int ret = 0;
ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d, label=%u, replace=%d)\n",
- __FUNCTION__,
+ __func__,
NIP6(*prefix), prefixlen,
ifindex,
(unsigned int)label,
}
/* remove a label */
-int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
- int ifindex)
+static int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
+ int ifindex)
{
struct ip6addrlbl_entry *p = NULL;
struct hlist_node *pos, *n;
int ret = -ESRCH;
ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d)\n",
- __FUNCTION__,
+ __func__,
NIP6(*prefix), prefixlen,
ifindex);
ipv6_addr_equal(&p->prefix, prefix)) {
hlist_del_rcu(&p->list);
ip6addrlbl_put(p);
- call_rcu(&p->rcu, ip6addrlbl_free_rcu);
ret = 0;
break;
}
return ret;
}
-int ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
- int ifindex)
+static int ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
+ int ifindex)
{
struct in6_addr prefix_buf;
int ret;
ADDRLABEL(KERN_DEBUG "%s(prefix=" NIP6_FMT ", prefixlen=%d, ifindex=%d)\n",
- __FUNCTION__,
+ __func__,
NIP6(*prefix), prefixlen,
ifindex);
int err = 0;
int i;
- ADDRLABEL(KERN_DEBUG "%s()\n", __FUNCTION__);
+ ADDRLABEL(KERN_DEBUG "%s()\n", __func__);
for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) {
int ret = ip6addrlbl_add(ip6addrlbl_init_table[i].prefix,
static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
void *arg)
{
+ struct net *net = sock_net(skb->sk);
struct ifaddrlblmsg *ifal;
struct nlattr *tb[IFAL_MAX+1];
struct in6_addr *pfx;
u32 label;
int err = 0;
+ if (net != &init_net)
+ return 0;
+
err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy);
if (err < 0)
return err;
static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb)
{
+ struct net *net = sock_net(skb->sk);
struct ip6addrlbl_entry *p;
struct hlist_node *pos;
int idx = 0, s_idx = cb->args[0];
int err;
+ if (net != &init_net)
+ return 0;
+
rcu_read_lock();
hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) {
if (idx >= s_idx) {
static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
void *arg)
{
+ struct net *net = sock_net(in_skb->sk);
struct ifaddrlblmsg *ifal;
struct nlattr *tb[IFAL_MAX+1];
struct in6_addr *addr;
struct ip6addrlbl_entry *p;
struct sk_buff *skb;
+ if (net != &init_net)
+ return 0;
+
err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy);
if (err < 0)
return err;
goto out;
}
- err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
+ err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
out:
return err;
}