Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7cbca67c authored by YOSHIFUJI Hideaki's avatar YOSHIFUJI Hideaki
Browse files

[IPV6]: Support Source Address Selection API (RFC5014).

parent 1d5d236d
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -249,4 +249,15 @@ struct in6_flowlabel_req
 * IP6T_SO_GET_REVISION_TARGET	69
 */

/* RFC5014: Source address selection */
#define IPV6_ADDR_PREFERENCES	72

#define IPV6_PREFER_SRC_TMP		0x0001
#define IPV6_PREFER_SRC_PUBLIC		0x0002
#define IPV6_PREFER_SRC_PUBTMP_DEFAULT	0x0100
#define IPV6_PREFER_SRC_COA		0x0004
#define IPV6_PREFER_SRC_HOME		0x0400
#define IPV6_PREFER_SRC_CGA		0x0008
#define IPV6_PREFER_SRC_NONCGA		0x0800

#endif
+5 −1
Original line number Diff line number Diff line
@@ -322,7 +322,11 @@ struct ipv6_pinfo {
	__u8			recverr:1,
	                        sndflow:1,
				pmtudisc:2,
				ipv6only:1;
				ipv6only:1,
				srcprefs:3;	/* 001: prefer temporary address
						 * 010: prefer public address
						 * 100: prefer care-of address
						 */
	__u8			tclass;

	__u32			dst_cookie;
+1 −0
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,

extern int			ipv6_dev_get_saddr(struct net_device *dev, 
					       struct in6_addr *daddr,
					       unsigned int srcprefs,
					       struct in6_addr *saddr);
extern int			ipv6_get_lladdr(struct net_device *dev,
						struct in6_addr *addr,
+6 −3
Original line number Diff line number Diff line
@@ -30,9 +30,12 @@ struct route_info {
#include <linux/ip.h>
#include <linux/ipv6.h>

#define RT6_LOOKUP_F_IFACE	0x1
#define RT6_LOOKUP_F_REACHABLE	0x2
#define RT6_LOOKUP_F_HAS_SADDR	0x4
#define RT6_LOOKUP_F_IFACE		0x00000001
#define RT6_LOOKUP_F_REACHABLE		0x00000002
#define RT6_LOOKUP_F_HAS_SADDR		0x00000004
#define RT6_LOOKUP_F_SRCPREF_TMP	0x00000008
#define RT6_LOOKUP_F_SRCPREF_PUBLIC	0x00000010
#define RT6_LOOKUP_F_SRCPREF_COA	0x00000020

extern struct rt6_info	*ip6_null_entry;

+14 −3
Original line number Diff line number Diff line
@@ -909,6 +909,7 @@ struct ipv6_saddr_dst {
	int ifindex;
	int scope;
	int label;
	unsigned int prefs;
};

static inline int ipv6_saddr_preferred(int type)
@@ -984,9 +985,12 @@ static int ipv6_get_saddr_eval(struct ipv6_saddr_score *score,
		break;
#ifdef CONFIG_IPV6_MIP6
	case IPV6_SADDR_RULE_HOA:
	    {
		/* Rule 4: Prefer home address */
		ret = !!(score->ifa->flags & IFA_F_HOMEADDRESS);
		int prefhome = !(dst->prefs & IPV6_PREFER_SRC_COA);
		ret = !(score->ifa->flags & IFA_F_HOMEADDRESS) ^ prefhome;
		break;
	    }
#endif
	case IPV6_SADDR_RULE_OIF:
		/* Rule 5: Prefer outgoing interface */
@@ -1000,11 +1004,16 @@ static int ipv6_get_saddr_eval(struct ipv6_saddr_score *score,
		break;
#ifdef CONFIG_IPV6_PRIVACY
	case IPV6_SADDR_RULE_PRIVACY:
	    {
		/* Rule 7: Prefer public address
		 * Note: prefer temprary address if use_tempaddr >= 2
		 */
		ret = (!(score->ifa->flags & IFA_F_TEMPORARY)) ^ (score->ifa->idev->cnf.use_tempaddr >= 2);
		int preftmp = dst->prefs & (IPV6_PREFER_SRC_PUBLIC|IPV6_PREFER_SRC_TMP) ?
				!!(dst->prefs & IPV6_PREFER_SRC_TMP) :
				score->ifa->idev->cnf.use_tempaddr >= 2;
		ret = (!(score->ifa->flags & IFA_F_TEMPORARY)) ^ preftmp;
		break;
	    }
#endif
	case IPV6_SADDR_RULE_ORCHID:
		/* Rule 8-: Prefer ORCHID vs ORCHID or
@@ -1030,7 +1039,8 @@ out:
}

int ipv6_dev_get_saddr(struct net_device *dst_dev,
		       struct in6_addr *daddr, struct in6_addr *saddr)
		       struct in6_addr *daddr, unsigned int prefs,
		       struct in6_addr *saddr)
{
	struct ipv6_saddr_score scores[2],
				*score = &scores[0], *hiscore = &scores[1];
@@ -1044,6 +1054,7 @@ int ipv6_dev_get_saddr(struct net_device *dst_dev,
	dst.ifindex = dst_dev ? dst_dev->ifindex : 0;
	dst.scope = __ipv6_addr_src_scope(dst_type);
	dst.label = ipv6_addr_label(daddr, dst_type, dst.ifindex);
	dst.prefs = prefs;

	hiscore->rule = -1;
	hiscore->ifa = NULL;
Loading