Blame SOURCES/0008-rh1127718-inet6_addr_gen.patch

6f6f40
From 99dde0b03a7380e29544aceac6e32432632a54dc Mon Sep 17 00:00:00 2001
6f6f40
From: Dan Williams <dcbw@redhat.com>
6f6f40
Date: Fri, 25 Jul 2014 14:33:38 -0500
6f6f40
Subject: [PATCH 1/2] link: update copy of kernel header
6f6f40
 include/linux/if_link.h
6f6f40
6f6f40
The next patch will use some of these defines, so update.
6f6f40
6f6f40
Taken from upstream kernel commit bc91b0f07ada5535427373a4e2050877bcc12218,
6f6f40
file 'include/uapi/linux/if_link.h'.
6f6f40
6f6f40
Signed-off-by: Dan Williams <dcbw@redhat.com>
6f6f40
Signed-off-by: Thomas Haller <thaller@redhat.com>
6f6f40
(cherry picked from commit b51815a9dbd8e45fd2558bbe337fb360ca2fd861)
6f6f40
6f6f40
Conflicts:
6f6f40
	include/linux/if_link.h
6f6f40
---
6f6f40
 include/linux/if_link.h | 194 ++++++++++++++++++++++++++++++++++++++++++++----
6f6f40
 1 file changed, 181 insertions(+), 13 deletions(-)
6f6f40
6f6f40
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
6f6f40
index a753d11..ff95760 100644
6f6f40
--- a/include/linux/if_link.h
6f6f40
+++ b/include/linux/if_link.h
6f6f40
@@ -1,5 +1,5 @@
6f6f40
-#ifndef _LINUX_IF_LINK_H
6f6f40
-#define _LINUX_IF_LINK_H
6f6f40
+#ifndef _UAPI_LINUX_IF_LINK_H
6f6f40
+#define _UAPI_LINUX_IF_LINK_H
6f6f40
 
6f6f40
 #include <linux/types.h>
6f6f40
 #include <linux/netlink.h>
6f6f40
@@ -143,12 +143,20 @@ enum {
6f6f40
 	IFLA_NUM_TX_QUEUES,
6f6f40
 	IFLA_NUM_RX_QUEUES,
6f6f40
 	IFLA_CARRIER,
6f6f40
+	IFLA_PHYS_PORT_ID,
6f6f40
+	IFLA_CARRIER_CHANGES,
6f6f40
 	__IFLA_MAX
6f6f40
 };
6f6f40
 
6f6f40
 
6f6f40
 #define IFLA_MAX (__IFLA_MAX - 1)
6f6f40
 
6f6f40
+/* backwards compatibility for userspace */
6f6f40
+#ifndef __KERNEL__
6f6f40
+#define IFLA_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifinfomsg))))
6f6f40
+#define IFLA_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct ifinfomsg))
6f6f40
+#endif
6f6f40
+
6f6f40
 enum {
6f6f40
 	IFLA_INET_UNSPEC,
6f6f40
 	IFLA_INET_CONF,
6f6f40
@@ -195,11 +203,38 @@ enum {
6f6f40
 	IFLA_INET6_MCAST,	/* MC things. What of them?	*/
6f6f40
 	IFLA_INET6_CACHEINFO,	/* time values and max reasm size */
6f6f40
 	IFLA_INET6_ICMP6STATS,	/* statistics (icmpv6)		*/
6f6f40
+	IFLA_INET6_TOKEN,	/* device token			*/
6f6f40
+	IFLA_INET6_ADDR_GEN_MODE, /* implicit address generator mode */
6f6f40
 	__IFLA_INET6_MAX
6f6f40
 };
6f6f40
 
6f6f40
 #define IFLA_INET6_MAX	(__IFLA_INET6_MAX - 1)
6f6f40
 
6f6f40
+enum in6_addr_gen_mode {
6f6f40
+	IN6_ADDR_GEN_MODE_EUI64,
6f6f40
+	IN6_ADDR_GEN_MODE_NONE,
6f6f40
+};
6f6f40
+
6f6f40
+enum {
6f6f40
+	BRIDGE_MODE_UNSPEC,
6f6f40
+	BRIDGE_MODE_HAIRPIN,
6f6f40
+};
6f6f40
+
6f6f40
+enum {
6f6f40
+	IFLA_BRPORT_UNSPEC,
6f6f40
+	IFLA_BRPORT_STATE,	/* Spanning tree state     */
6f6f40
+	IFLA_BRPORT_PRIORITY,	/* "             priority  */
6f6f40
+	IFLA_BRPORT_COST,	/* "             cost      */
6f6f40
+	IFLA_BRPORT_MODE,	/* mode (hairpin)          */
6f6f40
+	IFLA_BRPORT_GUARD,	/* bpdu guard              */
6f6f40
+	IFLA_BRPORT_PROTECT,	/* root port protection    */
6f6f40
+	IFLA_BRPORT_FAST_LEAVE,	/* multicast fast leave    */
6f6f40
+	IFLA_BRPORT_LEARNING,	/* mac learning */
6f6f40
+	IFLA_BRPORT_UNICAST_FLOOD, /* flood unicast traffic */
6f6f40
+	__IFLA_BRPORT_MAX
6f6f40
+};
6f6f40
+#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
6f6f40
+
6f6f40
 struct ifla_cacheinfo {
6f6f40
 	__u32	max_reasm_len;
6f6f40
 	__u32	tstamp;		/* ipv6InterfaceTable updated timestamp */
6f6f40
@@ -212,6 +247,8 @@ enum {
6f6f40
 	IFLA_INFO_KIND,
6f6f40
 	IFLA_INFO_DATA,
6f6f40
 	IFLA_INFO_XSTATS,
6f6f40
+	IFLA_INFO_SLAVE_KIND,
6f6f40
+	IFLA_INFO_SLAVE_DATA,
6f6f40
 	__IFLA_INFO_MAX,
6f6f40
 };
6f6f40
 
6f6f40
@@ -225,6 +262,7 @@ enum {
6f6f40
 	IFLA_VLAN_FLAGS,
6f6f40
 	IFLA_VLAN_EGRESS_QOS,
6f6f40
 	IFLA_VLAN_INGRESS_QOS,
6f6f40
+	IFLA_VLAN_PROTOCOL,
6f6f40
 	__IFLA_VLAN_MAX,
6f6f40
 };
6f6f40
 
6f6f40
@@ -267,6 +305,95 @@ enum macvlan_mode {
6f6f40
 
6f6f40
 #define MACVLAN_FLAG_NOPROMISC	1
6f6f40
 
6f6f40
+/* VXLAN section */
6f6f40
+enum {
6f6f40
+	IFLA_VXLAN_UNSPEC,
6f6f40
+	IFLA_VXLAN_ID,
6f6f40
+	IFLA_VXLAN_GROUP,	/* group or remote address */
6f6f40
+	IFLA_VXLAN_LINK,
6f6f40
+	IFLA_VXLAN_LOCAL,
6f6f40
+	IFLA_VXLAN_TTL,
6f6f40
+	IFLA_VXLAN_TOS,
6f6f40
+	IFLA_VXLAN_LEARNING,
6f6f40
+	IFLA_VXLAN_AGEING,
6f6f40
+	IFLA_VXLAN_LIMIT,
6f6f40
+	IFLA_VXLAN_PORT_RANGE,	/* source port */
6f6f40
+	IFLA_VXLAN_PROXY,
6f6f40
+	IFLA_VXLAN_RSC,
6f6f40
+	IFLA_VXLAN_L2MISS,
6f6f40
+	IFLA_VXLAN_L3MISS,
6f6f40
+	IFLA_VXLAN_PORT,	/* destination port */
6f6f40
+	IFLA_VXLAN_GROUP6,
6f6f40
+	IFLA_VXLAN_LOCAL6,
6f6f40
+	IFLA_VXLAN_UDP_CSUM,
6f6f40
+	IFLA_VXLAN_UDP_ZERO_CSUM6_TX,
6f6f40
+	IFLA_VXLAN_UDP_ZERO_CSUM6_RX,
6f6f40
+	__IFLA_VXLAN_MAX
6f6f40
+};
6f6f40
+#define IFLA_VXLAN_MAX	(__IFLA_VXLAN_MAX - 1)
6f6f40
+
6f6f40
+struct ifla_vxlan_port_range {
6f6f40
+	__be16	low;
6f6f40
+	__be16	high;
6f6f40
+};
6f6f40
+
6f6f40
+/* Bonding section */
6f6f40
+
6f6f40
+enum {
6f6f40
+	IFLA_BOND_UNSPEC,
6f6f40
+	IFLA_BOND_MODE,
6f6f40
+	IFLA_BOND_ACTIVE_SLAVE,
6f6f40
+	IFLA_BOND_MIIMON,
6f6f40
+	IFLA_BOND_UPDELAY,
6f6f40
+	IFLA_BOND_DOWNDELAY,
6f6f40
+	IFLA_BOND_USE_CARRIER,
6f6f40
+	IFLA_BOND_ARP_INTERVAL,
6f6f40
+	IFLA_BOND_ARP_IP_TARGET,
6f6f40
+	IFLA_BOND_ARP_VALIDATE,
6f6f40
+	IFLA_BOND_ARP_ALL_TARGETS,
6f6f40
+	IFLA_BOND_PRIMARY,
6f6f40
+	IFLA_BOND_PRIMARY_RESELECT,
6f6f40
+	IFLA_BOND_FAIL_OVER_MAC,
6f6f40
+	IFLA_BOND_XMIT_HASH_POLICY,
6f6f40
+	IFLA_BOND_RESEND_IGMP,
6f6f40
+	IFLA_BOND_NUM_PEER_NOTIF,
6f6f40
+	IFLA_BOND_ALL_SLAVES_ACTIVE,
6f6f40
+	IFLA_BOND_MIN_LINKS,
6f6f40
+	IFLA_BOND_LP_INTERVAL,
6f6f40
+	IFLA_BOND_PACKETS_PER_SLAVE,
6f6f40
+	IFLA_BOND_AD_LACP_RATE,
6f6f40
+	IFLA_BOND_AD_SELECT,
6f6f40
+	IFLA_BOND_AD_INFO,
6f6f40
+	__IFLA_BOND_MAX,
6f6f40
+};
6f6f40
+
6f6f40
+#define IFLA_BOND_MAX	(__IFLA_BOND_MAX - 1)
6f6f40
+
6f6f40
+enum {
6f6f40
+	IFLA_BOND_AD_INFO_UNSPEC,
6f6f40
+	IFLA_BOND_AD_INFO_AGGREGATOR,
6f6f40
+	IFLA_BOND_AD_INFO_NUM_PORTS,
6f6f40
+	IFLA_BOND_AD_INFO_ACTOR_KEY,
6f6f40
+	IFLA_BOND_AD_INFO_PARTNER_KEY,
6f6f40
+	IFLA_BOND_AD_INFO_PARTNER_MAC,
6f6f40
+	__IFLA_BOND_AD_INFO_MAX,
6f6f40
+};
6f6f40
+
6f6f40
+#define IFLA_BOND_AD_INFO_MAX	(__IFLA_BOND_AD_INFO_MAX - 1)
6f6f40
+
6f6f40
+enum {
6f6f40
+	IFLA_BOND_SLAVE_UNSPEC,
6f6f40
+	IFLA_BOND_SLAVE_STATE,
6f6f40
+	IFLA_BOND_SLAVE_MII_STATUS,
6f6f40
+	IFLA_BOND_SLAVE_LINK_FAILURE_COUNT,
6f6f40
+	IFLA_BOND_SLAVE_PERM_HWADDR,
6f6f40
+	IFLA_BOND_SLAVE_QUEUE_ID,
6f6f40
+	IFLA_BOND_SLAVE_AD_AGGREGATOR_ID,
6f6f40
+	__IFLA_BOND_SLAVE_MAX,
6f6f40
+};
6f6f40
+
6f6f40
+#define IFLA_BOND_SLAVE_MAX	(__IFLA_BOND_SLAVE_MAX - 1)
6f6f40
+
6f6f40
 /* SR-IOV virtual function management section */
6f6f40
 
6f6f40
 enum {
6f6f40
@@ -281,8 +408,10 @@ enum {
6f6f40
 	IFLA_VF_UNSPEC,
6f6f40
 	IFLA_VF_MAC,		/* Hardware queue specific attributes */
6f6f40
 	IFLA_VF_VLAN,
6f6f40
-	IFLA_VF_TX_RATE,	/* TX Bandwidth Allocation */
6f6f40
+	IFLA_VF_TX_RATE,	/* Max TX Bandwidth Allocation */
6f6f40
 	IFLA_VF_SPOOFCHK,	/* Spoof Checking on/off switch */
6f6f40
+	IFLA_VF_LINK_STATE,	/* link state enable/disable/auto switch */
6f6f40
+	IFLA_VF_RATE,		/* Min and Max TX Bandwidth Allocation */
6f6f40
 	__IFLA_VF_MAX,
6f6f40
 };
6f6f40
 
6f6f40
@@ -304,22 +433,28 @@ struct ifla_vf_tx_rate {
6f6f40
 	__u32 rate; /* Max TX bandwidth in Mbps, 0 disables throttling */
6f6f40
 };
6f6f40
 
6f6f40
+struct ifla_vf_rate {
6f6f40
+	__u32 vf;
6f6f40
+	__u32 min_tx_rate; /* Min Bandwidth in Mbps */
6f6f40
+	__u32 max_tx_rate; /* Max Bandwidth in Mbps */
6f6f40
+};
6f6f40
+
6f6f40
 struct ifla_vf_spoofchk {
6f6f40
 	__u32 vf;
6f6f40
 	__u32 setting;
6f6f40
 };
6f6f40
-#ifdef __KERNEL__
6f6f40
 
6f6f40
-/* We don't want this structure exposed to user space */
6f6f40
-struct ifla_vf_info {
6f6f40
+enum {
6f6f40
+	IFLA_VF_LINK_STATE_AUTO,	/* link state of the uplink */
6f6f40
+	IFLA_VF_LINK_STATE_ENABLE,	/* link always up */
6f6f40
+	IFLA_VF_LINK_STATE_DISABLE,	/* link always down */
6f6f40
+	__IFLA_VF_LINK_STATE_MAX,
6f6f40
+};
6f6f40
+
6f6f40
+struct ifla_vf_link_state {
6f6f40
 	__u32 vf;
6f6f40
-	__u8 mac[32];
6f6f40
-	__u32 vlan;
6f6f40
-	__u32 qos;
6f6f40
-	__u32 tx_rate;
6f6f40
-	__u32 spoofchk;
6f6f40
+	__u32 link_state;
6f6f40
 };
6f6f40
-#endif
6f6f40
 
6f6f40
 /* VF ports management section
6f6f40
  *
6f6f40
@@ -393,4 +528,37 @@ struct ifla_port_vsi {
6f6f40
 	__u8 pad[3];
6f6f40
 };
6f6f40
 
6f6f40
-#endif /* _LINUX_IF_LINK_H */
6f6f40
+
6f6f40
+/* IPoIB section */
6f6f40
+
6f6f40
+enum {
6f6f40
+	IFLA_IPOIB_UNSPEC,
6f6f40
+	IFLA_IPOIB_PKEY,
6f6f40
+	IFLA_IPOIB_MODE,
6f6f40
+	IFLA_IPOIB_UMCAST,
6f6f40
+	__IFLA_IPOIB_MAX
6f6f40
+};
6f6f40
+
6f6f40
+enum {
6f6f40
+	IPOIB_MODE_DATAGRAM  = 0, /* using unreliable datagram QPs */
6f6f40
+	IPOIB_MODE_CONNECTED = 1, /* using connected QPs */
6f6f40
+};
6f6f40
+
6f6f40
+#define IFLA_IPOIB_MAX (__IFLA_IPOIB_MAX - 1)
6f6f40
+
6f6f40
+
6f6f40
+/* HSR section */
6f6f40
+
6f6f40
+enum {
6f6f40
+	IFLA_HSR_UNSPEC,
6f6f40
+	IFLA_HSR_SLAVE1,
6f6f40
+	IFLA_HSR_SLAVE2,
6f6f40
+	IFLA_HSR_MULTICAST_SPEC,	/* Last byte of supervision addr */
6f6f40
+	IFLA_HSR_SUPERVISION_ADDR,	/* Supervision frame multicast addr */
6f6f40
+	IFLA_HSR_SEQ_NR,
6f6f40
+	__IFLA_HSR_MAX,
6f6f40
+};
6f6f40
+
6f6f40
+#define IFLA_HSR_MAX (__IFLA_HSR_MAX - 1)
6f6f40
+
6f6f40
+#endif /* _UAPI_LINUX_IF_LINK_H */
6f6f40
-- 
6f6f40
1.9.3
6f6f40
6f6f40
6f6f40
From 36365bdd3df389d8f720782708a4735ccb36128c Mon Sep 17 00:00:00 2001
6f6f40
From: Dan Williams <dcbw@redhat.com>
6f6f40
Date: Fri, 25 Jul 2014 14:36:29 -0500
6f6f40
Subject: [PATCH 2/2] link/inet6: add link IPv6 address generation mode support
6f6f40
6f6f40
Signed-off-by: Dan Williams <dcbw@redhat.com>
6f6f40
Signed-off-by: Thomas Haller <thaller@redhat.com>
6f6f40
(cherry picked from commit 558f966782539f6d975da705fd73cea561c9dc83)
6f6f40
6f6f40
Conflicts:
6f6f40
	include/Makefile.am
6f6f40
	lib/route/link/inet6.c
6f6f40
---
6f6f40
 include/Makefile.am                |   1 +
6f6f40
 include/netlink/route/link/inet6.h |  37 +++++++++++++
6f6f40
 lib/route/link/inet6.c             | 109 ++++++++++++++++++++++++++++++++++---
6f6f40
 3 files changed, 140 insertions(+), 7 deletions(-)
6f6f40
 create mode 100644 include/netlink/route/link/inet6.h
6f6f40
6f6f40
diff --git a/include/Makefile.am b/include/Makefile.am
6f6f40
index 1e07fdb..b9487e0 100644
6f6f40
--- a/include/Makefile.am
6f6f40
+++ b/include/Makefile.am
6f6f40
@@ -44,6 +44,7 @@ nobase_libnlinclude_HEADERS = \
6f6f40
 	netlink/route/link/bonding.h \
6f6f40
 	netlink/route/link/can.h \
6f6f40
 	netlink/route/link/inet.h \
6f6f40
+	netlink/route/link/inet6.h \
6f6f40
 	netlink/route/link/vlan.h \
6f6f40
 	netlink/route/qdisc/cbq.h \
6f6f40
 	netlink/route/qdisc/dsmark.h \
6f6f40
diff --git a/include/netlink/route/link/inet6.h b/include/netlink/route/link/inet6.h
6f6f40
new file mode 100644
6f6f40
index 0000000..8ffeab2
6f6f40
--- /dev/null
6f6f40
+++ b/include/netlink/route/link/inet6.h
6f6f40
@@ -0,0 +1,37 @@
6f6f40
+/*
6f6f40
+ * netlink/route/link/inet6.h	INET6 Link Module
6f6f40
+ *
6f6f40
+ *	This library is free software; you can redistribute it and/or
6f6f40
+ *	modify it under the terms of the GNU Lesser General Public
6f6f40
+ *	License as published by the Free Software Foundation version 2.1
6f6f40
+ *	of the License.
6f6f40
+ *
6f6f40
+ * Copyright (c) 2014 Dan Williams <dcbw@redhat.com>
6f6f40
+ */
6f6f40
+
6f6f40
+#ifndef NETLINK_LINK_INET6_H_
6f6f40
+#define NETLINK_LINK_INET6_H_
6f6f40
+
6f6f40
+#include <netlink/netlink.h>
6f6f40
+
6f6f40
+#ifdef __cplusplus
6f6f40
+extern "C" {
6f6f40
+#endif
6f6f40
+
6f6f40
+const char *		rtnl_link_inet6_addrgenmode2str  (uint8_t mode,
6f6f40
+							  char *buf,
6f6f40
+							  size_t len);
6f6f40
+
6f6f40
+uint8_t			rtnl_link_inet6_str2addrgenmode  (const char *mode);
6f6f40
+
6f6f40
+extern int		rtnl_link_inet6_get_addr_gen_mode(struct rtnl_link *,
6f6f40
+							  uint8_t *);
6f6f40
+
6f6f40
+extern int		rtnl_link_inet6_set_addr_gen_mode(struct rtnl_link *,
6f6f40
+							  uint8_t);
6f6f40
+
6f6f40
+#ifdef __cplusplus
6f6f40
+}
6f6f40
+#endif
6f6f40
+
6f6f40
+#endif
6f6f40
diff --git a/lib/route/link/inet6.c b/lib/route/link/inet6.c
6f6f40
index 6fa2741..e94bf0c 100644
6f6f40
--- a/lib/route/link/inet6.c
6f6f40
+++ b/lib/route/link/inet6.c
6f6f40
@@ -15,16 +15,25 @@
6f6f40
 #include <netlink/route/rtnl.h>
6f6f40
 #include <netlink-private/route/link/api.h>
6f6f40
 
6f6f40
+#define I6_ADDR_GEN_MODE_UNKNOWN	UINT8_MAX
6f6f40
+
6f6f40
 struct inet6_data
6f6f40
 {
6f6f40
 	uint32_t		i6_flags;
6f6f40
 	struct ifla_cacheinfo	i6_cacheinfo;
6f6f40
 	uint32_t		i6_conf[DEVCONF_MAX];
6f6f40
+	uint8_t			i6_addr_gen_mode;
6f6f40
 };
6f6f40
 
6f6f40
 static void *inet6_alloc(struct rtnl_link *link)
6f6f40
 {
6f6f40
-	return calloc(1, sizeof(struct inet6_data));
6f6f40
+	struct inet6_data *i6;
6f6f40
+
6f6f40
+	i6 = calloc(1, sizeof(struct inet6_data));
6f6f40
+	if (i6)
6f6f40
+		i6->i6_addr_gen_mode = I6_ADDR_GEN_MODE_UNKNOWN;
6f6f40
+
6f6f40
+	return i6;
6f6f40
 }
6f6f40
 
6f6f40
 static void *inet6_clone(struct rtnl_link *link, void *data)
6f6f40
@@ -43,11 +52,12 @@ static void inet6_free(struct rtnl_link *link, void *data)
6f6f40
 }
6f6f40
 
6f6f40
 static struct nla_policy inet6_policy[IFLA_INET6_MAX+1] = {
6f6f40
-	[IFLA_INET6_FLAGS]	= { .type = NLA_U32 },
6f6f40
-	[IFLA_INET6_CACHEINFO]	= { .minlen = sizeof(struct ifla_cacheinfo) },
6f6f40
-	[IFLA_INET6_CONF]	= { .minlen = 4 },
6f6f40
-	[IFLA_INET6_STATS]	= { .minlen = 8 },
6f6f40
-	[IFLA_INET6_ICMP6STATS]	= { .minlen = 8 },
6f6f40
+	[IFLA_INET6_FLAGS]		= { .type = NLA_U32 },
6f6f40
+	[IFLA_INET6_CACHEINFO]		= { .minlen = sizeof(struct ifla_cacheinfo) },
6f6f40
+	[IFLA_INET6_CONF]		= { .minlen = 4 },
6f6f40
+	[IFLA_INET6_STATS]		= { .minlen = 8 },
6f6f40
+	[IFLA_INET6_ICMP6STATS]		= { .minlen = 8 },
6f6f40
+	[IFLA_INET6_ADDR_GEN_MODE]	= { .type = NLA_U8 },
6f6f40
 };
6f6f40
 
6f6f40
 static const uint8_t map_stat_id_from_IPSTATS_MIB_v1[__IPSTATS_MIB_MAX] = {
6f6f40
@@ -155,7 +165,10 @@ static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr,
6f6f40
 	if (tb[IFLA_INET6_CONF])
6f6f40
 		nla_memcpy(&i6->i6_conf, tb[IFLA_INET6_CONF],
6f6f40
 			   sizeof(i6->i6_conf));
6f6f40
- 
6f6f40
+
6f6f40
+	if (tb[IFLA_INET6_ADDR_GEN_MODE])
6f6f40
+		i6->i6_addr_gen_mode = nla_get_u8 (tb[IFLA_INET6_ADDR_GEN_MODE]);
6f6f40
+
6f6f40
 	/*
6f6f40
 	 * Due to 32bit data alignment, these addresses must be copied to an
6f6f40
 	 * aligned location prior to access.
6f6f40
@@ -200,6 +213,19 @@ static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr,
6f6f40
 	return 0;
6f6f40
 }
6f6f40
 
6f6f40
+static int inet6_fill_af(struct rtnl_link *link, struct nl_msg *msg, void *data)
6f6f40
+{
6f6f40
+	struct inet6_data *id = data;
6f6f40
+
6f6f40
+	if (id->i6_addr_gen_mode != I6_ADDR_GEN_MODE_UNKNOWN)
6f6f40
+		NLA_PUT_U8(msg, IFLA_INET6_ADDR_GEN_MODE, id->i6_addr_gen_mode);
6f6f40
+
6f6f40
+	return 0;
6f6f40
+
6f6f40
+nla_put_failure:
6f6f40
+	return -NLE_MSGSIZE;
6f6f40
+}
6f6f40
+
6f6f40
 /* These live in include/net/if_inet6.h and should be moved to include/linux */
6f6f40
 #define IF_RA_OTHERCONF	0x80
6f6f40
 #define IF_RA_MANAGED	0x40
6f6f40
@@ -259,6 +285,22 @@ static char *inet6_devconf2str(int type, char *buf, size_t len)
6f6f40
 			  ARRAY_SIZE(inet6_devconf));
6f6f40
 }
6f6f40
 
6f6f40
+static const struct trans_tbl inet6_addr_gen_mode[] = {
6f6f40
+	__ADD(IN6_ADDR_GEN_MODE_EUI64, eui64)
6f6f40
+	__ADD(IN6_ADDR_GEN_MODE_NONE, none)
6f6f40
+};
6f6f40
+
6f6f40
+const char *rtnl_link_inet6_addrgenmode2str(uint8_t mode, char *buf, size_t len)
6f6f40
+{
6f6f40
+	return __type2str(mode, buf, len, inet6_addr_gen_mode,
6f6f40
+			  ARRAY_SIZE(inet6_addr_gen_mode));
6f6f40
+}
6f6f40
+
6f6f40
+uint8_t rtnl_link_inet6_str2addrgenmode(const char *mode)
6f6f40
+{
6f6f40
+	return (uint8_t) __str2type(mode, inet6_addr_gen_mode,
6f6f40
+			            ARRAY_SIZE(inet6_addr_gen_mode));
6f6f40
+}
6f6f40
 
6f6f40
 static void inet6_dump_details(struct rtnl_link *link,
6f6f40
 				struct nl_dump_params *p, void *data)
6f6f40
@@ -281,6 +323,10 @@ static void inet6_dump_details(struct rtnl_link *link,
6f6f40
 	nl_dump(p, " retrans-time %s\n",
6f6f40
 		nl_msec2str(i6->i6_cacheinfo.retrans_time, buf, sizeof(buf)));
6f6f40
 
6f6f40
+	nl_dump(p, " link-local address mode %s\n",
6f6f40
+		rtnl_link_inet6_addrgenmode2str(i6->i6_addr_gen_mode,
6f6f40
+						buf, sizeof(buf)));
6f6f40
+
6f6f40
 	nl_dump_line(p, "      devconf:\n");
6f6f40
 	nl_dump_line(p, "      ");
6f6f40
 
6f6f40
@@ -468,11 +514,60 @@ static struct rtnl_link_af_ops inet6_ops = {
6f6f40
 	.ao_free			= &inet6_free,
6f6f40
 	.ao_parse_protinfo		= &inet6_parse_protinfo,
6f6f40
 	.ao_parse_af			= &inet6_parse_protinfo,
6f6f40
+	.ao_fill_af			= &inet6_fill_af,
6f6f40
 	.ao_dump[NL_DUMP_DETAILS]	= &inet6_dump_details,
6f6f40
 	.ao_dump[NL_DUMP_STATS]		= &inet6_dump_stats,
6f6f40
 	.ao_protinfo_policy		= &protinfo_policy,
6f6f40
 };
6f6f40
 
6f6f40
+/**
6f6f40
+ * Get IPv6 link-local address generation mode
6f6f40
+ * @arg link		Link object
6f6f40
+ * @arg mode		Generation mode on success
6f6f40
+ *
6f6f40
+ * Returns the link's IPv6 link-local address generation mode.
6f6f40
+ *
6f6f40
+ * @return 0 on success
6f6f40
+ * @return -NLE_NOATTR configuration setting not available
6f6f40
+ * @return -NLE_INVAL generation mode unknown. If the link was received via
6f6f40
+ *                    netlink, it means that address generation mode is not
6f6f40
+ *                    supported by the kernel.
6f6f40
+ */
6f6f40
+int rtnl_link_inet6_get_addr_gen_mode(struct rtnl_link *link, uint8_t *mode)
6f6f40
+{
6f6f40
+	struct inet6_data *id;
6f6f40
+
6f6f40
+	if (!(id = rtnl_link_af_data(link, &inet6_ops)))
6f6f40
+		return -NLE_NOATTR;
6f6f40
+
6f6f40
+	if (id->i6_addr_gen_mode == I6_ADDR_GEN_MODE_UNKNOWN)
6f6f40
+		return -NLE_INVAL;
6f6f40
+
6f6f40
+	*mode = id->i6_addr_gen_mode;
6f6f40
+	return 0;
6f6f40
+}
6f6f40
+
6f6f40
+/**
6f6f40
+ * Set IPv6 link-local address generation mode
6f6f40
+ * @arg link		Link object
6f6f40
+ * @arg mode		Generation mode
6f6f40
+ *
6f6f40
+ * Sets the link's IPv6 link-local address generation mode.
6f6f40
+ *
6f6f40
+ * @return 0 on success
6f6f40
+ * @return -NLE_NOMEM could not allocate inet6 data
6f6f40
+ */
6f6f40
+int rtnl_link_inet6_set_addr_gen_mode(struct rtnl_link *link, uint8_t mode)
6f6f40
+{
6f6f40
+	struct inet6_data *id;
6f6f40
+
6f6f40
+	if (!(id = rtnl_link_af_alloc(link, &inet6_ops)))
6f6f40
+		return -NLE_NOMEM;
6f6f40
+
6f6f40
+	id->i6_addr_gen_mode = mode;
6f6f40
+	return 0;
6f6f40
+}
6f6f40
+
6f6f40
 static void __init inet6_init(void)
6f6f40
 {
6f6f40
 	rtnl_link_af_register(&inet6_ops);
6f6f40
-- 
6f6f40
1.9.3
6f6f40