diff options
| author | Donald Sharp <sharpd@nvidia.com> | 2023-01-04 18:32:43 -0500 | 
|---|---|---|
| committer | Donald Sharp <sharpd@nvidia.com> | 2023-11-01 17:13:06 -0400 | 
| commit | d4aa24ba7df066ee8a9f4bab5c1b4e9ff8474392 (patch) | |
| tree | 250831364f85b54568614167d4b6bf118348c632 | |
| parent | 8e3a96e846a15f34384a20a3ede2e894d7e97253 (diff) | |
*: Introduce Local Host Routes to FRR
Create Local routes in FRR:
S   0.0.0.0/0 [1/0] via 192.168.119.1, enp39s0, weight 1, 00:03:46
K>* 0.0.0.0/0 [0/100] via 192.168.119.1, enp39s0, 00:03:51
O   192.168.119.0/24 [110/100] is directly connected, enp39s0, weight 1, 00:03:46
C>* 192.168.119.0/24 is directly connected, enp39s0, 00:03:51
L>* 192.168.119.224/32 is directly connected, enp39s0, 00:03:51
O   192.168.119.229/32 [110/100] via 0.0.0.0, enp39s0 inactive, weight 1, 00:03:46
C>* 192.168.119.229/32 is directly connected, enp39s0, 00:03:46
Create ability to redistribute local routes.
Modify tests to support this change.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
42 files changed, 256 insertions, 80 deletions
@@ -547,6 +547,8 @@ int proto_redistnum(int afi, const char *s)  			return ZEBRA_ROUTE_KERNEL;  		else if (strmatch(s, "connected"))  			return ZEBRA_ROUTE_CONNECT; +		else if (strmatch(s, "local")) +			return ZEBRA_ROUTE_LOCAL;  		else if (strmatch(s, "static"))  			return ZEBRA_ROUTE_STATIC;  		else if (strmatch(s, "rip")) @@ -581,6 +583,8 @@ int proto_redistnum(int afi, const char *s)  			return ZEBRA_ROUTE_KERNEL;  		else if (strmatch(s, "connected"))  			return ZEBRA_ROUTE_CONNECT; +		else if (strmatch(s, "local")) +			return ZEBRA_ROUTE_LOCAL;  		else if (strmatch(s, "static"))  			return ZEBRA_ROUTE_STATIC;  		else if (strmatch(s, "ripng")) diff --git a/lib/route_types.txt b/lib/route_types.txt index 07289e1e08..93cbc36e97 100644 --- a/lib/route_types.txt +++ b/lib/route_types.txt @@ -49,6 +49,7 @@  ZEBRA_ROUTE_SYSTEM,     system,    NULL,   'X', 0, 0, 0,     "Reserved",      none  ZEBRA_ROUTE_KERNEL,     kernel,    zebra,  'K', 1, 1, 1,     "kernel route",  zebra  ZEBRA_ROUTE_CONNECT,    connected, zebra,  'C', 1, 1, 1,     "connected",     zebra +ZEBRA_ROUTE_LOCAL,      local,     zebra,  'L', 1, 1, 1,     "local",         zebra  ZEBRA_ROUTE_STATIC,     static,    zebra,  'S', 1, 1, 1,     "static",        zebra  ZEBRA_ROUTE_RIP,        rip,       ripd,   'R', 1, 0, 1,     "RIP",           ripd  ZEBRA_ROUTE_RIPNG,      ripng,     ripngd, 'R', 0, 1, 1,     "RIPng",         ripngd @@ -94,6 +95,7 @@ ZEBRA_ROUTE_ALL,        wildcard,  none,   '-', 0, 0, 0,     "-",             no  ZEBRA_ROUTE_SYSTEM, "Reserved route type, for internal use only"  ZEBRA_ROUTE_KERNEL, "Kernel routes (not installed via the zebra RIB)"  ZEBRA_ROUTE_CONNECT,"Connected routes (directly attached subnet or host)" +ZEBRA_ROUTE_LOCAL,  "Local routes (directly attached host route)"  ZEBRA_ROUTE_STATIC, "Statically configured routes"  ZEBRA_ROUTE_RIP,    "Routing Information Protocol (RIP)"  ZEBRA_ROUTE_RIPNG,  "Routing Information Protocol next-generation (IPv6) (RIPng)" diff --git a/lib/zclient.h b/lib/zclient.h index f18fc056fc..c0799ba3d6 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -865,7 +865,7 @@ int zclient_neigh_ip_encode(struct stream *s, uint16_t cmd, union sockunion *in,  	((uint32_t)250000000) /* Bottom 28 bits then rounded down */  #define ZEBRA_NHG_PROTO_SPACING (ZEBRA_NHG_PROTO_UPPER / ZEBRA_ROUTE_MAX)  #define ZEBRA_NHG_PROTO_LOWER                                                  \ -	(ZEBRA_NHG_PROTO_SPACING * (ZEBRA_ROUTE_CONNECT + 1)) +	(ZEBRA_NHG_PROTO_SPACING * (ZEBRA_ROUTE_LOCAL + 1))  extern uint32_t zclient_get_nhg_start(uint32_t proto); diff --git a/tests/topotests/all_protocol_startup/r1/ipv4_routes.ref b/tests/topotests/all_protocol_startup/r1/ipv4_routes.ref index 044cffae7a..a4a4aba3d1 100644 --- a/tests/topotests/all_protocol_startup/r1/ipv4_routes.ref +++ b/tests/topotests/all_protocol_startup/r1/ipv4_routes.ref @@ -8,6 +8,16 @@ C>* 192.168.6.0/26 is directly connected, r1-eth6, XX:XX:XX  C>* 192.168.7.0/26 is directly connected, r1-eth7, XX:XX:XX  C>* 192.168.8.0/26 is directly connected, r1-eth8, XX:XX:XX  C>* 192.168.9.0/26 is directly connected, r1-eth9, XX:XX:XX +L>* 192.168.0.1/32 is directly connected, r1-eth0, XX:XX:XX +L>* 192.168.1.1/32 is directly connected, r1-eth1, XX:XX:XX +L>* 192.168.2.1/32 is directly connected, r1-eth2, XX:XX:XX +L>* 192.168.3.1/32 is directly connected, r1-eth3, XX:XX:XX +L>* 192.168.4.1/32 is directly connected, r1-eth4, XX:XX:XX +L>* 192.168.5.1/32 is directly connected, r1-eth5, XX:XX:XX +L>* 192.168.6.1/32 is directly connected, r1-eth6, XX:XX:XX +L>* 192.168.7.1/32 is directly connected, r1-eth7, XX:XX:XX +L>* 192.168.8.1/32 is directly connected, r1-eth8, XX:XX:XX +L>* 192.168.9.1/32 is directly connected, r1-eth9, XX:XX:XX  O   192.168.0.0/24 [110/10] is directly connected, r1-eth0, weight 1, XX:XX:XX  O   192.168.3.0/26 [110/10] is directly connected, r1-eth3, weight 1, XX:XX:XX  S>* 1.1.1.1/32 [1/0] is directly connected, r1-eth1, weight 1, XX:XX:XX diff --git a/tests/topotests/all_protocol_startup/r1/ipv6_routes.ref b/tests/topotests/all_protocol_startup/r1/ipv6_routes.ref index ef12d615dc..a25b53aa21 100644 --- a/tests/topotests/all_protocol_startup/r1/ipv6_routes.ref +++ b/tests/topotests/all_protocol_startup/r1/ipv6_routes.ref @@ -19,6 +19,16 @@ C * fe80::/64 is directly connected, r1-eth6, XX:XX:XX  C * fe80::/64 is directly connected, r1-eth7, XX:XX:XX  C * fe80::/64 is directly connected, r1-eth8, XX:XX:XX  C * fe80::/64 is directly connected, r1-eth9, XX:XX:XX +L>* fc00:0:0:1::1/128 is directly connected, r1-eth1, XX:XX:XX +L>* fc00:0:0:2::1/128 is directly connected, r1-eth2, XX:XX:XX +L>* fc00:0:0:3::1/128 is directly connected, r1-eth3, XX:XX:XX +L>* fc00:0:0:4::1/128 is directly connected, r1-eth4, XX:XX:XX +L>* fc00:0:0:5::1/128 is directly connected, r1-eth5, XX:XX:XX +L>* fc00:0:0:6::1/128 is directly connected, r1-eth6, XX:XX:XX +L>* fc00:0:0:7::1/128 is directly connected, r1-eth7, XX:XX:XX +L>* fc00:0:0:8::1/128 is directly connected, r1-eth8, XX:XX:XX +L>* fc00:0:0:9::1/128 is directly connected, r1-eth9, XX:XX:XX +L>* fc00::1/128 is directly connected, r1-eth0, XX:XX:XX  O   fc00:0:0:4::/64 [110/10] is directly connected, r1-eth4, weight 1, XX:XX:XX  S>* 4:5::6:10/128 [1/0] via fc00::2, r1-eth0, weight 1, XX:XX:XX  S>* 4:5::6:11/128 [1/0] via fc00::2, r1-eth0, weight 1, XX:XX:XX diff --git a/tests/topotests/ospf_instance_redistribute/r1/sharp_installed.json b/tests/topotests/ospf_instance_redistribute/r1/sharp_installed.json index c0a1f6ac00..ebb3848248 100644 --- a/tests/topotests/ospf_instance_redistribute/r1/sharp_installed.json +++ b/tests/topotests/ospf_instance_redistribute/r1/sharp_installed.json @@ -8,6 +8,6 @@        "type":"sharp"      }    ], -  "routesTotal":4, -  "routesTotalFib":4 +  "routesTotal":5, +  "routesTotalFib":5  } diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/frr.conf b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/frr.conf index e365e25772..995958132c 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/frr.conf +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/frr.conf @@ -5,12 +5,18 @@ log file /tmp/r1-frr.log  !  interface r1-eth0   ip address 10.0.1.1/24 + ip ospf hello-interval 1 + ip ospf dead-interval 4  !  interface r1-eth1   ip address 10.0.20.1/24 + ip ospf hello-interval 1 + ip ospf dead-interval 4  !  interface r1-eth2 vrf neno   ip address 10.0.30.1/24 + ip ospf hello-interval 1 + ip ospf dead-interval 4  !  ip forwarding  ! diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt index 86c089ab3b..ca9ca77bf5 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt @@ -1,9 +1,11 @@  O   10.0.1.0/24 [110/10] is directly connected, r1-eth0, weight 1, XX:XX:XX  C>* 10.0.1.0/24 is directly connected, r1-eth0, XX:XX:XX +L>* 10.0.1.1/32 is directly connected, r1-eth0, XX:XX:XX  O>* 10.0.2.0/24 [110/20] via 10.0.20.2, r1-eth1, weight 1, XX:XX:XX  B>* 10.0.3.0/24 [20/20] via 10.0.30.3, r1-eth2 (vrf neno), weight 1, XX:XX:XX  O>* 10.0.4.0/24 [110/20] via 10.0.20.2, r1-eth1, weight 1, XX:XX:XX  O   10.0.20.0/24 [110/10] is directly connected, r1-eth1, weight 1, XX:XX:XX  C>* 10.0.20.0/24 is directly connected, r1-eth1, XX:XX:XX +L>* 10.0.20.1/32 is directly connected, r1-eth1, XX:XX:XX  B>* 10.0.30.0/24 [20/0] is directly connected, r1-eth2 (vrf neno), weight 1, XX:XX:XX  O>* 10.0.40.0/24 [110/20] via 10.0.20.2, r1-eth1, weight 1, XX:XX:XX diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-neno.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-neno.txt index 4e818eb6f1..6e1335243b 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-neno.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-neno.txt @@ -3,4 +3,5 @@ O>* 10.0.3.0/24 [110/20] via 10.0.30.3, r1-eth2, weight 1, XX:XX:XX  B>* 10.0.4.0/24 [20/20] via 10.0.20.2, r1-eth1 (vrf default), weight 1, XX:XX:XX  O   10.0.30.0/24 [110/10] is directly connected, r1-eth2, weight 1, XX:XX:XX  C>* 10.0.30.0/24 is directly connected, r1-eth2, XX:XX:XX +L>* 10.0.30.1/32 is directly connected, r1-eth2, XX:XX:XX  B>* 10.0.40.0/24 [20/20] via 10.0.20.2, r1-eth1 (vrf default), weight 1, XX:XX:XX diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/frr.conf b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/frr.conf index e87899ca77..29909de646 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/frr.conf +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/frr.conf @@ -5,14 +5,20 @@ log file /tmp/r2-frr.log  !  interface r2-eth0   ip address 10.0.2.2/24 + ip ospf hello-interval 1 + ip ospf dead-interval 4  !  interface r2-eth1   ip address 10.0.20.2/24 + ip ospf hello-interval 1 + ip ospf dead-interval 4  !  ip route 0.0.0.0/0 10.0.20.1  !  interface r2-eth2 vrf ray   ip address 10.0.40.2/24 + ip ospf hello-interval 1 + ip ospf dead-interval 4  !  ip forwarding  ! diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt index 9681d8a04e..70ae987894 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt @@ -2,9 +2,11 @@ S>* 0.0.0.0/0 [1/0] via 10.0.20.1, r2-eth1, weight 1, XX:XX:XX  O>* 10.0.1.0/24 [110/20] via 10.0.20.1, r2-eth1, weight 1, XX:XX:XX  O   10.0.2.0/24 [110/10] is directly connected, r2-eth0, weight 1, XX:XX:XX  C>* 10.0.2.0/24 is directly connected, r2-eth0, XX:XX:XX +L>* 10.0.2.2/32 is directly connected, r2-eth0, XX:XX:XX  O>* 10.0.3.0/24 [110/20] via 10.0.20.1, r2-eth1, weight 1, XX:XX:XX  B>* 10.0.4.0/24 [20/20] via 10.0.40.4, r2-eth2 (vrf ray), weight 1, XX:XX:XX  O   10.0.20.0/24 [110/10] is directly connected, r2-eth1, weight 1, XX:XX:XX  C>* 10.0.20.0/24 is directly connected, r2-eth1, XX:XX:XX +L>* 10.0.20.2/32 is directly connected, r2-eth1, XX:XX:XX  O>* 10.0.30.0/24 [110/20] via 10.0.20.1, r2-eth1, weight 1, XX:XX:XX  B>* 10.0.40.0/24 [20/0] is directly connected, r2-eth2 (vrf ray), weight 1, XX:XX:XX diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt index ce9903ae71..1495c88936 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt @@ -7,3 +7,4 @@ B   10.0.20.0/24 [20/0] is directly connected, r2-eth1 (vrf default) inactive, w  B>* 10.0.30.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default), weight 1, XX:XX:XX  O   10.0.40.0/24 [110/10] is directly connected, r2-eth2, weight 1, XX:XX:XX  C>* 10.0.40.0/24 is directly connected, r2-eth2, XX:XX:XX +L>* 10.0.40.2/32 is directly connected, r2-eth2, XX:XX:XX diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r3/frr.conf b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r3/frr.conf index 2657f589d8..35fe22e9f9 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r3/frr.conf +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r3/frr.conf @@ -5,9 +5,13 @@ log file /tmp/r3-frr.log  !  interface r3-eth0   ip address 10.0.3.3/24 + ip ospf hello-interval 1 + ip ospf dead-interval 4  !  interface r3-eth1   ip address 10.0.30.3/24 + ip ospf hello-interval 1 + ip ospf dead-interval 4  !  ip forwarding  ! diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r3/zebra-vrf-default.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r3/zebra-vrf-default.txt index f6f861b73b..b1701fe177 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r3/zebra-vrf-default.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r3/zebra-vrf-default.txt @@ -1,8 +1,10 @@  O   10.0.3.0/24 [110/10] is directly connected, r3-eth0, weight 1, XX:XX:XX  C>* 10.0.3.0/24 is directly connected, r3-eth0, XX:XX:XX +L>* 10.0.3.3/32 is directly connected, r3-eth0, XX:XX:XX  O>* 10.0.4.0/24 [110/20] via 10.0.30.1, r3-eth1, weight 1, XX:XX:XX  O   10.0.30.0/24 [110/10] is directly connected, r3-eth1, weight 1, XX:XX:XX  C>* 10.0.30.0/24 is directly connected, r3-eth1, XX:XX:XX +L>* 10.0.30.3/32 is directly connected, r3-eth1, XX:XX:XX  O>* 10.0.40.0/24 [110/20] via 10.0.30.1, r3-eth1, weight 1, XX:XX:XX diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r4/frr.conf b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r4/frr.conf index 79d8077062..721c3d91c3 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r4/frr.conf +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r4/frr.conf @@ -5,9 +5,13 @@ log file /tmp/r4-frr.log  !  interface r4-eth0   ip address 10.0.4.4/24 + ip ospf hello-interval 1 + ip ospf dead-interval 4  !  interface r4-eth1   ip address 10.0.40.4/24 + ip ospf hello-interval 1 + ip ospf dead-interval 4  !  ip forwarding  ! diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r4/zebra-vrf-default.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r4/zebra-vrf-default.txt index b6be5e7fdb..3723a8a8cb 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r4/zebra-vrf-default.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r4/zebra-vrf-default.txt @@ -1,7 +1,9 @@  O>* 10.0.3.0/24 [110/20] via 10.0.40.2, r4-eth1, weight 1, XX:XX:XX  O   10.0.4.0/24 [110/10] is directly connected, r4-eth0, weight 1, XX:XX:XX  C>* 10.0.4.0/24 is directly connected, r4-eth0, XX:XX:XX +L>* 10.0.4.4/32 is directly connected, r4-eth0, XX:XX:XX  O>* 10.0.30.0/24 [110/20] via 10.0.40.2, r4-eth1, weight 1, XX:XX:XX  O   10.0.40.0/24 [110/10] is directly connected, r4-eth1, weight 1, XX:XX:XX  C>* 10.0.40.0/24 is directly connected, r4-eth1, XX:XX:XX +L>* 10.0.40.4/32 is directly connected, r4-eth1, XX:XX:XX diff --git a/tests/topotests/ospf_netns_vrf/r1/ospfd.conf b/tests/topotests/ospf_netns_vrf/r1/ospfd.conf index e1e2bfb99a..ba13146561 100644 --- a/tests/topotests/ospf_netns_vrf/r1/ospfd.conf +++ b/tests/topotests/ospf_netns_vrf/r1/ospfd.conf @@ -3,6 +3,14 @@ hostname r1  password zebra  log file /tmp/r1-ospfd.log  ! +interface r1-eth0 vrf r1-ospf-cust1 +  ip ospf hello-interval 1 +  ip ospf dead-interval 4 +! +interface r1-eth1 vrf r1-ospf-cust1 +  ip ospf hello-interval 1 +  ip ospf dead-interval 4 +!  router ospf vrf r1-ospf-cust1    ospf router-id 10.0.255.1    redistribute kernel diff --git a/tests/topotests/ospf_netns_vrf/r1/zebraroute.txt b/tests/topotests/ospf_netns_vrf/r1/zebraroute.txt index 979af20c59..bf874ac762 100644 --- a/tests/topotests/ospf_netns_vrf/r1/zebraroute.txt +++ b/tests/topotests/ospf_netns_vrf/r1/zebraroute.txt @@ -1,8 +1,10 @@  VRF r1-ospf-cust1:  O   10.0.1.0/24 [110/10] is directly connected, r1-eth0, weight 1, XX:XX:XX  C>* 10.0.1.0/24 is directly connected, r1-eth0, XX:XX:XX +L>* 10.0.1.1/32 is directly connected, r1-eth0, XX:XX:XX  O>* 10.0.2.0/24 [110/20] via 10.0.3.3, r1-eth1, weight 1, XX:XX:XX  O   10.0.3.0/24 [110/10] is directly connected, r1-eth1, weight 1, XX:XX:XX  C>* 10.0.3.0/24 is directly connected, r1-eth1, XX:XX:XX +L>* 10.0.3.2/32 is directly connected, r1-eth1, XX:XX:XX  O>* 10.0.10.0/24 [110/20] via 10.0.3.1, r1-eth1, weight 1, XX:XX:XX diff --git a/tests/topotests/ospf_netns_vrf/r1/zebraroutedown.txt b/tests/topotests/ospf_netns_vrf/r1/zebraroutedown.txt index ec99fad762..e515205307 100644 --- a/tests/topotests/ospf_netns_vrf/r1/zebraroutedown.txt +++ b/tests/topotests/ospf_netns_vrf/r1/zebraroutedown.txt @@ -1,7 +1,9 @@  VRF r1-ospf-cust1:  O   10.0.1.0/24 [110/10] is directly connected, r1-eth0, weight 1, XX:XX:XX  C>* 10.0.1.0/24 is directly connected, r1-eth0, XX:XX:XX +L>* 10.0.1.1/32 is directly connected, r1-eth0, XX:XX:XX  O>* 10.0.2.0/24 [110/20] via 10.0.3.3, r1-eth1, weight 1, XX:XX:XX  O   10.0.3.0/24 [110/10] is directly connected, r1-eth1, weight 1, XX:XX:XX  C>* 10.0.3.0/24 is directly connected, r1-eth1, XX:XX:XX +L>* 10.0.3.2/32 is directly connected, r1-eth1, XX:XX:XX diff --git a/tests/topotests/ospf_netns_vrf/r2/ospfd.conf b/tests/topotests/ospf_netns_vrf/r2/ospfd.conf index c1984276f4..01b6b1526b 100644 --- a/tests/topotests/ospf_netns_vrf/r2/ospfd.conf +++ b/tests/topotests/ospf_netns_vrf/r2/ospfd.conf @@ -3,6 +3,13 @@ hostname r2  password zebra  log file /tmp/r2-ospfd.log  ! +interface r2-eth0 vrf r2-ospf-cust1 +  ip ospf hello-interval 1 +  ip ospf dead-interval 4 +! +interface r2-eth1 vrf r2-ospf-cust1 +  ip ospf hello-interval 1 +  ip ospf dead-interval 4  !  router ospf vrf r2-ospf-cust1    ospf router-id 10.0.255.2 diff --git a/tests/topotests/ospf_netns_vrf/r2/zebraroute.txt b/tests/topotests/ospf_netns_vrf/r2/zebraroute.txt index df66e92abc..3763ef8006 100644 --- a/tests/topotests/ospf_netns_vrf/r2/zebraroute.txt +++ b/tests/topotests/ospf_netns_vrf/r2/zebraroute.txt @@ -2,7 +2,9 @@ VRF r2-ospf-cust1:  O>* 10.0.1.0/24 [110/20] via 10.0.3.2, r2-eth1, weight 1, XX:XX:XX  O   10.0.2.0/24 [110/10] is directly connected, r2-eth0, weight 1, XX:XX:XX  C>* 10.0.2.0/24 is directly connected, r2-eth0, XX:XX:XX +L>* 10.0.2.1/32 is directly connected, r2-eth0, XX:XX:XX  O   10.0.3.0/24 [110/10] is directly connected, r2-eth1, weight 1, XX:XX:XX  C>* 10.0.3.0/24 is directly connected, r2-eth1, XX:XX:XX +L>* 10.0.3.3/32 is directly connected, r2-eth1, XX:XX:XX  O>* 10.0.10.0/24 [110/20] via 10.0.3.1, r2-eth1, weight 1, XX:XX:XX diff --git a/tests/topotests/ospf_netns_vrf/r2/zebraroutedown.txt b/tests/topotests/ospf_netns_vrf/r2/zebraroutedown.txt index 4afc354ca7..f6eaba6e1d 100644 --- a/tests/topotests/ospf_netns_vrf/r2/zebraroutedown.txt +++ b/tests/topotests/ospf_netns_vrf/r2/zebraroutedown.txt @@ -2,6 +2,8 @@ VRF r2-ospf-cust1:  O>* 10.0.1.0/24 [110/20] via 10.0.3.2, r2-eth1, weight 1, XX:XX:XX  O   10.0.2.0/24 [110/10] is directly connected, r2-eth0, weight 1, XX:XX:XX  C>* 10.0.2.0/24 is directly connected, r2-eth0, XX:XX:XX +L>* 10.0.2.1/32 is directly connected, r2-eth0, XX:XX:XX  O   10.0.3.0/24 [110/10] is directly connected, r2-eth1, weight 1, XX:XX:XX  C>* 10.0.3.0/24 is directly connected, r2-eth1, XX:XX:XX +L>* 10.0.3.3/32 is directly connected, r2-eth1, XX:XX:XX diff --git a/tests/topotests/ospf_netns_vrf/r3/ospfd.conf b/tests/topotests/ospf_netns_vrf/r3/ospfd.conf index b73d547e3e..abfaa5b9ef 100644 --- a/tests/topotests/ospf_netns_vrf/r3/ospfd.conf +++ b/tests/topotests/ospf_netns_vrf/r3/ospfd.conf @@ -4,6 +4,14 @@ password zebra  log file /tmp/r3-ospfd.log  !  ! +interface r3-eth0 vrf r3-ospf-cust1 +  ip ospf hello-interval 1 +  ip ospf dead-interval 4 +! +interface r3-eth1 vrf r3-ospf-cust1 +  ip ospf hello-interval 1 +  ip ospf dead-interval 4 +!  router ospf vrf r3-ospf-cust1    ospf router-id 10.0.255.3    redistribute kernel diff --git a/tests/topotests/ospf_netns_vrf/r3/zebraroute.txt b/tests/topotests/ospf_netns_vrf/r3/zebraroute.txt index b435c2ebe5..5eb92efd20 100644 --- a/tests/topotests/ospf_netns_vrf/r3/zebraroute.txt +++ b/tests/topotests/ospf_netns_vrf/r3/zebraroute.txt @@ -3,6 +3,8 @@ O>* 10.0.1.0/24 [110/20] via 10.0.3.2, r3-eth0, weight 1, XX:XX:XX  O>* 10.0.2.0/24 [110/20] via 10.0.3.3, r3-eth0, weight 1, XX:XX:XX  O   10.0.3.0/24 [110/10] is directly connected, r3-eth0, weight 1, XX:XX:XX  C>* 10.0.3.0/24 is directly connected, r3-eth0, XX:XX:XX +L>* 10.0.3.1/32 is directly connected, r3-eth0, XX:XX:XX  O   10.0.10.0/24 [110/10] is directly connected, r3-eth1, weight 1, XX:XX:XX  C>* 10.0.10.0/24 is directly connected, r3-eth1, XX:XX:XX +L>* 10.0.10.1/32 is directly connected, r3-eth1, XX:XX:XX diff --git a/tests/topotests/ospf_netns_vrf/r3/zebraroutedown.txt b/tests/topotests/ospf_netns_vrf/r3/zebraroutedown.txt index f30a4be6c6..26cc19660a 100644 --- a/tests/topotests/ospf_netns_vrf/r3/zebraroutedown.txt +++ b/tests/topotests/ospf_netns_vrf/r3/zebraroutedown.txt @@ -1,4 +1,5 @@  VRF r3-ospf-cust1:  O   10.0.10.0/24 [110/10] is directly connected, r3-eth1, weight 1, XX:XX:XX  C>* 10.0.10.0/24 is directly connected, r3-eth1, XX:XX:XX +L>* 10.0.10.1/32 is directly connected, r3-eth1, XX:XX:XX diff --git a/tests/topotests/route_scale/r1/installed.routes.json b/tests/topotests/route_scale/r1/installed.routes.json index 25d209f9eb..6e09f52f1c 100644 --- a/tests/topotests/route_scale/r1/installed.routes.json +++ b/tests/topotests/route_scale/r1/installed.routes.json @@ -11,6 +11,6 @@        "type":"sharp"      }    ], -  "routesTotal":1000032, -  "routesTotalFib":1000032 +  "routesTotal":1000064, +  "routesTotalFib":1000064  } diff --git a/tests/topotests/route_scale/r1/no.routes.json b/tests/topotests/route_scale/r1/no.routes.json index abebd1b143..13dc7675a1 100644 --- a/tests/topotests/route_scale/r1/no.routes.json +++ b/tests/topotests/route_scale/r1/no.routes.json @@ -6,6 +6,6 @@        "type":"connected"      }    ], -  "routesTotal":32, -  "routesTotalFib":32 +  "routesTotal":64, +  "routesTotalFib":64  } diff --git a/yang/frr-route-types.yang b/yang/frr-route-types.yang index 728607cabe..aa676cebc2 100644 --- a/yang/frr-route-types.yang +++ b/yang/frr-route-types.yang @@ -54,44 +54,47 @@ module frr-route-types {        enum connected {          value 2;        } -      enum static { +      enum local {          value 3;        } -      enum rip { +      enum static {          value 4;        } +      enum rip { +        value 5; +      }        enum ospf { -        value 6; +        value 7;        }        enum isis { -        value 8; +        value 9;        }        enum bgp { -        value 9; +        value 10;        }        enum eigrp { -        value 11; +        value 12;        }        enum nhrp { -        value 12; +        value 13;        }        enum table { -        value 15; +        value 16;        }        enum vnc { -        value 17; +        value 18;        }        enum vnc-direct { -        value 18; +        value 19;        }        enum babel { -        value 22; +        value 23;        }        enum sharp { -        value 23; +        value 24;        }        enum openfabric { -        value 26; +        value 27;        }      }    } @@ -104,41 +107,44 @@ module frr-route-types {        enum connected {          value 2;        } -      enum static { +      enum local {          value 3;        } +      enum static { +        value 4; +      }        enum ripng { -        value 5; +        value 6;        }        enum ospf6 { -        value 7; +        value 8;        }        enum isis { -        value 8; +        value 9;        }        enum bgp { -        value 9; +        value 10;        }        enum nhrp { -        value 12; +        value 13;        }        enum table { -        value 15; +        value 16;        }        enum vnc { -        value 17; +        value 18;        }        enum vnc-direct { -        value 18; +        value 19;        }        enum babel { -        value 22; +        value 23;        }        enum sharp { -        value 23; +        value 24;        }        enum openfabric { -        value 26; +        value 27;        }      }    } diff --git a/zebra/connected.c b/zebra/connected.c index ee0823f56f..78aca5ee5c 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -182,7 +182,7 @@ static void connected_update(struct interface *ifp, struct connected *ifc)  void connected_up(struct interface *ifp, struct connected *ifc)  {  	afi_t afi; -	struct prefix p; +	struct prefix p, plocal;  	struct nexthop nh = {  		.type = NEXTHOP_TYPE_IFINDEX,  		.ifindex = ifp->ifindex, @@ -194,6 +194,7 @@ void connected_up(struct interface *ifp, struct connected *ifc)  	uint32_t count = 0;  	struct listnode *cnode;  	struct connected *c; +	bool install_local = true;  	zvrf = ifp->vrf->info;  	if (!zvrf) { @@ -210,6 +211,7 @@ void connected_up(struct interface *ifp, struct connected *ifc)  	UNSET_FLAG(ifc->conf, ZEBRA_IFC_DOWN);  	prefix_copy(&p, CONNECTED_PREFIX(ifc)); +	prefix_copy(&plocal, ifc->address);  	/* Apply mask to the network. */  	apply_mask(&p); @@ -224,6 +226,8 @@ void connected_up(struct interface *ifp, struct connected *ifc)  		 */  		if (prefix_ipv4_any((struct prefix_ipv4 *)&p))  			return; + +		plocal.prefixlen = IPV4_MAX_BITLEN;  		break;  	case AFI_IP6:  #ifndef GNU_LINUX @@ -231,6 +235,11 @@ void connected_up(struct interface *ifp, struct connected *ifc)  		if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6))  			return;  #endif + +		if (IN6_IS_ADDR_LINKLOCAL(&plocal.u.prefix6)) +			install_local = false; + +		plocal.prefixlen = IPV6_MAX_BITLEN;  		break;  	case AFI_UNSPEC:  	case AFI_L2VPN: @@ -284,6 +293,15 @@ void connected_up(struct interface *ifp, struct connected *ifc)  		flags, &p, NULL, &nh, 0, zvrf->table_id, metric, 0, 0, 0,  		false); +	if (install_local) { +		rib_add(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_LOCAL, +			0, flags, &plocal, NULL, &nh, 0, zvrf->table_id, 0, 0, +			0, 0, false); +		rib_add(afi, SAFI_MULTICAST, zvrf->vrf->vrf_id, +			ZEBRA_ROUTE_LOCAL, 0, flags, &plocal, NULL, &nh, 0, +			zvrf->table_id, 0, 0, 0, 0, false); +	} +  	/* Schedule LSP forwarding entries for processing, if appropriate. */  	if (zvrf->vrf->vrf_id == VRF_DEFAULT) {  		if (IS_ZEBRA_DEBUG_MPLS) @@ -368,7 +386,7 @@ void connected_add_ipv4(struct interface *ifp, int flags,  void connected_down(struct interface *ifp, struct connected *ifc)  {  	afi_t afi; -	struct prefix p; +	struct prefix p, plocal;  	struct nexthop nh = {  		.type = NEXTHOP_TYPE_IFINDEX,  		.ifindex = ifp->ifindex, @@ -378,6 +396,7 @@ void connected_down(struct interface *ifp, struct connected *ifc)  	uint32_t count = 0;  	struct listnode *cnode;  	struct connected *c; +	bool remove_local = true;  	zvrf = ifp->vrf->info;  	if (!zvrf) { @@ -403,6 +422,7 @@ void connected_down(struct interface *ifp, struct connected *ifc)  	}  	prefix_copy(&p, CONNECTED_PREFIX(ifc)); +	prefix_copy(&plocal, ifc->address);  	/* Apply mask to the network. */  	apply_mask(&p); @@ -417,10 +437,18 @@ void connected_down(struct interface *ifp, struct connected *ifc)  		 */  		if (prefix_ipv4_any((struct prefix_ipv4 *)&p))  			return; + +		plocal.prefixlen = IPV4_MAX_BITLEN;  		break;  	case AFI_IP6:  		if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6))  			return; + +		plocal.prefixlen = IPV6_MAX_BITLEN; + +		if (IN6_IS_ADDR_LINKLOCAL(&plocal.u.prefix6)) +			remove_local = false; +  		break;  	case AFI_UNSPEC:  	case AFI_L2VPN: @@ -463,6 +491,16 @@ void connected_down(struct interface *ifp, struct connected *ifc)  	rib_delete(afi, SAFI_MULTICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT,  		   0, 0, &p, NULL, &nh, 0, zvrf->table_id, 0, 0, false); +	if (remove_local) { +		rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, +			   ZEBRA_ROUTE_LOCAL, 0, 0, &plocal, NULL, &nh, 0, +			   zvrf->table_id, 0, 0, false); + +		rib_delete(afi, SAFI_MULTICAST, zvrf->vrf->vrf_id, +			   ZEBRA_ROUTE_LOCAL, 0, 0, &plocal, NULL, &nh, 0, +			   zvrf->table_id, 0, 0, false); +	} +  	/* Schedule LSP forwarding entries for processing, if appropriate. */  	if (zvrf->vrf->vrf_id == VRF_DEFAULT) {  		if (IS_ZEBRA_DEBUG_MPLS) diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 71e7956324..2785ee2940 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -710,9 +710,10 @@ int zebra_add_import_table_entry(struct zebra_vrf *zvrf, struct route_node *rn,  		if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED))  			continue; -		if (same->type == re->type && same->instance == re->instance -		    && same->table == re->table -		    && same->type != ZEBRA_ROUTE_CONNECT) +		if (same->type == re->type && same->instance == re->instance && +		    same->table == re->table && +		    (same->type != ZEBRA_ROUTE_CONNECT && +		     same->type != ZEBRA_ROUTE_LOCAL))  			break;  	} diff --git a/zebra/rib.h b/zebra/rib.h index e70b5c1423..a8a1f049a9 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -169,7 +169,7 @@ struct route_entry {  /* Define route types that are equivalent to "connected". */  #define RIB_CONNECTED_ROUTE(R)                                                 \ -	((R)->type == ZEBRA_ROUTE_CONNECT || (R)->type == ZEBRA_ROUTE_NHRP) +	((R)->type == ZEBRA_ROUTE_CONNECT || (R)->type == ZEBRA_ROUTE_LOCAL || (R)->type == ZEBRA_ROUTE_NHRP)  /* meta-queue structure:   * sub-queue 0: nexthop group objects diff --git a/zebra/rt.h b/zebra/rt.h index af170a22aa..e5dc26150a 100644 --- a/zebra/rt.h +++ b/zebra/rt.h @@ -25,7 +25,8 @@ extern "C" {  #define RKERNEL_ROUTE(type) ((type) == ZEBRA_ROUTE_KERNEL)  #define RSYSTEM_ROUTE(type)                                                    \ -	((RKERNEL_ROUTE(type)) || (type) == ZEBRA_ROUTE_CONNECT) +	((RKERNEL_ROUTE(type)) || (type) == ZEBRA_ROUTE_CONNECT ||             \ +	 (type) == ZEBRA_ROUTE_LOCAL)  #ifndef HAVE_NETLINK  /* diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index ec35842b0a..cd5645469b 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -278,6 +278,7 @@ int zebra2proto(int proto)  		proto = RTPROT_ZEBRA;  		break;  	case ZEBRA_ROUTE_CONNECT: +	case ZEBRA_ROUTE_LOCAL:  	case ZEBRA_ROUTE_KERNEL:  		proto = RTPROT_KERNEL;  		break; diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 856c906bdc..4b3833e5e2 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -2391,7 +2391,7 @@ static void zread_hello(ZAPI_HANDLER_ARGS)  		client->synchronous = true;  	/* accept only dynamic routing protocols */ -	if ((proto < ZEBRA_ROUTE_MAX) && (proto > ZEBRA_ROUTE_CONNECT)) { +	if ((proto < ZEBRA_ROUTE_MAX) && (proto > ZEBRA_ROUTE_LOCAL)) {  		zlog_notice(  			"client %d says hello and bids fair to announce only %s routes vrf=%u",  			client->sock, zebra_route_string(proto), diff --git a/zebra/zebra_gr.c b/zebra/zebra_gr.c index 39fd8641de..f4241f1d72 100644 --- a/zebra/zebra_gr.c +++ b/zebra/zebra_gr.c @@ -327,7 +327,7 @@ void zread_client_capabilities(ZAPI_HANDLER_ARGS)  		return;  	/* GR only for dynamic clients */ -	if (client->proto <= ZEBRA_ROUTE_CONNECT) { +	if (client->proto <= ZEBRA_ROUTE_LOCAL) {  		LOG_GR("%s: GR capabilities for client %s not supported",  		       __func__, zebra_route_string(client->proto));  		return; diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index c2e34faed6..e59f5378a8 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -616,8 +616,9 @@ static int nhlfe_nexthop_active_ipv4(struct zebra_nhlfe *nhlfe,  		for (match_nh = match->nhe->nhg.nexthop; match_nh;  		     match_nh = match_nh->next) { -			if (match->type == ZEBRA_ROUTE_CONNECT -			    || nexthop->ifindex == match_nh->ifindex) { +			if ((match->type == ZEBRA_ROUTE_CONNECT || +			     match->type == ZEBRA_ROUTE_LOCAL) || +			    nexthop->ifindex == match_nh->ifindex) {  				nexthop->ifindex = match_nh->ifindex;  				return 1;  			} @@ -659,9 +660,10 @@ static int nhlfe_nexthop_active_ipv6(struct zebra_nhlfe *nhlfe,  	/* Locate a valid connected route. */  	RNODE_FOREACH_RE (rn, match) { -		if ((match->type == ZEBRA_ROUTE_CONNECT) -		    && !CHECK_FLAG(match->status, ROUTE_ENTRY_REMOVED) -		    && CHECK_FLAG(match->flags, ZEBRA_FLAG_SELECTED)) +		if (((match->type == ZEBRA_ROUTE_CONNECT || +		      match->type == ZEBRA_ROUTE_LOCAL)) && +		    !CHECK_FLAG(match->status, ROUTE_ENTRY_REMOVED) && +		    CHECK_FLAG(match->flags, ZEBRA_FLAG_SELECTED))  			break;  	} diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index 19e2657f1d..13aab1826d 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -2129,7 +2129,8 @@ zebra_nhg_connected_ifindex(struct route_node *rn, struct route_entry *match,  	 * of those ifindexes match as well.  	 */  	RNODE_FOREACH_RE (rn, re) { -		if (re->type != ZEBRA_ROUTE_CONNECT) +		if (re->type != ZEBRA_ROUTE_CONNECT && +		    re->type != ZEBRA_ROUTE_LOCAL)  			continue;  		if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 37c042c044..3b1da21d35 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -103,6 +103,9 @@ static const struct {  	[ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT,  				 ZEBRA_CONNECT_DISTANCE_DEFAULT,  				 META_QUEUE_CONNECTED}, +	[ZEBRA_ROUTE_LOCAL] = {ZEBRA_ROUTE_LOCAL, +			       ZEBRA_CONNECT_DISTANCE_DEFAULT, +			       META_QUEUE_CONNECTED},  	[ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC,  				ZEBRA_STATIC_DISTANCE_DEFAULT,  				META_QUEUE_STATIC}, @@ -522,7 +525,8 @@ struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,  			if (rn)  				route_lock_node(rn);  		} else { -			if (match->type != ZEBRA_ROUTE_CONNECT) { +			if (match->type != ZEBRA_ROUTE_CONNECT && +			    match->type != ZEBRA_ROUTE_LOCAL) {  				if (!CHECK_FLAG(match->status,  						ROUTE_ENTRY_INSTALLED))  					return NULL; @@ -624,7 +628,8 @@ struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p, vrf_id_t vrf_id)  	if (!match)  		return NULL; -	if (match->type == ZEBRA_ROUTE_CONNECT) +	if (match->type == ZEBRA_ROUTE_CONNECT || +	    match->type == ZEBRA_ROUTE_LOCAL)  		return match;  	if (CHECK_FLAG(match->status, ROUTE_ENTRY_INSTALLED)) @@ -1123,27 +1128,15 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,  	UNSET_FLAG(new->status, ROUTE_ENTRY_CHANGED);  } -/* Check if 'alternate' RIB entry is better than 'current'. */ -static struct route_entry *rib_choose_best(struct route_entry *current, -					   struct route_entry *alternate) +static struct route_entry *rib_choose_best_type(uint8_t route_type, +						struct route_entry *current, +						struct route_entry *alternate)  { -	if (current == NULL) -		return alternate; - -	/* filter route selection in following order: -	 * - connected beats other types -	 * - if both connected, loopback or vrf wins -	 * - lower distance beats higher -	 * - lower metric beats higher for equal distance -	 * - last, hence oldest, route wins tie break. -	 */ - -	/* Connected routes. Check to see if either are a vrf -	 * or loopback interface.  If not, pick the last connected -	 * route of the set of lowest metric connected routes. +	/* +	 * We know that alternate and current are now non-NULL  	 */ -	if (alternate->type == ZEBRA_ROUTE_CONNECT) { -		if (current->type != ZEBRA_ROUTE_CONNECT) +	if (alternate->type == route_type) { +		if (current->type != route_type)  			return alternate;  		/* both are connected.  are either loop or vrf? */ @@ -1172,7 +1165,41 @@ static struct route_entry *rib_choose_best(struct route_entry *current,  		return current;  	} -	if (current->type == ZEBRA_ROUTE_CONNECT) +	return NULL; +} + +/* Check if 'alternate' RIB entry is better than 'current'. */ +static struct route_entry *rib_choose_best(struct route_entry *current, +					   struct route_entry *alternate) +{ +	struct route_entry *possible; + +	if (current == NULL) +		return alternate; + +	/* filter route selection in following order: +	 * - Local beats Connected +	 * - connected beats other types +	 * - if both connected, loopback or vrf wins +	 * - lower distance beats higher +	 * - lower metric beats higher for equal distance +	 * - last, hence oldest, route wins tie break. +	 */ + +	/* Connected or Local routes. Check to see if either are a vrf +	 * or loopback interface.  If not, pick the last connected +	 * route of the set of lowest metric connected routes. +	 */ +	possible = rib_choose_best_type(ZEBRA_ROUTE_LOCAL, current, alternate); +	if (possible) +		return possible; + +	possible = rib_choose_best_type(ZEBRA_ROUTE_CONNECT, current, alternate); +	if (possible) +		return possible; + +	if (current->type == ZEBRA_ROUTE_CONNECT || +	    current->type == ZEBRA_ROUTE_LOCAL)  		return current;  	/* higher distance loses */ @@ -1507,7 +1534,8 @@ static bool rib_route_match_ctx(const struct route_entry *re,  			} else if (re->type == ZEBRA_ROUTE_KERNEL &&  				   re->metric != dplane_ctx_get_metric(ctx)) {  				result = false; -			} else if (re->type == ZEBRA_ROUTE_CONNECT) { +			} else if (re->type == ZEBRA_ROUTE_CONNECT || +				   re->type == ZEBRA_ROUTE_LOCAL) {  				result = nexthop_group_equal_no_recurse(  					&re->nhe->nhg, dplane_ctx_get_ng(ctx));  			} @@ -1565,7 +1593,7 @@ static bool rib_compare_routes(const struct route_entry *re1,  	 * v6 link-locals, and we also support multiple addresses in the same  	 * subnet on a single interface.  	 */ -	if (re1->type != ZEBRA_ROUTE_CONNECT) +	if (re1->type != ZEBRA_ROUTE_CONNECT && re1->type != ZEBRA_ROUTE_LOCAL)  		return true;  	return false; @@ -2968,7 +2996,8 @@ static void process_subq_early_route_delete(struct zebra_early_route *ere)  		if (re->type == ZEBRA_ROUTE_KERNEL &&  		    re->metric != ere->re->metric)  			continue; -		if (re->type == ZEBRA_ROUTE_CONNECT && +		if ((re->type == ZEBRA_ROUTE_CONNECT || +		     re->type == ZEBRA_ROUTE_LOCAL) &&  		    (rtnh = re->nhe->nhg.nexthop) &&  		    rtnh->type == NEXTHOP_TYPE_IFINDEX && nh) {  			if (rtnh->ifindex != nh->ifindex) diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 30d92c30f4..7a7f59e71a 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -513,10 +513,14 @@ static bool rnh_check_re_nexthops(const struct route_entry *re,  		goto done;  	} -	/* Some special checks if registration asked for them. */ +	/* +	 * Some special checks if registration asked for them. +	 * LOCAL routes are by their definition not CONNECTED +	 * and as such should not be considered here +	 */  	if (CHECK_FLAG(rnh->flags, ZEBRA_NHT_CONNECTED)) { -		if ((re->type == ZEBRA_ROUTE_CONNECT) -		    || (re->type == ZEBRA_ROUTE_STATIC)) +		if ((re->type == ZEBRA_ROUTE_CONNECT) || +		    (re->type == ZEBRA_ROUTE_STATIC))  			ret = true;  		if (re->type == ZEBRA_ROUTE_NHRP) { diff --git a/zebra/zebra_snmp.c b/zebra/zebra_snmp.c index 8cab184953..1c6d58159e 100644 --- a/zebra/zebra_snmp.c +++ b/zebra/zebra_snmp.c @@ -223,6 +223,8 @@ static int proto_trans(int type)  		return 1; /* other */  	case ZEBRA_ROUTE_CONNECT:  		return 2; /* local interface */ +	case ZEBRA_ROUTE_LOCAL: +		return 2;  	case ZEBRA_ROUTE_STATIC:  		return 3; /* static route */  	case ZEBRA_ROUTE_RIP: diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index d36c2f81c7..2a2ce58ac7 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -764,9 +764,10 @@ static void vty_show_ip_route(struct vty *vty, struct route_node *rn,  	}  	/* Distance and metric display. */ -	if (((re->type == ZEBRA_ROUTE_CONNECT) && +	if (((re->type == ZEBRA_ROUTE_CONNECT || +	      re->type == ZEBRA_ROUTE_LOCAL) &&  	     (re->distance || re->metric)) || -	    (re->type != ZEBRA_ROUTE_CONNECT)) +	    (re->type != ZEBRA_ROUTE_CONNECT && re->type != ZEBRA_ROUTE_LOCAL))  		len += vty_out(vty, " [%u/%u]", re->distance,  			       re->metric); @@ -2251,7 +2252,8 @@ static void show_ip_route_dump_vty(struct vty *vty, struct route_table *table)  				vrf_id_to_name(re->vrf_id));  			vty_out(vty, "   flags: %u\n", re->flags); -			if (re->type != ZEBRA_ROUTE_CONNECT) { +			if (re->type != ZEBRA_ROUTE_CONNECT && +			    re->type != ZEBRA_ROUTE_LOCAL) {  				vty_out(vty, "   distance: %u\n", re->distance);  				vty_out(vty, "   metric: %u\n", re->metric);  			} diff --git a/zebra/zserv.h b/zebra/zserv.h index 90aa4d53f4..53789122d1 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -237,8 +237,7 @@ DECLARE_HOOK(zserv_client_connect, (struct zserv *client), (client));  DECLARE_KOOH(zserv_client_close, (struct zserv *client), (client));  #define DYNAMIC_CLIENT_GR_DISABLED(_client)                                    \ -	((_client->proto <= ZEBRA_ROUTE_CONNECT)                               \ -	 || !(_client->gr_instance_count)) +	((_client->proto <= ZEBRA_ROUTE_LOCAL) || !(_client->gr_instance_count))  /*   * Initialize Zebra API server.  | 
