diff -Nru quagga-0.99.5.orig/bgpd/bgp_attr.c quagga-0.99.5/bgpd/bgp_attr.c --- quagga-0.99.5.orig/bgpd/bgp_attr.c 2006-05-13 02:24:30.000000000 +0300 +++ quagga-0.99.5/bgpd/bgp_attr.c 2006-10-19 22:06:41.506590750 +0300 @@ -299,6 +299,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); @@ -337,6 +342,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 -Nru quagga-0.99.5.orig/bgpd/bgp_attr.h quagga-0.99.5/bgpd/bgp_attr.h --- quagga-0.99.5.orig/bgpd/bgp_attr.h 2006-05-04 10:49:51.000000000 +0300 +++ quagga-0.99.5/bgpd/bgp_attr.h 2006-10-19 22:06:41.506590750 +0300 @@ -87,6 +87,12 @@ as_t aggregator_as; u_char origin; u_char mp_nexthop_len; + +#ifdef SUPPORT_REALMS + /* Realm used */ + u_int16_t realmto; +#endif + }; /* Router Reflector related structure. */ diff -Nru quagga-0.99.5.orig/bgpd/bgpd.c quagga-0.99.5/bgpd/bgpd.c --- quagga-0.99.5.orig/bgpd/bgpd.c 2006-10-19 22:05:27.000000000 +0300 +++ quagga-0.99.5/bgpd/bgpd.c 2006-10-19 22:06:41.530592250 +0300 @@ -631,6 +631,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 */ @@ -775,6 +779,10 @@ peer->weight = 0; peer->password = NULL; +#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++) @@ -1382,6 +1390,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 */ @@ -3048,7 +3063,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 *node, *nnode; + + 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; + for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer)) + { + peer->realm = group->conf->realm; + } + return 0; +} + +int +peer_realm_unset (struct peer *peer) +{ + struct peer_group *group; + struct listnode *node, *nnode; + + /* 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; + for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer)) + { + peer->realm = 0; + } + return 0; +} + + +#endif + int peer_timers_set (struct peer *peer, u_int32_t keepalive, u_int32_t holdtime) { @@ -4608,6 +4676,35 @@ 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 + + + + + + + + /* Dynamic capability. */ if (CHECK_FLAG (peer->flags, PEER_FLAG_DYNAMIC_CAPABILITY)) if (! peer_group_active (peer) || diff -Nru quagga-0.99.5.orig/bgpd/bgpd.h quagga-0.99.5/bgpd/bgpd.h --- quagga-0.99.5.orig/bgpd/bgpd.h 2006-10-19 22:05:27.000000000 +0300 +++ quagga-0.99.5/bgpd/bgpd.h 2006-10-19 22:06:41.530592250 +0300 @@ -419,6 +419,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; @@ -898,6 +903,11 @@ extern int peer_timers_set (struct peer *, u_int32_t, u_int32_t); extern int peer_timers_unset (struct peer *); +#ifdef SUPPORT_REALMS +extern int peer_realm_set (struct peer *, u_int32_t); +extern int peer_realm_unset (struct peer *); +#endif + extern int peer_timers_connect_set (struct peer *, u_int32_t); extern int peer_timers_connect_unset (struct peer *); diff -Nru quagga-0.99.5.orig/bgpd/bgp_route.c quagga-0.99.5/bgpd/bgp_route.c --- quagga-0.99.5.orig/bgpd/bgp_route.c 2006-10-19 22:05:27.000000000 +0300 +++ quagga-0.99.5/bgpd/bgp_route.c 2006-10-19 22:11:33.212821250 +0300 @@ -493,6 +493,19 @@ } 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) + +#endif static int bgp_input_modifier (struct peer *peer, struct prefix *p, struct attr *attr, @@ -502,6 +515,44 @@ struct bgp_info info; route_map_result_t ret; +#ifdef SUPPORT_REALMS + + u_int16_t realm_value = 0; + struct aspath *aspath; + + struct assegment *assegment; + + + /* Apply default realm value. */ + aspath = attr->aspath; + + if (peer->realm == REALM_PEER_AS) + { + realm_value = peer->as; + + } + else if (peer->realm == REALM_ORIGIN_AS) + { + if (aspath == NULL || aspath->segments == NULL) + return RMAP_PERMIT; + + assegment = aspath->segments; + + while (assegment) { + int i; + + for (i = 0; i < assegment->length; i++) + realm_value = assegment->as[i]; + + assegment = assegment->next; + } + } + else realm_value = (u_int16_t)(peer->realm & 0xFFFF); + + attr->realmto = realm_value; + +#endif + filter = &peer->filter[afi][safi]; /* Apply default weight value. */ @@ -573,6 +624,46 @@ struct bgp_info info; route_map_result_t ret; +#ifdef SUPPORT_REALMS + + u_int16_t realm_value = 0; + struct aspath *aspath; + + struct assegment *assegment; + + + /* Apply default realm value. */ + aspath = attr->aspath; + + if (peer->realm == REALM_PEER_AS) + { + realm_value = peer->as; + + } + else if (peer->realm == REALM_ORIGIN_AS) + { + if (aspath == NULL || aspath->segments == NULL) + return RMAP_PERMIT; + + assegment = aspath->segments; + + while (assegment) { + int i; + + for (i = 0; i < assegment->length; i++) + realm_value = assegment->as[i]; + + assegment = assegment->next; + } + } + else realm_value = (u_int16_t)(peer->realm & 0xFFFF); + + attr->realmto = realm_value; + +#endif + + + filter = &rsclient->filter[afi][safi]; /* Apply default weight value. */ @@ -5137,6 +5228,10 @@ 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, "%s ", attr->aspath); @@ -5198,6 +5293,10 @@ vty_out (vty, "%7d ",attr->weight); +#ifdef SUPPORT_REALMS + vty_out (vty, "%7u ", attr->realmto); +#endif + /* Print aspath */ if (attr->aspath) aspath_print_vty (vty, "%s ", attr->aspath); @@ -5485,6 +5584,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 */ @@ -5525,7 +5631,11 @@ #define BGP_SHOW_SCODE_HEADER "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal,%s r RIB-failure, S Stale, R Removed%s" #define BGP_SHOW_OCODE_HEADER "Origin codes: i - IGP, e - EGP, ? - incomplete%s%s" +#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 -Nru quagga-0.99.5.orig/bgpd/bgp_routemap.c quagga-0.99.5/bgpd/bgp_routemap.c --- quagga-0.99.5.orig/bgpd/bgp_routemap.c 2006-02-18 12:45:15.000000000 +0200 +++ quagga-0.99.5/bgpd/bgp_routemap.c 2006-10-19 22:06:41.518591500 +0300 @@ -1119,6 +1119,112 @@ 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) + +static 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; + + 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->segments == NULL) + return RMAP_OKAY; + + realm_value = bgp_info->peer->as; + + } + else if (*realm == REALM_ORIGIN_AS) + { + if (aspath == NULL || aspath->segments == NULL) + return RMAP_PERMIT; + + assegment = aspath->segments; + + while (assegment) { + int i; + + for (i = 0; i < assegment->length; i++) + realm_value = assegment->as[i]; + + assegment = assegment->next; + } + } + 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 + */ +static 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; +} + +static 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' */ @@ -2827,6 +2933,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>", @@ -3554,6 +3713,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); @@ -3622,6 +3785,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 -Nru quagga-0.99.5.orig/bgpd/bgp_vty.c quagga-0.99.5/bgpd/bgp_vty.c --- quagga-0.99.5.orig/bgpd/bgp_vty.c 2006-10-19 22:05:27.000000000 +0300 +++ quagga-0.99.5/bgpd/bgp_vty.c 2006-10-19 22:06:41.522591750 +0300 @@ -3025,7 +3025,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.*/ +static 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; +} + +static 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, @@ -7471,6 +7578,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++) @@ -9288,6 +9416,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 -Nru quagga-0.99.5.orig/bgpd/bgp_zebra.c quagga-0.99.5/bgpd/bgp_zebra.c --- quagga-0.99.5.orig/bgpd/bgp_zebra.c 2005-10-30 01:44:51.000000000 +0300 +++ quagga-0.99.5/bgpd/bgp_zebra.c 2006-10-19 22:06:41.526592000 +0300 @@ -640,6 +640,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 -Nru quagga-0.99.5.orig/bgpd/ChangeLog quagga-0.99.5/bgpd/ChangeLog --- quagga-0.99.5.orig/bgpd/ChangeLog 2006-08-27 09:53:53.000000000 +0300 +++ quagga-0.99.5/bgpd/ChangeLog 2006-10-19 22:06:41.506590750 +0300 @@ -570,6 +570,18 @@ (peer_create) use XSTRDUP * bgp_packet.c: (bgp_stream_dup) deleted, stream_dup should be used (various) update -> s/bgp_stream_dup/stream_dup + +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-04-11 Andrew J. Schorr diff -Nru quagga-0.99.5.orig/ChangeLog quagga-0.99.5/ChangeLog --- quagga-0.99.5.orig/ChangeLog 2006-08-28 01:04:41.000000000 +0300 +++ quagga-0.99.5/ChangeLog 2006-10-19 22:06:41.502590500 +0300 @@ -108,6 +108,14 @@ * Makefile.am (EXTRA_DIST): add INSTALL.quagga.txt, because people that patch releases need to know about autoconf required versions. +2005-07-30 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-06-30 Louis Lagendijk * configure.ac: Actually test whether libc has IPv6 support. diff -Nru quagga-0.99.5.orig/config.h.in quagga-0.99.5/config.h.in --- quagga-0.99.5.orig/config.h.in 2006-08-28 01:08:55.000000000 +0300 +++ quagga-0.99.5/config.h.in 2006-10-19 22:06:41.530592250 +0300 @@ -474,6 +474,9 @@ /* OSPFAPI */ #undef SUPPORT_OSPF_API +/* Realms support */ +#undef SUPPORT_REALMS + /* Enable IS-IS topology generator code */ #undef TOPOLOGY_GENERATE diff -Nru quagga-0.99.5.orig/configure quagga-0.99.5/configure --- quagga-0.99.5.orig/configure 2006-08-28 01:07:03.000000000 +0300 +++ quagga-0.99.5/configure 2006-10-19 22:06:41.542593000 +0300 @@ -419,7 +419,7 @@ # Identity of this package. PACKAGE_NAME='Quagga' PACKAGE_TARNAME='quagga' -PACKAGE_VERSION='0.99.5' +PACKAGE_VERSION='0.99.5-realms' PACKAGE_STRING='Quagga 0.99.5' PACKAGE_BUGREPORT='http://bugzilla.quagga.net' @@ -1046,6 +1046,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 --enable-isis-topology enable IS-IS topology generator @@ -1914,7 +1915,7 @@ # Define the identity of the package. PACKAGE='quagga' - VERSION='0.99.5' + VERSION='0.99.5-realms' cat >>confdefs.h <<_ACEOF @@ -9277,6 +9278,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" @@ -10979,6 +10985,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 -Nru quagga-0.99.5.orig/configure.ac quagga-0.99.5/configure.ac --- quagga-0.99.5.orig/configure.ac 2006-10-19 22:05:27.000000000 +0300 +++ quagga-0.99.5/configure.ac 2006-10-19 22:06:41.546593250 +0300 @@ -8,7 +8,7 @@ ## $Id: configure.ac,v 1.123 2006/08/27 22:06:12 paul Exp $ AC_PREREQ(2.53) -AC_INIT(Quagga, 0.99.5, [http://bugzilla.quagga.net]) +AC_INIT(Quagga, 0.99.5-realms, [http://bugzilla.quagga.net]) AC_CONFIG_SRCDIR(lib/zebra.h) dnl ----------------------------------- @@ -224,7 +224,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, @@ -439,6 +440,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 -Nru quagga-0.99.5.orig/lib/ChangeLog quagga-0.99.5/lib/ChangeLog --- quagga-0.99.5.orig/lib/ChangeLog 2006-08-27 09:40:36.000000000 +0300 +++ quagga-0.99.5/lib/ChangeLog 2006-10-19 22:06:41.550593500 +0300 @@ -483,6 +483,13 @@ * memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and MTYPE_BGP_CLEAR_NODE_QUEUE +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-05-24 Paul Jakma * memtypes.h: update this auto-built file. (maybe we should just diff -Nru quagga-0.99.5.orig/lib/Makefile.am quagga-0.99.5/lib/Makefile.am --- quagga-0.99.5.orig/lib/Makefile.am 2006-06-27 10:48:16.000000000 +0300 +++ quagga-0.99.5/lib/Makefile.am 2006-10-19 22:11:59.014433750 +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 memtypes.c workqueue.c + sigevent.c pqueue.c jhash.c memtypes.c workqueue.c rt_names.c BUILT_SOURCES = memtypes.h route_types.h @@ -27,7 +27,7 @@ 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.h if_rmap.h keychain.h \ privs.h sigevent.h pqueue.h jhash.h zassert.h memtypes.h \ - workqueue.h route_types.h + workqueue.h route_types.h rt_names.h EXTRA_DIST = regex.c regex-gnu.h memtypes.awk route_types.awk route_types.txt diff -Nru quagga-0.99.5.orig/lib/Makefile.in quagga-0.99.5/lib/Makefile.in --- quagga-0.99.5.orig/lib/Makefile.in 2006-08-28 01:07:27.000000000 +0300 +++ quagga-0.99.5/lib/Makefile.in 2006-10-19 22:12:12.259261500 +0300 @@ -65,7 +65,7 @@ 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 \ - memtypes.lo workqueue.lo + memtypes.lo workqueue.lo rt_names.lo libzebra_la_OBJECTS = $(am_libzebra_la_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp @@ -227,7 +227,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 memtypes.c workqueue.c + sigevent.c pqueue.c jhash.c memtypes.c workqueue.c rt_names.c BUILT_SOURCES = memtypes.h route_types.h libzebra_la_DEPENDENCIES = @LIB_REGEX@ @@ -239,7 +239,7 @@ 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.h if_rmap.h keychain.h \ privs.h sigevent.h pqueue.h jhash.h zassert.h memtypes.h \ - workqueue.h route_types.h + workqueue.h route_types.h rt_names.h EXTRA_DIST = regex.c regex-gnu.h memtypes.awk route_types.awk route_types.txt all: $(BUILT_SOURCES) @@ -340,8 +340,10 @@ @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)/rt_names.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sockunion.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/str.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stream.Plo@am__quote@ diff -Nru quagga-0.99.5.orig/lib/rt_names.c quagga-0.99.5/lib/rt_names.c --- quagga-0.99.5.orig/lib/rt_names.c 1970-01-01 02:00:00.000000000 +0200 +++ quagga-0.99.5/lib/rt_names.c 2006-10-19 22:06:41.554593750 +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 -Nru quagga-0.99.5.orig/lib/rt_names.h quagga-0.99.5/lib/rt_names.h --- quagga-0.99.5.orig/lib/rt_names.h 1970-01-01 02:00:00.000000000 +0200 +++ quagga-0.99.5/lib/rt_names.h 2006-10-19 22:06:41.554593750 +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 -Nru quagga-0.99.5.orig/lib/version.h quagga-0.99.5/lib/version.h --- quagga-0.99.5.orig/lib/version.h 2006-08-28 01:08:52.000000000 +0300 +++ quagga-0.99.5/lib/version.h 2006-10-19 22:06:41.554593750 +0300 @@ -26,7 +26,7 @@ #define QUAGGA_PROGNAME "Quagga" -#define QUAGGA_VERSION "0.99.5" +#define QUAGGA_VERSION "0.99.5-realms" #define ZEBRA_BUG_ADDRESS "http://bugzilla.quagga.net" diff -Nru quagga-0.99.5.orig/lib/zclient.c quagga-0.99.5/lib/zclient.c --- quagga-0.99.5.orig/lib/zclient.c 2006-01-31 22:55:54.000000000 +0200 +++ quagga-0.99.5/lib/zclient.c 2006-10-19 22:06:41.554593750 +0300 @@ -475,6 +475,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 -Nru quagga-0.99.5.orig/lib/zclient.h quagga-0.99.5/lib/zclient.h --- quagga-0.99.5.orig/lib/zclient.h 2006-01-31 22:55:54.000000000 +0200 +++ quagga-0.99.5/lib/zclient.h 2006-10-19 22:06:41.554593750 +0300 @@ -87,6 +87,10 @@ #define ZAPI_MESSAGE_DISTANCE 0x04 #define ZAPI_MESSAGE_METRIC 0x08 +#ifdef SUPPORT_REALMS + #define ZAPI_MESSAGE_REALMTO 0x10 +#endif + /* Zserv protocol message header */ struct zserv_header { @@ -117,6 +121,9 @@ u_char distance; u_int32_t metric; +#ifdef SUPPORT_REALMS + u_int16_t realmto; +#endif }; /* Prototypes of zebra client service functions. */ diff -Nru quagga-0.99.5.orig/lib/zebra.h quagga-0.99.5/lib/zebra.h --- quagga-0.99.5.orig/lib/zebra.h 2006-05-28 11:04:02.000000000 +0300 +++ quagga-0.99.5/lib/zebra.h 2006-10-19 22:06:41.558594000 +0300 @@ -232,6 +232,10 @@ #include #endif /* HAVE_LIBUTIL_H */ +#ifdef SUPPORT_REALMS +#include +#endif + #ifdef HAVE_GLIBC_BACKTRACE #include #endif /* HAVE_GLIBC_BACKTRACE */ diff -Nru quagga-0.99.5.orig/zebra/ChangeLog quagga-0.99.5/zebra/ChangeLog --- quagga-0.99.5.orig/zebra/ChangeLog 2006-08-06 19:00:38.000000000 +0300 +++ quagga-0.99.5/zebra/ChangeLog 2006-10-19 22:06:41.558594000 +0300 @@ -558,7 +558,16 @@ (remainder) Sanitise refcounting of route_node's. Convert to rib_queue_add, rib_addnode and rib_delnode. Change XMALLOC/memset to XCALLOC. Remove calls to nexthop_delete and nexthop_free. + +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-10 Paul Jakma * if_ioctl_solaris.c: (if_lookup_linklocal) fix order of args diff -Nru quagga-0.99.5.orig/zebra/connected.c quagga-0.99.5/zebra/connected.c --- quagga-0.99.5.orig/zebra/connected.c 2006-07-27 18:39:38.000000000 +0300 +++ quagga-0.99.5/zebra/connected.c 2006-10-19 22:07:49.674851000 +0300 @@ -200,8 +200,13 @@ if (prefix_ipv4_any (&p)) return; +#ifndef SUPPORT_REALMS rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, RT_TABLE_MAIN, ifp->metric, 0); +#else + rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, RT_TABLE_MAIN, + ifp->metric, 0, 0); +#endif rib_update (); } diff -Nru quagga-0.99.5.orig/zebra/rib.h quagga-0.99.5/zebra/rib.h --- quagga-0.99.5.orig/zebra/rib.h 2006-07-28 00:40:04.000000000 +0300 +++ quagga-0.99.5/zebra/rib.h 2006-10-19 22:06:41.562594250 +0300 @@ -73,6 +73,12 @@ u_char nexthop_num; u_char nexthop_active_num; u_char nexthop_fib_num; + +#ifdef SUPPORT_REALMS + /* Realm information */ + u_int16_t realmto; +#endif + }; /* Static route information. */ @@ -104,6 +110,11 @@ see ZEBRA_FLAG_REJECT ZEBRA_FLAG_BLACKHOLE */ + +#ifdef SUPPORT_REALMS + u_int16_t realmto; +#endif + }; #ifdef HAVE_IPV6 @@ -226,7 +237,11 @@ * also implicitly withdraw equal prefix of same type. */ extern int rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p, struct in_addr *gate, unsigned int ifindex, +#ifndef SUPPORT_REALMS u_int32_t vrf_id, u_int32_t, u_char); +#else + u_int32_t vrf_id, u_int32_t, u_char, u_int16_t); +#endif extern int rib_add_ipv4_multipath (struct prefix_ipv4 *, struct rib *); @@ -246,7 +261,12 @@ extern 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 + extern int static_delete_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, diff -Nru quagga-0.99.5.orig/zebra/rt_netlink.c quagga-0.99.5/zebra/rt_netlink.c --- quagga-0.99.5.orig/zebra/rt_netlink.c 2006-07-02 19:36:51.000000000 +0300 +++ quagga-0.99.5/zebra/rt_netlink.c 2006-10-19 22:06:41.566594500 +0300 @@ -738,6 +738,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) @@ -799,7 +805,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) @@ -931,8 +949,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); } @@ -1330,7 +1360,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; @@ -1390,6 +1426,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; @@ -1467,6 +1514,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) { @@ -1813,7 +1865,11 @@ unsigned 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 -Nru quagga-0.99.5.orig/zebra/zebra_rib.c quagga-0.99.5/zebra/zebra_rib.c --- quagga-0.99.5.orig/zebra/zebra_rib.c 2006-07-28 00:42:16.000000000 +0300 +++ quagga-0.99.5/zebra/zebra_rib.c 2006-10-19 22:09:24.588782750 +0300 @@ -1232,7 +1232,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; @@ -1315,6 +1320,10 @@ /* Link new rib to node.*/ rib_addnode (rn, rib); +#ifdef SUPPORT_REALMS + rib->realmto = realmto; +#endif + /* Free implicit route.*/ if (same) rib_delnode (rn, same); @@ -1558,6 +1567,10 @@ rib->distance = si->distance; rib->metric = 0; rib->nexthop_num = 0; +#ifdef SUPPORT_REALMS + rib->realmto = si->realmto; +#endif + switch (si->type) { @@ -1661,7 +1674,11 @@ /* 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; @@ -1716,6 +1733,10 @@ si->distance = distance; si->flags = flags; +#ifdef SUPPORT_REALMS + si->realmto = realmto; +#endif + if (gate) si->gate.ipv4 = *gate; if (ifname) diff -Nru quagga-0.99.5.orig/zebra/zebra_vty.c quagga-0.99.5/zebra/zebra_vty.c --- quagga-0.99.5.orig/zebra/zebra_vty.c 2005-10-03 17:20:36.000000000 +0300 +++ quagga-0.99.5/zebra/zebra_vty.c 2006-10-19 22:06:41.570594750 +0300 @@ -33,7 +33,12 @@ static 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; @@ -43,6 +48,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) { @@ -80,7 +102,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; @@ -106,7 +132,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); @@ -121,8 +151,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); @@ -140,7 +176,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, @@ -154,7 +194,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, @@ -166,7 +210,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. */ @@ -181,7 +229,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, @@ -196,7 +248,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, @@ -209,7 +265,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. */ @@ -224,7 +284,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, @@ -239,7 +303,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, @@ -252,7 +321,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, @@ -267,7 +340,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, @@ -283,7 +361,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, @@ -297,7 +380,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, @@ -311,7 +399,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, @@ -336,7 +429,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, @@ -351,7 +449,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, @@ -378,7 +481,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, @@ -393,7 +501,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, @@ -409,7 +522,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, @@ -423,7 +541,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, @@ -439,7 +562,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, @@ -456,7 +584,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, @@ -471,9 +604,72 @@ "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. */ static void vty_show_ip_route_detail (struct vty *vty, struct route_node *rn) @@ -492,6 +688,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)) @@ -555,7 +755,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"); @@ -1046,6 +1251,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; @@ -1895,6 +2107,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 -Nru quagga-0.99.5.orig/zebra/zserv.c quagga-0.99.5/zebra/zserv.c --- quagga-0.99.5.orig/zebra/zserv.c 2006-07-27 18:39:38.000000000 +0300 +++ quagga-0.99.5/zebra/zserv.c 2006-10-19 22:09:54.710665250 +0300 @@ -803,6 +803,12 @@ /* Table */ rib->table=zebrad.rtm_table_default; +#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); return 0; }