diff options
| author | Don Slice <dslice@cumulusnetworks.com> | 2017-02-02 12:58:33 -0500 |
|---|---|---|
| committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-04-06 10:29:19 -0400 |
| commit | a64448baa6150a7431d55e0e65d0b51d62c4b5be (patch) | |
| tree | adb195d3f8e26c4ae893f85fb1020e1d55d73241 /zebra/zebra_rib.c | |
| parent | cceb79ac9b05c2f5d3e4a74b9cd11e908ea634ec (diff) | |
zebra: labeled unicast handling
Support install of labeled-unicast routes by a client. This would be
BGP, in order to install routes corresponding to AFI/SAFI 1/4 (IPv4)
or 2/4 (IPv6). Convert labeled-unicast routes into label forwarding
entries (i.e., transit LSPs) when there is a static label binding.
Signed-off-by: Don Slice <dslice@cumulusnetworks.com>
Diffstat (limited to 'zebra/zebra_rib.c')
| -rw-r--r-- | zebra/zebra_rib.c | 47 |
1 files changed, 46 insertions, 1 deletions
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index b3e70e46fa..e4d583d5f2 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1084,7 +1084,25 @@ nexthop_active_update (struct route_node *rn, struct rib *rib, int set) return rib->nexthop_active_num; } +/* + * Is this RIB labeled-unicast? It must be of type BGP and all paths + * (nexthops) must have a label. + */ +int +zebra_rib_labeled_unicast (struct rib *rib) +{ + struct nexthop *nexthop = NULL, *tnexthop; + int recursing; + + if (rib->type != ZEBRA_ROUTE_BGP) + return 0; + + for (ALL_NEXTHOPS_RO(rib->nexthop, nexthop, tnexthop, recursing)) + if (!nexthop->nh_label || !nexthop->nh_label->num_labels) + return 0; + return 1; +} /* Update flag indicates whether this is a "replace" or not. Currently, this * is only used for IPv4. @@ -1177,7 +1195,12 @@ rib_uninstall (struct route_node *rn, struct rib *rib) if (! RIB_SYSTEM_ROUTE (rib)) rib_uninstall_kernel (rn, rib); - UNSET_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB); + + /* If labeled-unicast route, uninstall transit LSP. */ + if (zebra_rib_labeled_unicast (rib)) + zebra_mpls_lsp_uninstall (info->zvrf, rn, rib); + + UNSET_FLAG (rib->status, RIB_ENTRY_SELECTED_FIB); } if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_SELECTED)) @@ -1272,6 +1295,10 @@ rib_process_add_fib(struct zebra_vrf *zvrf, struct route_node *rn, zvrf_id (zvrf), buf, rn, new, new->type); } + /* If labeled-unicast route, install transit LSP. */ + if (zebra_rib_labeled_unicast (new)) + zebra_mpls_lsp_install (zvrf, rn, new); + if (!RIB_SYSTEM_ROUTE (new)) { if (rib_install_kernel (rn, new, NULL)) @@ -1301,6 +1328,10 @@ rib_process_del_fib(struct zebra_vrf *zvrf, struct route_node *rn, zvrf_id (zvrf), buf, rn, old, old->type); } + /* If labeled-unicast route, uninstall transit LSP. */ + if (zebra_rib_labeled_unicast (old)) + zebra_mpls_lsp_uninstall (zvrf, rn, old); + if (!RIB_SYSTEM_ROUTE (old)) rib_uninstall_kernel (rn, old); @@ -1354,6 +1385,10 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn, /* Non-system route should be installed. */ if (!RIB_SYSTEM_ROUTE (new)) { + /* If labeled-unicast route, install transit LSP. */ + if (zebra_rib_labeled_unicast (new)) + zebra_mpls_lsp_install (zvrf, rn, new); + if (rib_install_kernel (rn, new, old)) { char buf[SRCDEST2STR_BUFFER]; @@ -1368,6 +1403,10 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn, { if (RIB_SYSTEM_ROUTE(new)) { + /* If labeled-unicast route, uninstall transit LSP. */ + if (zebra_rib_labeled_unicast (old)) + zebra_mpls_lsp_uninstall (zvrf, rn, old); + if (!RIB_SYSTEM_ROUTE (old)) rib_uninstall_kernel (rn, old); } @@ -1404,6 +1443,10 @@ rib_process_update_fib (struct zebra_vrf *zvrf, struct route_node *rn, nh_active ? "install failed" : "nexthop inactive"); } + /* If labeled-unicast route, uninstall transit LSP. */ + if (zebra_rib_labeled_unicast (old)) + zebra_mpls_lsp_uninstall (zvrf, rn, old); + if (!RIB_SYSTEM_ROUTE (old)) rib_uninstall_kernel (rn, old); UNSET_FLAG (new->status, RIB_ENTRY_SELECTED_FIB); @@ -2934,8 +2977,10 @@ rib_tables_iter_next (rib_tables_iter_t *iter) } afi_safis[] = { { AFI_IP, SAFI_UNICAST }, { AFI_IP, SAFI_MULTICAST }, + { AFI_IP, SAFI_LABELED_UNICAST }, { AFI_IP6, SAFI_UNICAST }, { AFI_IP6, SAFI_MULTICAST }, + { AFI_IP6, SAFI_LABELED_UNICAST }, }; table = NULL; |
