You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
[IPV6] ADDRCONF: Support RFC3484 configurable address selection policy 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 <yoshfuji@linux-ipv6.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
303065a854
commit
2a8cc6c890
32
include/linux/if_addrlabel.h
Normal file
32
include/linux/if_addrlabel.h
Normal file
@@ -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 <yoshfuji@linux-ipv6.org>
|
||||
*/
|
||||
|
||||
#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
|
||||
@@ -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)
|
||||
};
|
||||
|
||||
@@ -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)
|
||||
*/
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
551
net/ipv6/addrlabel.c
Normal file
551
net/ipv6/addrlabel.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user