summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCalin Velea <vcalinus@gemenii.ro>2007-04-09 15:29:51 -0500
committerJeffrey C. Ollie <jeff@ocjtech.us>2007-04-09 15:29:51 -0500
commit8d3e3ccfd0d0cb82b253f937339d1c6189a2bf54 (patch)
treeb8bc9ff4aad0c8e7933e91895f6f3cf7d93f8e24
parentc15deb1b7428a2baedfb615b1a41fe28d48c598c (diff)
downloadquagga-8d3e3ccfd0d0cb82b253f937339d1c6189a2bf54.tar.bz2
quagga-8d3e3ccfd0d0cb82b253f937339d1c6189a2bf54.tar.xz
Appying patch from http://vcalinus.gemenii.ro/quagga-0.99.5-realms.diffquagga-0.99.5-realms.diff
-rw-r--r--ChangeLog9
-rw-r--r--bgpd/ChangeLog13
-rw-r--r--bgpd/bgp_attr.c10
-rw-r--r--bgpd/bgp_attr.h6
-rw-r--r--bgpd/bgp_route.c110
-rw-r--r--bgpd/bgp_routemap.c170
-rw-r--r--bgpd/bgp_vty.c141
-rw-r--r--bgpd/bgp_zebra.c9
-rw-r--r--bgpd/bgpd.c99
-rw-r--r--bgpd/bgpd.h10
-rwxr-xr-xconfigure.ac13
-rw-r--r--lib/ChangeLog8
-rw-r--r--lib/Makefile.am4
-rw-r--r--lib/rt_names.c412
-rw-r--r--lib/rt_names.h28
-rw-r--r--lib/zclient.c5
-rw-r--r--lib/zclient.h7
-rw-r--r--lib/zebra.h4
-rw-r--r--zebra/ChangeLog10
-rw-r--r--zebra/connected.c5
-rw-r--r--zebra/rib.h20
-rw-r--r--zebra/rt_netlink.c58
-rw-r--r--zebra/zebra_rib.c21
-rw-r--r--zebra/zebra_vty.c222
-rw-r--r--zebra/zserv.c6
25 files changed, 1391 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index 4763e5cb..83d22abc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -108,6 +108,15 @@
* 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 <vcalinus@gemenii.ro>
+
+ * 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 <louis.lagendijk@gmail.com>
* configure.ac: Actually test whether libc has IPv6 support.
diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog
index b27132c9..13d6777a 100644
--- a/bgpd/ChangeLog
+++ b/bgpd/ChangeLog
@@ -570,6 +570,19 @@
(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 <vcalinus@gemenii.ro>
+
+ * 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 <ajschorr@alumni.princeton.edu>
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 4c72d80a..72d66b52 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -299,6 +299,11 @@ attrhash_key_make (struct attr *attr)
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 @@ attrhash_cmp (struct attr *attr1, struct attr *attr2)
&& 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 --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index 777869ce..6f6a1262 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -87,6 +87,12 @@ struct attr
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 --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 5623cadc..20276b49 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -493,6 +493,19 @@ bgp_cluster_filter (struct peer *peer, struct attr *attr)
}
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 @@ bgp_input_modifier (struct peer *peer, struct prefix *p, struct attr *attr,
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 @@ bgp_import_modifier (struct peer *rsclient, struct peer *peer,
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. */
@@ -5153,6 +5244,10 @@ route_vty_out (struct vty *vty, struct prefix *p,
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);
@@ -5214,6 +5309,10 @@ route_vty_out_tmp (struct vty *vty, struct prefix *p,
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);
@@ -5501,6 +5600,13 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
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 */
@@ -5541,7 +5647,11 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
#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 --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 806a5072..e660568c 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -1119,6 +1119,112 @@ struct route_map_rule_cmd route_set_metric_cmd =
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 @@ ALIAS (no_set_metric,
"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 @@ bgp_route_map_init (void)
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 @@ bgp_route_map_init (void)
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 --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index ec4b6c22..93096dc0 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -2985,7 +2985,114 @@ ALIAS (no_neighbor_weight,
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,
@@ -7431,6 +7538,27 @@ bgp_show_peer (struct vty *vty, struct peer *p)
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++)
@@ -9242,6 +9370,17 @@ bgp_vty_init (void)
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 --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 0cb9e0e2..a25297ab 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -640,6 +640,15 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp)
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 --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 8ed598d2..6256c54a 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -631,6 +631,10 @@ peer_global_config_reset (struct peer *peer)
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 */
@@ -774,6 +778,10 @@ peer_new ()
peer->ostatus = Idle;
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++)
@@ -1370,6 +1378,13 @@ peer_group2peer_config_copy (struct peer_group *group, struct peer *peer,
/* 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 */
@@ -3016,7 +3031,60 @@ peer_weight_unset (struct peer *peer)
}
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)
{
@@ -4451,6 +4519,35 @@ bgp_config_write_peer (struct vty *vty, struct bgp *bgp,
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 --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 9e2aa3e0..dc451e78 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -410,6 +410,11 @@ struct peer
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;
@@ -889,6 +894,11 @@ extern int peer_weight_unset (struct peer *);
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 --git a/configure.ac b/configure.ac
index 4f5956e0..7c0b5df7 100755
--- a/configure.ac
+++ b/configure.ac
@@ -8,7 +8,7 @@
## $Id$
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 @@ AC_ARG_ENABLE(configfile_mask,
[ --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,
@@ -432,6 +433,14 @@ case "$host" in
;;
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 --git a/lib/ChangeLog b/lib/ChangeLog
index 01f45ba5..e2c25ca6 100644
--- a/lib/ChangeLog
+++ b/lib/ChangeLog
@@ -483,6 +483,14 @@
* memtypes.c: Add MTYPE_BGP_PROCESS_QUEUE and
MTYPE_BGP_CLEAR_NODE_QUEUE
+2005-04-24 Calin Velea <vcalinus@gemenii.ro>
+
+ * 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 <paul@dishone.st>
* memtypes.h: update this auto-built file. (maybe we should just
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 315e919b..2bd25235 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -12,7 +12,7 @@ libzebra_la_SOURCES = \
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 @@ pkginclude_HEADERS = \
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 --git a/lib/rt_names.c b/lib/rt_names.c
new file mode 100644
index 00000000..6ed2d7ab
--- /dev/null
+++ b/lib/rt_names.c
@@ -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, <kuznet@ms2.inr.ac.ru>
+ *
+ * Fix: 23 Apr 2005 Calin Velea <vcalinus@gemenii.ro>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/time.h>
+
+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 --git a/lib/rt_names.h b/lib/rt_names.h
new file mode 100644
index 00000000..6ac29204
--- /dev/null
+++ b/lib/rt_names.h
@@ -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 --git a/lib/zclient.c b/lib/zclient.c
index a253af61..b6858fab 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -475,6 +475,11 @@ zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
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 --git a/lib/zclient.h b/lib/zclient.h
index 69ada144..749f1182 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -87,6 +87,10 @@ struct zclient
#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 @@ struct zapi_ipv4
u_char distance;
u_int32_t metric;
+#ifdef SUPPORT_REALMS
+ u_int16_t realmto;
+#endif
};
/* Prototypes of zebra client service functions. */
diff --git a/lib/zebra.h b/lib/zebra.h
index 2e2f8cda..2b7ff442 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -232,6 +232,10 @@ typedef int socklen_t;
#include <libutil.h>
#endif /* HAVE_LIBUTIL_H */
+#ifdef SUPPORT_REALMS
+#include <rt_names.h>
+#endif
+
#ifdef HAVE_GLIBC_BACKTRACE
#include <execinfo.h>
#endif /* HAVE_GLIBC_BACKTRACE */
diff --git a/zebra/ChangeLog b/zebra/ChangeLog
index 62287d0b..9a26750f 100644
--- a/zebra/ChangeLog
+++ b/zebra/ChangeLog
@@ -558,7 +558,17 @@
(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 <vcalinus@gemenii.ro>
+
+ * 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 <paul@dishone.st>
* if_ioctl_solaris.c: (if_lookup_linklocal) fix order of args
diff --git a/zebra/connected.c b/zebra/connected.c
index 44002e76..2b31aa3a 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -200,8 +200,13 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
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 --git a/zebra/rib.h b/zebra/rib.h
index 04fbbecf..dd1bfbbc 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -73,6 +73,12 @@ struct rib
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 @@ struct static_ipv4
see ZEBRA_FLAG_REJECT
ZEBRA_FLAG_BLACKHOLE
*/
+
+#ifdef SUPPORT_REALMS
+ u_int16_t realmto;
+#endif
+
};
#ifdef HAVE_IPV6
@@ -226,7 +237,11 @@ extern struct route_table *vrf_static_table (afi_t afi, safi_t safi, u_int32_t i
* 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 void rib_init (void);
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 --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 216625e9..5e19ec6a 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -738,6 +738,12 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
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 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
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 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
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 @@ netlink_talk (struct nlmsghdr *n, struct nlsock *nl)
/* 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 @@ netlink_route (int cmd, int family, void *dest, int length, void *gate,
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 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
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 @@ kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate,
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 --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index acad065a..8d4e732c 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -1232,7 +1232,12 @@ rib_delnode (struct route_node *rn, struct rib *rib)
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 @@ rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
/* 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 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si)
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 @@ static_uninstall_ipv4 (struct prefix *p, struct static_ipv4 *si)
/* 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 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname,
si->distance = distance;
si->flags = flags;
+#ifdef SUPPORT_REALMS
+ si->realmto = realmto;
+#endif
+
if (gate)
si->gate.ipv4 = *gate;
if (ifname)
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 68e6f920..33906e3d 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -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 @@ zebra_static_ipv4 (struct vty *vty, int add_cmd, const char *dest_str,
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 @@ zebra_static_ipv4 (struct vty *vty, int add_cmd, const char *dest_str,
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 @@ zebra_static_ipv4 (struct vty *vty, int add_cmd, const char *dest_str,
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 @@ zebra_static_ipv4 (struct vty *vty, int add_cmd, const char *dest_str,
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 @@ DEFUN (ip_route,
"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 @@ DEFUN (ip_route_flags,
"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 @@ DEFUN (ip_route_flags2,
"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 @@ DEFUN (ip_route_mask,
"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 @@ DEFUN (ip_route_mask_flags,
"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 @@ DEFUN (ip_route_mask_flags2,
"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 @@ DEFUN (ip_route_distance,
"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 @@ DEFUN (ip_route_flags_distance,
"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 @@ DEFUN (ip_route_flags_distance2,
"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 @@ DEFUN (ip_route_mask_distance,
"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 @@ DEFUN (ip_route_mask_flags_distance,
"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 @@ DEFUN (ip_route_mask_flags_distance2,
"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 @@ DEFUN (no_ip_route,
"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 @@ DEFUN (no_ip_route_flags2,
"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 @@ DEFUN (no_ip_route_mask,
"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 @@ DEFUN (no_ip_route_mask_flags2,
"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 @@ DEFUN (no_ip_route_distance,
"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 @@ DEFUN (no_ip_route_flags_distance,
"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 @@ DEFUN (no_ip_route_flags_distance2,
"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 @@ DEFUN (no_ip_route_mask_distance,
"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 @@ DEFUN (no_ip_route_mask_flags_distance,
"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 @@ DEFUN (no_ip_route_mask_flags_distance2,
"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_show_ip_route_detail (struct vty *vty, struct route_node *rn)
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 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn)
}
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 @@ static_config_ipv4 (struct vty *vty)
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 @@ zebra_vty_init (void)
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 --git a/zebra/zserv.c b/zebra/zserv.c
index 1703d3f5..1713c536 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -803,6 +803,12 @@ zread_ipv4_add (struct zserv *client, u_short length)
/* 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;
}