All of lore.kernel.org
 help / color / mirror / Atom feed
From: Robert Shearman <rshearma@brocade.com>
To: <davem@davemloft.net>
Cc: <netdev@vger.kernel.org>, Robert Shearman <rshearma@brocade.com>,
	"Eric W. Biederman" <ebiederm@xmission.com>
Subject: [PATCH net-next] mpls: Infer payload of packet from via address family.
Date: Wed, 11 Mar 2015 12:58:22 +0000	[thread overview]
Message-ID: <1426078702-23246-1-git-send-email-rshearma@brocade.com> (raw)

This ensures that if a routing protocol incorrectly advertises a label
for a prefix whose address-family is inconsistent with that of the
nexthop, then the traffic will be dropped, rather than the issue being
silently worked around.

The accessible skb length should also be validated prior to the IPv4
or IPv6 headers being accessed, since only the label header will have
previously been validated.

Rename mpls_egress to mpls_egress_to_ip to make it more obvious that
the function is used for traffic going out as IP, not for labeled
traffic (or for the not-yet-implemented pseudo-wires).

Cc: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Robert Shearman <rshearma@brocade.com>
---
 net/mpls/af_mpls.c | 91 ++++++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 68 insertions(+), 23 deletions(-)

diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index 0ad8f7141..d1074b8 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -81,35 +81,81 @@ static bool mpls_pkt_too_big(const struct sk_buff *skb, unsigned int mtu)
 	return true;
 }
 
-static bool mpls_egress(struct mpls_route *rt, struct sk_buff *skb,
-			struct mpls_entry_decoded dec)
+static int mpls_pkt_determine_af(struct sk_buff *skb)
 {
-	/* RFC4385 and RFC5586 encode other packets in mpls such that
-	 * they don't conflict with the ip version number, making
-	 * decoding by examining the ip version correct in everything
-	 * except for the strangest cases.
-	 *
-	 * The strange cases if we choose to support them will require
-	 * manual configuration.
+	if (!pskb_may_pull(skb, sizeof(struct iphdr))) {
+		return AF_PACKET;
+	}
+
+	/* At the moment, this is only used at the end of the LSP when
+	 * the payload is expected to be IP. More comprehensive checks
+	 * will be required if this is to be used where pseudo-wire
+	 * traffic not using RFC4385/RFC5586 encap could be present.
 	 */
-	struct iphdr *hdr4 = ip_hdr(skb);
+
+	switch (ip_hdr(skb)->version) {
+	case 4:
+		return AF_INET;
+	case 6:
+		return AF_INET6;
+	default:
+		return AF_PACKET;
+	}
+}
+
+static bool mpls_egress_to_ip(struct mpls_route *rt, struct sk_buff *skb,
+			struct mpls_entry_decoded dec)
+{
 	bool success = true;
+	int af;
+
+	switch (rt->rt_via_table) {
+	case NEIGH_ARP_TABLE:
+		af = AF_INET;
+		break;
+	case NEIGH_ND_TABLE:
+		af = AF_INET6;
+		break;
+	case NEIGH_LINK_TABLE:
+		af = mpls_pkt_determine_af(skb);
+		break;
+	default:
+		/* Unexpected rt_via_table value */
+		WARN_ON(true);
+		af = AF_PACKET;
+		break;
+	}
 
-	if (hdr4->version == 4) {
-		skb->protocol = htons(ETH_P_IP);
-		csum_replace2(&hdr4->check,
-			      htons(hdr4->ttl << 8),
-			      htons(dec.ttl << 8));
-		hdr4->ttl = dec.ttl;
+	switch (af) {
+	case AF_INET: {
+		struct iphdr *hdr4 = ip_hdr(skb);
+		if (pskb_may_pull(skb, sizeof(struct iphdr)) &&
+			hdr4->version == 4) {
+			skb->protocol = htons(ETH_P_IP);
+			csum_replace2(&hdr4->check,
+				htons(hdr4->ttl << 8),
+				htons(dec.ttl << 8));
+			hdr4->ttl = dec.ttl;
+		} else {
+			success = false;
+		}
+		break;
 	}
-	else if (hdr4->version == 6) {
+	case AF_INET6: {
 		struct ipv6hdr *hdr6 = ipv6_hdr(skb);
-		skb->protocol = htons(ETH_P_IPV6);
-		hdr6->hop_limit = dec.ttl;
+		if (pskb_may_pull(skb, sizeof(struct ipv6hdr)) &&
+			hdr6->version == 6) {
+			skb->protocol = htons(ETH_P_IPV6);
+			hdr6->hop_limit = dec.ttl;
+		} else {
+			success = false;
+		}
+		break;
 	}
-	else
-		/* version 0 and version 1 are used by pseudo wires */
+	default:
 		success = false;
+		break;
+	}
 	return success;
 }
 
@@ -184,8 +230,7 @@ static int mpls_forward(struct sk_buff *skb, struct net_device *dev,
 	skb->protocol = htons(ETH_P_MPLS_UC);
 
 	if (unlikely(!new_header_size && dec.bos)) {
-		/* Penultimate hop popping */
-		if (!mpls_egress(rt, skb, dec))
+		if (!mpls_egress_to_ip(rt, skb, dec))
 			goto drop;
 	} else {
 		bool bos;
-- 
2.1.4

             reply	other threads:[~2015-03-11 12:58 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-03-11 12:58 Robert Shearman [this message]
2015-03-11 17:29 ` [PATCH net-next] mpls: Infer payload of packet from via address family Eric W. Biederman
2015-03-11 22:02   ` Robert Shearman
2015-03-12 18:19     ` Eric W. Biederman
2015-03-12 20:54       ` [PATCH net-next ] mpls: In mpls_egress verify the packet length Eric W. Biederman
2015-03-12 22:25         ` David Miller
2015-03-12 22:50           ` Eric W. Biederman
2015-03-12 23:22             ` Eric W. Biederman
2015-03-13  3:05               ` David Miller
2015-03-13 14:51       ` [PATCH net-next] mpls: Infer payload of packet from via address family Robert Shearman
2015-03-13 17:08         ` Eric W. Biederman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1426078702-23246-1-git-send-email-rshearma@brocade.com \
    --to=rshearma@brocade.com \
    --cc=davem@davemloft.net \
    --cc=ebiederm@xmission.com \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.