Line data Source code
1 : /* 2 : * Copyright (c) 2018 Cisco and/or its affiliates. 3 : * Licensed under the Apache License, Version 2.0 (the "License"); 4 : * you may not use this file except in compliance with the License. 5 : * You may obtain a copy of the License at: 6 : * 7 : * http://www.apache.org/licenses/LICENSE-2.0 8 : * 9 : * Unless required by applicable law or agreed to in writing, software 10 : * distributed under the License is distributed on an "AS IS" BASIS, 11 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : * See the License for the specific language governing permissions and 13 : * limitations under the License. 14 : */ 15 : 16 : 17 : #include <vnet/mfib/mfib_entry_src.h> 18 : #include <vnet/mfib/mfib_entry_cover.h> 19 : #include <vnet/mfib/mfib_table.h> 20 : #include <vnet/fib/fib_path_list.h> 21 : 22 : static void 23 10 : mfib_entry_src_rr_deactivate (mfib_entry_t *mfib_entry, 24 : mfib_entry_src_t *msrc) 25 : { 26 : mfib_entry_t *cover; 27 : 28 : /* 29 : * remove the depednecy on the covering entry 30 : */ 31 10 : if (FIB_NODE_INDEX_INVALID != msrc->mfes_cover) 32 : { 33 8 : cover = mfib_entry_get(msrc->mfes_cover); 34 8 : mfib_entry_cover_untrack(cover, msrc->mfes_sibling); 35 8 : msrc->mfes_cover = FIB_NODE_INDEX_INVALID; 36 : } 37 : 38 10 : fib_path_list_unlock(msrc->mfes_pl); 39 10 : msrc->mfes_pl = FIB_NODE_INDEX_INVALID; 40 10 : msrc->mfes_itfs = NULL; 41 10 : msrc->mfes_exts = NULL; 42 10 : } 43 : 44 : static void 45 8 : mfib_entry_src_rr_activate (mfib_entry_t *mfib_entry, 46 : mfib_entry_src_t *msrc) 47 : { 48 : mfib_entry_src_t *csrc; 49 : mfib_entry_t *cover; 50 : 51 16 : msrc->mfes_cover = mfib_table_get_less_specific(mfib_entry->mfe_fib_index, 52 8 : &mfib_entry->mfe_prefix); 53 : 54 8 : ASSERT(FIB_NODE_INDEX_INVALID != msrc->mfes_cover); 55 : 56 8 : cover = mfib_entry_get(msrc->mfes_cover); 57 : 58 8 : msrc->mfes_sibling = 59 8 : mfib_entry_cover_track(cover, mfib_entry_get_index(mfib_entry)); 60 : 61 8 : csrc = mfib_entry_get_best_src(cover); 62 : 63 8 : msrc->mfes_pl = csrc->mfes_pl; 64 8 : fib_path_list_lock(msrc->mfes_pl); 65 8 : msrc->mfes_route_flags = csrc->mfes_route_flags; 66 8 : msrc->mfes_itfs = csrc->mfes_itfs; 67 8 : msrc->mfes_exts = csrc->mfes_exts; 68 8 : msrc->mfes_rpf_id = csrc->mfes_rpf_id; 69 8 : } 70 : 71 : static mfib_src_res_t 72 4 : mfib_entry_src_rr_cover_change (mfib_entry_t *mfib_entry, 73 : mfib_entry_src_t *msrc) 74 : { 75 4 : mfib_entry_src_rr_deactivate(mfib_entry, msrc); 76 4 : mfib_entry_src_rr_activate(mfib_entry, msrc); 77 : 78 4 : return (MFIB_SRC_REEVALUATE); 79 : } 80 : 81 : static mfib_src_res_t 82 18 : mfib_entry_src_rr_cover_update (mfib_entry_t *mfib_entry, 83 : mfib_entry_src_t *msrc) 84 : { 85 : /* 86 : * path lists are updated (i.e. not shared) in the mfib world, 87 : * so there's no need to check for a new one. but we do need to 88 : * copy down any new flags and input interfaces 89 : */ 90 : mfib_entry_src_t *csrc; 91 : mfib_entry_t *cover; 92 : 93 18 : cover = mfib_entry_get(msrc->mfes_cover); 94 : 95 18 : msrc->mfes_route_flags = cover->mfe_flags; 96 18 : msrc->mfes_itfs = cover->mfe_itfs; 97 18 : msrc->mfes_rpf_id = cover->mfe_rpf_id; 98 : 99 : /* The update to the cover could have removed the extensions. 100 : * When a cover is removed from the table, the covereds see it first 101 : * updated (to have no forwarding) and then changed 102 : */ 103 18 : csrc = mfib_entry_get_best_src(cover); 104 18 : msrc->mfes_exts = (csrc ? csrc->mfes_exts : NULL); 105 : 106 18 : return (MFIB_SRC_REEVALUATE); 107 : } 108 : 109 : void 110 559 : mfib_entry_src_rr_module_init (void) 111 : { 112 559 : mfib_entry_src_vft mvft = { 113 : .mev_activate = mfib_entry_src_rr_activate, 114 : .mev_deactivate = mfib_entry_src_rr_deactivate, 115 : .mev_cover_change = mfib_entry_src_rr_cover_change, 116 : .mev_cover_update = mfib_entry_src_rr_cover_update, 117 : }; 118 : 119 559 : mfib_entry_src_register(MFIB_SOURCE_RR, &mvft); 120 559 : }