Skip to content

Commit

Permalink
[IPV6] ADDRCONF: Support RFC3484 configurable address selection polic…
Browse files Browse the repository at this point in the history
…y table.

Policy table is implemented as an RCU linear list since we do not expect
large list nor frequent updates.

Signed-off-by: YOSHIFUJI Hideaki <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
yoshfuji authored and davem330 committed Jan 28, 2008
1 parent 303065a commit 2a8cc6c
Show file tree
Hide file tree
Showing 6 changed files with 608 additions and 31 deletions.
32 changes: 32 additions & 0 deletions include/linux/if_addrlabel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* if_addrlabel.h - netlink interface for address labels
*
* Copyright (C)2007 USAGI/WIDE Project, All Rights Reserved.
*
* Authors:
* YOSHIFUJI Hideaki @ USAGI/WIDE <[email protected]>
*/

#ifndef __LINUX_IF_ADDRLABEL_H
#define __LINUX_IF_ADDRLABEL_H

struct ifaddrlblmsg
{
__u8 ifal_family; /* Address family */
__u8 __ifal_reserved; /* Reserved */
__u8 ifal_prefixlen; /* Prefix length */
__u8 ifal_flags; /* Flags */
__u32 ifal_index; /* Link index */
__u32 ifal_seq; /* sequence number */
};

enum
{
IFAL_ADDRESS = 1,
IFAL_LABEL = 2,
__IFAL_MAX
};

#define IFAL_MAX (__IFAL_MAX - 1)

#endif
7 changes: 7 additions & 0 deletions include/linux/rtnetlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ enum {
RTM_NEWNDUSEROPT = 68,
#define RTM_NEWNDUSEROPT RTM_NEWNDUSEROPT

RTM_NEWADDRLABEL = 72,
#define RTM_NEWADDRLABEL RTM_NEWADDRLABEL
RTM_DELADDRLABEL,
#define RTM_NEWADDRLABEL RTM_NEWADDRLABEL
RTM_GETADDRLABEL,
#define RTM_GETADDRLABEL RTM_GETADDRLABEL

__RTM_MAX,
#define RTM_MAX (((__RTM_MAX + 3) & ~3) - 1)
};
Expand Down
8 changes: 8 additions & 0 deletions include/net/addrconf.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,14 @@ extern void addrconf_join_solict(struct net_device *dev,
extern void addrconf_leave_solict(struct inet6_dev *idev,
struct in6_addr *addr);

/*
* IPv6 Address Label subsystem (addrlabel.c)
*/
extern int ipv6_addr_label_init(void);
extern void ipv6_addr_label_rtnl_register(void);
extern u32 ipv6_addr_label(const struct in6_addr *addr,
int type, int ifindex);

/*
* multicast prototypes (mcast.c)
*/
Expand Down
1 change: 1 addition & 0 deletions net/ipv6/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
obj-$(CONFIG_IPV6) += ipv6.o

ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \
addrlabel.o \
route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o udplite.o \
raw.o protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
exthdrs.o sysctl_net_ipv6.o datagram.o \
Expand Down
40 changes: 9 additions & 31 deletions net/ipv6/addrconf.c
Original file line number Diff line number Diff line change
Expand Up @@ -874,36 +874,6 @@ static inline int ipv6_saddr_preferred(int type)
return 0;
}

/* static matching label */
static inline int ipv6_addr_label(const struct in6_addr *addr, int type,
int ifindex)
{
/*
* prefix (longest match) label
* -----------------------------
* ::1/128 0
* ::/0 1
* 2002::/16 2
* ::/96 3
* ::ffff:0:0/96 4
* fc00::/7 5
* 2001::/32 6
*/
if (type & IPV6_ADDR_LOOPBACK)
return 0;
else if (type & IPV6_ADDR_COMPATv4)
return 3;
else if (type & IPV6_ADDR_MAPPED)
return 4;
else if (addr->s6_addr32[0] == htonl(0x20010000))
return 6;
else if (addr->s6_addr16[0] == htons(0x2002))
return 2;
else if ((addr->s6_addr[0] & 0xfe) == 0xfc)
return 5;
return 1;
}

int ipv6_dev_get_saddr(struct net_device *daddr_dev,
struct in6_addr *daddr, struct in6_addr *saddr)
{
Expand Down Expand Up @@ -4189,7 +4159,13 @@ EXPORT_SYMBOL(unregister_inet6addr_notifier);

int __init addrconf_init(void)
{
int err = 0;
int err;

if ((err = ipv6_addr_label_init()) < 0) {
printk(KERN_CRIT "IPv6 Addrconf: cannot initialize default policy table: %d.\n",
err);
return err;
}

/* The addrconf netdev notifier requires that loopback_dev
* has it's ipv6 private information allocated and setup
Expand Down Expand Up @@ -4240,6 +4216,8 @@ int __init addrconf_init(void)
__rtnl_register(PF_INET6, RTM_GETMULTICAST, NULL, inet6_dump_ifmcaddr);
__rtnl_register(PF_INET6, RTM_GETANYCAST, NULL, inet6_dump_ifacaddr);

ipv6_addr_label_rtnl_register();

#ifdef CONFIG_SYSCTL
addrconf_sysctl.sysctl_header =
register_sysctl_table(addrconf_sysctl.addrconf_root_dir);
Expand Down
Loading

0 comments on commit 2a8cc6c

Please sign in to comment.