diff -Naur quagga-0.98.3/ChangeLog quagga-0.98.3-realms/ChangeLog --- quagga-0.98.3/ChangeLog 2005-04-01 13:22:43.000000000 +0300 +++ quagga-0.98.3-realms/ChangeLog 2005-04-25 00:15:22.000000000 +0300 @@ -1,3 +1,10 @@ +2005-04-24 Calin Velea + * configure.ac: Modified to include realms --enable-realms which + uses the realms patch to add suport for route realms under Linux. + This patch is an enhanced version of Arcady Stepanov's original + realms patch for zebra-0.93b. It adds route-map and neighbor default + realm setting in bgpd and static route realm setting in zebra + 2005-04-01 Hasso Tepper * configure.ac: Bump version to 0.98.3. diff -Naur quagga-0.98.3/bgpd/ChangeLog quagga-0.98.3-realms/bgpd/ChangeLog --- quagga-0.98.3/bgpd/ChangeLog 2005-03-21 12:34:37.000000000 +0200 +++ quagga-0.98.3-realms/bgpd/ChangeLog 2005-04-25 00:15:43.000000000 +0300 @@ -1,3 +1,15 @@ +2005-04-24 Calin Velea + * bgp_attr.c: Modified attrhash_cmp and attrhash_key_make to use realms + * bgp_attr.h: Added realm attribute to attr struct + * bgp_route.c: Changed bgp_input_modifier and bgp_import_modifier + to apply default realm to routes + * bgp_routemap.c: Added realm route map commands + * bgp_vty.c: Added neighbor realm commands + * bgp_zebra.c: Added API realm message + * bgpd.c: Added functions to set default peer realm + * bgpd.h: Added flag for peer default realm, peer default realm + functions prototypes + 2005-03-21 Hasso Tepper * bgp_route.c: Don't crash while clearing route tables if there is diff -Naur quagga-0.98.3/bgpd/bgp_attr.c quagga-0.98.3-realms/bgpd/bgp_attr.c --- quagga-0.98.3/bgpd/bgp_attr.c 2004-12-09 16:46:46.000000000 +0200 +++ quagga-0.98.3-realms/bgpd/bgp_attr.c 2005-04-23 20:20:22.000000000 +0300 @@ -58,7 +58,7 @@ { BGP_ATTR_MP_UNREACH_NLRI, "MP_UNREACH_NLRI" }, { 0, NULL } }; - + struct hash *cluster_hash; void * @@ -192,7 +192,7 @@ { cluster_hash = hash_create (cluster_hash_key_make, cluster_hash_cmp); } - + /* Unknown transit attribute. */ struct hash *transit_hash; @@ -287,6 +287,11 @@ key += attr->aggregator_addr.s_addr; key += attr->weight; +#ifdef SUPPORT_REALMS + key += attr->realmto; +#endif + + key += attr->mp_nexthop_global_in.s_addr; if (attr->aspath) key += aspath_key_make (attr->aspath); @@ -325,6 +330,11 @@ && attr1->aggregator_as == attr2->aggregator_as && attr1->aggregator_addr.s_addr == attr2->aggregator_addr.s_addr && attr1->weight == attr2->weight + +#ifdef SUPPORT_REALMS + && attr1->realmto == attr2->realmto +#endif + #ifdef HAVE_IPV6 && attr1->mp_nexthop_len == attr2->mp_nexthop_len && IPV6_ADDR_SAME (&attr1->mp_nexthop_global, &attr2->mp_nexthop_global) diff -Naur quagga-0.98.3/bgpd/bgp_attr.h quagga-0.98.3-realms/bgpd/bgp_attr.h --- quagga-0.98.3/bgpd/bgp_attr.h 2004-06-04 20:58:18.000000000 +0300 +++ quagga-0.98.3-realms/bgpd/bgp_attr.h 2005-04-21 21:39:43.000000000 +0300 @@ -81,6 +81,13 @@ /* Unknown transitive attribute. */ struct transit *transit; + + +#ifdef SUPPORT_REALMS + /* Realm used */ + u_int16_t realmto; +#endif + }; /* Router Reflector related structure. */ diff -Naur quagga-0.98.3/bgpd/bgp_route.c quagga-0.98.3-realms/bgpd/bgp_route.c --- quagga-0.98.3/bgpd/bgp_route.c 2005-03-21 12:34:37.000000000 +0200 +++ quagga-0.98.3-realms/bgpd/bgp_route.c 2005-04-23 22:14:09.000000000 +0300 @@ -413,7 +413,28 @@ } return 0; } - + +#ifdef SUPPORT_REALMS + +#define REALM_PEER_AS 0xFFFFA +#define REALM_ORIGIN_AS 0xFFFFB + +/* Attr. Flags and Attr. Type Code. */ +#define AS_HEADER_SIZE 2 + +/* Two octet is used for AS value. */ +#define AS_VALUE_SIZE sizeof (as_t) + +/* To fetch and store as segment value. */ +struct assegment +{ + u_char type; + u_char length; + as_t asval[1]; +}; + +#endif + int bgp_input_modifier (struct peer *peer, struct prefix *p, struct attr *attr, afi_t afi, safi_t safi) @@ -422,6 +443,50 @@ struct bgp_info info; route_map_result_t ret; +#ifdef SUPPORT_REALMS + + u_int16_t realm_value = 0; + struct aspath *aspath; + + caddr_t pnt; + caddr_t end; + struct assegment *assegment; + + + /* Apply default realm value. */ + aspath = attr->aspath; + + if (peer->realm == REALM_PEER_AS) + { + if (aspath == NULL || aspath->length == 0) + return RMAP_PERMIT; + + pnt = aspath->data; + assegment = (struct assegment *) pnt; + realm_value = ntohs (assegment->asval[0]); + + } + else if (peer->realm == REALM_ORIGIN_AS) + { + if (aspath == NULL || aspath->length == 0) + return RMAP_PERMIT; + + pnt = aspath->data; + end = aspath->data + aspath->length; + + while (pnt < end) + { + assegment = (struct assegment *) pnt; + realm_value = ntohs (assegment->asval[assegment->length - 1]); + pnt += (assegment->length * AS_VALUE_SIZE) + AS_HEADER_SIZE; + } + } + else realm_value = (u_int16_t)(peer->realm & 0xFFFF); + + attr->realmto = realm_value; + +#endif + filter = &peer->filter[afi][safi]; /* Apply default weight value. */ @@ -450,7 +515,7 @@ } return RMAP_PERMIT; } - + int bgp_export_modifier (struct peer *rsclient, struct peer *peer, struct prefix *p, struct attr *attr, afi_t afi, safi_t safi) @@ -493,6 +558,51 @@ struct bgp_info info; route_map_result_t ret; +#ifdef SUPPORT_REALMS + + u_int16_t realm_value = 0; + struct aspath *aspath; + + caddr_t pnt; + caddr_t end; + struct assegment *assegment; + + + /* Apply default realm value. */ + aspath = attr->aspath; + + if (peer->realm == REALM_PEER_AS) + { + if (aspath == NULL || aspath->length == 0) + return RMAP_PERMIT; + + pnt = aspath->data; + assegment = (struct assegment *) pnt; + realm_value = ntohs (assegment->asval[0]); + + } + else if (peer->realm == REALM_ORIGIN_AS) + { + if (aspath == NULL || aspath->length == 0) + return RMAP_PERMIT; + + pnt = aspath->data; + end = aspath->data + aspath->length; + + while (pnt < end) + { + assegment = (struct assegment *) pnt; + realm_value = ntohs (assegment->asval[assegment->length - 1]); + pnt += (assegment->length * AS_VALUE_SIZE) + AS_HEADER_SIZE; + } + } + else realm_value = (u_int16_t)(peer->realm & 0xFFFF); + + attr->realmto = realm_value; + +#endif + + filter = &rsclient->filter[afi][safi]; /* Apply default weight value. */ @@ -4768,6 +4878,11 @@ vty_out (vty, "%7u ",attr->weight); +#ifdef SUPPORT_REALMS + vty_out (vty, "%7u ", attr->realmto); +#endif + + /* Print aspath */ if (attr->aspath) aspath_print_vty (vty, attr->aspath); @@ -5188,6 +5303,13 @@ if (CHECK_FLAG (binfo->flags, BGP_INFO_SELECTED)) vty_out (vty, ", best"); +#ifdef SUPPORT_REALMS + if (attr->realmto) { + char realmbuf[64]; + vty_out (vty, ", realm %s", rtnl_rtrealm_n2a (attr->realmto, realmbuf, sizeof (realmbuf))); + } +#endif + vty_out (vty, "%s", VTY_NEWLINE); /* Line 4 display Community */ @@ -5225,8 +5347,14 @@ } vty_out (vty, "%s", VTY_NEWLINE); } - + + +#ifdef SUPPORT_REALMS + #define BGP_SHOW_HEADER " Network Next Hop Metric LocPrf Weight Realm Path%s" +#else #define BGP_SHOW_HEADER " Network Next Hop Metric LocPrf Weight Path%s" +#endif + #define BGP_SHOW_DAMP_HEADER " Network From Reuse Path%s" #define BGP_SHOW_FLAP_HEADER " Network From Flaps Duration Reuse Path%s" diff -Naur quagga-0.98.3/bgpd/bgp_routemap.c quagga-0.98.3-realms/bgpd/bgp_routemap.c --- quagga-0.98.3/bgpd/bgp_routemap.c 2004-10-13 08:06:09.000000000 +0300 +++ quagga-0.98.3-realms/bgpd/bgp_routemap.c 2005-04-23 21:56:14.000000000 +0300 @@ -1054,6 +1054,123 @@ route_set_metric_compile, route_set_metric_free, }; + +#ifdef SUPPORT_REALMS +/* `set realm REALM' */ + +#define REALM_PEER_AS 0xFFFFA +#define REALM_ORIGIN_AS 0xFFFFB + +/* Attr. Flags and Attr. Type Code. */ +#define AS_HEADER_SIZE 2 + +/* Two octet is used for AS value. */ +#define AS_VALUE_SIZE sizeof (as_t) + +/* To fetch and store as segment value. */ +struct assegment +{ + u_char type; + u_char length; + as_t asval[1]; +}; + +route_map_result_t +route_set_realm (void *rule, struct prefix *prefix, + route_map_object_t type, void *object) +{ + u_int32_t *realm; + u_int16_t realm_value = 0; + struct bgp_info *bgp_info; + struct aspath *aspath; + + caddr_t pnt; + caddr_t end; + struct assegment *assegment; + + if(type != RMAP_BGP) + return RMAP_OKAY; + + bgp_info = object; + aspath = bgp_info->attr->aspath; + realm = (u_int32_t*) rule; + + if (*realm == REALM_PEER_AS) + { + if (aspath == NULL || aspath->length == 0) + return RMAP_OKAY; + + pnt = aspath->data; + assegment = (struct assegment *) pnt; + realm_value = ntohs (assegment->asval[0]); + + } + else if (*realm == REALM_ORIGIN_AS) + { + if (aspath == NULL || aspath->length == 0) + return RMAP_OKAY; + + pnt = aspath->data; + end = aspath->data + aspath->length; + + while (pnt < end) + { + assegment = (struct assegment *) pnt; + realm_value = ntohs (assegment->asval[assegment->length - 1]); + pnt += (assegment->length * AS_VALUE_SIZE) + AS_HEADER_SIZE; + } + } + else realm_value = (u_int16_t)(*realm & 0xFFFF); + + bgp_info->attr->realmto = realm_value; + + return RMAP_OKAY; +} + +/* + * set realm REALM - to set 'to' realm of route + */ +void * +route_set_realm_compile (char *arg) +{ + u_int32_t *realm; + u_int32_t realmid; + + if (strcmp(arg, "peer-as") == 0) + { + realmid = REALM_PEER_AS; + } + else if (strcmp(arg, "origin-as") == 0) + { + realmid = REALM_ORIGIN_AS; + } + else if (rtnl_rtrealm_a2n (&realmid, arg) < 0) + { + return NULL; + } + + realm = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)); + *realm = (u_int32_t)realmid; + + return realm; +} + +void +route_set_realm_free (void *rule) +{ + XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +} + +/* Set realms rule structure. */ +struct route_map_rule_cmd route_set_realm_cmd = +{ + "realm", + route_set_realm, + route_set_realm_compile, + route_set_realm_free, +}; +#endif + /* `set as-path prepend ASPATH' */ @@ -2682,6 +2799,59 @@ "Metric value for destination routing protocol\n" "Metric value\n") +#ifdef SUPPORT_REALMS +DEFUN (set_realm, + set_realm_cmd, + "set realm (<1-255>|WORD)", + SET_STR + "Set realm id or name for Linux FIB routes\n" + "Realm id for Linux FIB routes\n" + "Realm name for Linux FIB routes\n") +{ + return bgp_route_set_add (vty, vty->index, "realm", argv[0]); +} + +ALIAS (set_realm, + set_realm_origin_peer_cmd, + "set realm (origin-as|peer-as)", + MATCH_STR + "Set realm for Linux FIB routes\n" + "Use route origin AS as realm id\n" + "Use route peer AS as realm id\n") + +DEFUN (no_set_realm, + no_set_realm_cmd, + "no set realm", + NO_STR + SET_STR + "Realm value(s) for Linux FIB routes\n") +{ + if (argc == 0) + return bgp_route_set_delete (vty, vty->index, "realm", NULL); + + return bgp_route_set_delete (vty, vty->index, "realm", argv[0]); +} + +ALIAS (no_set_realm, + no_set_realm_val_cmd, + "no set realm (<0-255>|WORD)", + NO_STR + SET_STR + "Realm value(s) for Linux FIB routes\n" + "Realm value\n" + "Realm name\n") + +ALIAS (no_set_realm, + no_set_realm_origin_peer_cmd, + "no set realm (origin-as|peer-as)", + NO_STR + SET_STR + "Realm value(s) for Linux FIB routes\n" + "Origin AS - realm\n" + "Peer AS - realm\n") + +#endif + DEFUN (set_local_pref, set_local_pref_cmd, "set local-preference <0-4294967295>", @@ -3407,6 +3577,10 @@ route_map_install_set (&route_set_local_pref_cmd); route_map_install_set (&route_set_weight_cmd); route_map_install_set (&route_set_metric_cmd); +#ifdef SUPPORT_REALMS + route_map_install_set (&route_set_realm_cmd); + +#endif route_map_install_set (&route_set_aspath_prepend_cmd); route_map_install_set (&route_set_origin_cmd); route_map_install_set (&route_set_atomic_aggregate_cmd); @@ -3469,6 +3643,13 @@ install_element (RMAP_NODE, &set_metric_addsub_cmd); install_element (RMAP_NODE, &no_set_metric_cmd); install_element (RMAP_NODE, &no_set_metric_val_cmd); +#ifdef SUPPORT_REALMS + install_element (RMAP_NODE, &set_realm_cmd); + install_element (RMAP_NODE, &set_realm_origin_peer_cmd); + install_element (RMAP_NODE, &no_set_realm_cmd); + install_element (RMAP_NODE, &no_set_realm_val_cmd); + install_element (RMAP_NODE, &no_set_realm_origin_peer_cmd); +#endif install_element (RMAP_NODE, &set_aspath_prepend_cmd); install_element (RMAP_NODE, &no_set_aspath_prepend_cmd); install_element (RMAP_NODE, &no_set_aspath_prepend_val_cmd); diff -Naur quagga-0.98.3/bgpd/bgp_vty.c quagga-0.98.3-realms/bgpd/bgp_vty.c --- quagga-0.98.3/bgpd/bgp_vty.c 2004-10-13 08:06:09.000000000 +0300 +++ quagga-0.98.3-realms/bgpd/bgp_vty.c 2005-04-24 23:01:31.000000000 +0300 @@ -2812,7 +2812,7 @@ NEIGHBOR_ADDR_STR "Neighbor's BGP port\n" "TCP port number\n") - + /* neighbor weight. */ int peer_weight_set_vty (struct vty *vty, const char *ip_str, @@ -2877,7 +2877,114 @@ NEIGHBOR_ADDR_STR2 "Set default weight for routes from this neighbor\n" "default weight\n") - + +#ifdef SUPPORT_REALMS + +#define REALM_PEER_AS 0xFFFFA +#define REALM_ORIGIN_AS 0xFFFFB + +/* neighbor realm.*/ +int +peer_realm_set_vty (struct vty *vty, const char *ip_str, + const char *realm_str) +{ + struct peer *peer; + u_int32_t realmid; + + if (strcmp(realm_str, "peer-as") == 0) + { + realmid = REALM_PEER_AS; + } + else if (strcmp(realm_str, "origin-as") == 0) + { + realmid = REALM_ORIGIN_AS; + } + else + { + if (rtnl_rtrealm_a2n (&realmid, realm_str) < 0) + { + vty_out (vty, "%% Invalid realm value%s", VTY_NEWLINE); + return CMD_WARNING; + } + } + + + peer = peer_and_group_lookup_vty (vty, ip_str); + if (! peer) + return CMD_WARNING; + + peer_realm_set (peer, realmid); + + return CMD_SUCCESS; +} + +int +peer_realm_unset_vty (struct vty *vty, const char *ip_str) +{ + struct peer *peer; + + peer = peer_and_group_lookup_vty (vty, ip_str); + if (! peer) + return CMD_WARNING; + + peer_realm_unset (peer); + + return CMD_SUCCESS; +} + +DEFUN (neighbor_realm, + neighbor_realm_cmd, + NEIGHBOR_CMD2 "realm (<0-255>|WORD)", + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Set default realm for routes from this neighbor\n" + "default realm id\n" + "default realm name\n") +{ + return peer_realm_set_vty (vty, argv[0], argv[1]); +} + +ALIAS (neighbor_realm, + neighbor_realm_origin_peer_cmd, + NEIGHBOR_CMD2 "realm (origin-as|peer-as)", + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Set default realm for routes from this neighbor\n" + "Set default realm to received route origin AS\n" + "Set default realm to peer AS") + +DEFUN (no_neighbor_realm, + no_neighbor_realm_cmd, + NO_NEIGHBOR_CMD2 "realm", + NO_STR + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Set default realm for routes from this neighbor\n") +{ + return peer_realm_unset_vty (vty, argv[0]); +} + +ALIAS (no_neighbor_realm, + no_neighbor_realm_val_cmd, + NO_NEIGHBOR_CMD2 "realm (<0-255>|WORD)", + NO_STR + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Set default realm for routes from this neighbor\n" + "default realm id\n" + "default realm name\n") + +ALIAS (no_neighbor_realm, + no_neighbor_realm_origin_peer_cmd, + NO_NEIGHBOR_CMD2 "realm (origin-as|peer-as)", + NO_STR + NEIGHBOR_STR + NEIGHBOR_ADDR_STR2 + "Set default realm for routes from this neighbor\n" + "Set default realm to received route origin AS\n" + "Set default realm to peer AS") +#endif + /* Override capability negotiation. */ DEFUN (neighbor_override_capability, neighbor_override_capability_cmd, @@ -7083,6 +7190,27 @@ vty_out (vty, "%s", VTY_NEWLINE); +#ifdef SUPPORT_REALMS + + /* Default realm */ + if (CHECK_FLAG (p->config, PEER_CONFIG_REALM)) + { + char realmbuf[64]; + if (p->realm == REALM_PEER_AS) + vty_out (vty, " Default realm is peer-as%s", + VTY_NEWLINE); + else if (p->realm == REALM_ORIGIN_AS) + vty_out (vty, " Default realm is origin-as%s", + VTY_NEWLINE); + else vty_out (vty, " Default realm is %s%s", + rtnl_rtrealm_n2a (p->realm, realmbuf, sizeof (realmbuf)), VTY_NEWLINE); + } + + vty_out (vty, "%s", VTY_NEWLINE); + + +#endif + /* Address Family Information */ for (afi = AFI_IP ; afi < AFI_MAX ; afi++) for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++) @@ -8839,6 +8967,17 @@ install_element (BGP_NODE, &no_neighbor_weight_cmd); install_element (BGP_NODE, &no_neighbor_weight_val_cmd); +#ifdef SUPPORT_REALMS + + /* "neighbor realm" commands. */ + install_element (BGP_NODE, &neighbor_realm_cmd); + install_element (BGP_NODE, &neighbor_realm_origin_peer_cmd); + install_element (BGP_NODE, &no_neighbor_realm_cmd); + install_element (BGP_NODE, &no_neighbor_realm_origin_peer_cmd); + install_element (BGP_NODE, &no_neighbor_realm_val_cmd); + +#endif + /* "neighbor override-capability" commands. */ install_element (BGP_NODE, &neighbor_override_capability_cmd); install_element (BGP_NODE, &no_neighbor_override_capability_cmd); diff -Naur quagga-0.98.3/bgpd/bgp_zebra.c quagga-0.98.3-realms/bgpd/bgp_zebra.c --- quagga-0.98.3/bgpd/bgp_zebra.c 2004-10-13 08:06:09.000000000 +0300 +++ quagga-0.98.3-realms/bgpd/bgp_zebra.c 2005-04-21 21:39:44.000000000 +0300 @@ -662,6 +662,15 @@ SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE); api.distance = distance; } + +#ifdef SUPPORT_REALMS + if (info->attr->realmto) + { + SET_FLAG (api.message, ZAPI_MESSAGE_REALMTO); + api.realmto = info->attr->realmto; + } +#endif + zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, (struct prefix_ipv4 *) p, &api); } diff -Naur quagga-0.98.3/bgpd/bgpd.c quagga-0.98.3-realms/bgpd/bgpd.c --- quagga-0.98.3/bgpd/bgpd.c 2004-12-09 16:46:46.000000000 +0200 +++ quagga-0.98.3-realms/bgpd/bgpd.c 2005-04-23 23:08:55.000000000 +0300 @@ -632,6 +632,10 @@ peer->keepalive = 0; peer->connect = 0; peer->v_connect = BGP_DEFAULT_CONNECT_RETRY; + +#ifdef SUPPORT_REALMS + peer->realm = 0; +#endif } /* Check peer's AS number and determin is this peer IBGP or EBGP */ @@ -708,6 +712,10 @@ peer->version = BGP_VERSION_4; peer->weight = 0; +#ifdef SUPPORT_REALMS + peer->realm = 0; +#endif + /* Set default flags. */ for (afi = AFI_IP; afi < AFI_MAX; afi++) for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) @@ -1271,6 +1279,13 @@ /* Weight */ peer->weight = conf->weight; +#ifdef CONFIG_REALMS + + /* Realm */ + peer->realm = conf->realm; + +#endif + /* peer flags apply */ peer->flags = conf->flags; /* peer af_flags apply */ @@ -2872,7 +2887,7 @@ peer->port = BGP_PORT_DEFAULT; return 0; } - + /* neighbor weight. */ int peer_weight_set (struct peer *peer, u_int16_t weight) @@ -2920,7 +2935,60 @@ } return 0; } - + +#ifdef SUPPORT_REALMS + +/* neighbor realm. */ +int +peer_realm_set (struct peer *peer, u_int32_t realm) +{ + struct peer_group *group; + struct listnode *nn; + + SET_FLAG (peer->config, PEER_CONFIG_REALM); + peer->realm = realm; + + if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) + return 0; + + /* peer-group member updates. */ + group = peer->group; + LIST_LOOP (group->peer, peer, nn) + { + peer->realm = group->conf->realm; + } + return 0; +} + +int +peer_realm_unset (struct peer *peer) +{ + struct peer_group *group; + struct listnode *nn; + + /* Set default realm. */ + if (peer_group_active (peer)) + peer->realm = peer->group->conf->realm; + else + peer->realm = 0; + + UNSET_FLAG (peer->config, PEER_CONFIG_REALM); + + if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) + return 0; + + /* peer-group member updates. */ + group = peer->group; + LIST_LOOP (group->peer, peer, nn) + { + peer->realm = 0; + } + return 0; +} + + +#endif + int peer_timers_set (struct peer *peer, u_int32_t keepalive, u_int32_t holdtime) { @@ -4356,6 +4424,28 @@ vty_out (vty, " neighbor %s weight %d%s", addr, peer->weight, VTY_NEWLINE); +#ifdef SUPPORT_REALMS + +#define REALM_PEER_AS 0xFFFFA +#define REALM_ORIGIN_AS 0xFFFFB + + /* Default realm. */ + if (CHECK_FLAG (peer->config, PEER_CONFIG_REALM)) + if (! peer_group_active (peer) || + g_peer->realm != peer->realm) + { + char realmbuf[64]; + if (peer->realm == REALM_PEER_AS) + vty_out (vty, " neighbor %s realm peer-as%s", addr, + VTY_NEWLINE); + else if (peer->realm == REALM_ORIGIN_AS) + vty_out (vty, " neighbor %s realm origin-as%s", addr, + VTY_NEWLINE); + else vty_out (vty, " neighbor %s realm %s%s", addr, + rtnl_rtrealm_n2a (peer->realm, realmbuf, sizeof (realmbuf)), VTY_NEWLINE); + } +#endif + /* Route refresh. */ if (CHECK_FLAG (peer->flags, PEER_FLAG_NO_ROUTE_REFRESH_CAP)) if (! peer_group_active (peer) || diff -Naur quagga-0.98.3/bgpd/bgpd.h quagga-0.98.3-realms/bgpd/bgpd.h --- quagga-0.98.3/bgpd/bgpd.h 2004-10-13 08:06:09.000000000 +0300 +++ quagga-0.98.3-realms/bgpd/bgpd.h 2005-04-23 21:44:33.000000000 +0300 @@ -392,6 +392,11 @@ u_int32_t connect; u_int32_t routeadv; +#ifdef SUPPORT_REALMS +#define PEER_CONFIG_REALM (1 << 4) /* Default realm. */ + u_int32_t realm; +#endif + /* Timer values. */ u_int32_t v_start; u_int32_t v_connect; @@ -856,6 +861,11 @@ int peer_weight_set (struct peer *, u_int16_t); int peer_weight_unset (struct peer *); +#ifdef SUPPORT_REALMS +int peer_realm_set (struct peer *, u_int32_t); +int peer_realm_unset (struct peer *); +#endif + int peer_timers_set (struct peer *, u_int32_t, u_int32_t); int peer_timers_unset (struct peer *); diff -Naur quagga-0.98.3/config.h.in quagga-0.98.3-realms/config.h.in --- quagga-0.98.3/config.h.in 2005-04-01 14:44:53.000000000 +0300 +++ quagga-0.98.3-realms/config.h.in 2005-04-21 22:09:48.000000000 +0300 @@ -441,6 +441,9 @@ /* OSPFAPI */ #undef SUPPORT_OSPF_API +/* Realms support */ +#undef SUPPORT_REALMS + /* SNMP */ #undef UCD_COMPATIBLE diff -Naur quagga-0.98.3/configure quagga-0.98.3-realms/configure --- quagga-0.98.3/configure 2005-04-01 14:43:33.000000000 +0300 +++ quagga-0.98.3-realms/configure 2005-04-25 01:10:28.000000000 +0300 @@ -423,7 +423,7 @@ # Identity of this package. PACKAGE_NAME='Quagga' PACKAGE_TARNAME='quagga' -PACKAGE_VERSION='0.98.3' +PACKAGE_VERSION='0.98.3-realms' PACKAGE_STRING='Quagga 0.98.3' PACKAGE_BUGREPORT='http://bugzilla.quagga.net' @@ -1065,6 +1065,7 @@ --enable-vty-group=ARG set vty sockets to have specified group as owner --enable-configfile-mask=ARG set mask for config files --enable-logfile-mask=ARG set mask for log files + --enable-realms enable REALMS support under Linux --disable-rtadv disable IPV6 router advertisement feature --enable-irdp enable IRDP server support in zebra --disable-capabilities disable using POSIX capabilities @@ -1821,7 +1822,7 @@ # Define the identity of the package. PACKAGE='quagga' - VERSION='0.98.3' + VERSION='0.98.3-realms' cat >>confdefs.h <<_ACEOF @@ -19508,6 +19509,11 @@ fi; +# Check whether --enable-realms or --disable-realms was given. +if test "${enable_realms+set}" = set; then + enableval="$enable_realms" + +fi; # Check whether --enable-rtadv or --disable-rtadv was given. if test "${enable_rtadv+set}" = set; then enableval="$enable_rtadv" @@ -20974,6 +20980,19 @@ ;; esac +if test "${enable_realms}" = "yes"; then + if test "${opsys}" != "gnu-linux"; then + echo "Sorry, only Linux has REALMS support" + exit 1 + fi + +cat >>confdefs.h <<\_ACEOF +#define SUPPORT_REALMS +_ACEOF + +fi + + case "${enable_vtysh}" in "yes") VTYSH="vtysh"; diff -Naur quagga-0.98.3/configure.ac quagga-0.98.3-realms/configure.ac --- quagga-0.98.3/configure.ac 2005-04-25 01:23:08.000000000 +0300 +++ quagga-0.98.3-realms/configure.ac 2005-04-25 01:23:20.000000000 +0300 @@ -8,7 +8,7 @@ ## $Id: configure.ac,v 1.85.2.7 2005/04/01 10:25:48 hasso Exp $ AC_PREREQ(2.53) -AC_INIT(Quagga, 0.98.3, [http://bugzilla.quagga.net]) +AC_INIT(Quagga, 0.98.3-realms, [http://bugzilla.quagga.net]) AC_CONFIG_SRCDIR(lib/zebra.h) AM_INIT_AUTOMAKE(1.6) AM_CONFIG_HEADER(config.h) @@ -146,7 +146,8 @@ [ --enable-configfile-mask=ARG set mask for config files]) AC_ARG_ENABLE(logfile_mask, [ --enable-logfile-mask=ARG set mask for log files]) - +AC_ARG_ENABLE(realms, +[ --enable-realms enable REALMS support under Linux]) AC_ARG_ENABLE(rtadv, [ --disable-rtadv disable IPV6 router advertisement feature]) AC_ARG_ENABLE(irdp, @@ -322,6 +323,14 @@ ;; esac +if test "${enable_realms}" = "yes"; then + if test "${opsys}" != "gnu-linux"; then + echo "Sorry, only Linux has REALMS support" + exit 1 + fi + AC_DEFINE(SUPPORT_REALMS,, Realms support) +fi + dnl --------------------- dnl Integrated VTY option dnl --------------------- diff -Naur quagga-0.98.3/lib/ChangeLog quagga-0.98.3-realms/lib/ChangeLog --- quagga-0.98.3/lib/ChangeLog 2005-03-25 20:08:08.000000000 +0200 +++ quagga-0.98.3-realms/lib/ChangeLog 2005-04-25 00:50:53.000000000 +0300 @@ -1,3 +1,9 @@ +2005-04-24 Calin Velea + * rt_names.c, rt_names.h: Library for realm name support - original + iproute2 version modified to support name database reloading + * zclient.c, zclient.h: API realmto message + * zebra.h: Include rt_names.h + 2005-03-25 Andrew J. Schorr * zebra.h: Must check whether __attribute__ should be defined before diff -Naur quagga-0.98.3/lib/Makefile.am quagga-0.98.3-realms/lib/Makefile.am --- quagga-0.98.3/lib/Makefile.am 2004-11-26 21:36:42.000000000 +0200 +++ quagga-0.98.3-realms/lib/Makefile.am 2005-04-24 21:26:45.000000000 +0300 @@ -12,7 +12,7 @@ sockunion.c prefix.c thread.c if.c memory.c buffer.c table.c hash.c \ filter.c routemap.c distribute.c stream.c str.c log.c plist.c \ zclient.c sockopt.c smux.c md5.c if_rmap.c keychain.c privs.c \ - sigevent.c pqueue.c jhash.c + sigevent.c pqueue.c jhash.c rt_names.c libzebra_la_DEPENDENCIES = @LIB_REGEX@ @@ -23,7 +23,7 @@ memory.h network.h prefix.h routemap.h distribute.h sockunion.h \ str.h stream.h table.h thread.h vector.h version.h vty.h zebra.h \ plist.h zclient.h sockopt.h smux.h md5-gnu.h if_rmap.h keychain.h \ - privs.h sigevent.h pqueue.h jhash.h zassert.h + privs.h sigevent.h pqueue.h jhash.h zassert.h rt_names.h EXTRA_DIST = regex.c regex-gnu.h diff -Naur quagga-0.98.3/lib/Makefile.in quagga-0.98.3-realms/lib/Makefile.in --- quagga-0.98.3/lib/Makefile.in 2005-04-01 14:43:57.000000000 +0300 +++ quagga-0.98.3-realms/lib/Makefile.in 2005-04-24 21:26:13.000000000 +0300 @@ -171,7 +171,7 @@ sockunion.c prefix.c thread.c if.c memory.c buffer.c table.c hash.c \ filter.c routemap.c distribute.c stream.c str.c log.c plist.c \ zclient.c sockopt.c smux.c md5.c if_rmap.c keychain.c privs.c \ - sigevent.c pqueue.c jhash.c + sigevent.c pqueue.c jhash.c rt_names.c libzebra_la_DEPENDENCIES = @LIB_REGEX@ @@ -183,7 +183,7 @@ memory.h network.h prefix.h routemap.h distribute.h sockunion.h \ str.h stream.h table.h thread.h vector.h version.h vty.h zebra.h \ plist.h zclient.h sockopt.h smux.h md5-gnu.h if_rmap.h keychain.h \ - privs.h sigevent.h pqueue.h jhash.h zassert.h + privs.h sigevent.h pqueue.h jhash.h zassert.h rt_names.h EXTRA_DIST = regex.c regex-gnu.h @@ -199,7 +199,7 @@ sockunion.lo prefix.lo thread.lo if.lo memory.lo buffer.lo \ table.lo hash.lo filter.lo routemap.lo distribute.lo stream.lo \ str.lo log.lo plist.lo zclient.lo sockopt.lo smux.lo md5.lo \ - if_rmap.lo keychain.lo privs.lo sigevent.lo pqueue.lo jhash.lo + if_rmap.lo keychain.lo privs.lo sigevent.lo pqueue.lo jhash.lo rt_names.lo libzebra_la_OBJECTS = $(am_libzebra_la_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) @@ -218,6 +218,7 @@ @AMDEP_TRUE@ ./$(DEPDIR)/pqueue.Plo ./$(DEPDIR)/prefix.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/privs.Plo ./$(DEPDIR)/routemap.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/sigevent.Plo ./$(DEPDIR)/smux.Plo \ +@AMDEP_TRUE@ ./$(DEPDIR)/rt_names.Plo ./$(DEPDIR)/rt_names.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/sockopt.Plo ./$(DEPDIR)/sockunion.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/str.Plo ./$(DEPDIR)/stream.Plo \ @AMDEP_TRUE@ ./$(DEPDIR)/table.Plo ./$(DEPDIR)/thread.Plo \ @@ -310,6 +311,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/privs.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/routemap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sigevent.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rt_names.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/smux.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sockopt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sockunion.Plo@am__quote@ diff -Naur quagga-0.98.3/lib/rt_names.c quagga-0.98.3-realms/lib/rt_names.c --- quagga-0.98.3/lib/rt_names.c 1970-01-01 02:00:00.000000000 +0200 +++ quagga-0.98.3-realms/lib/rt_names.c 2005-04-25 00:21:11.000000000 +0300 @@ -0,0 +1,412 @@ +/* + * rt_names.c rtnetlink names DB. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Authors: Alexey Kuznetsov, + * + * Fix: 23 Apr 2005 Calin Velea + * + * bgpd-specific fixes + * + * - Modified rtnl_tab_initialize() function to free allocated entries + * before re-reading table; rtnl_rtrealm_initialize() to zero + * unused entries at first call + * - Modified rtnl_rtrealm_a2n() to read realm table each time; otherwise + * bgpd restart was necessary to be in sync with /etc/iproute2/rt_realms + * + */ + +#include +#include +#include +#include +#include +#include +#include + +static void rtnl_tab_initialize(char *file, char **tab, int size) +{ + int i; + char buf[512]; + FILE *fp; + + for(i = 1; i < 255; i++) + if(tab[i]) { + free(tab[i]); + tab[i] = NULL; + } + + + fp = fopen(file, "r"); + if (!fp) + return; + while (fgets(buf, sizeof(buf), fp)) { + char *p = buf; + int id; + char namebuf[512]; + + while (*p == ' ' || *p == '\t') + p++; + if (*p == '#' || *p == '\n' || *p == 0) + continue; + if (sscanf(p, "0x%x %s\n", &id, namebuf) != 2 && + sscanf(p, "0x%x %s #", &id, namebuf) != 2 && + sscanf(p, "%d %s\n", &id, namebuf) != 2 && + sscanf(p, "%d %s #", &id, namebuf) != 2) { + fprintf(stderr, "Database %s is corrupted at %s\n", + file, p); + return; + } + + if (id<0 || id>size) + continue; + + tab[id] = strdup(namebuf); + } + fclose(fp); +} + + +static char * rtnl_rtprot_tab[256] = { + "none", + "redirect", + "kernel", + "boot", + "static", + NULL, + NULL, + NULL, + "gated", + "ra", + "mrt", + "zebra", + "bird", +}; + + + +static int rtnl_rtprot_init; + +static void rtnl_rtprot_initialize(void) +{ + rtnl_rtprot_init = 1; + rtnl_tab_initialize("/etc/iproute2/rt_protos", + rtnl_rtprot_tab, 256); +} + +char * rtnl_rtprot_n2a(int id, char *buf, int len) +{ + if (id<0 || id>=256) { + snprintf(buf, len, "%d", id); + return buf; + } + if (!rtnl_rtprot_tab[id]) { + if (!rtnl_rtprot_init) + rtnl_rtprot_initialize(); + } + if (rtnl_rtprot_tab[id]) + return rtnl_rtprot_tab[id]; + snprintf(buf, len, "%d", id); + return buf; +} + +int rtnl_rtprot_a2n(u_int32_t *id, char *arg) +{ + static char *cache = NULL; + static unsigned long res; + char *end; + int i; + + if (cache && strcmp(cache, arg) == 0) { + *id = res; + return 0; + } + + if (!rtnl_rtprot_init) + rtnl_rtprot_initialize(); + + for (i=0; i<256; i++) { + if (rtnl_rtprot_tab[i] && + strcmp(rtnl_rtprot_tab[i], arg) == 0) { + cache = rtnl_rtprot_tab[i]; + res = i; + *id = res; + return 0; + } + } + + res = strtoul(arg, &end, 0); + if (!end || end == arg || *end || res > 255) + return -1; + *id = res; + return 0; +} + + + +static char * rtnl_rtscope_tab[256] = { + "global", +}; + +static int rtnl_rtscope_init; + +static void rtnl_rtscope_initialize(void) +{ + rtnl_rtscope_init = 1; + rtnl_rtscope_tab[255] = "nowhere"; + rtnl_rtscope_tab[254] = "host"; + rtnl_rtscope_tab[253] = "link"; + rtnl_rtscope_tab[200] = "site"; + rtnl_tab_initialize("/etc/iproute2/rt_scopes", + rtnl_rtscope_tab, 256); +} + +char * rtnl_rtscope_n2a(int id, char *buf, int len) +{ + if (id<0 || id>=256) { + snprintf(buf, len, "%d", id); + return buf; + } + if (!rtnl_rtscope_tab[id]) { + if (!rtnl_rtscope_init) + rtnl_rtscope_initialize(); + } + if (rtnl_rtscope_tab[id]) + return rtnl_rtscope_tab[id]; + snprintf(buf, len, "%d", id); + return buf; +} + +int rtnl_rtscope_a2n(u_int32_t *id, char *arg) +{ + static char *cache = NULL; + static unsigned long res; + char *end; + int i; + + if (cache && strcmp(cache, arg) == 0) { + *id = res; + return 0; + } + + if (!rtnl_rtscope_init) + rtnl_rtscope_initialize(); + + for (i=0; i<256; i++) { + if (rtnl_rtscope_tab[i] && + strcmp(rtnl_rtscope_tab[i], arg) == 0) { + cache = rtnl_rtscope_tab[i]; + res = i; + *id = res; + return 0; + } + } + + res = strtoul(arg, &end, 0); + if (!end || end == arg || *end || res > 255) + return -1; + *id = res; + return 0; +} + + + +static char * rtnl_rtrealm_tab[256] = { + "unknown", +}; + +static int rtnl_rtrealm_init = 0; + +static void rtnl_rtrealm_initialize(void) +{ + int i; + + if(!rtnl_rtrealm_init) + for(i = 1; i < 255; i++) + rtnl_rtrealm_tab[i] = NULL; + + rtnl_rtrealm_init = 1; + rtnl_tab_initialize("/etc/iproute2/rt_realms", + rtnl_rtrealm_tab, 256); +} + +char * rtnl_rtrealm_n2a(int id, char *buf, int len) +{ + if (id<0 || id>=256) { + snprintf(buf, len, "%d", id); + return buf; + } + if (!rtnl_rtrealm_tab[id]) { + if (!rtnl_rtrealm_init) + rtnl_rtrealm_initialize(); + } + if (rtnl_rtrealm_tab[id]) + return rtnl_rtrealm_tab[id]; + snprintf(buf, len, "%d", id); + return buf; +} + + +int rtnl_rtrealm_a2n(u_int32_t *id, char *arg) +{ + static char *cache = NULL; + static unsigned long cache_res; + unsigned long res; + char *end; + int i; + + if (cache && strcmp(cache, arg) == 0) { + *id = cache_res; + return 0; + } + rtnl_rtrealm_initialize(); + + for (i=0; i<256; i++) { + if (rtnl_rtrealm_tab[i] && + strcmp(rtnl_rtrealm_tab[i], arg) == 0) { + cache = rtnl_rtrealm_tab[i]; + cache_res = i; + *id = cache_res; + return 0; + } + } + + res = strtoul(arg, &end, 0); + if (!end || end == arg || *end || res > 255) + return -1; + *id = res; + return 0; +} + + + +static char * rtnl_rttable_tab[256] = { + "unspec", +}; + +static int rtnl_rttable_init; + +static void rtnl_rttable_initialize(void) +{ + rtnl_rttable_init = 1; + rtnl_rttable_tab[255] = "local"; + rtnl_rttable_tab[254] = "main"; + rtnl_tab_initialize("/etc/iproute2/rt_tables", + rtnl_rttable_tab, 256); +} + +char * rtnl_rttable_n2a(int id, char *buf, int len) +{ + if (id<0 || id>=256) { + snprintf(buf, len, "%d", id); + return buf; + } + if (!rtnl_rttable_tab[id]) { + if (!rtnl_rttable_init) + rtnl_rttable_initialize(); + } + if (rtnl_rttable_tab[id]) + return rtnl_rttable_tab[id]; + snprintf(buf, len, "%d", id); + return buf; +} + +int rtnl_rttable_a2n(u_int32_t *id, char *arg) +{ + static char *cache = NULL; + static unsigned long res; + char *end; + int i; + + if (cache && strcmp(cache, arg) == 0) { + *id = res; + return 0; + } + + if (!rtnl_rttable_init) + rtnl_rttable_initialize(); + + for (i=0; i<256; i++) { + if (rtnl_rttable_tab[i] && + strcmp(rtnl_rttable_tab[i], arg) == 0) { + cache = rtnl_rttable_tab[i]; + res = i; + *id = res; + return 0; + } + } + + i = strtoul(arg, &end, 0); + if (!end || end == arg || *end || i > 255) + return -1; + *id = i; + return 0; +} + + +static char * rtnl_rtdsfield_tab[256] = { + "0", +}; + +static int rtnl_rtdsfield_init; + +static void rtnl_rtdsfield_initialize(void) +{ + rtnl_rtdsfield_init = 1; + rtnl_tab_initialize("/etc/iproute2/rt_dsfield", + rtnl_rtdsfield_tab, 256); +} + +char * rtnl_dsfield_n2a(int id, char *buf, int len) +{ + if (id<0 || id>=256) { + snprintf(buf, len, "%d", id); + return buf; + } + if (!rtnl_rtdsfield_tab[id]) { + if (!rtnl_rtdsfield_init) + rtnl_rtdsfield_initialize(); + } + if (rtnl_rtdsfield_tab[id]) + return rtnl_rtdsfield_tab[id]; + snprintf(buf, len, "0x%02x", id); + return buf; +} + + +int rtnl_dsfield_a2n(u_int32_t *id, char *arg) +{ + static char *cache = NULL; + static unsigned long res; + char *end; + int i; + + if (cache && strcmp(cache, arg) == 0) { + *id = res; + return 0; + } + + if (!rtnl_rtdsfield_init) + rtnl_rtdsfield_initialize(); + + for (i=0; i<256; i++) { + if (rtnl_rtdsfield_tab[i] && + strcmp(rtnl_rtdsfield_tab[i], arg) == 0) { + cache = rtnl_rtdsfield_tab[i]; + res = i; + *id = res; + return 0; + } + } + + res = strtoul(arg, &end, 16); + if (!end || end == arg || *end || res > 255) + return -1; + *id = res; + return 0; +} + diff -Naur quagga-0.98.3/lib/rt_names.h quagga-0.98.3-realms/lib/rt_names.h --- quagga-0.98.3/lib/rt_names.h 1970-01-01 02:00:00.000000000 +0200 +++ quagga-0.98.3-realms/lib/rt_names.h 2005-04-23 19:21:15.000000000 +0300 @@ -0,0 +1,28 @@ +#ifndef RT_NAMES_H_ +#define RT_NAMES_H_ 1 + +const char* rtnl_rtprot_n2a(int id, char *buf, int len); +const char* rtnl_rtscope_n2a(int id, char *buf, int len); +const char* rtnl_rttable_n2a(int id, char *buf, int len); +const char* rtnl_rtrealm_n2a(int id, char *buf, int len); +const char* rtnl_dsfield_n2a(int id, char *buf, int len); +int rtnl_rtprot_a2n(int *id, char *arg); +int rtnl_rtscope_a2n(int *id, char *arg); +int rtnl_rttable_a2n(int *id, char *arg); +int rtnl_rtrealm_a2n(__u32 *id, char *arg); +int rtnl_dsfield_a2n(__u32 *id, char *arg); + +const char *inet_proto_n2a(int proto, char *buf, int len); +int inet_proto_a2n(char *buf); + + +const char * ll_type_n2a(int type, char *buf, int len); + +const char *ll_addr_n2a(unsigned char *addr, int alen, int type, char *buf, int blen); +int ll_addr_a2n(unsigned char *lladdr, int len, char *arg); + +const char * ll_proto_n2a(unsigned short id, char *buf, int len); +int ll_proto_a2n(unsigned short *id, char *buf); + + +#endif diff -Naur quagga-0.98.3/lib/version.h quagga-0.98.3-realms/lib/version.h --- quagga-0.98.3/lib/version.h 2005-04-01 14:44:18.000000000 +0300 +++ quagga-0.98.3-realms/lib/version.h 2005-04-25 00:50:38.000000000 +0300 @@ -26,7 +26,7 @@ #define QUAGGA_PROGNAME "Quagga" -#define QUAGGA_VERSION "0.98.3" +#define QUAGGA_VERSION "0.98.3-realms" #define ZEBRA_BUG_ADDRESS "http://bugzilla.quagga.net" diff -Naur quagga-0.98.3/lib/zclient.c quagga-0.98.3-realms/lib/zclient.c --- quagga-0.98.3/lib/zclient.c 2004-12-07 20:53:52.000000000 +0200 +++ quagga-0.98.3-realms/lib/zclient.c 2005-04-21 21:39:51.000000000 +0300 @@ -391,6 +391,11 @@ if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC)) stream_putl (s, api->metric); +#ifdef SUPPORT_REALMS + if (CHECK_FLAG (api->message, ZAPI_MESSAGE_REALMTO)) + stream_putw (s, api->realmto); +#endif + /* Put length at the first point of the stream. */ stream_putw_at (s, 0, stream_get_endp (s)); diff -Naur quagga-0.98.3/lib/zclient.h quagga-0.98.3-realms/lib/zclient.h --- quagga-0.98.3/lib/zclient.h 2004-10-06 00:01:24.000000000 +0300 +++ quagga-0.98.3-realms/lib/zclient.h 2005-04-21 21:39:51.000000000 +0300 @@ -81,6 +81,10 @@ #define ZAPI_MESSAGE_DISTANCE 0x04 #define ZAPI_MESSAGE_METRIC 0x08 +#ifdef SUPPORT_REALMS + #define ZAPI_MESSAGE_REALMTO 0x10 +#endif + /* Zebra IPv4 route message API. */ struct zapi_ipv4 { @@ -99,6 +103,11 @@ u_char distance; u_int32_t metric; + +#ifdef SUPPORT_REALMS + u_int16_t realmto; +#endif + }; /* Prototypes of zebra client service functions. */ diff -Naur quagga-0.98.3/lib/zebra.h quagga-0.98.3-realms/lib/zebra.h --- quagga-0.98.3/lib/zebra.h 2005-03-25 20:08:08.000000000 +0200 +++ quagga-0.98.3-realms/lib/zebra.h 2005-04-21 21:39:51.000000000 +0300 @@ -205,6 +205,10 @@ #include #endif /* HAVE_LIBUTIL_H */ +#ifdef SUPPORT_REALMS +#include +#endif + #ifdef HAVE_GLIBC_BACKTRACE #include #endif /* HAVE_GLIBC_BACKTRACE */ diff -Naur quagga-0.98.3/zebra/ChangeLog quagga-0.98.3-realms/zebra/ChangeLog --- quagga-0.98.3/zebra/ChangeLog 2005-04-01 12:25:51.000000000 +0300 +++ quagga-0.98.3-realms/zebra/ChangeLog 2005-04-25 00:18:15.000000000 +0300 @@ -1,3 +1,11 @@ +2005-04-24 Calin Velea + * rt_netlink.c: Modified netlink_route(), netlink_routing_table(), + netlink_route_change() to use realms when working with kernel + table + * zebra_rib.c, zebra_vty.c, zserv.c, connected.c: realm support + for static routes + * rib.h: Add realm attribute to rib and static_ipv4 structs + 2005-04-01 Hasso Tepper * rt_netlink.c (netlink_talk): Don't assume we use netlink_cmd diff -Naur quagga-0.98.3/zebra/connected.c quagga-0.98.3-realms/zebra/connected.c --- quagga-0.98.3/zebra/connected.c 2005-03-12 20:54:45.000000000 +0200 +++ quagga-0.98.3-realms/zebra/connected.c 2005-04-21 21:39:58.000000000 +0300 @@ -82,7 +82,11 @@ if (prefix_ipv4_any (&p)) return; +#ifndef SUPPORT_REALMS rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, 0, 0); +#else + rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, 0, 0, 0, 0); +#endif rib_update (); } diff -Naur quagga-0.98.3/zebra/rib.h quagga-0.98.3-realms/zebra/rib.h --- quagga-0.98.3/zebra/rib.h 2004-10-12 23:50:58.000000000 +0300 +++ quagga-0.98.3-realms/zebra/rib.h 2005-04-21 21:39:59.000000000 +0300 @@ -60,6 +60,12 @@ u_char nexthop_fib_num; struct nexthop *nexthop; + +#ifdef SUPPORT_REALMS + /* Realm information */ + u_int16_t realmto; +#endif + }; /* Static route information. */ @@ -91,6 +97,11 @@ see ZEBRA_FLAG_REJECT ZEBRA_FLAG_BLACKHOLE */ + +#ifdef SUPPORT_REALMS + u_int16_t realmto; +#endif + }; #ifdef HAVE_IPV6 @@ -213,7 +224,11 @@ int rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p, struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, +#ifndef SUPPORT_REALMS u_int32_t, u_char); +#else + u_int32_t, u_char, u_int16_t); +#endif int rib_add_ipv4_multipath (struct prefix_ipv4 *, struct rib *); @@ -235,7 +250,12 @@ int static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, +#ifndef SUPPORT_REALMS u_char flags, u_char distance, u_int32_t vrf_id); +#else + u_char flags, u_char distance, u_int32_t vrf_id, u_int16_t realmto); +#endif + int static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, diff -Naur quagga-0.98.3/zebra/rt_netlink.c quagga-0.98.3-realms/zebra/rt_netlink.c --- quagga-0.98.3/zebra/rt_netlink.c 2005-03-31 23:26:59.000000000 +0300 +++ quagga-0.98.3-realms/zebra/rt_netlink.c 2005-04-21 21:40:00.000000000 +0300 @@ -689,6 +689,12 @@ void *dest; void *gate; +#ifdef SUPPORT_REALMS + u_int32_t rta_flow; + u_int16_t realmto = 0; +#endif + + rtm = NLMSG_DATA (h); if (h->nlmsg_type != RTM_NEWROUTE) @@ -750,7 +756,19 @@ memcpy (&p.prefix, dest, 4); p.prefixlen = rtm->rtm_dst_len; +#ifndef SUPPORT_REALMS rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, table, metric, 0); +#else + if (tb[RTA_FLOW]) + { + rta_flow = *(u_int32_t *) RTA_DATA (tb[RTA_FLOW]); + realmto = rta_flow & 0xFFFF; + } + + rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, table, metric, 0, + realmto); +#endif + } #ifdef HAVE_IPV6 if (rtm->rtm_family == AF_INET6) @@ -881,8 +899,20 @@ inet_ntoa (p.prefix), p.prefixlen); } - if (h->nlmsg_type == RTM_NEWROUTE) + if (h->nlmsg_type == RTM_NEWROUTE) { +#ifndef SUPPORT_REALMS rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, 0, 0); +#else + if (tb[RTA_FLOW]) + { + u_int32_t rta_flow = *(u_int32_t *) RTA_DATA (tb[RTA_FLOW]); + u_int16_t realmto = rta_flow & 0xFFFF; + rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, 0, 0, + realmto); + } +#endif + + } else rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table); } @@ -1269,7 +1299,13 @@ /* Routing table change via netlink interface. */ int netlink_route (int cmd, int family, void *dest, int length, void *gate, +#ifdef SUPPORT_REALMS + int index, int zebra_flags, int table, + u_int16_t realmto, u_int16_t realmfrom) +#else int index, int zebra_flags, int table) +#endif + { int ret; int bytelen; @@ -1329,6 +1365,17 @@ addattr32 (&req.n, sizeof req, RTA_OIF, index); } +#ifdef SUPPORT_REALMS + if (realmto || realmfrom) + { + u_int32_t rta_flow; + rta_flow = ((u_int32_t) realmfrom) << 16; + rta_flow |= (u_int32_t) realmto; + + addattr32 (&req.n, sizeof req, RTA_FLOW, rta_flow); + } +#endif + /* Destination netlink address. */ memset (&snl, 0, sizeof snl); snl.nl_family = AF_NETLINK; @@ -1410,6 +1457,11 @@ goto skip; } +#ifdef SUPPORT_REALMS + if (rib->realmto) + addattr32 (&req.n, sizeof req, RTA_FLOW, rib->realmto); +#endif + /* Multipath case. */ if (rib->nexthop_active_num == 1 || MULTIPATH_NUM == 1) { @@ -1654,7 +1706,11 @@ int index, int flags, int table) { return netlink_route (RTM_DELROUTE, AF_INET6, &dest->prefix, +#ifndef SUPPORT_REALMS dest->prefixlen, gate, index, flags, table); +#else + dest->prefixlen, gate, index, flags, table, 0, 0); +#endif } #endif /* HAVE_IPV6 */ diff -Naur quagga-0.98.3/zebra/zebra_rib.c quagga-0.98.3-realms/zebra/zebra_rib.c --- quagga-0.98.3/zebra/zebra_rib.c 2004-12-07 23:12:56.000000000 +0200 +++ quagga-0.98.3-realms/zebra/zebra_rib.c 2005-04-21 21:40:00.000000000 +0300 @@ -977,7 +977,12 @@ int rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p, struct in_addr *gate, unsigned int ifindex, u_int32_t vrf_id, +#ifndef SUPPORT_REALMS u_int32_t metric, u_char distance) +#else + u_int32_t metric, u_char distance, u_int16_t realmto) +#endif + { struct rib *rib; struct rib *same = NULL; @@ -1062,6 +1067,10 @@ /* Link new rib to node.*/ rib_addnode (rn, rib); +#ifdef SUPPORT_REALMS + rib->realmto = realmto; +#endif + /* Process this route node. */ rib_process (rn, same); @@ -1331,6 +1340,10 @@ rib->distance = si->distance; rib->metric = 0; rib->nexthop_num = 0; +#ifdef SUPPORT_REALMS + rib->realmto = si->realmto; +#endif + switch (si->type) { @@ -1435,10 +1448,15 @@ route_unlock_node (rn); } + /* Add static route into static route configuration. */ int static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, +#ifndef SUPPORT_REALMS u_char flags, u_char distance, u_int32_t vrf_id) +#else + u_char flags, u_char distance, u_int32_t vrf_id, u_int16_t realmto) +#endif { u_char type = 0; struct route_node *rn; @@ -1493,6 +1511,10 @@ si->distance = distance; si->flags = flags; +#ifdef SUPPORT_REALMS + si->realmto = realmto; +#endif + if (gate) si->gate.ipv4 = *gate; if (ifname) diff -Naur quagga-0.98.3/zebra/zebra_vty.c quagga-0.98.3-realms/zebra/zebra_vty.c --- quagga-0.98.3/zebra/zebra_vty.c 2004-12-18 18:03:29.000000000 +0200 +++ quagga-0.98.3-realms/zebra/zebra_vty.c 2005-04-21 22:17:21.000000000 +0300 @@ -88,12 +88,17 @@ return '?'; } }; - + /* General fucntion for static route. */ int zebra_static_ipv4 (struct vty *vty, int add_cmd, const char *dest_str, const char *mask_str, const char *gate_str, +#ifndef SUPPORT_REALMS const char *flag_str, const char *distance_str) +#else + const char *flag_str, const char *distance_str, const char *realm_str) +#endif + { int ret; u_char distance; @@ -103,6 +108,23 @@ const char *ifname; u_char flag = 0; +#ifdef SUPPORT_REALMS + u_int16_t realmto = 0; + u_int32_t realmid; + int res; + + if (realm_str != NULL) { + res = rtnl_rtrealm_a2n (&realmid, realm_str); + if (res < 0) { + vty_out (vty, "%%Realm '%s' not found in rt_realms has invalid value%s", + realm_str, VTY_NEWLINE); + return CMD_ERR_INCOMPLETE; + } + realmto = (u_int16_t)realmid; + } +#endif + + ret = str2prefix (dest_str, &p); if (ret <= 0) { @@ -140,7 +162,11 @@ return CMD_WARNING; } if (add_cmd) +#ifndef SUPPORT_REALMS static_add_ipv4 (&p, NULL, NULL, ZEBRA_FLAG_BLACKHOLE, distance, 0); +#else + static_add_ipv4 (&p, NULL, NULL, ZEBRA_FLAG_BLACKHOLE, distance, 0, realmto); +#endif else static_delete_ipv4 (&p, NULL, NULL, distance, 0); return CMD_SUCCESS; @@ -166,7 +192,11 @@ if (gate_str == NULL) { if (add_cmd) +#ifndef SUPPORT_REALMS static_add_ipv4 (&p, NULL, NULL, flag, distance, 0); +#else + static_add_ipv4 (&p, NULL, NULL, flag, distance, 0, realmto); +#endif else static_delete_ipv4 (&p, NULL, NULL, distance, 0); @@ -181,8 +211,14 @@ else ifname = gate_str; - if (add_cmd) + if (add_cmd) { +#ifndef SUPPORT_REALMS static_add_ipv4 (&p, ifname ? NULL : &gate, ifname, flag, distance, 0); +#else + static_add_ipv4 (&p, ifname ? NULL : &gate, ifname, flag, distance, 0, realmto); +#endif + + } else static_delete_ipv4 (&p, ifname ? NULL : &gate, ifname, distance, 0); @@ -200,7 +236,11 @@ "IP gateway interface name\n" "Null interface\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, NULL); +#else + return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, NULL, NULL); +#endif } DEFUN (ip_route_flags, @@ -214,7 +254,11 @@ "Emit an ICMP unreachable when matched\n" "Silently discard pkts when matched\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], NULL); +#else + return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], NULL, NULL); +#endif } DEFUN (ip_route_flags2, @@ -226,7 +270,11 @@ "Emit an ICMP unreachable when matched\n" "Silently discard pkts when matched\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], NULL); +#else + return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], NULL, NULL); +#endif } /* Mask as A.B.C.D format. */ @@ -241,7 +289,11 @@ "IP gateway interface name\n" "Null interface\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, NULL); +#else + return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, NULL); +#endif } DEFUN (ip_route_mask_flags, @@ -256,7 +308,11 @@ "Emit an ICMP unreachable when matched\n" "Silently discard pkts when matched\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL); +#else + return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL, NULL); +#endif } DEFUN (ip_route_mask_flags2, @@ -269,7 +325,11 @@ "Emit an ICMP unreachable when matched\n" "Silently discard pkts when matched\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], NULL); +#else + return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], NULL, NULL); +#endif } /* Distance option value. */ @@ -284,7 +344,11 @@ "Null interface\n" "Distance value for this route\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, argv[2]); +#else + return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, argv[2], NULL); +#endif } DEFUN (ip_route_flags_distance, @@ -299,7 +363,12 @@ "Silently discard pkts when matched\n" "Distance value for this route\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], argv[3]); +#else + return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], argv[2], argv[3], NULL); +#endif + } DEFUN (ip_route_flags_distance2, @@ -312,7 +381,11 @@ "Silently discard pkts when matched\n" "Distance value for this route\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], argv[2]); +#else + return zebra_static_ipv4 (vty, 1, argv[0], NULL, NULL, argv[1], argv[2], NULL); +#endif } DEFUN (ip_route_mask_distance, @@ -327,7 +400,12 @@ "Null interface\n" "Distance value for this route\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3]); +#else + return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], NULL); +#endif + } DEFUN (ip_route_mask_flags_distance, @@ -343,7 +421,12 @@ "Emit an ICMP unreachable when matched\n" "Silently discard pkts when matched\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4]); +#else + return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4], NULL); +#endif + } DEFUN (ip_route_mask_flags_distance2, @@ -357,7 +440,12 @@ "Emit an ICMP unreachable when matched\n" "Silently discard pkts when matched\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3]); +#else + return zebra_static_ipv4 (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3], NULL); +#endif + } DEFUN (no_ip_route, @@ -371,7 +459,12 @@ "IP gateway interface name\n" "Null interface\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, NULL); +#else + return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, NULL, NULL); +#endif + } ALIAS (no_ip_route, @@ -396,7 +489,12 @@ "Emit an ICMP unreachable when matched\n" "Silently discard pkts when matched\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, NULL, NULL); +#else + return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, NULL, NULL, NULL); +#endif + } DEFUN (no_ip_route_mask, @@ -411,7 +509,12 @@ "IP gateway interface name\n" "Null interface\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, NULL); +#else + return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, NULL, NULL); +#endif + } ALIAS (no_ip_route_mask, @@ -438,7 +541,12 @@ "Emit an ICMP unreachable when matched\n" "Silently discard pkts when matched\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, NULL, NULL); +#else + return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, NULL, NULL, NULL); +#endif + } DEFUN (no_ip_route_distance, @@ -453,7 +561,12 @@ "Null interface\n" "Distance value for this route\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, argv[2]); +#else + return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], NULL, argv[2], NULL); +#endif + } DEFUN (no_ip_route_flags_distance, @@ -469,7 +582,12 @@ "Silently discard pkts when matched\n" "Distance value for this route\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], argv[2], argv[3]); +#else + return zebra_static_ipv4 (vty, 0, argv[0], NULL, argv[1], argv[2], argv[3], NULL); +#endif + } DEFUN (no_ip_route_flags_distance2, @@ -483,7 +601,12 @@ "Silently discard pkts when matched\n" "Distance value for this route\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, argv[1], argv[2]); +#else + return zebra_static_ipv4 (vty, 0, argv[0], NULL, NULL, argv[1], argv[2], NULL); +#endif + } DEFUN (no_ip_route_mask_distance, @@ -499,7 +622,12 @@ "Null interface\n" "Distance value for this route\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3]); +#else + return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3], NULL); +#endif + } DEFUN (no_ip_route_mask_flags_distance, @@ -516,7 +644,12 @@ "Silently discard pkts when matched\n" "Distance value for this route\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4]); +#else + return zebra_static_ipv4 (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4], NULL); +#endif + } DEFUN (no_ip_route_mask_flags_distance2, @@ -531,8 +664,71 @@ "Silently discard pkts when matched\n" "Distance value for this route\n") { +#ifndef SUPPORT_REALMS return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3]); +#else + return zebra_static_ipv4 (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3], NULL); +#endif + +} + +#ifdef SUPPORT_REALMS +DEFUN (ip_route_realm, + ip_route_realm_cmd, + "ip route A.B.C.D/M (A.B.C.D|INTERFACE) realm (<1-255>|WORD)", + IP_STR + "Establish static routes\n" + "IP destination prefix (e.g. 10.0.0.0/8)\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Destination realm value or name\n") +{ + return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, NULL, argv[2]); +} + +DEFUN (ip_route_mask_realm, + ip_route_mask_realm_cmd, + "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) realm (<1-255>|WORD)", + IP_STR + "Establish static routes\n" + "IP destination prefix\n" + "IP destination prefix mask\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Destination realm value or name\n") +{ + return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, NULL, argv[3]); +} + +DEFUN (ip_route_pref_realm, + ip_route_pref_realm_cmd, + "ip route A.B.C.D/M (A.B.C.D|INTERFACE) <1-255> realm (<1-255>|WORD)", + IP_STR + "Establish static routes\n" + "IP destination prefix (e.g. 10.0.0.0/8)\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Distance value for this route\n" + "Destination realm value or name\n") +{ + return zebra_static_ipv4 (vty, 1, argv[0], NULL, argv[1], NULL, argv[2], argv[3]); } + +DEFUN (ip_route_mask_pref_realm, + ip_route_mask_pref_realm_cmd, + "ip route A.B.C.D A.B.C.D (A.B.C.D|INTERFACE) <1-255> realm (<1-255>|WORD)", + IP_STR + "Establish static routes\n" + "IP destination prefix\n" + "IP destination prefix mask\n" + "IP gateway address\n" + "IP gateway interface name\n" + "Distance value for this route\n") +{ + return zebra_static_ipv4 (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3], argv[4]); +} +#endif /* SUPPORT_REALMS */ + /* New RIB. Detailed information for IPv4 route. */ void @@ -552,6 +748,10 @@ vty_out (vty, ", best"); if (rib->refcnt) vty_out (vty, ", refcnt %ld", rib->refcnt); +#ifdef SUPPORT_REALMS + if (rib->realmto) + vty_out (vty, ", realm %5u", rib->realmto); +#endif if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE)) vty_out (vty, ", blackhole"); if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT)) @@ -615,7 +815,12 @@ } if (! CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE)) vty_out (vty, " inactive"); - +#ifdef SUPPORT_REALMS + if (rib->realmto) { + char realmbuf[50]; + vty_out (vty, " realm %5s", rtnl_rtrealm_n2a (rib->realmto, realmbuf, sizeof (realmbuf))); + } +#endif if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) { vty_out (vty, " (recursive"); @@ -1106,6 +1311,13 @@ if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT) vty_out (vty, " %d", si->distance); +#ifdef SUPPORT_REALMS + if (si->realmto) { + char realmbuf[11]; + vty_out (vty, " realm %s", rtnl_rtrealm_n2a (si->realmto, realmbuf, sizeof realmbuf)); + } +#endif + vty_out (vty, "%s", VTY_NEWLINE); write = 1; @@ -1955,6 +2167,12 @@ install_element (CONFIG_NODE, &no_ip_route_mask_cmd); install_element (CONFIG_NODE, &no_ip_route_mask_flags_cmd); install_element (CONFIG_NODE, &no_ip_route_mask_flags2_cmd); +#ifdef SUPPORT_REALMS + install_element (CONFIG_NODE, &ip_route_realm_cmd); + install_element (CONFIG_NODE, &ip_route_mask_realm_cmd); + install_element (CONFIG_NODE, &ip_route_pref_realm_cmd); + install_element (CONFIG_NODE, &ip_route_mask_pref_realm_cmd); +#endif install_element (CONFIG_NODE, &ip_route_distance_cmd); install_element (CONFIG_NODE, &ip_route_flags_distance_cmd); install_element (CONFIG_NODE, &ip_route_flags_distance2_cmd); diff -Naur quagga-0.98.3/zebra/zserv.c quagga-0.98.3-realms/zebra/zserv.c --- quagga-0.98.3/zebra/zserv.c 2005-01-05 10:30:35.000000000 +0200 +++ quagga-0.98.3-realms/zebra/zserv.c 2005-04-21 21:40:00.000000000 +0300 @@ -877,6 +877,13 @@ if (CHECK_FLAG (message, ZAPI_MESSAGE_METRIC)) rib->metric = stream_getl (s); +#ifdef SUPPORT_REALMS + if (CHECK_FLAG (message, ZAPI_MESSAGE_REALMTO)) + rib->realmto = stream_getw (s); + else + rib->realmto = 0; +#endif + rib_add_ipv4_multipath (&p, rib); }