summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@nvidia.com>2023-01-04 18:32:43 -0500
committerDonald Sharp <sharpd@nvidia.com>2023-11-01 17:13:06 -0400
commitd4aa24ba7df066ee8a9f4bab5c1b4e9ff8474392 (patch)
tree250831364f85b54568614167d4b6bf118348c632
parent8e3a96e846a15f34384a20a3ede2e894d7e97253 (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>
-rw-r--r--lib/log.c4
-rw-r--r--lib/route_types.txt2
-rw-r--r--lib/zclient.h2
-rw-r--r--tests/topotests/all_protocol_startup/r1/ipv4_routes.ref10
-rw-r--r--tests/topotests/all_protocol_startup/r1/ipv6_routes.ref10
-rw-r--r--tests/topotests/ospf_instance_redistribute/r1/sharp_installed.json4
-rw-r--r--tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/frr.conf6
-rw-r--r--tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt2
-rw-r--r--tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-neno.txt1
-rw-r--r--tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/frr.conf6
-rw-r--r--tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt2
-rw-r--r--tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt1
-rw-r--r--tests/topotests/ospf_multi_vrf_bgp_route_leak/r3/frr.conf4
-rw-r--r--tests/topotests/ospf_multi_vrf_bgp_route_leak/r3/zebra-vrf-default.txt2
-rw-r--r--tests/topotests/ospf_multi_vrf_bgp_route_leak/r4/frr.conf4
-rw-r--r--tests/topotests/ospf_multi_vrf_bgp_route_leak/r4/zebra-vrf-default.txt2
-rw-r--r--tests/topotests/ospf_netns_vrf/r1/ospfd.conf8
-rw-r--r--tests/topotests/ospf_netns_vrf/r1/zebraroute.txt2
-rw-r--r--tests/topotests/ospf_netns_vrf/r1/zebraroutedown.txt2
-rw-r--r--tests/topotests/ospf_netns_vrf/r2/ospfd.conf7
-rw-r--r--tests/topotests/ospf_netns_vrf/r2/zebraroute.txt2
-rw-r--r--tests/topotests/ospf_netns_vrf/r2/zebraroutedown.txt2
-rw-r--r--tests/topotests/ospf_netns_vrf/r3/ospfd.conf8
-rw-r--r--tests/topotests/ospf_netns_vrf/r3/zebraroute.txt2
-rw-r--r--tests/topotests/ospf_netns_vrf/r3/zebraroutedown.txt1
-rw-r--r--tests/topotests/route_scale/r1/installed.routes.json4
-rw-r--r--tests/topotests/route_scale/r1/no.routes.json4
-rw-r--r--yang/frr-route-types.yang56
-rw-r--r--zebra/connected.c42
-rw-r--r--zebra/redistribute.c7
-rw-r--r--zebra/rib.h2
-rw-r--r--zebra/rt.h3
-rw-r--r--zebra/rt_netlink.c1
-rw-r--r--zebra/zapi_msg.c2
-rw-r--r--zebra/zebra_gr.c2
-rw-r--r--zebra/zebra_mpls.c12
-rw-r--r--zebra/zebra_nhg.c3
-rw-r--r--zebra/zebra_rib.c79
-rw-r--r--zebra/zebra_rnh.c10
-rw-r--r--zebra/zebra_snmp.c2
-rw-r--r--zebra/zebra_vty.c8
-rw-r--r--zebra/zserv.h3
42 files changed, 256 insertions, 80 deletions
diff --git a/lib/log.c b/lib/log.c
index 306c995c15..a92f9e8855 100644
--- a/lib/log.c
+++ b/lib/log.c
@@ -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.