Re: [net-next,v2,4/5] seg6: add support for the SRv6 End.DT4 behavior

2020-11-13 Thread David Ahern
On 11/13/20 7:29 PM, Andrea Mayer wrote:
> Hi Jakub,
> 
> On Fri, 13 Nov 2020 18:01:26 -0800
> Jakub Kicinski  wrote:
> 
>>> UAPI solution 2
>>>
>>> we turn "table" into an optional parameter and we add the "vrftable" 
>>> optional
>>> parameter. DT4 can only be used with the "vrftable" (hence it is a required
>>> parameter for DT4).
>>> DT6 can be used with "vrftable" (new vrf mode) or with "table" (legacy mode)
>>> (hence it is an optional parameter for DT6).
>>>
>>> UAPI solution 2 examples:
>>>
>>> ip -6 route add 2001:db8::1/128 encap seg6local action End.DT4 vrftable 100 
>>> dev eth0
>>> ip -6 route add 2001:db8::1/128 encap seg6local action End.DT6 vrftable 100 
>>> dev eth0
>>> ip -6 route add 2001:db8::1/128 encap seg6local action End.DT6 table 100 
>>> dev eth0
>>>
>>> IMO solution 2 is nicer from UAPI POV because we always have only one 
>>> parameter, maybe solution 1 is slightly easier to implement, all in all 
>>> we prefer solution 2 but we can go for 1 if you prefer.
>>
>> Agreed, 2 looks better to me as well. But let's not conflate uABI with
>> iproute2's command line. I'm more concerned about the kernel ABI.
> 
> Sorry I was a little imprecise here. I reported only the user command 
> perspective.
> From the kernel point of view in solution 2 the vrftable will be a new
> [SEG6_LOCAL_VRFTABLE] optional parameter.
> 
>> BTW you prefer to operate on tables (and therefore require
>> net.vrf.strict_mode=1) because that's closer to the spirit of the RFC,
>> correct? As I said from the implementation perspective passing any VRF
>> ifindex down from user space to the kernel should be fine?
> 
> Yes, I definitely prefer to operate on tables (and so on the table ID) due to
> the spirit of the RFC. We have discussed in depth this design choice with
> David Ahern when implementing the DT4 patch and we are confident that 
> operating
> with VRF strict mode is a sound approach also for DT6. 
> 

I like the vrftable option. Straightforward extension from current table
argument.


Re: [net-next,v2,4/5] seg6: add support for the SRv6 End.DT4 behavior

2020-11-13 Thread Andrea Mayer
Hi Jakub,

On Fri, 13 Nov 2020 18:01:26 -0800
Jakub Kicinski  wrote:

> > UAPI solution 2
> > 
> > we turn "table" into an optional parameter and we add the "vrftable" 
> > optional
> > parameter. DT4 can only be used with the "vrftable" (hence it is a required
> > parameter for DT4).
> > DT6 can be used with "vrftable" (new vrf mode) or with "table" (legacy mode)
> > (hence it is an optional parameter for DT6).
> > 
> > UAPI solution 2 examples:
> > 
> > ip -6 route add 2001:db8::1/128 encap seg6local action End.DT4 vrftable 100 
> > dev eth0
> > ip -6 route add 2001:db8::1/128 encap seg6local action End.DT6 vrftable 100 
> > dev eth0
> > ip -6 route add 2001:db8::1/128 encap seg6local action End.DT6 table 100 
> > dev eth0
> > 
> > IMO solution 2 is nicer from UAPI POV because we always have only one 
> > parameter, maybe solution 1 is slightly easier to implement, all in all 
> > we prefer solution 2 but we can go for 1 if you prefer.
> 
> Agreed, 2 looks better to me as well. But let's not conflate uABI with
> iproute2's command line. I'm more concerned about the kernel ABI.

Sorry I was a little imprecise here. I reported only the user command 
perspective.
>From the kernel point of view in solution 2 the vrftable will be a new
[SEG6_LOCAL_VRFTABLE] optional parameter.

> BTW you prefer to operate on tables (and therefore require
> net.vrf.strict_mode=1) because that's closer to the spirit of the RFC,
> correct? As I said from the implementation perspective passing any VRF
> ifindex down from user space to the kernel should be fine?

Yes, I definitely prefer to operate on tables (and so on the table ID) due to
the spirit of the RFC. We have discussed in depth this design choice with
David Ahern when implementing the DT4 patch and we are confident that operating
with VRF strict mode is a sound approach also for DT6. 

Thanks
Andrea,


Re: [net-next,v2,4/5] seg6: add support for the SRv6 End.DT4 behavior

2020-11-13 Thread Jakub Kicinski
On Sat, 14 Nov 2020 02:50:58 +0100 Andrea Mayer wrote:
> Hi Jakub,
> Please see my responses inline:
> 
> On Fri, 13 Nov 2020 15:54:37 -0800
> Jakub Kicinski  wrote:
> 
> > On Sat, 14 Nov 2020 00:00:24 +0100 Andrea Mayer wrote:  
> > > On Fri, 13 Nov 2020 13:40:10 -0800
> > > Jakub Kicinski  wrote:
> > > 
> > > I can tackle the v6 version but how do we face the compatibility issue 
> > > raised
> > > by Stefano in his message?
> > > 
> > > if it is ok to implement a uAPI that breaks the existing scripts, it is 
> > > relatively
> > > easy to replicate the VRF-based approach also in v6.  
> > 
> > We need to keep existing End.DT6 as is, and add a separate
> > implementation.  
> 
> ok
> 
> >
> > The way to distinguish between the two could be either by  
> 
> > 1) passing via
> > netlink a flag attribute (which would request use of VRF in both
> > cases);  
> 
> yes, feasible... see UAPI solution 1
> 
> > 2) using a different attribute than SEG6_LOCAL_TABLE for the
> > table id (or perhaps passing VRF's ifindex instead), e.g.
> > SEG6_LOCAL_TABLE_VRF;  
> 
> yes, feasible... see UAPI solution 2
> 
> > 3) or adding a new command
> > (SEG6_LOCAL_ACTION_END_DT6_VRF) which would behave like End.DT4.  
> 
> no, we prefer not to add a new command, because it is better to keep a 
> semantic one-to-one relationship between these commands and the SRv6 
> behaviors defined in the draft.
> 
> 
> UAPI solution 1
> 
> we add a new parameter "vrfmode". DT4 can only be used with the 
> vrfmode parameter (hence it is a required parameter for DT4).
> DT6 can be used with "vrfmode" (new vrf based mode) or without "vrfmode" 
> (legacy mode)(hence "vrfmode" is an optional parameter for DT6)
> 
> UAPI solution 1 examples:
> 
> ip -6 route add 2001:db8::1/128 encap seg6local action End.DT4 vrfmode table 
> 100 dev eth0
> ip -6 route add 2001:db8::1/128 encap seg6local action End.DT6 vrfmode table 
> 100 dev eth0
> ip -6 route add 2001:db8::1/128 encap seg6local action End.DT6 table 100 dev 
> eth0
> 
> UAPI solution 2
> 
> we turn "table" into an optional parameter and we add the "vrftable" optional
> parameter. DT4 can only be used with the "vrftable" (hence it is a required
> parameter for DT4).
> DT6 can be used with "vrftable" (new vrf mode) or with "table" (legacy mode)
> (hence it is an optional parameter for DT6).
> 
> UAPI solution 2 examples:
> 
> ip -6 route add 2001:db8::1/128 encap seg6local action End.DT4 vrftable 100 
> dev eth0
> ip -6 route add 2001:db8::1/128 encap seg6local action End.DT6 vrftable 100 
> dev eth0
> ip -6 route add 2001:db8::1/128 encap seg6local action End.DT6 table 100 dev 
> eth0
> 
> IMO solution 2 is nicer from UAPI POV because we always have only one 
> parameter, maybe solution 1 is slightly easier to implement, all in all 
> we prefer solution 2 but we can go for 1 if you prefer.

Agreed, 2 looks better to me as well. But let's not conflate uABI with
iproute2's command line. I'm more concerned about the kernel ABI.

BTW you prefer to operate on tables (and therefore require
net.vrf.strict_mode=1) because that's closer to the spirit of the RFC,
correct? As I said from the implementation perspective passing any VRF
ifindex down from user space to the kernel should be fine?


Re: [net-next,v2,4/5] seg6: add support for the SRv6 End.DT4 behavior

2020-11-13 Thread Andrea Mayer
Hi Jakub,
Please see my responses inline:

On Fri, 13 Nov 2020 15:54:37 -0800
Jakub Kicinski  wrote:

> On Sat, 14 Nov 2020 00:00:24 +0100 Andrea Mayer wrote:
> > On Fri, 13 Nov 2020 13:40:10 -0800
> > Jakub Kicinski  wrote:
> > 
> > I can tackle the v6 version but how do we face the compatibility issue 
> > raised
> > by Stefano in his message?
> > 
> > if it is ok to implement a uAPI that breaks the existing scripts, it is 
> > relatively
> > easy to replicate the VRF-based approach also in v6.
> 
> We need to keep existing End.DT6 as is, and add a separate
> implementation.

ok

>
> The way to distinguish between the two could be either by

> 1) passing via
> netlink a flag attribute (which would request use of VRF in both
> cases);

yes, feasible... see UAPI solution 1

> 2) using a different attribute than SEG6_LOCAL_TABLE for the
> table id (or perhaps passing VRF's ifindex instead), e.g.
> SEG6_LOCAL_TABLE_VRF;

yes, feasible... see UAPI solution 2

> 3) or adding a new command
> (SEG6_LOCAL_ACTION_END_DT6_VRF) which would behave like End.DT4.

no, we prefer not to add a new command, because it is better to keep a 
semantic one-to-one relationship between these commands and the SRv6 
behaviors defined in the draft.


UAPI solution 1

we add a new parameter "vrfmode". DT4 can only be used with the 
vrfmode parameter (hence it is a required parameter for DT4).
DT6 can be used with "vrfmode" (new vrf based mode) or without "vrfmode" 
(legacy mode)(hence "vrfmode" is an optional parameter for DT6)

UAPI solution 1 examples:

ip -6 route add 2001:db8::1/128 encap seg6local action End.DT4 vrfmode table 
100 dev eth0
ip -6 route add 2001:db8::1/128 encap seg6local action End.DT6 vrfmode table 
100 dev eth0
ip -6 route add 2001:db8::1/128 encap seg6local action End.DT6 table 100 dev 
eth0

UAPI solution 2

we turn "table" into an optional parameter and we add the "vrftable" optional
parameter. DT4 can only be used with the "vrftable" (hence it is a required
parameter for DT4).
DT6 can be used with "vrftable" (new vrf mode) or with "table" (legacy mode)
(hence it is an optional parameter for DT6).

UAPI solution 2 examples:

ip -6 route add 2001:db8::1/128 encap seg6local action End.DT4 vrftable 100 dev 
eth0
ip -6 route add 2001:db8::1/128 encap seg6local action End.DT6 vrftable 100 dev 
eth0
ip -6 route add 2001:db8::1/128 encap seg6local action End.DT6 table 100 dev 
eth0

IMO solution 2 is nicer from UAPI POV because we always have only one 
parameter, maybe solution 1 is slightly easier to implement, all in all 
we prefer solution 2 but we can go for 1 if you prefer.

Waiting for your advice!

Thanks,
Andrea


Re: [net-next,v2,4/5] seg6: add support for the SRv6 End.DT4 behavior

2020-11-13 Thread Jakub Kicinski
On Sat, 14 Nov 2020 00:00:24 +0100 Andrea Mayer wrote:
> On Fri, 13 Nov 2020 13:40:10 -0800
> Jakub Kicinski  wrote:
> 
> > On Fri, 13 Nov 2020 11:40:36 -0800 Jakub Kicinski wrote:  
> > > > agreed. The v6 variant has existed for a while. The v4 version is
> > > > independent.
> > > 
> > > Okay, I'm not sure what's the right call so I asked DaveM.  
> > 
> > DaveM raised a concern that unless we implement v6 now we can't be sure
> > the interface we create for v4 is going to fit there.
> > 
> > So Andrea unless it's a major hurdle, could you take a stab at the v6
> > version with VRFs as part of this series?  
> 
> I can tackle the v6 version but how do we face the compatibility issue raised
> by Stefano in his message?
> 
> if it is ok to implement a uAPI that breaks the existing scripts, it is 
> relatively
> easy to replicate the VRF-based approach also in v6.

We need to keep existing End.DT6 as is, and add a separate
implementation.

The way to distinguish between the two could be either by passing via
netlink a flag attribute (which would request use of VRF in both
cases); using a different attribute than SEG6_LOCAL_TABLE for the
table id (or perhaps passing VRF's ifindex instead), e.g.
SEG6_LOCAL_TABLE_VRF; or adding a new command
(SEG6_LOCAL_ACTION_END_DT6_VRF) which would behave like End.DT4.


Re: [net-next,v2,4/5] seg6: add support for the SRv6 End.DT4 behavior

2020-11-13 Thread Andrea Mayer
Hi Jakub,

On Fri, 13 Nov 2020 13:40:10 -0800
Jakub Kicinski  wrote:

> On Fri, 13 Nov 2020 11:40:36 -0800 Jakub Kicinski wrote:
> > > agreed. The v6 variant has existed for a while. The v4 version is
> > > independent.  
> > 
> > Okay, I'm not sure what's the right call so I asked DaveM.
> 
> DaveM raised a concern that unless we implement v6 now we can't be sure
> the interface we create for v4 is going to fit there.
> 
> So Andrea unless it's a major hurdle, could you take a stab at the v6
> version with VRFs as part of this series?

I can tackle the v6 version but how do we face the compatibility issue raised
by Stefano in his message?

if it is ok to implement a uAPI that breaks the existing scripts, it is 
relatively
easy to replicate the VRF-based approach also in v6.

Waiting for your advice!

Thanks,
Andrea


Re: [net-next,v2,4/5] seg6: add support for the SRv6 End.DT4 behavior

2020-11-13 Thread Jakub Kicinski
On Fri, 13 Nov 2020 11:40:36 -0800 Jakub Kicinski wrote:
> > agreed. The v6 variant has existed for a while. The v4 version is
> > independent.  
> 
> Okay, I'm not sure what's the right call so I asked DaveM.

DaveM raised a concern that unless we implement v6 now we can't be sure
the interface we create for v4 is going to fit there.

So Andrea unless it's a major hurdle, could you take a stab at the v6
version with VRFs as part of this series?


Re: [net-next,v2,4/5] seg6: add support for the SRv6 End.DT4 behavior

2020-11-13 Thread Stefano Salsano

Il 2020-11-13 20:40, Jakub Kicinski ha scritto:

On Fri, 13 Nov 2020 10:04:44 -0700 David Ahern wrote:

On 11/13/20 10:02 AM, Stefano Salsano wrote:

Il 2020-11-13 17:55, Jakub Kicinski ha scritto:

On Thu, 12 Nov 2020 18:49:17 -0700 David Ahern wrote:

On 11/12/20 6:28 PM, Andrea Mayer wrote:

The implementation of SRv6 End.DT4 differs from the the
implementation of SRv6
End.DT6 due to the different *route input* lookup functions. For
IPv6 is it
possible to force the routing lookup specifying a routing table
through the
ip6_pol_route() function (as it is done in the
seg6_lookup_any_nexthop()).


It is unfortunate that the IPv6 variant got in without the VRF piece.


Should we make it a requirement for this series to also extend the v6
version to support the preferred VRF-based operation? Given VRF is
better and we require v4 features to be implemented for v6?


I think it is better to separate the two aspects... adding a missing
feature in IPv4 datapath should not depend on improving the quality of
the implementation of the IPv6 datapath :-)

I think that Andrea is willing to work on improving the IPv6
implementation, but this should be considered after this patchset...


agreed. The v6 variant has existed for a while. The v4 version is
independent.


Okay, I'm not sure what's the right call so I asked DaveM.

TBH I wasn't expecting this reaction, we're talking about a 200 LoC
patch which would probably be 90% reused for v6...



Jakub, we've considered the possibility to extend the v6 version to 
support the preferred VRF-based operation as you suggested


at first glance, it would break the uAPI compatibility with existing 
scripts that use SRv6 DT6, currently we configure the decap operation in 
this way


ip -6 route add 2001:db8::1/128 encap seg6local action End.DT6 table 100 
dev eth0


if the v6 version is extended to support the VRF-based operation, in 
order to configure the decap operation we have to do (like we do in the 
v4 version)


ip link add vrf0 type vrf table 100
sysctl -w net.vrf.strict_mode=1
ip -6 route add 2001:db8::1/128 encap seg6local action End.DT6 table 100 
dev eth0


(of course the sysctl is needed globally once... while the "ip link 
add..." command is needed once for every table X that is used in a script)


considering how much we care of not breaking existing functionality... 
it is not clear IMO if we should go into this direction or we should 
think twice... and maybe look for another design to introduce VRFs into v6


so I would prefer finalizing the DT4 patchset and then start discussing 
the VRF support in v6 version


--
***
Stefano Salsano
Professore Associato
Dipartimento Ingegneria Elettronica
Universita' di Roma Tor Vergata
Viale Politecnico, 1 - 00133 Roma - ITALY

http://netgroup.uniroma2.it/Stefano_Salsano/

E-mail  : stefano.sals...@uniroma2.it
Cell.   : +39 320 4307310
Office  : (Tel.) +39 06 72597770 (Fax.) +39 06 72597435
***



Re: [net-next,v2,4/5] seg6: add support for the SRv6 End.DT4 behavior

2020-11-13 Thread Jakub Kicinski
On Fri, 13 Nov 2020 10:04:44 -0700 David Ahern wrote:
> On 11/13/20 10:02 AM, Stefano Salsano wrote:
> > Il 2020-11-13 17:55, Jakub Kicinski ha scritto:  
> >> On Thu, 12 Nov 2020 18:49:17 -0700 David Ahern wrote:  
> >>> On 11/12/20 6:28 PM, Andrea Mayer wrote:  
>  The implementation of SRv6 End.DT4 differs from the the
>  implementation of SRv6
>  End.DT6 due to the different *route input* lookup functions. For
>  IPv6 is it
>  possible to force the routing lookup specifying a routing table
>  through the
>  ip6_pol_route() function (as it is done in the
>  seg6_lookup_any_nexthop()).  
> >>>
> >>> It is unfortunate that the IPv6 variant got in without the VRF piece.  
> >>
> >> Should we make it a requirement for this series to also extend the v6
> >> version to support the preferred VRF-based operation? Given VRF is
> >> better and we require v4 features to be implemented for v6?  
> > 
> > I think it is better to separate the two aspects... adding a missing
> > feature in IPv4 datapath should not depend on improving the quality of
> > the implementation of the IPv6 datapath :-)
> > 
> > I think that Andrea is willing to work on improving the IPv6
> > implementation, but this should be considered after this patchset...
>
> agreed. The v6 variant has existed for a while. The v4 version is
> independent.

Okay, I'm not sure what's the right call so I asked DaveM.

TBH I wasn't expecting this reaction, we're talking about a 200 LoC
patch which would probably be 90% reused for v6...


Re: [net-next,v2,4/5] seg6: add support for the SRv6 End.DT4 behavior

2020-11-13 Thread Stefano Salsano

Il 2020-11-13 17:55, Jakub Kicinski ha scritto:

On Thu, 12 Nov 2020 18:49:17 -0700 David Ahern wrote:

On 11/12/20 6:28 PM, Andrea Mayer wrote:

The implementation of SRv6 End.DT4 differs from the the implementation of SRv6
End.DT6 due to the different *route input* lookup functions. For IPv6 is it
possible to force the routing lookup specifying a routing table through the
ip6_pol_route() function (as it is done in the seg6_lookup_any_nexthop()).


It is unfortunate that the IPv6 variant got in without the VRF piece.


Should we make it a requirement for this series to also extend the v6
version to support the preferred VRF-based operation? Given VRF is
better and we require v4 features to be implemented for v6?


I think it is better to separate the two aspects... adding a missing 
feature in IPv4 datapath should not depend on improving the quality of 
the implementation of the IPv6 datapath :-)


I think that Andrea is willing to work on improving the IPv6 
implementation, but this should be considered after this patchset...


my 2c

Stefano

--
***
Stefano Salsano
Professore Associato
Dipartimento Ingegneria Elettronica
Universita' di Roma Tor Vergata
Viale Politecnico, 1 - 00133 Roma - ITALY

http://netgroup.uniroma2.it/Stefano_Salsano/

E-mail  : stefano.sals...@uniroma2.it
Cell.   : +39 320 4307310
Office  : (Tel.) +39 06 72597770 (Fax.) +39 06 72597435
***



Re: [net-next,v2,4/5] seg6: add support for the SRv6 End.DT4 behavior

2020-11-13 Thread David Ahern
On 11/13/20 10:02 AM, Stefano Salsano wrote:
> Il 2020-11-13 17:55, Jakub Kicinski ha scritto:
>> On Thu, 12 Nov 2020 18:49:17 -0700 David Ahern wrote:
>>> On 11/12/20 6:28 PM, Andrea Mayer wrote:
 The implementation of SRv6 End.DT4 differs from the the
 implementation of SRv6
 End.DT6 due to the different *route input* lookup functions. For
 IPv6 is it
 possible to force the routing lookup specifying a routing table
 through the
 ip6_pol_route() function (as it is done in the
 seg6_lookup_any_nexthop()).
>>>
>>> It is unfortunate that the IPv6 variant got in without the VRF piece.
>>
>> Should we make it a requirement for this series to also extend the v6
>> version to support the preferred VRF-based operation? Given VRF is
>> better and we require v4 features to be implemented for v6?
> 
> I think it is better to separate the two aspects... adding a missing
> feature in IPv4 datapath should not depend on improving the quality of
> the implementation of the IPv6 datapath :-)
> 
> I think that Andrea is willing to work on improving the IPv6
> implementation, but this should be considered after this patchset...
> 

agreed. The v6 variant has existed for a while. The v4 version is
independent.


Re: [net-next,v2,4/5] seg6: add support for the SRv6 End.DT4 behavior

2020-11-13 Thread Jakub Kicinski
On Thu, 12 Nov 2020 18:49:17 -0700 David Ahern wrote:
> On 11/12/20 6:28 PM, Andrea Mayer wrote:
> > The implementation of SRv6 End.DT4 differs from the the implementation of 
> > SRv6
> > End.DT6 due to the different *route input* lookup functions. For IPv6 is it
> > possible to force the routing lookup specifying a routing table through the
> > ip6_pol_route() function (as it is done in the seg6_lookup_any_nexthop()).  
> 
> It is unfortunate that the IPv6 variant got in without the VRF piece.

Should we make it a requirement for this series to also extend the v6
version to support the preferred VRF-based operation? Given VRF is
better and we require v4 features to be implemented for v6?


Re: [net-next,v2,4/5] seg6: add support for the SRv6 End.DT4 behavior

2020-11-12 Thread David Ahern
On 11/12/20 6:28 PM, Andrea Mayer wrote:
> The implementation of SRv6 End.DT4 differs from the the implementation of SRv6
> End.DT6 due to the different *route input* lookup functions. For IPv6 is it
> possible to force the routing lookup specifying a routing table through the
> ip6_pol_route() function (as it is done in the seg6_lookup_any_nexthop()).

It is unfortunate that the IPv6 variant got in without the VRF piece.


Re: [net-next,v2,4/5] seg6: add support for the SRv6 End.DT4 behavior

2020-11-12 Thread Andrea Mayer
Hi Jakub,
many thanks for your review. Please see my responses inline:

On Tue, 10 Nov 2020 15:12:55 -0800
Jakub Kicinski  wrote:

> On Sat,  7 Nov 2020 16:31:38 +0100 Andrea Mayer wrote:
> > SRv6 End.DT4 is defined in the SRv6 Network Programming [1].
> > 
> > The SRv6 End.DT4 is used to implement IPv4 L3VPN use-cases in
> > multi-tenants environments. It decapsulates the received packets and it
> > performs IPv4 routing lookup in the routing table of the tenant.
> > 
> > The SRv6 End.DT4 Linux implementation leverages a VRF device in order to
> > force the routing lookup into the associated routing table.
> 
> How does the behavior of DT4 compare to DT6?
> 

The implementation of SRv6 End.DT4 differs from the the implementation of SRv6
End.DT6 due to the different *route input* lookup functions. For IPv6 is it
possible to force the routing lookup specifying a routing table through the
ip6_pol_route() function (as it is done in the seg6_lookup_any_nexthop()).

Conversely, for the IPv4 we cannot force the lookup into a specific table with
the functions that are currently exposed by the kernel.

> The implementation looks quite different.
>

Long story short:
A long time ago, we discussed here on the mailing list how best to implement the
SRv6 DT4. After some time, we identified with the help of David Ahern the VRF as
the key infrastructure on which to build the SRv6 End.DT4. Indeed, the use of
VRF allows us not to touch in any way the core components of the kernel (i.e.:
the ipv4 routing system) and to exploit an already existing infrastructure.

I would say that also the SRv6 End.DT6 should leverage the VRF as we did for
SRv6 End.DT4. We can also try to change End.DT6 implementation, if needed.

> > To make the End.DT4 work properly, it must be guaranteed that the routing
> > table used for routing lookup operations is bound to one and only one
> > VRF during the tunnel creation. Such constraint has to be enforced by
> > enabling the VRF strict_mode sysctl parameter, i.e:
> >  $ sysctl -wq net.vrf.strict_mode=1.
> > 
> > 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 behavior.
> > 
> > The iproute2 counterpart required for configuring the SRv6 End.DT4
> > behavior is already implemented along with the other supported SRv6
> > behaviors [3].
> > 
> > [1] https://tools.ietf.org/html/draft-ietf-spring-srv6-network-programming
> > [2] 
> > https://speakerdeck.com/line_developers/line-data-center-networking-with-srv6
> > [3] https://patchwork.ozlabs.org/patch/799837/
> > 
> > Signed-off-by: Andrea Mayer 
> > ---
> >  net/ipv6/seg6_local.c | 205 ++
> >  1 file changed, 205 insertions(+)
> > 
> > diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c
> > index 4b0f155d641d..a41074acd43e 100644
> > --- a/net/ipv6/seg6_local.c
> > +++ b/net/ipv6/seg6_local.c
> > @@ -57,6 +57,14 @@ struct bpf_lwt_prog {
> > char *name;
> >  };
> >  
> > +struct seg6_end_dt4_info {
> > +   struct net *net;
> > +   /* VRF device associated to the routing table used by the SRv6 End.DT4
> > +* behavior for routing IPv4 packets.
> > +*/
> > +   int vrf_ifindex;
> > +};
> > +
> >  struct seg6_local_lwt {
> > int action;
> > struct ipv6_sr_hdr *srh;
> > @@ -66,6 +74,7 @@ struct seg6_local_lwt {
> > int iif;
> > int oif;
> > struct bpf_lwt_prog bpf;
> > +   struct seg6_end_dt4_info dt4_info;
> >  
> > int headroom;
> > struct seg6_action_desc *desc;
> > @@ -413,6 +422,194 @@ static int input_action_end_dx4(struct sk_buff *skb,
> > return -EINVAL;
> >  }
> >  
> > +#ifdef CONFIG_NET_L3_MASTER_DEV
> > +
> 
> no need for this empty line.
> 

Ok.

> > +static struct net *fib6_config_get_net(const struct fib6_config *fib6_cfg)
> > +{
> > +   const struct nl_info *nli = _cfg->fc_nlinfo;
> > +
> > +   return nli->nl_net;
> > +}
> > +
> > +static int seg6_end_dt4_build(struct seg6_local_lwt *slwt, const void *cfg,
> > + struct netlink_ext_ack *extack)
> > +{
> > +   struct seg6_end_dt4_info *info = >dt4_info;
> > +   int vrf_ifindex;
> > +   struct net *net;
> > +
> > +   net = fib6_config_get_net(cfg);
> > +
> > +   vrf_ifindex = l3mdev_ifindex_lookup_by_table_id(L3MDEV_TYPE_VRF, net,
> > +   slwt->table);
> > +   if (vrf_ifindex < 0) {
> > +   if (vrf_ifindex == -EPERM) {
> > +   NL_SET_ERR_MSG(extack,
> > +  "Strict mode for VRF is disabled");
> > +   } else if (vrf_ifindex == -ENODEV) {
> > +   NL_SET_ERR_MSG(extack, "No such device");
> 
> That's what -ENODEV already says.
>

Yes, sorry for this very trivial message. I will improve it in v3.
 
> > +   } else {
> > +   NL_SET_ERR_MSG(extack, "Unknown error");
> 
> Useless error.
> 

Ok, I will 

Re: [net-next,v2,4/5] seg6: add support for the SRv6 End.DT4 behavior

2020-11-10 Thread Jakub Kicinski
On Sat,  7 Nov 2020 16:31:38 +0100 Andrea Mayer wrote:
> SRv6 End.DT4 is defined in the SRv6 Network Programming [1].
> 
> The SRv6 End.DT4 is used to implement IPv4 L3VPN use-cases in
> multi-tenants environments. It decapsulates the received packets and it
> performs IPv4 routing lookup in the routing table of the tenant.
> 
> The SRv6 End.DT4 Linux implementation leverages a VRF device in order to
> force the routing lookup into the associated routing table.

How does the behavior of DT4 compare to DT6?

The implementation looks quite different.

> To make the End.DT4 work properly, it must be guaranteed that the routing
> table used for routing lookup operations is bound to one and only one
> VRF during the tunnel creation. Such constraint has to be enforced by
> enabling the VRF strict_mode sysctl parameter, i.e:
>  $ sysctl -wq net.vrf.strict_mode=1.
> 
> 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 behavior.
> 
> The iproute2 counterpart required for configuring the SRv6 End.DT4
> behavior is already implemented along with the other supported SRv6
> behaviors [3].
> 
> [1] https://tools.ietf.org/html/draft-ietf-spring-srv6-network-programming
> [2] 
> https://speakerdeck.com/line_developers/line-data-center-networking-with-srv6
> [3] https://patchwork.ozlabs.org/patch/799837/
> 
> Signed-off-by: Andrea Mayer 
> ---
>  net/ipv6/seg6_local.c | 205 ++
>  1 file changed, 205 insertions(+)
> 
> diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c
> index 4b0f155d641d..a41074acd43e 100644
> --- a/net/ipv6/seg6_local.c
> +++ b/net/ipv6/seg6_local.c
> @@ -57,6 +57,14 @@ struct bpf_lwt_prog {
>   char *name;
>  };
>  
> +struct seg6_end_dt4_info {
> + struct net *net;
> + /* VRF device associated to the routing table used by the SRv6 End.DT4
> +  * behavior for routing IPv4 packets.
> +  */
> + int vrf_ifindex;
> +};
> +
>  struct seg6_local_lwt {
>   int action;
>   struct ipv6_sr_hdr *srh;
> @@ -66,6 +74,7 @@ struct seg6_local_lwt {
>   int iif;
>   int oif;
>   struct bpf_lwt_prog bpf;
> + struct seg6_end_dt4_info dt4_info;
>  
>   int headroom;
>   struct seg6_action_desc *desc;
> @@ -413,6 +422,194 @@ static int input_action_end_dx4(struct sk_buff *skb,
>   return -EINVAL;
>  }
>  
> +#ifdef CONFIG_NET_L3_MASTER_DEV
> +

no need for this empty line.

> +static struct net *fib6_config_get_net(const struct fib6_config *fib6_cfg)
> +{
> + const struct nl_info *nli = _cfg->fc_nlinfo;
> +
> + return nli->nl_net;
> +}
> +
> +static int seg6_end_dt4_build(struct seg6_local_lwt *slwt, const void *cfg,
> +   struct netlink_ext_ack *extack)
> +{
> + struct seg6_end_dt4_info *info = >dt4_info;
> + int vrf_ifindex;
> + struct net *net;
> +
> + net = fib6_config_get_net(cfg);
> +
> + vrf_ifindex = l3mdev_ifindex_lookup_by_table_id(L3MDEV_TYPE_VRF, net,
> + slwt->table);
> + if (vrf_ifindex < 0) {
> + if (vrf_ifindex == -EPERM) {
> + NL_SET_ERR_MSG(extack,
> +"Strict mode for VRF is disabled");
> + } else if (vrf_ifindex == -ENODEV) {
> + NL_SET_ERR_MSG(extack, "No such device");

That's what -ENODEV already says.

> + } else {
> + NL_SET_ERR_MSG(extack, "Unknown error");

Useless error.

> + pr_debug("seg6local: SRv6 End.DT4 creation error=%d\n",
> +  vrf_ifindex);
> + }
> +
> + return vrf_ifindex;
> + }
> +
> + info->net = net;
> + info->vrf_ifindex = vrf_ifindex;
> +
> + return 0;
> +}
> +
> +/* The SRv6 End.DT4 behavior extracts the inner (IPv4) packet and routes the
> + * IPv4 packet by looking at the configured routing table.
> + *
> + * In the SRv6 End.DT4 use case, we can receive traffic (IPv6+Segment Routing
> + * Header packets) from several interfaces and the IPv6 destination address 
> (DA)
> + * is used for retrieving the specific instance of the End.DT4 behavior that
> + * should process the packets.
> + *
> + * However, the inner IPv4 packet is not really bound to any receiving
> + * interface and thus the End.DT4 sets the VRF (associated with the
> + * corresponding routing table) as the *receiving* interface.
> + * In other words, the End.DT4 processes a packet as if it has been received
> + * directly by the VRF (and not by one of its slave devices, if any).
> + * In this way, the VRF interface is used for routing the IPv4 packet in
> + * according to the routing table configured by the End.DT4 instance.
> + *
> + * This design allows you to get some interesting features like:
> + *  1) the statistics on rx packets;
> + *  2) the 

[net-next,v2,4/5] seg6: add support for the SRv6 End.DT4 behavior

2020-11-07 Thread Andrea Mayer
SRv6 End.DT4 is defined in the SRv6 Network Programming [1].

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

The SRv6 End.DT4 Linux implementation leverages a VRF device in order to
force the routing lookup into the associated routing table.

To make the End.DT4 work properly, it must be guaranteed that the routing
table used for routing lookup operations is bound to one and only one
VRF during the tunnel creation. Such constraint has to be enforced by
enabling the VRF strict_mode sysctl parameter, i.e:
 $ sysctl -wq net.vrf.strict_mode=1.

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 behavior.

The iproute2 counterpart required for configuring the SRv6 End.DT4
behavior is already implemented along with the other supported SRv6
behaviors [3].

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

Signed-off-by: Andrea Mayer 
---
 net/ipv6/seg6_local.c | 205 ++
 1 file changed, 205 insertions(+)

diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c
index 4b0f155d641d..a41074acd43e 100644
--- a/net/ipv6/seg6_local.c
+++ b/net/ipv6/seg6_local.c
@@ -57,6 +57,14 @@ struct bpf_lwt_prog {
char *name;
 };
 
+struct seg6_end_dt4_info {
+   struct net *net;
+   /* VRF device associated to the routing table used by the SRv6 End.DT4
+* behavior for routing IPv4 packets.
+*/
+   int vrf_ifindex;
+};
+
 struct seg6_local_lwt {
int action;
struct ipv6_sr_hdr *srh;
@@ -66,6 +74,7 @@ struct seg6_local_lwt {
int iif;
int oif;
struct bpf_lwt_prog bpf;
+   struct seg6_end_dt4_info dt4_info;
 
int headroom;
struct seg6_action_desc *desc;
@@ -413,6 +422,194 @@ static int input_action_end_dx4(struct sk_buff *skb,
return -EINVAL;
 }
 
+#ifdef CONFIG_NET_L3_MASTER_DEV
+
+static struct net *fib6_config_get_net(const struct fib6_config *fib6_cfg)
+{
+   const struct nl_info *nli = _cfg->fc_nlinfo;
+
+   return nli->nl_net;
+}
+
+static int seg6_end_dt4_build(struct seg6_local_lwt *slwt, const void *cfg,
+ struct netlink_ext_ack *extack)
+{
+   struct seg6_end_dt4_info *info = >dt4_info;
+   int vrf_ifindex;
+   struct net *net;
+
+   net = fib6_config_get_net(cfg);
+
+   vrf_ifindex = l3mdev_ifindex_lookup_by_table_id(L3MDEV_TYPE_VRF, net,
+   slwt->table);
+   if (vrf_ifindex < 0) {
+   if (vrf_ifindex == -EPERM) {
+   NL_SET_ERR_MSG(extack,
+  "Strict mode for VRF is disabled");
+   } else if (vrf_ifindex == -ENODEV) {
+   NL_SET_ERR_MSG(extack, "No such device");
+   } else {
+   NL_SET_ERR_MSG(extack, "Unknown error");
+
+   pr_debug("seg6local: SRv6 End.DT4 creation error=%d\n",
+vrf_ifindex);
+   }
+
+   return vrf_ifindex;
+   }
+
+   info->net = net;
+   info->vrf_ifindex = vrf_ifindex;
+
+   return 0;
+}
+
+/* The SRv6 End.DT4 behavior extracts the inner (IPv4) packet and routes the
+ * IPv4 packet by looking at the configured routing table.
+ *
+ * In the SRv6 End.DT4 use case, we can receive traffic (IPv6+Segment Routing
+ * Header packets) from several interfaces and the IPv6 destination address 
(DA)
+ * is used for retrieving the specific instance of the End.DT4 behavior that
+ * should process the packets.
+ *
+ * However, the inner IPv4 packet is not really bound to any receiving
+ * interface and thus the End.DT4 sets the VRF (associated with the
+ * corresponding routing table) as the *receiving* interface.
+ * In other words, the End.DT4 processes a packet as if it has been received
+ * directly by the VRF (and not by one of its slave devices, if any).
+ * In this way, the VRF interface is used for routing the IPv4 packet in
+ * according to the routing table configured by the End.DT4 instance.
+ *
+ * This design allows you to get some interesting features like:
+ *  1) the statistics on rx packets;
+ *  2) the possibility to install a packet sniffer on the receiving interface
+ * (the VRF one) for looking at the incoming packets;
+ *  3) the possibility to leverage the netfilter prerouting hook for the inner
+ * IPv4 packet.
+ *
+ * This function returns:
+ *  - the sk_buff* when the VRF rcv handler has processed the packet correctly;
+ *  - NULL when the skb is consumed by the VRF rcv handler;