📄 bgp_routemap.c
字号:
"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_int32_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_int32_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_int32_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; int none;};/* For community set mechanism. */route_map_result_troute_set_community (void *rule, struct prefix *prefix, route_map_object_t type, void *object){ struct rmap_com_set *rcs; struct bgp_info *binfo; struct attr *attr; struct community *new = NULL; struct community *old; struct community *merge; if (type == RMAP_BGP) { rcs = rule; binfo = object; attr = binfo->attr; old = attr->community; /* "none" case. */ if (rcs->none) { attr->flag &= ~(ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES)); attr->community = NULL; return RMAP_OKAY; } /* "additive" case. */ if (rcs->additive && old) { merge = community_merge (community_dup (old), rcs->com); new = community_uniq_sort (merge); community_free (merge); } else new = community_dup (rcs->com); attr->community = new; attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES); } return RMAP_OKAY;}/* Compile function for set community. */void *route_set_community_compile (char *arg){ struct rmap_com_set *rcs; struct community *com = NULL; char *sp; int additive = 0; int none = 0; if (strcmp (arg, "none") == 0) none = 1; else { sp = strstr (arg, "additive"); if (sp && sp > arg) { /* "additive" keyworkd is included. */ additive = 1; *(sp - 1) = '\0'; } com = community_str2com (arg); if (additive) *(sp - 1) = ' '; if (! com) return NULL; } rcs = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct rmap_com_set)); memset (rcs, 0, sizeof (struct rmap_com_set)); rcs->com = com; rcs->additive = additive; rcs->none = none; return rcs;}/* Free function for set community. */voidroute_set_community_free (void *rule){ struct rmap_com_set *rcs = rule; if (rcs->com) community_free (rcs->com); XFREE (MTYPE_ROUTE_MAP_COMPILED, rcs);}/* Set community rule structure. */struct route_map_rule_cmd route_set_community_cmd = { "community", route_set_community, route_set_community_compile, route_set_community_free,};/* `set comm-list (<1-99>|<100-199>|WORD) delete' *//* For community set mechanism. */route_map_result_troute_set_community_delete (void *rule, struct prefix *prefix, route_map_object_t type, void *object)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -