auto RP

RP常见机制有以下三种:
1.手工静态指定
需要在每个多播路由器上手工配置RP信息,同时还要定义group-rp的映射关系
2.Auto-RP:cisco专业的协议
3.采用BSR(bootstrap router自举路由器协议)
动态方式通告RP信息,只需在RP和BSR路由器上配置即可,其他PIM多播域内的路由器会自动学习到RP的信息,BSR是标准的RP选举与维护机制,所有支持PIM-SM的设备都会支持BSR机制。

静态配置RP
ip pim rp-address X.X.X.X 后跟ACL编号(override)
X.X.X.XRP路由器的IP地址,ACL编号表示RP只为该组播地址服务,override表示静态RP优先于Auto-RP和BSR选举
默认情况下auto-rp优于BSR优于静态
access-list 1 permit 239.1.1.0 0.0.0.255
以上静态指定RP的命令需要在所有组播路由器上配置

配置Auto-RP
静态RP带来一些问题:
1.需要更改RP地址时候,每个路由器都得配置
2.RP失效时,静态配置的PIM域无法轻易地切换到备用RP上
配置Auto-RP的步骤:
1.必须配置所有的C–RP
2.必须配置所有的映射代理

采用 ip pim send-rp-announce 即可配置C-RP,候选RP,使用该命令需要制定接口(路由器通过接口取得IP地址)和TTL值,当路由器配置为C-RP时候,该路由器每隔60s向保留地址224.0.1.39发送一条RP-announce消息,超时时间为180s。
采用ip pim send-rp-discovery配置映射代理,映射代理负责侦听来自C-RP的RP-announce消息并选举出RP,之后通过RP-discovery消息(每隔60秒向保留地址224.0.1.40发送)将RP宣告到PIM域中。
注意:必须在发送send-rp-discovery和send-rp-announce上指定的接口配置IP pim sparse-mode,对应的在静态RP的配置时没必要在RP的接口上配置PIM-SM。
总结:
候选RP向映射代理发送竟选消息(RP-Announce),最后映射代理从候选RP的竟选消息中选出IP地址最高的为活动RP,然后发送RP-Discovery通告给每台路由器,竟选活动RP只根据IP地址大小,没有优先级之分。
所有的C-RP向映射代理发送竟选消息,使用目的地址为224.0.1.39,每60秒发送一次,而映射代理从众多C-RP中选出活动RP后,以目的地址为224.0.1.40发给每台路由器,也是每60秒发送一次。

debug ip pim auto-rp:来显示auto-rp的全部操作过程。
Show ip pim rp:可以显示路由器正在接收的多播组以及这些多播组所映射到的RP情况。
采用ip pim send-rp-announce中加入关键字interval可以修改C-RP发送RP announce消息的时间间隔,默认为60s。
eg:ip pim send-rp-announce loopback 0 scope 5 interval 10,修改间隔为10s。

采用ip pim send-rp-announce中加入关键字group-list可以指定路由器为特定组播组的RP。
eg:ip pim send-rp-announce loopback 0 scope 5 group-list 10
access-list 10 permit 224.0.0.0 7.255.255.255
Show ip pim rp mapping:可以查看路由器映射到某个RP的所有组播组(不同的多播映射到不同的RP)。
Show ip pim rp mapping in-use:显示该路由器上正在使用的多播组地址范围。
Show ip pim rp-hash:显示某特定组将要被映射到那个RP。

通过设置RP通告过滤器(announcement filter),可以防止映射代理接收未经授权的路由器,这些路由器可能被有意或者无意的配置成为C-RP。采用命令:ip pim rp-announce-filter
eg:ip pim rp-announce-filter rp-list 1 group-list 11
access-list 1 permit 10.224.1.1
access-list 1 permit 10.224.1.2
access-list 11 permit 224.0.0.0 15.255.255.255
★在稀疏模式应用环境,多播包必须首先在共享树上进行转发,这就意味着侦听224.0.1.40的路由器为了接收RP-Discovery消息,就必须向他们的RP通告希望加入该多播组,现在的情况是路由器连RP-Discovery消息都没有接收到,那么又怎么知道谁是RP呢?解决的办法是采用稀疏-密集模式。
配置稀疏-密集模式,接口上配置:ip pim sparse-dense-mode
(备注:在环回口上无需配置ip pim sparse-dense-mode,只要配置ip pim sparse-mode即可)

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为了解决规范族中的冲突问题,我们需要使用LR分析法。LR分析法是一种自底向上的语法分析方法,它使用一个状态机来表示文法的推导过程,并使用一个分析表来指导分析过程。在这个过程中,我们需要使用项目集来表示状态机的状态。 下面是一份C++代码,它可以允许规范族有冲突的项目集,并使用向前查看一个符号来进行处理,并且能够解决存在的无效归约问题: ```cpp #include <iostream> #include <vector> #include <map> using namespace std; // 定义文法符号类型 enum SymbolType { TERMINAL, NONTERMINAL }; // 定义文法符号结构体 struct Symbol { SymbolType type; // 符号类型,终结符或非终结符 string name; // 符号名称 bool operator==(const Symbol& other) const { return type == other.type && name == other.name; } bool operator<(const Symbol& other) const { if (type != other.type) { return type < other.type; } return name < other.name; } }; // 定义产生式结构体 struct Production { Symbol left; // 左部符号 vector<Symbol> right; // 右部符号序列 bool operator==(const Production& other) const { return left == other.left && right == other.right; } }; // 定义项目结构体 struct Item { Production prod; // 产生式 int dot_position; // 点的位置 Symbol lookahead; // 向前查看符号 bool operator==(const Item& other) const { return prod == other.prod && dot_position == other.dot_position && lookahead == other.lookahead; } }; // 定义状态结构体 struct State { int id; // 状态编号 vector<Item> items; // 项目集合 map<Symbol, int> transitions; // 转移函数 bool operator==(const State& other) const { return id == other.id && items == other.items && transitions == other.transitions; } }; // 定义文法结构体 struct Grammar { vector<Symbol> terminals; // 终结符集合 vector<Symbol> nonterminals; // 非终结符集合 Symbol start_symbol; // 开始符号 vector<Production> productions; // 产生式集合 }; // 初始化文法 Grammar init_grammar() { Grammar g; // 初始化终结符集合 g.terminals.push_back({ TERMINAL, "+" }); g.terminals.push_back({ TERMINAL, "-" }); g.terminals.push_back({ TERMINAL, "*" }); g.terminals.push_back({ TERMINAL, "/" }); g.terminals.push_back({ TERMINAL, "(" }); g.terminals.push_back({ TERMINAL, ")" }); g.terminals.push_back({ TERMINAL, "num" }); // 初始化非终结符集合 g.nonterminals.push_back({ NONTERMINAL, "E" }); g.nonterminals.push_back({ NONTERMINAL, "T" }); g.nonterminals.push_back({ NONTERMINAL, "F" }); // 初始化开始符号 g.start_symbol = { NONTERMINAL, "E" }; // 初始化产生式集合 g.productions.push_back({ { NONTERMINAL, "E" }, { { NONTERMINAL, "E" }, { TERMINAL, "+" }, { NONTERMINAL, "T" } } }); g.productions.push_back({ { NONTERMINAL, "E" }, { { NONTERMINAL, "E" }, { TERMINAL, "-" }, { NONTERMINAL, "T" } } }); g.productions.push_back({ { NONTERMINAL, "E" }, { { NONTERMINAL, "T" } } }); g.productions.push_back({ { NONTERMINAL, "T" }, { { NONTERMINAL, "T" }, { TERMINAL, "*" }, { NONTERMINAL, "F" } } }); g.productions.push_back({ { NONTERMINAL, "T" }, { { NONTERMINAL, "T" }, { TERMINAL, "/" }, { NONTERMINAL, "F" } } }); g.productions.push_back({ { NONTERMINAL, "T" }, { { NONTERMINAL, "F" } } }); g.productions.push_back({ { NONTERMINAL, "F" }, { { TERMINAL, "(" }, { NONTERMINAL, "E" }, { TERMINAL, ")" } } }); g.productions.push_back({ { NONTERMINAL, "F" }, { { TERMINAL, "num" } } }); return g; } // 判断一个符号是否为终结符 bool is_terminal(Symbol s) { return s.type == TERMINAL; } // 判断一个符号是否为非终结符 bool is_nonterminal(Symbol s) { return s.type == NONTERMINAL; } // 判断一个符号是否为空串 bool is_epsilon(Symbol s) { return s.name.empty(); } // 判断一个符号是否为文法的开始符号 bool is_start_symbol(Grammar g, Symbol s) { return g.start_symbol == s; } // 判断一个文法符号是否可以产生空串 bool can_produce_epsilon(Grammar g, Symbol s) { if (is_terminal(s)) { return false; } for (auto p : g.productions) { if (p.left == s) { bool all_produce_epsilon = true; for (auto r : p.right) { if (!can_produce_epsilon(g, r)) { all_produce_epsilon = false; break; } } if (all_produce_epsilon) { return true; } } } return false; } // 计算一个符号的 FIRST 集合 vector<Symbol> compute_first(Grammar g, Symbol s) { vector<Symbol> result; // 如果 s 是终结符,则 FIRST(s) = { s } if (is_terminal(s)) { result.push_back(s); return result; } // 如果 s 是非终结符,则 FIRST(s) = FIRST(第一个产生式的右部符号) for (auto p : g.productions) { if (p.left == s) { if (!is_epsilon(p.right[0])) { auto first = compute_first(g, p.right[0]); result.insert(result.end(), first.begin(), first.end()); } } } // 如果 s 可以产生空串,则 FIRST(s) = FIRST(第一个非空符号) ∪ { ε } if (can_produce_epsilon(g, s)) { for (auto p : g.productions) { if (p.left == s) { bool all_produce_epsilon = true; for (auto r : p.right) { if (!can_produce_epsilon(g, r)) { auto first = compute_first(g, r); result.insert(result.end(), first.begin(), first.end()); all_produce_epsilon = false; break; } } if (all_produce_epsilon) { result.push_back({ NONTERMINAL, "" }); } } } } return result; } // 计算一个项目集的闭包 vector<Item> closure(Grammar g, vector<Item> items) { vector<Item> result = items; while (true) { bool added_new_items = false; for (auto item : result) { if (item.dot_position >= item.prod.right.size()) { continue; } auto next_symbol = item.prod.right[item.dot_position]; if (is_terminal(next_symbol)) { continue; } auto lookahead = item.lookahead; for (int i = item.dot_position + 1; i < item.prod.right.size(); i++) { auto symbol = item.prod.right[i]; auto first = compute_first(g, symbol); bool can_produce_epsilon = false; for (auto f : first) { if (!is_epsilon(f)) { lookahead = f; break; } else { can_produce_epsilon = true; } } if (!can_produce_epsilon) { break; } if (i == item.prod.right.size() - 1) { lookahead = item.lookahead; } } for (auto p : g.productions) { if (p.left == next_symbol) { auto new_item = Item{ p, 0, lookahead }; if (find(result.begin(), result.end(), new_item) == result.end()) { result.push_back(new_item); added_new_items = true; } } } } if (!added_new_items) { break; } } return result; } // 计算一个项目集的 GOTO 集合 vector<Item> goto_set(Grammar g, vector<Item> items, Symbol symbol) { vector<Item> result; for (auto item : items) { if (item.dot_position >= item.prod.right.size()) { continue; } auto next_symbol = item.prod.right[item.dot_position]; if (next_symbol == symbol) { Item new_item{ item.prod, item.dot_position + 1, item.lookahead }; result.push_back(new_item); } } return closure(g, result); } // 计算 LR(0) 自动机 vector<State> compute_lr0_automaton(Grammar g) { vector<State> states; // 初始化初始状态 State initial_state{ 0, closure(g, { Item{ g.productions[0], 0, { TERMINAL, "$" } } }) }; states.push_back(initial_state); // 计算所有状态 int next_state_id = 1; while (true) { bool added_new_state = false; for (auto state : states) { for (auto symbol : g.terminals) { auto goto_items = goto_set(g, state.items, symbol); if (goto_items.empty()) { continue; } auto existing_state = find(states.begin(), states.end(), State{ -1, goto_items, {} }); if (existing_state != states.end()) { state.transitions[symbol] = existing_state->id; } else { State new_state{ next_state_id++, goto_items, {} }; states.push_back(new_state); state.transitions[symbol] = new_state.id; added_new_state = true; } } for (auto symbol : g.nonterminals) { auto goto_items = goto_set(g, state.items, symbol); if (goto_items.empty()) { continue; } auto existing_state = find(states.begin(), states.end(), State{ -1, goto_items, {} }); if (existing_state != states.end()) { state.transitions[symbol] = existing_state->id; } else { State new_state{ next_state_id++, goto_items, {} }; states.push_back(new_state); state.transitions[symbol] = new_state.id; added_new_state = true; } } } if (!added_new_state) { break; } } return states; } // 计算一个项目的 LR(1) 向前看集合 vector<Symbol> compute_lr1_lookahead(Grammar g, Item item, map<Item, vector<Symbol>>& lookahead_cache) { if (lookahead_cache.find(item) != lookahead_cache.end()) { return lookahead_cache[item]; } vector<Symbol> result; if (item.dot_position < item.prod.right.size()) { auto next_symbol = item.prod.right[item.dot_position]; if (is_terminal(next_symbol)) { result.push_back(next_symbol); } else if (is_nonterminal(next_symbol)) { for (auto f : compute_first(g, item.lookahead)) { if (!is_epsilon(f)) { result.push_back(f); } } if (can_produce_epsilon(g, next_symbol)) { auto rest_item = Item{ item.prod, item.dot_position + 1, item.lookahead }; auto rest_lookahead = compute_lr1_lookahead(g, rest_item, lookahead_cache); result.insert(result.end(), rest_lookahead.begin(), rest_lookahead.end()); } } } else { result.push_back(item.lookahead); } lookahead_cache[item] = result; return result; } // 计算 LR(1) 自动机 vector<State> compute_lr1_automaton(Grammar g) { vector<State> states; // 初始化初始状态 map<Item, vector<Symbol>> lookahead_cache; vector<Item> initial_items; for (auto p : g.productions) { auto first = compute_first(g, p.right[0]); bool can_produce_epsilon = false; for (auto f : first) { if (!is_epsilon(f)) { auto item = Item{ p, 0, f }; initial_items.push_back(item); } else { can_produce_epsilon = true; } } if (can_produce_epsilon) { auto item = Item{ p, 0, { NONTERMINAL, "" } }; initial_items.push_back(item); } } State initial_state{ 0, closure(g, initial_items), {} }; states.push_back(initial_state); // 计算所有状态 int next_state_id = 1; while (true) { bool added_new_state = false; for (auto state : states) { for (auto symbol : g.terminals) { auto goto_items = goto_set(g, state.items, symbol); if (goto_items.empty()) { continue; } map<Item, Symbol> items_with_lookahead; for (auto item : state.items) { auto lookahead = compute_lr1_lookahead(g, item, lookahead_cache); items_with_lookahead[item] = lookahead[0]; } map<Production, vector<Symbol>> reduce_productions; for (auto item : state.items) { if (item.dot_position < item.prod.right.size()) { continue; } reduce_productions[item.prod].push_back(item.lookahead); } if (!reduce_productions.empty()) { for (auto rp : reduce_productions) { auto new_item = Item{ rp.first, rp.first.right.size(), rp.second[0] }; auto existing_state = find(states.begin(), states.end(), State{ -1, { new_item }, {} }); if (existing_state != states.end()) { state.transitions[symbol] = -(existing_state->id); } else { State new_state{ -(next_state_id++), { new_item }, {} }; states.push_back(new_state); state.transitions[symbol] = new_state.id; added_new_state = true; } } } else { auto existing_state = find(states.begin(), states.end(), State{ -1, goto_items, {} }); if (existing_state != states.end()) { state.transitions[symbol] = existing_state->id; } else { State new_state{ next_state_id++, goto_items, {} }; states.push_back(new_state); state.transitions[symbol] = new_state.id; added_new_state = true; } } } for (auto symbol : g.nonterminals) { auto goto_items = goto_set(g, state.items, symbol); if (goto_items.empty()) { continue; } auto existing_state = find(states.begin(), states.end(), State{ -1, goto_items, {} }); if (existing_state != states.end()) { state.transitions[symbol] = existing_state->id; } else { State new_state{ next_state_id++, goto_items, {} }; states.push_back(new_state); state.transitions[symbol] = new_state.id; added_new_state = true; } } } if (!added_new_state) { break; } } return states; } // 判断一个符号是否为文法的结束符号 bool is_end_symbol(Symbol s) { return s == Symbol{ TERMINAL, "$" }; } // 打印状态集合 void print_states(vector<State> states) { for (auto state : states) { cout << "state " << state.id << ":" << endl; for (auto item : state.items) { cout << " "; cout << item.prod.left.name << " ->"; for (int i = 0; i < item.prod.right.size(); i++) { if (i == item.dot_position) { cout << " ."; } cout << " " << item.prod.right[i].name; } if (item.dot_position == item.prod.right.size()) { cout << " ."; } cout << ", " << item.lookahead.name << endl; } cout << endl; } } // 打印 LR 分析表 void print_lr_table(Grammar g, vector<State> states) { // 计算 ACTION 表和 GOTO 表 vector<map<Symbol, int>> action_table(states.size()); vector<map<Symbol, int>> goto_table(states.size()); for (auto state : states) { for (auto item : state.items) { if (item.dot_position == item.prod.right.size()) { if (is_start_symbol(g, item.prod.left) && is_end_symbol(item.lookahead)) {
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值