Commit Graph

330 Commits

Author SHA1 Message Date
Philippe Guibert
162c5d83ad bgpd: add a function to compare two label lists
Create a bgp_labels_same() function that does the
same operations as the static function labels_same from
bgp_mplsvpn.c.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2023-06-16 10:54:58 +02:00
Donald Sharp
6e233c77d8 bgpd: blnc cannot be NULL at if statement time
It is impossible for the blnc statement to ever be NULL at
line 1470 as that the if statement at 1453 guarantees it
to be set to something.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-06-01 08:58:16 -04:00
Philippe Guibert
60e5bc23b9 bgpd: update time of last change when label nexthop entry changed
A timer attribute is added for each label nexthop entry, in order
to know when the last change occured.
The timer value will be used for troubleshooting by a show
command in the next commit.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2023-05-09 21:00:57 +02:00
Philippe Guibert
882d7b8179 bgpd: export redistributed routes with label allocation per nexthop
The label allocation per nexthop mode requires to use a nexthop
tracking context. For redistributed routes, a nexthop tracking
context is created, and the resolution helps to know the real
nexthop ip address used. The below configuration example has
been used:

 > vrf vrf1
 >  ip route 172.31.0.14/32 192.0.2.14
 >  ip route 172.31.0.15/32 192.0.2.12
 >  ip route 172.31.0.30/32 192.0.2.30
 > exit
 > router bgp 65500 vrf vrf1
 >  address-family ipv4 unicast
 >   redistribute static
 >   label vpn export per-nexthop
 > [..]

The static routes are correctly imported in the BGP IPv4 RIB.
Contrary to label allocation per vrf mode, some nexthop tracking
are created/or reused:

 > # show bgp vrf vrf1 nexthop
 > 192.0.2.12 valid [IGP metric 0], #paths 3, peer 192.0.2.12
 >  if r1-eth1
 >  Last update: Fri Jan 13 15:49:42 2023
 > 192.0.2.14 valid [IGP metric 0], #paths 1
 >  if r1-eth1
 >  Last update: Fri Jan 13 15:49:42 2023
 > 192.0.2.30 valid [IGP metric 0], #paths 1
 >  if r1-eth1
 >  Last update: Fri Jan 13 15:49:51 2023
 > [..]

This results in having a BGP VPN route for each of the static
routes:

 > # show bgp ipv4 vpn
 > [..]
 > Route Distinguisher: 444:1
 >  *> 172.31.0.14/32   192.0.2.14@9<            0         32768 ?
 >  *> 172.31.0.15/32   192.0.2.12@9<            0         32768 ?
 >  *> 172.31.0.30/32   192.0.2.30@9<            0         32768 ?
 > [..]

Without that patch, only the redistributed routes that rely on a
pre-existing nexthop tracking context could be exported.

Also, a command in the code about redistributed routes is modified
accordingly, to explain that redistribute routes may be submitted
to nexthop tracking in the case label allocation per next-hop is
used.

note:
VNC routes have been removed from the redistribution,
because of a test failure in the bgp_l3vpn_to_bgp_direct test.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2023-05-09 21:00:57 +02:00
Philippe Guibert
1c6aa043ef bgpd: use nexthop interface when adding LSP in BGP MPLSVPN
BGP MPLSVPN next hop label allocation was using only the next-hop
IP address. As MPLSVPN contexts rely on bnc contexts, the real
nexthop interface is known, and the LSP entry to enter can apply
to the specific interface. To illustrate, the BGP service is able
to handle the following two iproute2 commands:

 > ip -f mpls route add 105 via inet 192.0.2.45 dev r1-eth1
 > ip -f mpls route add 105 via inet 192.0.2.46 dev r1-eth2

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2023-05-09 21:00:57 +02:00
Philippe Guibert
577be36a41 bgpd: add support for l3vpn per-nexthop label
This commit introduces a new method to associate a label to
prefixes to export to a VPNv4 backbone. All the methods to
associate a label to a BGP update is documented in rfc4364,
chapter 4.3.2. Initially, the "single label for an entire
VRF" method was available. This commit adds "single label
for each attachment circuit" method.

The change impacts the control-plane, because each BGP update
is checked to know if the nexthop has reachability in the VRF
or not. If this is the case, then a unique label for a given
destination IP in the VRF will be picked up. This label will
be reused for an other BGP update that will have the same
nexthop IP address.

The change impacts the data-plane, because the MPLs pop
mechanism applied to incoming labelled packets changes: the
MPLS label is popped, and the packet is directly sent to the
connected nexthop described in the previous outgoing BGP VPN
update.

By default per-vrf mode is done, but the user may choose
the per-nexthop mode, by using the vty command from the
previous commit. In the latter case, a per-vrf label
will however be allocated to handle networks that are not directly
connected. This is the case for local traffic for instance.

The change also include the following:

-  ECMP case
In case a route is learnt in a given VRF, and is resolved via an
ECMP nexthop. This implies that when exporting the route as a BGP
update, if label allocation per nexthop is used, then two possible
MPLS values could be picked up, which is not possible with the
current implementation. Actually, the NLRI for VPNv4 stores one
prefix, and one single label value, not two. Today, RFC8277 with
multiple label capability is not yet available.
To avoid this corner case, when a route is resolved via more than one
nexthop, the label allocation per nexthop will not apply, and the
default per-vrf label will be chosen.
Let us imagine BGP redistributes a static route using the `172.31.0.20`
nexthop. The nexthop resolution will find two different nexthops fo a
unique BGP update.

 > r1# show running-config
 > [..]
 > vrf vrf1
 >  ip route 172.31.0.30/32 172.31.0.20
 > r1# show bgp vrf vrf1 nexthop
 > [..]
 > 172.31.0.20 valid [IGP metric 0], #paths 1
 >  gate 192.0.2.11
 >  gate 192.0.2.12
 >  Last update: Mon Jan 16 09:27:09 2023
 >  Paths:
 >    1/1 172.31.0.30/32 VRF vrf1 flags 0x20018

To avoid this situation, BGP updates that resolve over multiple
nexthops are using the unique per-vrf label.

- recursive route case

Prefixes that need a recursive route to be resolved can
also be eligible for mpls allocation per nexthop. In that
case, the nexthop will be the recursive nexthop calculated.

To achieve this, all nexthop types in bnc contexts are valid,
except for the blackhole nexthops.

- network declared prefixes

Nexthop tracking is used to look for the reachability of the
prefixes. When the the 'no bgp network import-check' command
is used, network declared prefixes are maintained active,
even if there is no active nexthop.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2023-05-09 21:00:57 +02:00
Philippe Guibert
9fa282eeb6 bgpd: encode_label call, remove unnecessary braces
Remove unnecessary braces.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2023-05-09 21:00:57 +02:00
Donatas Abraitis
786e2b8bdb Revert "MPLS allocation mode per next hop"
Broken tests, let's revert now.

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2023-05-03 13:52:46 +03:00
Donatas Abraitis
99a1ab0b21
Merge pull request #12646 from pguibert6WIND/mpls_alloc_per_nh
MPLS allocation mode per next hop
2023-05-02 18:36:45 +03:00
Donald Sharp
ef96e3753f bgpd: Use the actual pointer type instead of a void
Let's cut to the chase, we know the pointer type and
it allows us to not to some gyrations.

Signed-off-by: Donald Sharp <sharpd@nvidia.com>
2023-04-10 14:14:01 -04:00
Philippe Guibert
b314ae7eb4 bgpd: update time of last change when label nexthop entry changed
A timer attribute is added for each label nexthop entry, in order
to know when the last change occured.
The timer value will be used for troubleshooting by a show
command in the next commit.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2023-03-22 12:06:29 +01:00
Philippe Guibert
c9b416cbd1 bgpd: export redistributed routes with label allocation per nexthop
The label allocation per nexthop mode requires to use a nexthop
tracking context. For redistributed routes, a nexthop tracking
context is created, and the resolution helps to know the real
nexthop ip address used. The below configuration example has
been used:

 > vrf vrf1
 >  ip route 172.31.0.14/32 192.0.2.14
 >  ip route 172.31.0.15/32 192.0.2.12
 >  ip route 172.31.0.30/32 192.0.2.30
 > exit
 > router bgp 65500 vrf vrf1
 >  address-family ipv4 unicast
 >   redistribute static
 >   label vpn export per-nexthop
 > [..]

The static routes are correctly imported in the BGP IPv4 RIB.
Contrary to label allocation per vrf mode, some nexthop tracking
are created/or reused:

 > # show bgp vrf vrf1 nexthop
 > 192.0.2.12 valid [IGP metric 0], #paths 3, peer 192.0.2.12
 >  if r1-eth1
 >  Last update: Fri Jan 13 15:49:42 2023
 > 192.0.2.14 valid [IGP metric 0], #paths 1
 >  if r1-eth1
 >  Last update: Fri Jan 13 15:49:42 2023
 > 192.0.2.30 valid [IGP metric 0], #paths 1
 >  if r1-eth1
 >  Last update: Fri Jan 13 15:49:51 2023
 > [..]

This results in having a BGP VPN route for each of the static
routes:

 > # show bgp ipv4 vpn
 > [..]
 > Route Distinguisher: 444:1
 >  *> 172.31.0.14/32   192.0.2.14@9<            0         32768 ?
 >  *> 172.31.0.15/32   192.0.2.12@9<            0         32768 ?
 >  *> 172.31.0.30/32   192.0.2.30@9<            0         32768 ?
 > [..]

Without that patch, only the redistributed routes that rely on a
pre-existing nexthop tracking context could be exported.

Also, a command in the code about redistributed routes is modified
accordingly, to explain that redistribute routes may be submitted
to nexthop tracking in the case label allocation per next-hop is
used.

note:
VNC routes have been removed from the redistribution,
because of a test failure in the bgp_l3vpn_to_bgp_direct test.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2023-03-22 12:06:29 +01:00
Philippe Guibert
aa27437604 bgpd: use nexthop interface when adding LSP in BGP MPLSVPN
BGP MPLSVPN next hop label allocation was using only the next-hop
IP address. As MPLSVPN contexts rely on bnc contexts, the real
nexthop interface is known, and the LSP entry to enter can apply
to the specific interface. To illustrate, the BGP service is able
to handle the following two iproute2 commands:

 > ip -f mpls route add 105 via inet 192.0.2.45 dev r1-eth1
 > ip -f mpls route add 105 via inet 192.0.2.46 dev r1-eth2

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2023-03-22 12:06:29 +01:00
Philippe Guibert
92d5e31ace bgpd: add support for l3vpn per-nexthop label
This commit introduces a new method to associate a label to
prefixes to export to a VPNv4 backbone. All the methods to
associate a label to a BGP update is documented in rfc4364,
chapter 4.3.2. Initially, the "single label for an entire
VRF" method was available. This commit adds "single label
for each attachment circuit" method.

The change impacts the control-plane, because each BGP update
is checked to know if the nexthop has reachability in the VRF
or not. If this is the case, then a unique label for a given
destination IP in the VRF will be picked up. This label will
be reused for an other BGP update that will have the same
nexthop IP address.

The change impacts the data-plane, because the MPLs pop
mechanism applied to incoming labelled packets changes: the
MPLS label is popped, and the packet is directly sent to the
connected nexthop described in the previous outgoing BGP VPN
update.

By default per-vrf mode is done, but the user may choose
the per-nexthop mode, by using the vty command from the
previous commit. In the latter case, a per-vrf label
will however be allocated to handle networks that are not directly
connected. This is the case for local traffic for instance.

The change also include the following:

-  ECMP case
In case a route is learnt in a given VRF, and is resolved via an
ECMP nexthop. This implies that when exporting the route as a BGP
update, if label allocation per nexthop is used, then two possible
MPLS values could be picked up, which is not possible with the
current implementation. Actually, the NLRI for VPNv4 stores one
prefix, and one single label value, not two. Today, RFC8277 with
multiple label capability is not yet available.
To avoid this corner case, when a route is resolved via more than one
nexthop, the label allocation per nexthop will not apply, and the
default per-vrf label will be chosen.
Let us imagine BGP redistributes a static route using the `172.31.0.20`
nexthop. The nexthop resolution will find two different nexthops fo a
unique BGP update.

 > r1# show running-config
 > [..]
 > vrf vrf1
 >  ip route 172.31.0.30/32 172.31.0.20
 > r1# show bgp vrf vrf1 nexthop
 > [..]
 > 172.31.0.20 valid [IGP metric 0], #paths 1
 >  gate 192.0.2.11
 >  gate 192.0.2.12
 >  Last update: Mon Jan 16 09:27:09 2023
 >  Paths:
 >    1/1 172.31.0.30/32 VRF vrf1 flags 0x20018

To avoid this situation, BGP updates that resolve over multiple
nexthops are using the unique per-vrf label.

- recursive route case

Prefixes that need a recursive route to be resolved can
also be eligible for mpls allocation per nexthop. In that
case, the nexthop will be the recursive nexthop calculated.

To achieve this, all nexthop types in bnc contexts are valid,
except for the blackhole nexthops.

- network declared prefixes

Nexthop tracking is used to look for the reachability of the
prefixes. When the the 'no bgp network import-check' command
is used, network declared prefixes are maintained active,
even if there is no active nexthop.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2023-03-22 12:06:29 +01:00
Philippe Guibert
02a3c6bef7 bgpd: encode_label call, remove unnecessary braces
Remove unnecessary braces.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2023-03-22 12:06:29 +01:00
Donatas Abraitis
8ea624a496 bgpd: Unlock bgp dest node if leak_update() fails
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2023-03-15 14:52:21 +02:00
Russ White
f48c8a92fb
Merge pull request #12854 from opensourcerouting/fix/bgp_withdraw_attr_not_used
bgpd: Drop struct attr from bgp_withdraw()
2023-02-21 08:18:37 -05:00
Russ White
ba755d35e5
Merge pull request #12248 from pguibert6WIND/bgpasdot
lib, bgp: add initial support for asdot format
2023-02-21 08:01:03 -05:00
Donatas Abraitis
bf0c616383 bgpd: Drop struct attr from bgp_withdraw()
It's not used at all.

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2023-02-21 11:35:59 +02:00
Philippe Guibert
616e9f0d9f bgpd: handle case where passed RD is null
The function vpn_leak_to_vrf_update_onevrf() has the RD parameter
set to NULL. Test the RD value before displaying it in the called
function.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2023-02-10 18:17:32 +01:00
Philippe Guibert
4a8cd6ad7f bgpd: support for as notation format for route distinguisher
RD may be built based on an AS number. Like for the AS, the RD
may use the AS notation. The two below examples can illustrate:

RD 1.1:20 stands for an AS4B:NN RD with AS4B=65536 in dot format.
RD 0.1:20 stands for an AS2B:NNNN RD with AS2B=0.1 in dot+ format.

This commit adds the asnotation mode to prefix_rd2str() API so as
to pick up the relevant display.

Two new printfrr extensions are available to display the RD with
the two above display methods.
- The pRDD extension stands for dot asnotation format
- The pRDE extension stands for dot+ asnotation format.
- The pRD extension has been renamed to pRDP extension

The code is changed each time '%pRD' printf extension is called.
Possibly, the asnotation may change the output, then a macro defines
the asnotation mode to use. A side effect of forging the mode to
use is that the string could not be concatenated with other strings
in vty_out and snprintfrr. Those functions have been called multiple
times. When zlog_debug needs to display the RD with some other string,
the prefix_rd2str() old API is used instead of the printf extension.

Some code has been kept untouched:
- code related to running-config. Actually, wherever an RD is displayed,
its configured name should be dumped.
- bgp rfapi code
- bgp evpn multihoming code (partially done), since the logic is
missing to get the asnotation of 'struct bgp_evpn_es'.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2023-02-10 10:27:23 +01:00
David Lamparter
acddc0ed3c *: auto-convert to SPDX License IDs
Done with a combination of regex'ing and banging my head against a wall.

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
2023-02-09 14:09:11 +01:00
Donatas Abraitis
4ee5265aa7 bgpd: Add more context in logs about from where to where routes are leaked
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2023-02-06 18:44:11 +02:00
Donatas Abraitis
1aa2c93e2c bgpd: Drop struct bgp from vpn_leak_to_vrf_withdraw()
Not used at all, just drop it.

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2023-02-06 18:44:11 +02:00
Ryoga Saito
dd2d28ea99 bgpd: Skip RD match if ACCEPT_OWN is not enabled
RFC7611 introduces new extended community ACCEPT_OWN and is already
implemented for FRR in the previous PR. However, this PR broke
compatibility about importing VPN routes.

Let's consider the following situation. There are 2 routers and these
routers connects with iBGP session. These routers have two VRF, vrf10
and vrf20, and RD 0:10, 0:20 is configured as the route distinguisher
of vrf10 and vrf20 respectively.

    +- R1 --------+    +- R2 --------+
    | +---------+ |    | +---------+ |
    | |  VRF10  | |    | |  VRF10  | |
    | | RD 0:10 +--------+ RD 0:10 | |
    | +---------+ |    | +---------+ |
    | +---------+ |    | +---------+ |
    | |  VRF20  +--------+  VRF20  | |
    | | RD 0:20 | |    | | RD 0:20 | |
    | +---------+ |    | +---------+ |
    +-------------+    +-------------+

In this situation, the VPN routes from R1's VRF10 should be imported to
R2's VRF10 and the VPN routes from R2's VRF10 should be imported to R2's
VRF20. However, the current implementation of ACCEPT_OWN will always
reject routes if the RD of VPN routes are matched with the RD of VRF.

Similar issues will happen in local VRF2VRF route leaks. In such cases,
the route reaked from VRF10 should be imported to VRF20. However, the
current implementation of ACCEPT_OWN will not permit them.

    +- R1 ---------------------+
    |      +------------+      |
    | +----v----+  +----v----+ |
    | |  VRF10  |  |  VRF20  | |
    | | RD 0:10 |  | RD 0:10 | |
    | +---------+  +---------+ |
    +--------------------------+

So, this commit add additional condition in RD match. If the route
doesn't have ACCEPT_OWN extended community, source VRF check will be
skipped.

[RFC7611]: https://datatracker.ietf.org/doc/html/rfc7611

Signed-off-by: Ryoga Saito <ryoga.saito@linecorp.com>
2023-01-20 15:28:39 +09:00
Russ White
775ce087f1
Merge pull request #12643 from opensourcerouting/fix/cosmetic_log_changes
bgpd: Drop redundant `vrf` keyword in BGP debug log changes
2023-01-17 09:40:28 -05:00
Donatas Abraitis
b2a100e439 bgpd: Drop redundant vrf keyword in BGP debug log changes
Before:

```
nexthop is not valid (in vrf VRF vrf100)
updating RD 65001:100, 10.100.1.1/32 to vrf VRF vrf200
```

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2023-01-16 21:36:08 +02:00
Donatas Abraitis
8a02d9fe1e bgpd: Set nh ifindex to VRF's interface, not the real
The kernel will lookup the real interface later.

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2023-01-15 12:43:37 +02:00
Donatas Abraitis
c479b28e51 bgpd: Allow importing local routes with accept-own mechanism
Before this patch we allowed importing routes between VRFs in the same node,
only for external routes, but not for local (e.g.: redistribute).

Relax here a bit, and allow importing local routes between VRFs when the RT
list is modified using route reflectors.

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2023-01-15 12:21:36 +02:00
Donald Sharp
2bb8b49ce1 Revert "Merge pull request #11127 from louis-6wind/bgp-leak"
This reverts commit 16aa1809e7, reversing
changes made to f616e71608.
2023-01-13 08:13:52 -05:00
Russ White
962ae985ee
Merge pull request #12515 from opensourcerouting/fix/show_ip_bgp_detail_weird_output
bgpd: Show the real prefix for `show bgp detail`
2022-12-27 15:05:55 -05:00
Donatas Abraitis
27bb782a98 bgpd: Adopt show bgp detail-routes command for L3VPN outputs as well
```
unet> sh pe2 vtysh -c 'sh ip bgp ipv4 vpn detail-routes'
BGP table version is 4, local router ID is 10.10.10.20, vrf id 0
Default local pref 100, local AS 65001
Route Distinguisher: 192.168.2.2:2
BGP routing table entry for 192.168.2.2:2:10.0.0.0/24, version 1
not allocated
Paths: (1 available, best #1)
  Not advertised to any peer
  65000
    192.168.2.1 from 0.0.0.0 (10.10.10.20) vrf RED(4) announce-nh-self
      Origin incomplete, metric 0, localpref 50, valid, sourced, local, best (First path received)
      Extended Community: RT:192.168.2.2:2
      Originator: 10.10.10.20
      Remote label: 2222
      Last update: Tue Dec 20 13:01:20 2022
BGP routing table entry for 192.168.2.2:2:172.16.255.1/32, version 2
not allocated
Paths: (1 available, best #1)
  Not advertised to any peer
  65000
    192.168.2.1 from 0.0.0.0 (10.10.10.20) vrf RED(4) announce-nh-self
      Origin incomplete, localpref 50, valid, sourced, local, best (First path received)
      Extended Community: RT:192.168.2.2:2
      Originator: 10.10.10.20
      Remote label: 2222
      Last update: Tue Dec 20 13:01:20 2022
BGP routing table entry for 192.168.2.2:2:192.168.1.0/24, version 3
not allocated
Paths: (1 available, best #1)
  Not advertised to any peer
  65000
    192.168.2.1 from 0.0.0.0 (10.10.10.20) vrf RED(4) announce-nh-self
      Origin incomplete, localpref 50, valid, sourced, local, best (First path received)
      Extended Community: RT:192.168.2.2:2
      Originator: 10.10.10.20
      Remote label: 2222
      Last update: Tue Dec 20 13:01:20 2022
BGP routing table entry for 192.168.2.2:2:192.168.2.0/24, version 4
not allocated
Paths: (1 available, best #1)
  Not advertised to any peer
  65000
    192.168.2.1 from 0.0.0.0 (10.10.10.20) vrf RED(4) announce-nh-self
      Origin incomplete, metric 0, localpref 50, valid, sourced, local, best (First path received)
      Extended Community: RT:192.168.2.2:2
      Originator: 10.10.10.20
      Remote label: 2222
      Last update: Tue Dec 20 13:01:20 2022

Displayed  4 routes and 4 total paths
```

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
2022-12-20 13:13:34 +02:00
Louis Scalbert
5f6c0ba6d2 bgpd: resend routes deleted by kernel after interface addresses deletion
When the last IPv4 address of an interface is deleted, Linux removes all
routes includes BGP ones using this interface without any Netlink
advertisement. bgpd keeps them in RIB as valid (e.g. installed in FIB).

The previous patch invalidates the associated nexthop groups in zebra
but bgpd is not notified of the event.

> 2022/05/09 17:37:52.925 ZEBRA: [TQKA8-0276P] Not Notifying Owner: connected about prefix 29.0.0.0/24(40) 3 vrf: 7

Look for the bgp_path_info that are unsynchronized with the kernel and
flag them for refresh in their attributes. A VPN route leaking update is
calles and the refresh flag triggers a route refresh to zebra and then a
kernel FIB installation.

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
2022-12-16 15:07:49 +01:00
Louis Scalbert
6030b8b40d bgpd: update route leaking when a VRF loopback is received
At bgpd startup, VRF instances are sent from zebra before the
interfaces. When importing a l3vpn prefix from another local VRF
instance, the interfaces are not known yet. The prefix nexthop interface
cannot be set to the loopback or the VRF interface, which causes setting
invalid routes in zebra.

Update route leaking when the loopback or a VRF interface is received
from zebra.

At a VRF interface deletion, zebra voluntarily sends a
ZEBRA_INTERFACE_ADD message to move it to VRF_DEFAULT. Do not update if
such a message is received. VRF destruction will destroy all the related
routes without adding codes.

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
2022-12-16 14:52:47 +01:00
Louis Scalbert
14aabc0156 bgpd: fix invalid nexthop interface on leaked routes
There is two cases where the nexthop interface is incorrect:

- Case 1: leaked routes from prefixes stated in 'network <prefix>' are
  inactive because they have no nexthop IP address or interface.
- Case 2: leaked routes from 'redistribute connected' contains the
  original nexthop interface.

======
Case 1
======
> router bgp 5227 vrf r1-cust1
>  bgp router-id 192.168.1.1
>  no bgp network import-check
> !
>  address-family ipv4 unicast
>   network 10.2.3.4/32
>   network 192.168.1.0/24
>   rd vpn export 10:1
>   rt vpn import 52:100
>   rt vpn export 52:101
>   export vpn
>   import vpn
>  exit-address-family
> exit
> !
> router bgp 5227 vrf r1-cust4
>  bgp router-id 192.168.1.1
> !
>  address-family ipv4 unicast
>   network 29.0.0.0/24
>   rd vpn export 10:1
>   rt vpn import 52:101
>   rt vpn export 52:100
>   export vpn
>   import vpn
>  exit-address-family
> exit

Extract from the routing table:

> VRF r1-cust1:
> S>* 192.0.0.0/24 [1/0] via 192.168.1.2, r1-eth4, weight 1, 00:47:53
> C>* 192.168.1.0/24 is directly connected, r1-eth4, 00:44:15
> B>* 29.0.0.0/24 [20/0] is directly connected, unknown (vrf r1-cust4), inactive, weight 1, 00:00:02
>
> VRF r1-cust4:
> B   10.2.3.4/32 [20/0] is directly connected, unknown (vrf r1-cust1) inactive, weight 1, 00:00:02
> C>* 29.0.0.0/24 is directly connected, r1-cust5, 00:27:40
> B   192.0.0.0/24 [20/0] is directly connected, unknown (vrf r1-cust1) inactive, weight 1, 00:03:40
> B   192.168.1.0/24 [20/0] is directly connected, unknown (vrf r1-cust1) inactive, weight 1, 00:00:02

======
Case 2
======

The previous is modified with the following settings:

> router bgp 5227 vrf r1-cust1
>  address-family ipv4 unicast
>   no network 192.168.1.0/24
>   redistribute connected
> !
> vrf r1-cust1
> ip route 29.0.0.0/24 r1-cust5 nexthop-vrf r1-cust5

Extract from the routing table:
> VRF r1-cust1:
> S>* 192.0.0.0/24 [1/0] via 192.168.1.2, r1-eth4, weight 1, 00:47:53
> C>* 192.168.1.0/24 is directly connected, r1-eth4, 00:44:15
> S>* 29.0.0.0/24 [1/0] is directly connected, r1-cust5 (vrf r1-cust5), weight 1, 00:00:30
>
> VRF r1-cust4:
> B   10.2.3.4/32 [20/0] is directly connected, unknown (vrf r1-cust1) inactive, weight 1, 00:00:02
> C>* 29.0.0.0/24 is directly connected, r1-cust5, 00:27:40
> B   192.0.0.0/24 [20/0] is directly connected, unknown (vrf r1-cust1) inactive, weight 1, 00:03:40
> B>* 192.168.1.0/24 [20/0] is directly connected, r1-eth4 (vrf r1-cust1), weight 1, 00:00:02

The nexthop interface is r1-eth4. It causes issue to traffic leaving
r1-cust4. The following ping to r1-eth4 local address 192.168.1.1 from
r1-cust5 local add does
not respond.

> # tcpdump -lnni r1-cust1 'icmp' &
> # ip vrf exec r1-cust4 ping -c1 192.168.1.1 -I 29.0.0.1
> PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
PING 192.168.1.1 (192.168.1.1) from 29.0.0.1 : 56(84) bytes of data.
18:49:20.635638 IP 29.0.0.1 > 192.168.1.1: ICMP echo request, id 15897, seq 1, length 64
18:49:27.113827 IP 29.0.0.1 > 29.0.0.1: ICMP host 192.168.1.1 unreachable, length 92

Fix description:

When leaking prefix from other VRFs, if the nexthop IP address is not
set in the bgp path info attribures, reset nh_ifindex to the index of
master interface of the incoming BGP instance.

The result is for case 1 and 2:

> VRF r1-cust1:
> S>* 192.0.0.0/24 [1/0] via 192.168.1.2, r1-eth4, weight 1, 00:47:53
> C>* 192.168.1.0/24 is directly connected, r1-eth4, 00:44:15
> B>* 29.0.0.0/24 [20/0] is directly connected, r1-cust4 (vrf r1-cust4), weight 1, 00:00:08
>
> VRF r1-cust4:
> B>* 10.2.3.4/32 [20/0] is directly connected, r1-cust1 (vrf r1-cust1), weight 1, 00:00:08
> C>* 29.0.0.0/24 is directly connected, r1-cust5, 00:27:40
> B>* 192.0.0.0/24 [20/0] is directly connected, r1-cust1 (vrf r1-cust1), weight 1, 00:00:08
> B>* 192.168.1.0/24 [20/0] is directly connected, r1-cust1 (vrf r1-cust1), weight 1, 00:00:08

> # tcpdump -lnni r1-cust1 'icmp' &
> # ping -c1 192.168.1.1 -I 29.0.0.1
> PING 192.168.1.1 (192.168.1.1) from 29.0.0.1 : 56(84) bytes of data.
> 18:48:32.506281 IP 29.0.0.1 > 192.168.1.1: ICMP echo request, id 15870, seq 1, length 64
> 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.050 ms
> 18:48:32.506304 IP 192.168.1.1 > 29.0.0.1: ICMP echo reply, id 15870, seq 1, length 64

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>

 1, 00:47:53
4:15
vrf r1-cust4), inactive, weight 1, 00:00:02

vrf r1-cust1) inactive, weight 1, 00:00:02
40
(vrf r1-cust1) inactive, weight 1, 00:03:40
n (vrf r1-cust1) inactive, weight 1, 00:00:02

dress is not
the index of

 1, 00:47:53
4:15
(vrf r1-cust4), weight 1, 00:00:08

(vrf r1-cust1), weight 1, 00:00:08
40
 (vrf r1-cust1), weight 1, 00:00:08
t1 (vrf r1-cust1), weight 1, 00:00:08
2022-12-16 14:52:47 +01:00
Louis Scalbert
1e24860bf7 bgpd: fix prefix VRF leaking with 'network import-check' (4/5)
If 'network import-check' is defined on the source BGP session, prefixes
that are stated in the network command cannot be leaked to the other
VRFs BGP table even if they are present in the origin VRF RIB if the
'rt import' statement is defined after the 'network <prefix>' ones.

When a prefix nexthop is updated, update the prefix route leaking. The
current state of nexthop validation is now stored in the attributes of
the bgp path info. Attributes are compared with the previous ones at
route leaking update so that a nexthop validation change now triggers
the update of destination VRF BGP table.

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
2022-12-16 14:52:47 +01:00
Louis Scalbert
1565c70984 bgpd: fix prefix VRF leaking with 'network import-check' (2/5)
Move setting of some variables backwards to prepare next commits.

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
2022-12-16 14:52:47 +01:00
Louis Scalbert
0f001a82a8 bgpd: fix prefix VRF leaking with 'network import-check' (1/5)
If 'network import-check' is defined on the source BGP session, prefixes
that are stated in the network command cannot be leaked to the other
VRFs BGP table even if they are present in the origin VRF RIB.

Always validate the nexthop of BGP static routes (i.e. defined with the
network statement) if 'network import-check' is defined on the source
BGP session and the prefix is present in source RIB.

It fixes the issue when the 'rt import' statement is defined after the
'network' ones.

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
2022-12-16 14:52:47 +01:00
Louis Scalbert
1c4c40696f bgpd: fix prefix VRF leaking with 'no network import-check'
Prefixes that are stated in the network command cannot be leaked to
the other VRFs BGP table whether or not they are present in the origin
VRF RIB.

Always validate the nexthop of BGP static routes (i.e. defined with the
network statement) if 'no network import-check' is defined on the source
BGP session.

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
2022-12-16 14:52:47 +01:00
Donatas Abraitis
a1dcf3022a
Merge pull request #12438 from proelbtn/fix-#12349
bgpd: Stop overriding nexthop in vpn_leak_from_vrf_update when the peer is BGP unnumberred
2022-12-15 09:09:09 +02:00
Ryoga Saito
f784007d67 bgpd: Stop overriding nexthop when BGP unnumberred
When we use vrf-to-vrf export, the nexthop has already not been
overridden when the peer is BGP unnumberred. However, when we use normal
export, the nexthop will be oberridden. This behavior will make the VPN
routes invalid in VPN RIB.

This PR stops overriding nexthop even if we use normal export.

Signed-off-by: Ryoga Saito <ryoga.saito@linecorp.com>
2022-12-05 00:06:40 +09:00
Ryoga Saito
4915b5fd88 bgpd: Fix delete_vrf_tovpn_sid
The first argument of sid_unregister should be default bgp instance.
However, these functions passed VRF bgp instance to this funciton.

Signed-off-by: Ryoga Saito <ryoga.saito@linecorp.com>
2022-12-04 17:02:37 +09:00
Donatas Abraitis
84f784fafa
Merge pull request #12219 from cscarpitta/feature/srv6-usid-behavior-support
bgpd, zebra: Add support for SRv6 uSID Behaviors
2022-11-14 16:13:39 +02:00
Carmine Scarpitta
05d99980f3 bgpd: Use SRv6 codepoints in the BGP Advertisement
Currently bgpd uses the opaque codepoint (0xFFFF) in the BGP
advertisement. In this commit, we update bgpd to use the SRv6 codepoints
defined in the IANA SRv6 Endpoint Behaviors Registry
(https://www.iana.org/assignments/segment-routing/segment-routing.xhtml)

Signed-off-by: Carmine Scarpitta <carmine.scarpitta@uniroma2.it>
2022-11-08 22:44:23 +01:00
David Lamparter
08efd203be
Merge pull request #12236 from cscarpitta/fix/replace-inet-top-in-bgp-mplsvpn 2022-11-01 13:01:49 +01:00
Carmine Scarpitta
1f3ba79974 bgpd: Replace inet_ntop with %pI6
This commit changes some debug prints to use `%pI6` instead of
`inet_ntop` to print SRv6 SIDs.

Signed-off-by: Carmine Scarpitta <carmine.scarpitta@uniroma2.it>
2022-10-30 08:25:07 +01:00
Carmine Scarpitta
a1d5e05fb3 bgpd: Do not set chunk pointer to NULL after free
`srv6_locator_chunk_free()` takes care of freeing the memory allocated
for a `struct srv6_locator_chunk` and setting the
`struct srv6_locator_chunk` pointer to NULL.

It is not necessary to explicitly set the pointer to NULL after invoking
`srv6_locator_chunk_free()`.

Signed-off-by: Carmine Scarpitta <carmine.scarpitta@uniroma2.it>
2022-10-29 17:23:59 +02:00
Carmine Scarpitta
6946731314 lib, bgpd: Enhance srv6_locator_chunk_free() API
A programmer can use the `srv6_locator_chunk_free()` function to free
the memory allocated for a `struct srv6_locator_chunk`.

The programmer invokes `srv6_locator_chunk_free()` by passing a single
pointer to the `struct srv6_locator_chunk` to be freed.
`srv6_locator_chunk_free()` uses `XFREE()` to free the memory.
It is the responsibility of the programmer to set the
`struct srv6_locator_chunk` pointer to NULL after freeing memory with
`srv6_locator_chunk_free()`.

This commit modifies the `srv6_locator_chunk_free()` function to take a
double pointer instead of a single pointer. In this way, setting the
`struct srv6_locator_chunk` pointer to NULL is no longer the
programmer's responsibility but is the responsibility of
`srv6_locator_chunk_free()`. This prevents programmers from making
mistakes such as forgetting to set the pointer to NULL after invoking
`srv6_locator_chunk_free()`.

Signed-off-by: Carmine Scarpitta <carmine.scarpitta@uniroma2.it>
2022-10-29 17:04:35 +02:00
Carmine Scarpitta
e606d8ec84 bgpd: Add no sid vpn per-vrf export command
The command `sid vpn per-vrf export (1-255)|auto` can be used to export
IPv4 and IPv6 routes from a VRF to the VPN RIB using a single SRv6 SID
(End.DT46 behavior).

This commit implements the no form of the above command, which can be
used to disable the export of the IPv4/IPv6 routes:
`no sid vpn per-vrf export`.

Signed-off-by: Carmine Scarpitta <carmine.scarpitta@uniroma2.it>
2022-10-18 16:08:24 +02:00
Carmine Scarpitta
527588aa78 bgpd: add support for per-VRF SRv6 SID
In the current implementation of bgpd, SRv6 SIDs can be configured only
under the address-family. This enables bgpd to leak IPv6 routes using
an SRv6 End.DT6 behavior and IPv4 routes using an SRv6 End.DT4
behavior. It is not possible to leak both IPv6 and IPv4 routes using a
single SRv6 SID.

This commit adds a new CLI command
"sid vpn per-vrf export <sid_idx|auto>" that enables bgpd to leak both
IPv6 and IPv4 routes using a single SRv6 SID (End.DT46 behavior).

Signed-off-by: Carmine Scarpitta <carmine.scarpitta@uniroma2.it>
2022-10-18 16:08:23 +02:00