📄 ospf6_asbr.c
字号:
voidospf6_asbr_redistribute_add (int type, int ifindex, struct prefix *prefix, u_int nexthop_num, struct in6_addr *nexthop){ int ret; struct ospf6_route troute; struct ospf6_external_info tinfo; struct ospf6_route *route, *match; struct ospf6_external_info *info; struct prefix prefix_id; struct route_node *node; char pbuf[64], ibuf[16]; listnode lnode; struct ospf6_area *oa; if (! ospf6_zebra_is_redistribute (type)) return; if (IS_OSPF6_DEBUG_ASBR) { prefix2str (prefix, pbuf, sizeof (pbuf)); zlog_info ("Redistribute %s (%s)", pbuf, ZROUTE_NAME (type)); } /* if route-map was specified but not found, do not advertise */ if (ospf6->rmap[type].name) { if (ospf6->rmap[type].map == NULL) ospf6_asbr_routemap_update (NULL); if (ospf6->rmap[type].map == NULL) { zlog_warn ("route-map \"%s\" not found, suppress redistributing", ospf6->rmap[type].name); return; } } /* apply route-map */ if (ospf6->rmap[type].map) { memset (&troute, 0, sizeof (troute)); memset (&tinfo, 0, sizeof (tinfo)); troute.route_option = &tinfo; ret = route_map_apply (ospf6->rmap[type].map, prefix, RMAP_OSPF6, &troute); if (ret != RMAP_MATCH) { if (IS_OSPF6_DEBUG_ASBR) zlog_info ("Denied by route-map \"%s\"", ospf6->rmap[type].name); return; } } match = ospf6_route_lookup (prefix, ospf6->external_table); if (match) { info = match->route_option; /* copy result of route-map */ if (ospf6->rmap[type].map) { if (troute.path.metric_type) match->path.metric_type = troute.path.metric_type; if (troute.path.cost) match->path.cost = troute.path.cost; if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding)) memcpy (&info->forwarding, &tinfo.forwarding, sizeof (struct in6_addr)); } info->type = type; match->nexthop[0].ifindex = ifindex; if (nexthop_num && nexthop) memcpy (&match->nexthop[0].address, nexthop, sizeof (struct in6_addr)); /* create/update binding in external_id_table */ prefix_id.family = AF_INET; prefix_id.prefixlen = 32; prefix_id.u.prefix4.s_addr = htonl (info->id); node = route_node_get (ospf6->external_id_table, &prefix_id); node->info = match; if (IS_OSPF6_DEBUG_ASBR) { inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf)); zlog_info ("Advertise as AS-External Id:%s", ibuf); } match->path.origin.id = htonl (info->id); ospf6_as_external_lsa_originate (match); return; } /* create new entry */ route = ospf6_route_create (); route->type = OSPF6_DEST_TYPE_NETWORK; memcpy (&route->prefix, prefix, sizeof (struct prefix)); info = (struct ospf6_external_info *) XMALLOC (MTYPE_OSPF6_EXTERNAL_INFO, sizeof (struct ospf6_external_info)); memset (info, 0, sizeof (struct ospf6_external_info)); route->route_option = info; info->id = ospf6->external_id++; /* copy result of route-map */ if (ospf6->rmap[type].map) { if (troute.path.metric_type) route->path.metric_type = troute.path.metric_type; if (troute.path.cost) route->path.cost = troute.path.cost; if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding)) memcpy (&info->forwarding, &tinfo.forwarding, sizeof (struct in6_addr)); } info->type = type; route->nexthop[0].ifindex = ifindex; if (nexthop_num && nexthop) memcpy (&route->nexthop[0].address, nexthop, sizeof (struct in6_addr)); /* create/update binding in external_id_table */ prefix_id.family = AF_INET; prefix_id.prefixlen = 32; prefix_id.u.prefix4.s_addr = htonl (info->id); node = route_node_get (ospf6->external_id_table, &prefix_id); node->info = route; route = ospf6_route_add (route, ospf6->external_table); route->route_option = info; if (IS_OSPF6_DEBUG_ASBR) { inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf)); zlog_info ("Advertise as AS-External Id:%s", ibuf); } route->path.origin.id = htonl (info->id); ospf6_as_external_lsa_originate (route); /* Router-Bit (ASBR Flag) may have to be updated */ for (lnode = listhead (ospf6->area_list); lnode; nextnode (lnode)) { oa = (struct ospf6_area *) getdata (lnode); OSPF6_ROUTER_LSA_SCHEDULE (oa); }}voidospf6_asbr_redistribute_remove (int type, int ifindex, struct prefix *prefix){ struct ospf6_route *match; struct ospf6_external_info *info = NULL; struct route_node *node; struct ospf6_lsa *lsa; struct prefix prefix_id; char pbuf[64], ibuf[16]; listnode lnode; struct ospf6_area *oa; match = ospf6_route_lookup (prefix, ospf6->external_table); if (match == NULL) { if (IS_OSPF6_DEBUG_ASBR) { prefix2str (prefix, pbuf, sizeof (pbuf)); zlog_info ("No such route %s to withdraw", pbuf); } return; } info = match->route_option; assert (info); if (info->type != type) { if (IS_OSPF6_DEBUG_ASBR) { prefix2str (prefix, pbuf, sizeof (pbuf)); zlog_info ("Original protocol mismatch: %s", pbuf); } return; } if (IS_OSPF6_DEBUG_ASBR) { prefix2str (prefix, pbuf, sizeof (pbuf)); inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf)); zlog_info ("Withdraw %s (AS-External Id:%s)", pbuf, ibuf); } lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL), htonl (info->id), ospf6->router_id, ospf6->lsdb); if (lsa) ospf6_lsa_purge (lsa); /* remove binding in external_id_table */ prefix_id.family = AF_INET; prefix_id.prefixlen = 32; prefix_id.u.prefix4.s_addr = htonl (info->id); node = route_node_lookup (ospf6->external_id_table, &prefix_id); assert (node); node->info = NULL; route_unlock_node (node); ospf6_route_remove (match, ospf6->external_table); XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info); /* Router-Bit (ASBR Flag) may have to be updated */ for (lnode = listhead (ospf6->area_list); lnode; nextnode (lnode)) { oa = (struct ospf6_area *) getdata (lnode); OSPF6_ROUTER_LSA_SCHEDULE (oa); }}DEFUN (ospf6_redistribute, ospf6_redistribute_cmd, "redistribute (static|kernel|connected|ripng|bgp)", "Redistribute\n" "Static route\n" "Kernel route\n" "Connected route\n" "RIPng route\n" "BGP route\n" ){ int type = 0; if (strncmp (argv[0], "sta", 3) == 0) type = ZEBRA_ROUTE_STATIC; else if (strncmp (argv[0], "ker", 3) == 0) type = ZEBRA_ROUTE_KERNEL; else if (strncmp (argv[0], "con", 3) == 0) type = ZEBRA_ROUTE_CONNECT; else if (strncmp (argv[0], "rip", 3) == 0) type = ZEBRA_ROUTE_RIPNG; else if (strncmp (argv[0], "bgp", 3) == 0) type = ZEBRA_ROUTE_BGP; ospf6_asbr_redistribute_unset (type); ospf6_asbr_routemap_unset (type); ospf6_asbr_redistribute_set (type); return CMD_SUCCESS;}DEFUN (ospf6_redistribute_routemap, ospf6_redistribute_routemap_cmd, "redistribute (static|kernel|connected|ripng|bgp) route-map WORD", "Redistribute\n" "Static routes\n" "Kernel route\n" "Connected route\n" "RIPng route\n" "BGP route\n" "Route map reference\n" "Route map name\n" ){ int type = 0; if (strncmp (argv[0], "sta", 3) == 0) type = ZEBRA_ROUTE_STATIC; else if (strncmp (argv[0], "ker", 3) == 0) type = ZEBRA_ROUTE_KERNEL; else if (strncmp (argv[0], "con", 3) == 0) type = ZEBRA_ROUTE_CONNECT; else if (strncmp (argv[0], "rip", 3) == 0) type = ZEBRA_ROUTE_RIPNG; else if (strncmp (argv[0], "bgp", 3) == 0) type = ZEBRA_ROUTE_BGP; ospf6_asbr_redistribute_unset (type); ospf6_asbr_routemap_set (type, argv[1]); ospf6_asbr_redistribute_set (type); return CMD_SUCCESS;}DEFUN (no_ospf6_redistribute, no_ospf6_redistribute_cmd, "no redistribute (static|kernel|connected|ripng|bgp)", NO_STR "Redistribute\n" "Static route\n" "Kernel route\n" "Connected route\n" "RIPng route\n" "BGP route\n" ){ int type = 0; if (strncmp (argv[0], "sta", 3) == 0) type = ZEBRA_ROUTE_STATIC; else if (strncmp (argv[0], "ker", 3) == 0) type = ZEBRA_ROUTE_KERNEL; else if (strncmp (argv[0], "con", 3) == 0) type = ZEBRA_ROUTE_CONNECT; else if (strncmp (argv[0], "rip", 3) == 0) type = ZEBRA_ROUTE_RIPNG; else if (strncmp (argv[0], "bgp", 3) == 0) type = ZEBRA_ROUTE_BGP; ospf6_asbr_redistribute_unset (type); ospf6_asbr_routemap_unset (type); return CMD_SUCCESS;}intospf6_redistribute_config_write (struct vty *vty){ int type; for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { if (type == ZEBRA_ROUTE_OSPF6) continue; if (! ospf6_zebra_is_redistribute (type)) continue; if (ospf6->rmap[type].name) vty_out (vty, " redistribute %s route-map %s%s", ZROUTE_NAME (type), ospf6->rmap[type].name, VNL); else vty_out (vty, " redistribute %s%s", ZROUTE_NAME (type), VNL); } return 0;}voidospf6_redistribute_show_config (struct vty *vty){ int type; int nroute[ZEBRA_ROUTE_MAX]; int total; struct ospf6_route *route; struct ospf6_external_info *info; total = 0; for (type = 0; type < ZEBRA_ROUTE_MAX; type++) nroute[type] = 0; for (route = ospf6_route_head (ospf6->external_table); route; route = ospf6_route_next (route)) { info = route->route_option; nroute[info->type]++; total++; } vty_out (vty, "Redistributing External Routes from:%s", VNL); for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { if (type == ZEBRA_ROUTE_OSPF6) continue; if (! ospf6_zebra_is_redistribute (type)) continue; if (ospf6->rmap[type].name) vty_out (vty, " %d: %s with route-map \"%s\"%s%s", nroute[type], ZROUTE_NAME (type), ospf6->rmap[type].name, (ospf6->rmap[type].map ? "" : " (not found !)"), VNL); else vty_out (vty, " %d: %s%s", nroute[type], ZROUTE_NAME (type), VNL); } vty_out (vty, "Total %d routes%s", total, VNL);}/* Routemap Functions */route_map_result_tospf6_routemap_rule_match_address_prefixlist (void *rule, struct prefix *prefix, route_map_object_t type, void *object){ struct prefix_list *plist; if (type != RMAP_OSPF6) return RMAP_NOMATCH; plist = prefix_list_lookup (AFI_IP6, (char *) rule); if (plist == NULL) return RMAP_NOMATCH; return (prefix_list_apply (plist, prefix) == PREFIX_DENY ? RMAP_NOMATCH : RMAP_MATCH);}void *ospf6_routemap_rule_match_address_prefixlist_compile (char *arg){ return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);}voidospf6_routemap_rule_match_address_prefixlist_free (void *rule){ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);}struct route_map_rule_cmdospf6_routemap_rule_match_address_prefixlist_cmd ={ "ipv6 address prefix-list", ospf6_routemap_rule_match_address_prefixlist, ospf6_routemap_rule_match_address_prefixlist_compile, ospf6_routemap_rule_match_address_prefixlist_free,};route_map_result_tospf6_routemap_rule_set_metric_type (void *rule, struct prefix *prefix, route_map_object_t type, void *object){ char *metric_type = rule; struct ospf6_route *route = object; if (type != RMAP_OSPF6) return RMAP_OKAY; if (strcmp (metric_type, "type-2") == 0) route->path.metric_type = 2; else route->path.metric_type = 1; return RMAP_OKAY;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -