diff options
-rw-r--r-- | bgpd/ChangeLog | 5 | ||||
-rw-r--r-- | bgpd/bgp_route.c | 11 | ||||
-rw-r--r-- | bgpd/bgp_routemap.c | 95 | ||||
-rw-r--r-- | bgpd/bgpd.h | 9 |
4 files changed, 97 insertions, 23 deletions
diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index 958a1766..c97dbcef 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -1,3 +1,8 @@ +2003-08-11 kunihiro <kunihiro@zebra.org + + * bgp_route{,map}.c: Extend 'set ip next-hop' in route-maps with + ability to specify 'peer-address' rather than IP. + 2003-06-09 Paul Jakma <paul@dishone.st> * bgp_clist.c (community_list_delete): honour deny statements diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 8ca1ac8a..bb6b1b18 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -437,8 +437,13 @@ bgp_input_modifier (struct peer *peer, struct prefix *p, struct attr *attr, info.peer = peer; info.attr = attr; + SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_IN); + /* Apply BGP route map to the attribute. */ ret = route_map_apply (ROUTE_MAP_IN (filter), p, RMAP_BGP, &info); + + peer->rmap_type = 0; + if (ret == RMAP_DENYMATCH) { /* Free newly generated AS path and community by route-map. */ @@ -702,12 +707,16 @@ bgp_announce_check (struct bgp_info *ri, struct peer *peer, struct prefix *p, dummy_attr = *attr; info.attr = &dummy_attr; } - + + SET_FLAG (peer->rmap_type, PEER_RMAP_TYPE_OUT); + if (ri->suppress) ret = route_map_apply (UNSUPPRESS_MAP (filter), p, RMAP_BGP, &info); else ret = route_map_apply (ROUTE_MAP_OUT (filter), p, RMAP_BGP, &info); + peer->rmap_type = 0; + if (ret == RMAP_DENYMATCH) { bgp_attr_flush (attr); diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 5cfb5c8c..9bc4e6d5 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -622,22 +622,51 @@ struct route_map_rule_cmd route_match_origin_cmd = /* `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_t route_set_ip_nexthop (void *rule, struct prefix *prefix, route_map_object_t type, void *object) { - struct in_addr *address; + struct rmap_ip_nexthop_set *rins = rule; + struct in_addr peer_address; struct bgp_info *bgp_info; + struct peer *peer; if (type == RMAP_BGP) { - /* Fetch routemap's rule information. */ - address = rule; bgp_info = object; - - /* Set next hop value. */ - bgp_info->attr->flag |= ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP); - bgp_info->attr->nexthop = *address; + 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; @@ -648,27 +677,44 @@ route_set_ip_nexthop (void *rule, struct prefix *prefix, 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; - struct in_addr *address; - address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr)); - - ret = inet_aton (arg, address); - - if (ret == 0) + if (strcmp (arg, "peer-address") == 0) + peer_address = 1; + else { - XFREE (MTYPE_ROUTE_MAP_COMPILED, address); - return NULL; + 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; + } } - return address; + 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. */ void route_set_ip_nexthop_free (void *rule) { - XFREE (MTYPE_ROUTE_MAP_COMPILED, 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. */ @@ -2369,15 +2415,19 @@ ALIAS (no_match_origin, DEFUN (set_ip_nexthop, set_ip_nexthop_cmd, - "set ip next-hop A.B.C.D", + "set ip next-hop (A.B.C.D|peer-address)", SET_STR IP_STR "Next hop address\n" - "IP address of next hop\n") + "IP address of next hop\n" + "Use peer address (for BGP only)\n") { union sockunion su; int ret; + if (strncmp (argv[0], "peer-address", 1) == 0) + return bgp_route_set_add (vty, vty->index, "ip next-hop", "peer-address"); + ret = str2sockunion (argv[0], &su); if (ret < 0) { @@ -2396,7 +2446,7 @@ DEFUN (no_set_ip_nexthop, IP_STR "Next hop address\n") { - if (argc == 0) + if (argc == 0 || strncmp (argv[0], "peer-address", 1) == 0) return bgp_route_set_delete (vty, vty->index, "ip next-hop", NULL); return bgp_route_set_delete (vty, vty->index, "ip next-hop", argv[0]); @@ -2404,12 +2454,13 @@ DEFUN (no_set_ip_nexthop, ALIAS (no_set_ip_nexthop, no_set_ip_nexthop_val_cmd, - "no set ip next-hop A.B.C.D", + "no set ip next-hop (A.B.C.D|peer-address)", NO_STR SET_STR IP_STR "Next hop address\n" - "IP address of next hop\n") + "IP address of next hop\n" + "Use peer address (for BGP only)\n") DEFUN (set_metric, set_metric_cmd, diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 933516d0..11c6bdec 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -430,6 +430,15 @@ struct peer /* allowas-in. */ char allowas_in[AFI_MAX][SAFI_MAX]; + + /* The kind of route-map Flags.*/ + u_char rmap_type; +#define PEER_RMAP_TYPE_IN (1 << 0) /* neighbor route-map in */ +#define PEER_RMAP_TYPE_OUT (1 << 1) /* neighbor route-map out */ +#define PEER_RMAP_TYPE_NETWORK (1 << 2) /* network route-map */ +#define PEER_RMAP_TYPE_REDISTRIBUTE (1 << 3) /* redistribute route-map */ +#define PEER_RMAP_TYPE_DEFAULT (1 << 4) /* default-originate route-map */ +#define PEER_RMAP_TYPE_NOSET (1 << 5) /* not allow to set commands */ }; /* This structure's member directly points incoming packet data |