linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [v2,net-next 0/2] Add support for SRv6 End.DT4 action
@ 2020-03-18 23:16 Carmine Scarpitta
  2020-03-18 23:16 ` [v2,net-next 1/2] Perform IPv4 FIB lookup in a predefined FIB table Carmine Scarpitta
  2020-03-18 23:16 ` [v2,net-next 2/2] Add support for SRv6 End.DT4 action Carmine Scarpitta
  0 siblings, 2 replies; 4+ messages in thread
From: Carmine Scarpitta @ 2020-03-18 23:16 UTC (permalink / raw)
  To: davem
  Cc: kuznet, yoshfuji, kuba, netdev, linux-kernel, ahmed.abdelsalam,
	david.lebrun, dav.lebrun, stefano.salsano, andrea.mayer,
	paolo.lungaroni, hiroki.shirokura, Carmine Scarpitta

Hi,

this patch series adds the support for SRv6 End.DT4 action.
End.DT4 decapsulates the received packets and does IPv4 routing
lookup in a specific routing table.

The IPv4 routing subsystem does not allow to specify the routing
table in which the lookup has to be performed.

Patch 1 enables to perform IPv4 FIB lookup in a predefined FIB table.
Patch 2 adds the support for SRv6 End.DT4 action.

v2:
- Fix an issue of "fi" member of struct "fib_result" used
  uninitialized
- Wrap the check of the "tbl_known" flag in a "#ifdef
  CONFIG_IP_MULTIPLE_TABLES" directive

Thanks,
Carmine Scarpitta

Carmine Scarpitta (2):
  Perform IPv4 FIB lookup in a predefined FIB table
  Add support for SRv6 End.DT4 action

 include/net/route.h   |  2 +-
 net/ipv4/route.c      | 23 ++++++++++++++------
 net/ipv6/seg6_local.c | 49 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 67 insertions(+), 7 deletions(-)

-- 
2.17.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [v2,net-next 1/2] Perform IPv4 FIB lookup in a predefined FIB table
  2020-03-18 23:16 [v2,net-next 0/2] Add support for SRv6 End.DT4 action Carmine Scarpitta
@ 2020-03-18 23:16 ` Carmine Scarpitta
  2020-03-19  1:47   ` David Miller
  2020-03-18 23:16 ` [v2,net-next 2/2] Add support for SRv6 End.DT4 action Carmine Scarpitta
  1 sibling, 1 reply; 4+ messages in thread
From: Carmine Scarpitta @ 2020-03-18 23:16 UTC (permalink / raw)
  To: davem
  Cc: kuznet, yoshfuji, kuba, netdev, linux-kernel, ahmed.abdelsalam,
	david.lebrun, dav.lebrun, stefano.salsano, andrea.mayer,
	paolo.lungaroni, hiroki.shirokura, Carmine Scarpitta

In IPv4, the routing subsystem is invoked by calling ip_route_input_rcu()
which performs the recognition logic and calls ip_route_input_slow().

ip_route_input_slow() initialises both "fi" and "table" members
of the fib_result structure to null before calling fib_lookup().

fib_lookup() performs fib lookup in the routing table configured
by the policy routing rules.

In this patch, we allow invoking the ip4 routing subsystem
with known routing table. This is useful for use-cases implementing
a separate routing table per tenant.

The patch introduces a new flag named "tbl_known" to the definition of
ip_route_input_rcu() and ip_route_input_slow().

When the flag is set, ip_route_input_slow() will call fib_table_lookup()
using the defined table instead of using fib_lookup().

Signed-off-by: Carmine Scarpitta <carmine.scarpitta@uniroma2.it>
Acked-by: Ahmed Abdelsalam <ahmed.abdelsalam@gssi.it>
Acked-by: Andrea Mayer <andrea.mayer@uniroma2.it>
Acked-by: Paolo Lungaroni <paolo.lungaroni@cnit.it>
---
 include/net/route.h |  2 +-
 net/ipv4/route.c    | 23 +++++++++++++++++------
 2 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/include/net/route.h b/include/net/route.h
index a9c60fc68e36..4ff977bd7029 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -183,7 +183,7 @@ int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 src,
 			 u8 tos, struct net_device *devin);
 int ip_route_input_rcu(struct sk_buff *skb, __be32 dst, __be32 src,
 		       u8 tos, struct net_device *devin,
-		       struct fib_result *res);
+		       struct fib_result *res, bool tbl_known);
 
 int ip_route_use_hint(struct sk_buff *skb, __be32 dst, __be32 src,
 		      u8 tos, struct net_device *devin,
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index d5c57b3f77d5..e1eca68eede2 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -2077,7 +2077,7 @@ int ip_route_use_hint(struct sk_buff *skb, __be32 daddr, __be32 saddr,
 
 static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
 			       u8 tos, struct net_device *dev,
-			       struct fib_result *res)
+			       struct fib_result *res, bool tbl_known)
 {
 	struct in_device *in_dev = __in_dev_get_rcu(dev);
 	struct flow_keys *flkeys = NULL, _flkeys;
@@ -2110,7 +2110,6 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
 		goto martian_source;
 
 	res->fi = NULL;
-	res->table = NULL;
 	if (ipv4_is_lbcast(daddr) || (saddr == 0 && daddr == 0))
 		goto brd_input;
 
@@ -2155,7 +2154,18 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
 		fl4.fl4_dport = 0;
 	}
 
+#ifdef CONFIG_IP_MULTIPLE_TABLES
+	if (!tbl_known) {
+		res->table = NULL;
+		err = fib_lookup(net, &fl4, res, 0);
+	} else {
+		err = fib_table_lookup(res->table, &fl4, res, FIB_LOOKUP_NOREF);
+	}
+#else
+	res->table = NULL;
 	err = fib_lookup(net, &fl4, res, 0);
+#endif
+
 	if (err != 0) {
 		if (!IN_DEV_FORWARD(in_dev))
 			err = -EHOSTUNREACH;
@@ -2292,7 +2302,7 @@ int ip_route_input_noref(struct sk_buff *skb, __be32 daddr, __be32 saddr,
 
 	tos &= IPTOS_RT_MASK;
 	rcu_read_lock();
-	err = ip_route_input_rcu(skb, daddr, saddr, tos, dev, &res);
+	err = ip_route_input_rcu(skb, daddr, saddr, tos, dev, &res, false);
 	rcu_read_unlock();
 
 	return err;
@@ -2301,7 +2311,8 @@ EXPORT_SYMBOL(ip_route_input_noref);
 
 /* called with rcu_read_lock held */
 int ip_route_input_rcu(struct sk_buff *skb, __be32 daddr, __be32 saddr,
-		       u8 tos, struct net_device *dev, struct fib_result *res)
+		       u8 tos, struct net_device *dev, struct fib_result *res,
+		       bool tbl_known)
 {
 	/* Multicast recognition logic is moved from route cache to here.
 	   The problem was that too many Ethernet cards have broken/missing
@@ -2347,7 +2358,7 @@ int ip_route_input_rcu(struct sk_buff *skb, __be32 daddr, __be32 saddr,
 		return err;
 	}
 
-	return ip_route_input_slow(skb, daddr, saddr, tos, dev, res);
+	return ip_route_input_slow(skb, daddr, saddr, tos, dev, res, tbl_known);
 }
 
 /* called with rcu_read_lock() */
@@ -3192,7 +3203,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
 		skb->dev	= dev;
 		skb->mark	= mark;
 		err = ip_route_input_rcu(skb, dst, src, rtm->rtm_tos,
-					 dev, &res);
+					 dev, &res, false);
 
 		rt = skb_rtable(skb);
 		if (err == 0 && rt->dst.error)
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [v2,net-next 2/2] Add support for SRv6 End.DT4 action
  2020-03-18 23:16 [v2,net-next 0/2] Add support for SRv6 End.DT4 action Carmine Scarpitta
  2020-03-18 23:16 ` [v2,net-next 1/2] Perform IPv4 FIB lookup in a predefined FIB table Carmine Scarpitta
@ 2020-03-18 23:16 ` Carmine Scarpitta
  1 sibling, 0 replies; 4+ messages in thread
From: Carmine Scarpitta @ 2020-03-18 23:16 UTC (permalink / raw)
  To: davem
  Cc: kuznet, yoshfuji, kuba, netdev, linux-kernel, ahmed.abdelsalam,
	david.lebrun, dav.lebrun, stefano.salsano, andrea.mayer,
	paolo.lungaroni, hiroki.shirokura, Carmine Scarpitta

SRv6 End.DT4 is defined in the SRv6 Network Programming doc within IETF [1].

End.DT4 is used to implement IPv4 L3VPN use-cases in multi-tenants
environments. It decapsulates the received packets and does IPv4 routing
lookup in the routing table of the tenant.

At JANOG44, LINE corporation presented their multi-tenant DC architecture
using SRv6 [2]. In the slides, they reported that the linux kernel is
missing the support of SRv6 End.DT4 action.

This patch adds support to SRv6 End.DT4 action.

The iproute2 part required for this action was already implemented along
with the other supported SRv6 actions [3].

[1] https://tools.ietf.org/html/draft-ietf-spring-srv6-network-programming-08
[2] https://speakerdeck.com/line_developers/line-data-center-networking-with-srv6
[3] https://patchwork.ozlabs.org/patch/799837/

Signed-off-by: Carmine Scarpitta <carmine.scarpitta@uniroma2.it>
Acked-by: Ahmed Abdelsalam <ahmed.abdelsalam@gssi.it>
Acked-by: Andrea Mayer <andrea.mayer@uniroma2.it>
Acked-by: Paolo Lungaroni <paolo.lungaroni@cnit.it>
---
 net/ipv6/seg6_local.c | 49 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c
index 7cbc19731997..d54a921ea96d 100644
--- a/net/ipv6/seg6_local.c
+++ b/net/ipv6/seg6_local.c
@@ -151,6 +151,26 @@ static void advance_nextseg(struct ipv6_sr_hdr *srh, struct in6_addr *daddr)
 	*daddr = *addr;
 }
 
+static int seg6_lookup_nexthop_v4(struct sk_buff *skb, u32 tbl_id)
+{
+	struct net *net = dev_net(skb->dev);
+	struct fib_result res;
+	struct iphdr *iph;
+	u8 tos;
+
+	iph = ip_hdr(skb);
+	tos = iph->tos & IPTOS_RT_MASK;
+
+	res.table = fib_get_table(net, tbl_id);
+	if (!res.table)
+		return -ENOENT;
+
+	skb_dst_drop(skb);
+
+	return ip_route_input_rcu(skb, iph->daddr, iph->saddr,
+				  tos, skb->dev, &res, true);
+}
+
 static int
 seg6_lookup_any_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
 			u32 tbl_id, bool local_delivery)
@@ -401,6 +421,30 @@ static int input_action_end_dx4(struct sk_buff *skb,
 	return -EINVAL;
 }
 
+static int input_action_end_dt4(struct sk_buff *skb,
+				struct seg6_local_lwt *slwt)
+{
+	int err;
+
+	if (!decap_and_validate(skb, IPPROTO_IPIP))
+		goto drop;
+
+	if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+		goto drop;
+
+	skb_set_transport_header(skb, sizeof(struct iphdr));
+
+	err = seg6_lookup_nexthop_v4(skb, slwt->table);
+	if (err)
+		goto drop;
+
+	return dst_input(skb);
+
+drop:
+	kfree_skb(skb);
+	return -EINVAL;
+}
+
 static int input_action_end_dt6(struct sk_buff *skb,
 				struct seg6_local_lwt *slwt)
 {
@@ -589,6 +633,11 @@ static struct seg6_action_desc seg6_action_table[] = {
 		.attrs		= (1 << SEG6_LOCAL_NH4),
 		.input		= input_action_end_dx4,
 	},
+	{
+		.action		= SEG6_LOCAL_ACTION_END_DT4,
+		.attrs		= (1 << SEG6_LOCAL_TABLE),
+		.input		= input_action_end_dt4,
+	},
 	{
 		.action		= SEG6_LOCAL_ACTION_END_DT6,
 		.attrs		= (1 << SEG6_LOCAL_TABLE),
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [v2,net-next 1/2] Perform IPv4 FIB lookup in a predefined FIB table
  2020-03-18 23:16 ` [v2,net-next 1/2] Perform IPv4 FIB lookup in a predefined FIB table Carmine Scarpitta
@ 2020-03-19  1:47   ` David Miller
  0 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2020-03-19  1:47 UTC (permalink / raw)
  To: carmine.scarpitta
  Cc: kuznet, yoshfuji, kuba, netdev, linux-kernel, ahmed.abdelsalam,
	david.lebrun, dav.lebrun, stefano.salsano, andrea.mayer,
	paolo.lungaroni, hiroki.shirokura

From: Carmine Scarpitta <carmine.scarpitta@uniroma2.it>
Date: Thu, 19 Mar 2020 00:16:34 +0100

> This is useful for use-cases implementing a separate routing table
> per tenant.

We have this capability already, it is called VRF.

I'm not adding yet another way to do the same exact thing.

Sorry.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-03-19  1:48 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-18 23:16 [v2,net-next 0/2] Add support for SRv6 End.DT4 action Carmine Scarpitta
2020-03-18 23:16 ` [v2,net-next 1/2] Perform IPv4 FIB lookup in a predefined FIB table Carmine Scarpitta
2020-03-19  1:47   ` David Miller
2020-03-18 23:16 ` [v2,net-next 2/2] Add support for SRv6 End.DT4 action Carmine Scarpitta

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).