lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <1431664722-59539-1-git-send-email-roopa@cumulusnetworks.com>
Date:	Thu, 14 May 2015 21:38:42 -0700
From:	roopa@...ulusnetworks.com
To:	ebiederm@...ssion.com
Cc:	davem@...emloft.net, rshearma@...cade.com, netdev@...r.kernel.org,
	vivek@...ulusnetworks.com
Subject: [PATCH net] mpls: modify RTA_NEWDST netlink attribute to include family

From: Roopa Prabhu <roopa@...ulusnetworks.com>

RTA_NEWDST netlink attribute today is used to carry mpls
labels. This patch encodes family in RTA_NEWDST.

RTA_NEWDST by its name and its use in iproute2 can be
used as a generic new dst. But it is currently used only for
mpls labels ie with family AF_MPLS. Encoding family in the
attribute will help its reuse in the future.

One usecase where family with RTA_NEWDST becomes necessary
is when we implement mpls label edge router function.

This is a uapi change but RTA_NEWDST has not made
into any release yet. so, trying to rush this change into
4.1 if acceptable.

(iproute2 patch will follow)

Signed-off-by: Roopa Prabhu <roopa@...ulusnetworks.com>
---
eric, if you had already thought about other ways to represent
labels for LER function, pls let me know. I am looking for suggestions.

 include/uapi/linux/rtnetlink.h |    7 ++-
 net/mpls/af_mpls.c             |  118 +++++++++++++++++++++++++++++++---------
 net/mpls/internal.h            |    5 +-
 3 files changed, 100 insertions(+), 30 deletions(-)

diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
index 974db03..79879cb 100644
--- a/include/uapi/linux/rtnetlink.h
+++ b/include/uapi/linux/rtnetlink.h
@@ -356,8 +356,13 @@ struct rtvia {
 	__u8			rtvia_addr[0];
 };
 
-/* RTM_CACHEINFO */
+/* RTA_NEWDST */
+struct rtnewdst {
+	__kernel_sa_family_t	family;
+	__u8	dst[0];
+};
 
+/* RTM_CACHEINFO */
 struct rta_cacheinfo {
 	__u32	rta_clntref;
 	__u32	rta_lastuse;
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index 91ed656..6c31108 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -599,18 +599,13 @@ static int nla_put_via(struct sk_buff *skb,
 	return 0;
 }
 
-int nla_put_labels(struct sk_buff *skb, int attrtype,
+int nla_put_labels(struct sk_buff *skb, void *addr,
 		   u8 labels, const u32 label[])
 {
-	struct nlattr *nla;
-	struct mpls_shim_hdr *nla_label;
+	struct mpls_shim_hdr *nla_label = addr;
 	bool bos;
 	int i;
-	nla = nla_reserve(skb, attrtype, labels*4);
-	if (!nla)
-		return -EMSGSIZE;
 
-	nla_label = nla_data(nla);
 	bos = true;
 	for (i = labels - 1; i >= 0; i--) {
 		nla_label[i] = mpls_entry_encode(label[i], 0, 0, bos);
@@ -620,25 +615,45 @@ int nla_put_labels(struct sk_buff *skb, int attrtype,
 	return 0;
 }
 
-int nla_get_labels(const struct nlattr *nla,
-		   u32 max_labels, u32 *labels, u32 label[])
+int nla_put_newdst(struct sk_buff *skb, int attrtype, int family,
+		   u8 labels, const u32 label[])
 {
-	unsigned len = nla_len(nla);
-	unsigned nla_labels;
-	struct mpls_shim_hdr *nla_label;
-	bool bos;
-	int i;
+	struct nlattr *nla;
+	struct rtnewdst *newdst;
 
-	/* len needs to be an even multiple of 4 (the label size) */
-	if (len & 3)
-		return -EINVAL;
+	nla = nla_reserve(skb, attrtype, 2 + (labels * 4));
+	if (!nla)
+		return -EMSGSIZE;
 
-	/* Limit the number of new labels allowed */
-	nla_labels = len/4;
-	if (nla_labels > max_labels)
-		return -EINVAL;
+	newdst = nla_data(nla);
+	newdst->family = family;
+
+	nla_put_labels(skb, &newdst->dst, labels, label);
+
+	return 0;
+}
+EXPORT_SYMBOL(nla_put_newdst);
+
+int nla_put_dst(struct sk_buff *skb, int attrtype, u8 labels,
+		const u32 label[])
+{
+	struct nlattr *nla;
+
+	nla = nla_reserve(skb, attrtype, labels * 4);
+	if (!nla)
+		return -EMSGSIZE;
+
+	nla_put_labels(skb, nla_data(nla), labels, label);
+
+	return 0;
+}
+
+int nla_get_labels(void *addr, u32 nla_labels, u32 *labels, u32 label[])
+{
+	struct mpls_shim_hdr *nla_label = addr;
+	bool bos;
+	int i;
 
-	nla_label = nla_data(nla);
 	bos = true;
 	for (i = nla_labels - 1; i >= 0; i--, bos = false) {
 		struct mpls_entry_decoded dec;
@@ -665,6 +680,54 @@ int nla_get_labels(const struct nlattr *nla,
 	return 0;
 }
 
+int nla_get_newdst(const struct nlattr *nla, u32 max_labels,
+		   u32 *labels, u32 label[])
+{
+	struct rtnewdst *newdst = nla_data(nla);
+	unsigned nla_labels;
+	unsigned len;
+
+	if (nla_len(nla) < offsetof(struct rtnewdst, dst))
+		return -EINVAL;
+
+	len = nla_len(nla) - sizeof(struct rtnewdst);
+
+	/* len needs to be an even multiple of 4 (the label size) */
+	if (len & 3)
+		return -EINVAL;
+
+	/* Limit the number of new labels allowed */
+	nla_labels = len / 4;
+	if (nla_labels > max_labels)
+		return -EINVAL;
+
+	nla_get_labels(&newdst->dst, nla_labels, labels, label);
+
+	return 0;
+}
+EXPORT_SYMBOL(nla_get_newdst);
+
+int nla_get_dst(const struct nlattr *nla,
+		u32 max_labels, u32 *labels, u32 label[])
+{
+	unsigned len = nla_len(nla);
+	unsigned nla_labels;
+
+	/* len needs to be an even multiple of 4 (the label size) */
+	if (len & 3)
+		return -EINVAL;
+
+	/* Limit the number of new labels allowed */
+	nla_labels = len / 4;
+	if (nla_labels > max_labels)
+		return -EINVAL;
+
+	nla_get_labels(nla_data(nla), nla_labels, labels, label);
+
+	return 0;
+}
+EXPORT_SYMBOL(nla_get_dst);
+
 static int rtm_to_route_config(struct sk_buff *skb,  struct nlmsghdr *nlh,
 			       struct mpls_route_config *cfg)
 {
@@ -721,7 +784,7 @@ static int rtm_to_route_config(struct sk_buff *skb,  struct nlmsghdr *nlh,
 			cfg->rc_ifindex = nla_get_u32(nla);
 			break;
 		case RTA_NEWDST:
-			if (nla_get_labels(nla, MAX_NEW_LABELS,
+			if (nla_get_newdst(nla, MAX_NEW_LABELS,
 					   &cfg->rc_output_labels,
 					   cfg->rc_output_label))
 				goto errout;
@@ -729,8 +792,8 @@ static int rtm_to_route_config(struct sk_buff *skb,  struct nlmsghdr *nlh,
 		case RTA_DST:
 		{
 			u32 label_count;
-			if (nla_get_labels(nla, 1, &label_count,
-					   &cfg->rc_label))
+			if (nla_get_dst(nla, 1, &label_count,
+					&cfg->rc_label))
 				goto errout;
 
 			/* The first 16 labels are reserved, and may not be set */
@@ -831,14 +894,15 @@ static int mpls_dump_route(struct sk_buff *skb, u32 portid, u32 seq, int event,
 	rtm->rtm_flags = 0;
 
 	if (rt->rt_labels &&
-	    nla_put_labels(skb, RTA_NEWDST, rt->rt_labels, rt->rt_label))
+	    nla_put_newdst(skb, RTA_NEWDST, AF_MPLS, rt->rt_labels,
+			   rt->rt_label))
 		goto nla_put_failure;
 	if (nla_put_via(skb, rt->rt_via_table, rt->rt_via, rt->rt_via_alen))
 		goto nla_put_failure;
 	dev = rtnl_dereference(rt->rt_dev);
 	if (dev && nla_put_u32(skb, RTA_OIF, dev->ifindex))
 		goto nla_put_failure;
-	if (nla_put_labels(skb, RTA_DST, 1, &label))
+	if (nla_put_dst(skb, RTA_DST, 1, &label))
 		goto nla_put_failure;
 
 	nlmsg_end(skb, nlh);
diff --git a/net/mpls/internal.h b/net/mpls/internal.h
index b064c34..99d7a79 100644
--- a/net/mpls/internal.h
+++ b/net/mpls/internal.h
@@ -49,7 +49,8 @@ static inline struct mpls_entry_decoded mpls_entry_decode(struct mpls_shim_hdr *
 	return result;
 }
 
-int nla_put_labels(struct sk_buff *skb, int attrtype,  u8 labels, const u32 label[]);
-int nla_get_labels(const struct nlattr *nla, u32 max_labels, u32 *labels, u32 label[]);
+int nla_put_labels(struct sk_buff *skb, void *addr,  u8 labels,
+		   const u32 label[]);
+int nla_get_labels(void *addr, u32 nla_labels, u32 *labels, u32 label[]);
 
 #endif /* MPLS_INTERNAL_H */
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ