📄 bgp_routemap.c
字号:
{ struct community_list *list; struct bgp_info *bgp_info; struct rmap_community *rcom; if (type == RMAP_BGP) { bgp_info = object; rcom = rule; list = community_list_lookup (bgp_clist, rcom->name, COMMUNITY_LIST_MASTER); if (! list) return RMAP_NOMATCH; if (rcom->exact) { if (community_list_exact_match (bgp_info->attr->community, list)) return RMAP_MATCH; } else { if (community_list_match (bgp_info->attr->community, list)) return RMAP_MATCH; } } return RMAP_NOMATCH;}/* Compile function for community match. */void *route_match_community_compile (char *arg){ struct rmap_community *rcom; int len; char *p; rcom = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_community)); p = strchr (arg, ' '); if (p) { len = p - arg; rcom->name = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, len + 1); memcpy (rcom->name, arg, len); rcom->exact = 1; } else { rcom->name = XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg); rcom->exact = 0; } return rcom;}/* Compile function for community match. */voidroute_match_community_free (void *rule){ struct rmap_community *rcom = rule; XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom->name); XFREE (MTYPE_ROUTE_MAP_COMPILED, rcom);}/* Route map commands for community matching. */struct route_map_rule_cmd route_match_community_cmd = { "community", route_match_community, route_match_community_compile, route_match_community_free};/* Match function for extcommunity match. */route_map_result_troute_match_ecommunity (void *rule, struct prefix *prefix, route_map_object_t type, void *object){ struct community_list *list; struct bgp_info *bgp_info; if (type == RMAP_BGP) { bgp_info = object; list = community_list_lookup (bgp_clist, (char *) rule, EXTCOMMUNITY_LIST_MASTER); if (! list) return RMAP_NOMATCH; if (ecommunity_list_match (bgp_info->attr->ecommunity, list)) return RMAP_MATCH; } return RMAP_NOMATCH;}/* Compile function for extcommunity match. */void *route_match_ecommunity_compile (char *arg){ return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);}/* Compile function for extcommunity match. */voidroute_match_ecommunity_free (void *rule){ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);}/* Route map commands for community matching. */struct route_map_rule_cmd route_match_ecommunity_cmd = { "extcommunity", route_match_ecommunity, route_match_ecommunity_compile, route_match_ecommunity_free};/* `match nlri` and `set nlri` are replaced by `address-family ipv4` and `address-family vpnv4'. *//* `match origin' */route_map_result_troute_match_origin (void *rule, struct prefix *prefix, route_map_object_t type, void *object){ u_char *origin; struct bgp_info *bgp_info; if (type == RMAP_BGP) { origin = rule; bgp_info = object; if (bgp_info->attr->origin == *origin) return RMAP_MATCH; } return RMAP_NOMATCH;}void *route_match_origin_compile (char *arg){ u_char *origin; origin = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_char)); if (strcmp (arg, "igp") == 0) *origin = 0; else if (strcmp (arg, "egp") == 0) *origin = 1; else *origin = 2; return origin;}/* Free route map's compiled `ip address' value. */voidroute_match_origin_free (void *rule){ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);}/* Route map commands for origin matching. */struct route_map_rule_cmd route_match_origin_cmd ={ "origin", route_match_origin, route_match_origin_compile, route_match_origin_free};/* `set ip next-hop IP_ADDRESS' *//* Set nexthop to object. ojbect must be pointer to struct attr. */struct rmap_ip_nexthop_set{ struct in_addr *address; int peer_address;};route_map_result_troute_set_ip_nexthop (void *rule, struct prefix *prefix, route_map_object_t type, void *object){ struct rmap_ip_nexthop_set *rins = rule; struct in_addr peer_address; struct bgp_info *bgp_info; struct peer *peer; if (type == RMAP_BGP) { bgp_info = object; peer = bgp_info->peer; if (rins->peer_address) { if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN) && peer->su_remote && sockunion_family (peer->su_remote) == AF_INET) { inet_aton (sockunion_su2str (peer->su_remote), &peer_address); bgp_info->attr->nexthop = peer_address; bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP); } else if (CHECK_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT) && peer->su_local && sockunion_family (peer->su_local) == AF_INET) { inet_aton (sockunion_su2str (peer->su_local), &peer_address); bgp_info->attr->nexthop = peer_address; bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP); } } else { /* Set next hop value. */ bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP); bgp_info->attr->nexthop = *rins->address; } } return RMAP_OKAY;}/* Route map `ip nexthop' compile function. Given string is converted to struct in_addr structure. */void *route_set_ip_nexthop_compile (char *arg){ struct rmap_ip_nexthop_set *rins; struct in_addr *address = NULL; int peer_address = 0; int ret; if (strcmp (arg, "peer-address") == 0) peer_address = 1; else { address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr)); ret = inet_aton (arg, address); if (ret == 0) { XFREE (MTYPE_ROUTE_MAP_COMPILED, address); return NULL; } } rins = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_ip_nexthop_set)); memset (rins, 0, sizeof (struct rmap_ip_nexthop_set)); rins->address = address; rins->peer_address = peer_address; return rins;}/* Free route map's compiled `ip nexthop' value. */voidroute_set_ip_nexthop_free (void *rule){ struct rmap_ip_nexthop_set *rins = rule; if (rins->address) XFREE (MTYPE_ROUTE_MAP_COMPILED, rins->address); XFREE (MTYPE_ROUTE_MAP_COMPILED, rins);}/* Route map commands for ip nexthop set. */struct route_map_rule_cmd route_set_ip_nexthop_cmd ={ "ip next-hop", route_set_ip_nexthop, route_set_ip_nexthop_compile, route_set_ip_nexthop_free};/* `set local-preference LOCAL_PREF' *//* Set local preference. */route_map_result_troute_set_local_pref (void *rule, struct prefix *prefix, route_map_object_t type, void *object){ u_int32_t *local_pref; struct bgp_info *bgp_info; if (type == RMAP_BGP) { /* Fetch routemap's rule information. */ local_pref = rule; bgp_info = object; /* Set local preference value. */ bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF); bgp_info->attr->local_pref = *local_pref; } return RMAP_OKAY;}/* set local preference compilation. */void *route_set_local_pref_compile (char *arg){ u_int32_t *local_pref; char *endptr = NULL; /* Local preference value shoud be integer. */ if (! all_digit (arg)) return NULL; local_pref = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)); *local_pref = strtoul (arg, &endptr, 10); if (*endptr != '\0' || *local_pref == ULONG_MAX) { XFREE (MTYPE_ROUTE_MAP_COMPILED, local_pref); return NULL; } return local_pref;}/* Free route map's local preference value. */voidroute_set_local_pref_free (void *rule){ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);}/* Set local preference rule structure. */struct route_map_rule_cmd route_set_local_pref_cmd = { "local-preference", route_set_local_pref, route_set_local_pref_compile, route_set_local_pref_free,};/* `set weight WEIGHT' *//* Set weight. */route_map_result_troute_set_weight (void *rule, struct prefix *prefix, route_map_object_t type, void *object){ u_int16_t *weight; struct bgp_info *bgp_info; if (type == RMAP_BGP) { /* Fetch routemap's rule information. */ weight = rule; bgp_info = object; /* Set weight value. */ bgp_info->attr->weight = *weight; } return RMAP_OKAY;}/* set local preference compilation. */void *route_set_weight_compile (char *arg){ u_int16_t *weight; char *endptr = NULL; /* Local preference value shoud be integer. */ if (! all_digit (arg)) return NULL; weight = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int16_t)); *weight = strtoul (arg, &endptr, 10); if (*endptr != '\0' || *weight == ULONG_MAX) { XFREE (MTYPE_ROUTE_MAP_COMPILED, weight); return NULL; } return weight;}/* Free route map's local preference value. */voidroute_set_weight_free (void *rule){ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);}/* Set local preference rule structure. */struct route_map_rule_cmd route_set_weight_cmd = { "weight", route_set_weight, route_set_weight_compile, route_set_weight_free,};/* `set metric METRIC' *//* Set metric to attribute. */route_map_result_troute_set_metric (void *rule, struct prefix *prefix, route_map_object_t type, void *object){ char *metric; u_int32_t metric_val; struct bgp_info *bgp_info; if (type == RMAP_BGP) { /* Fetch routemap's rule information. */ metric = rule; bgp_info = object; if (! (bgp_info->attr->flag & ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))) bgp_info->attr->med = 0; bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC); if (all_digit (metric)) { metric_val = strtoul (metric, (char **)NULL, 10); bgp_info->attr->med = metric_val; } else { metric_val = strtoul (metric+1, (char **)NULL, 10); if (strncmp (metric, "+", 1) == 0) { if (bgp_info->attr->med/2 + metric_val/2 > ULONG_MAX/2) bgp_info->attr->med = ULONG_MAX-1; else bgp_info->attr->med += metric_val; } else if (strncmp (metric, "-", 1) == 0) { if (bgp_info->attr->med <= metric_val) bgp_info->attr->med = 0; else bgp_info->attr->med -= metric_val; } } } return RMAP_OKAY;}/* set metric compilation. */void *route_set_metric_compile (char *arg){ u_int32_t metric; char *endptr = NULL; if (all_digit (arg)) { /* set metric value check*/ metric = strtoul (arg, &endptr, 10); if (*endptr != '\0' || metric == ULONG_MAX) return NULL; } else { /* set metric +/-value check */ if ((strncmp (arg, "+", 1) != 0 && strncmp (arg, "-", 1) != 0) || (! all_digit (arg+1))) return NULL; metric = strtoul (arg+1, &endptr, 10); if (*endptr != '\0' || metric == ULONG_MAX) return NULL; } return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);}/* Free route map's compiled `set metric' value. */voidroute_set_metric_free (void *rule){ XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);}/* Set metric rule structure. */struct route_map_rule_cmd route_set_metric_cmd = { "metric", route_set_metric, route_set_metric_compile, route_set_metric_free,};/* `set as-path prepend ASPATH' *//* For AS path prepend mechanism. */route_map_result_troute_set_aspath_prepend (void *rule, struct prefix *prefix, route_map_object_t type, void *object){ struct aspath *aspath; struct aspath *new; struct bgp_info *binfo; if (type == RMAP_BGP) { aspath = rule; binfo = object; if (binfo->attr->aspath->refcnt) new = aspath_dup (binfo->attr->aspath); else new = binfo->attr->aspath; aspath_prepend (aspath, new); binfo->attr->aspath = new; } return RMAP_OKAY;}/* Compile function for as-path prepend. */void *route_set_aspath_prepend_compile (char *arg){ struct aspath *aspath; aspath = aspath_str2aspath (arg); if (! aspath) return NULL; return aspath;}/* Compile function for as-path prepend. */voidroute_set_aspath_prepend_free (void *rule){ struct aspath *aspath = rule; aspath_free (aspath);}/* Set metric rule structure. */struct route_map_rule_cmd route_set_aspath_prepend_cmd = { "as-path prepend", route_set_aspath_prepend, route_set_aspath_prepend_compile, route_set_aspath_prepend_free,};/* `set community COMMUNITY' */struct rmap_com_set{ struct community *com; int additive;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -