And here it is:
https://github.com/KaloNK/quagga/commit/fefc5bb127ea5575d2267e9f0feb403dbaf454f3

Also attached here as single file with all the commits as from
https://github.com/KaloNK/quagga/compare/master...realms_patchset.diff


On 2015-09-25 18:01, Kaloyan Kovachev wrote:

When i remove conditional compilation from the rest of the code
(except rt_name.c), will prepare a new diff with all the changes as
single file.

diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 5c832ed..a198bd2 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -379,6 +379,7 @@ attrhash_key_make (void *p)
       MIX(extra->weight);
       MIX(extra->mp_nexthop_global_in.s_addr);
       MIX(extra->originator_id.s_addr);
+      MIX(extra->realm);
     }
   
   if (attr->aspath)
@@ -426,6 +427,7 @@ attrhash_cmp (const void *p1, const void *p2)
           && ae1->aggregator_as == ae2->aggregator_as
           && ae1->aggregator_addr.s_addr == ae2->aggregator_addr.s_addr
           && ae1->weight == ae2->weight
+          && ae1->realm == ae2->realm
 #ifdef HAVE_IPV6
           && ae1->mp_nexthop_len == ae2->mp_nexthop_len
           && IPV6_ADDR_SAME (&ae1->mp_nexthop_global, &ae2->mp_nexthop_global)
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index b59fa8e..7c60155 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -85,6 +85,9 @@ struct attr_extra
   
   /* MP Nexthop length */
   u_char mp_nexthop_len;
+
+  /* Realm number */
+  u_int16_t realm;
 };
 
 /* BGP core attribute structure. */
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 34ba1ab..ae58171 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -691,6 +691,12 @@ bgp_input_modifier (struct peer *peer, struct prefix *p, struct attr *attr,
   struct bgp_filter *filter;
   struct bgp_info info;
   route_map_result_t ret;
+  u_int16_t realm_value = 0;
+
+
+  /* Apply default realm value. */
+  realm_value = (u_int16_t)(peer->realm & 0xFFFF);
+  (bgp_attr_extra_get (attr))->realm = realm_value;
 
   filter = &peer->filter[afi][safi];
 
@@ -726,6 +732,12 @@ bgp_export_modifier (struct peer *rsclient, struct peer *peer,
   struct bgp_filter *filter;
   struct bgp_info info;
   route_map_result_t ret;
+  u_int16_t realm_value = 0;
+
+
+  /* Apply default realm value. */
+  realm_value = (u_int16_t)(peer->realm & 0xFFFF);
+  (bgp_attr_extra_get (attr))->realm = realm_value;
 
   filter = &peer->filter[afi][safi];
 
@@ -5714,6 +5726,10 @@ route_vty_out (struct vty *vty, struct prefix *p,
 
       vty_out (vty, "%7u ", (attr->extra ? attr->extra->weight : 0));
     
+#ifdef SUPPORT_REALMS
+      vty_out (vty, "%7u ", (attr->extra ? attr->extra->realm : 0));
+#endif
+
       /* Print aspath */
       if (attr->aspath)
         aspath_print_vty (vty, "%s", attr->aspath, " ");
@@ -5779,6 +5795,10 @@ route_vty_out_tmp (struct vty *vty, struct prefix *p,
       
       vty_out (vty, "%7u ", (attr->extra ? attr->extra->weight : 0));
       
+#ifdef SUPPORT_REALMS
+      vty_out (vty, "%7u ", (attr->extra ? attr->extra->realm : 0));
+#endif
+
       /* Print aspath */
       if (attr->aspath)
         aspath_print_vty (vty, "%s", attr->aspath, " ");
@@ -6057,6 +6077,13 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
       if (attr->extra && attr->extra->weight != 0)
 	vty_out (vty, ", weight %u", attr->extra->weight);
 	
+#ifdef SUPPORT_REALMS
+      if (attr->extra && attr->extra->realm != 0) {
+        char realmbuf[64];
+        vty_out (vty, ", realm %s", rtnl_rtrealm_n2a (attr->extra->realm, realmbuf, sizeof (realmbuf)));
+      }
+#endif
+
       if (! CHECK_FLAG (binfo->flags, BGP_INFO_HISTORY))
 	vty_out (vty, ", valid");
 
@@ -6136,7 +6163,11 @@ route_vty_out_detail (struct vty *vty, struct bgp *bgp, struct prefix *p,
 			      "h history, * valid, > best, = multipath,%s"\
 		"              i internal, 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 5467cfd..dca17cf 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -1159,6 +1159,61 @@ struct route_map_rule_cmd route_set_metric_cmd =
   route_value_free,
 };
 
+#ifdef SUPPORT_REALMS
+/* `set realm REALM' */
+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;
+
+  if(type != RMAP_BGP)
+    return RMAP_OKAY;
+
+  bgp_info = object;
+  realm = (u_int32_t*) rule;
+
+  realm_value = (u_int16_t)(*realm & 0xFFFF);
+  (bgp_attr_extra_get (bgp_info->attr))->realm = realm_value;
+
+  return RMAP_OKAY;
+}
+
+static void *
+route_set_realm_compile (const char *arg)
+{
+  u_int32_t *realm;
+  u_int32_t realmid;
+
+  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 /* SUPPORT_REALMS */
+
 /* `set as-path prepend ASPATH' */
 
 /* For AS path prepend mechanism. */
@@ -3036,6 +3091,41 @@ DEFUN (set_local_pref,
   return bgp_route_set_add (vty, vty->index, "local-preference", argv[0]);
 }
 
+#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]);
+}
+
+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")
+#endif /* SUPPORT_REALMS */
+
 DEFUN (no_set_local_pref,
        no_set_local_pref_cmd,
        "no set local-preference",
@@ -3899,6 +3989,9 @@ 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_aspath_exclude_cmd);
   route_map_install_set (&route_set_origin_cmd);
@@ -3971,6 +4064,11 @@ bgp_route_map_init (void)
   install_element (RMAP_NODE, &set_metric_rtt_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, &no_set_realm_cmd);
+  install_element (RMAP_NODE, &no_set_realm_val_cmd);
+#endif
   install_element (RMAP_NODE, &set_aspath_prepend_cmd);
   install_element (RMAP_NODE, &set_aspath_prepend_lastas_cmd);
   install_element (RMAP_NODE, &set_aspath_exclude_cmd);
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 6233163..8f734de 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -3303,6 +3303,78 @@ DEFUN (no_neighbor_strict_capability,
   return peer_flag_unset_vty (vty, argv[0], PEER_FLAG_STRICT_CAP_MATCH);
 }
 
+#ifdef SUPPORT_REALMS
+/* 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 (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]);
+}
+
+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")
+#endif /* SUPPORT_REALMS */
+
 static int
 peer_timers_set_vty (struct vty *vty, const char *ip_str, 
                      const char *keep_str, const char *hold_str)
@@ -7822,6 +7894,17 @@ bgp_show_peer (struct vty *vty, struct peer *p)
 
   vty_out (vty, "%s", VTY_NEWLINE);
 
+  /* Default realm */
+  if (CHECK_FLAG (p->config, PEER_CONFIG_REALM))
+  {
+    char realmbuf[64];
+
+    vty_out (vty, "  Default realm is %s%s",
+    rtnl_rtrealm_n2a (p->realm, realmbuf, sizeof (realmbuf)), VTY_NEWLINE);
+  }
+
+  vty_out (vty, "%s", VTY_NEWLINE);
+
   /* Address Family Information */
   for (afi = AFI_IP ; afi < AFI_MAX ; afi++)
     for (safi = SAFI_UNICAST ; safi < SAFI_MAX ; safi++)
@@ -9628,6 +9711,13 @@ 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, &no_neighbor_realm_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 2616351..80d8ee0 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -743,6 +743,12 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp, sa
 	  api.distance = distance;
 	}
 
+      if (info->attr->extra->realm)
+	{
+	  SET_FLAG (api.message, ZAPI_MESSAGE_REALM);
+	  api.realm = info->attr->extra->realm;
+	}
+
       if (BGP_DEBUG(zebra, ZEBRA))
 	{
 	  int i;
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 4de854e..f57dbd2 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -644,6 +644,7 @@ peer_global_config_reset (struct peer *peer)
   peer->keepalive = 0;
   peer->connect = 0;
   peer->v_connect = BGP_DEFAULT_CONNECT_RETRY;
+  peer->realm = 0;
 }
 
 /* Check peer's AS number and determines if this peer is IBGP or EBGP */
@@ -810,6 +811,7 @@ peer_new (struct bgp *bgp)
   peer->status = Idle;
   peer->ostatus = Idle;
   peer->weight = 0;
+  peer->realm = 0;
   peer->password = NULL;
   peer->bgp = bgp;
   peer = peer_lock (peer); /* initial reference */
@@ -1437,6 +1439,9 @@ peer_group2peer_config_copy (struct peer_group *group, struct peer *peer,
   /* Weight */
   peer->weight = conf->weight;
 
+  /* Realm */
+  peer->realm = conf->realm;
+
   /* peer flags apply */
   peer->flags = conf->flags;
   /* peer af_flags apply */
@@ -3223,6 +3228,54 @@ peer_weight_unset (struct peer *peer)
   return 0;
 }
 
+/* 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;
+}
+
 int
 peer_timers_set (struct peer *peer, u_int32_t keepalive, u_int32_t holdtime)
 {
@@ -4925,6 +4978,18 @@ 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
+      /* Default realm. */
+      if (CHECK_FLAG (peer->config, PEER_CONFIG_REALM))
+        if (! peer_group_active (peer) ||
+           g_peer->realm != peer->realm)
+       {
+         char realmbuf[64];
+         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 58d1eca..35d8c0e 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -455,11 +455,13 @@ struct peer
 #define PEER_CONFIG_TIMER             (1 << 1) /* keepalive & holdtime */
 #define PEER_CONFIG_CONNECT           (1 << 2) /* connect */
 #define PEER_CONFIG_ROUTEADV          (1 << 3) /* route advertise */
+#define PEER_CONFIG_REALM             (1 << 4) /* Default realm. */
   u_int32_t weight;
   u_int32_t holdtime;
   u_int32_t keepalive;
   u_int32_t connect;
   u_int32_t routeadv;
+  u_int32_t realm;
 
   /* Timer values. */
   u_int32_t v_start;
@@ -892,6 +894,9 @@ extern int bgp_confederation_peers_check (struct bgp *, as_t);
 extern int bgp_confederation_peers_add (struct bgp *, as_t);
 extern int bgp_confederation_peers_remove (struct bgp *, as_t);
 
+extern int peer_realm_set (struct peer *, u_int32_t);
+extern int peer_realm_unset (struct peer *);
+
 extern int bgp_timers_set (struct bgp *, u_int32_t, u_int32_t);
 extern int bgp_timers_unset (struct bgp *);
 
diff --git a/configure.ac b/configure.ac
index 6da65f3..6395665 100755
--- a/configure.ac
+++ b/configure.ac
@@ -274,6 +274,8 @@ AC_ARG_ENABLE(configfile_mask,
   AS_HELP_STRING([--enable-configfile-mask=ARG], [set mask for config files]))
 AC_ARG_ENABLE(logfile_mask,
   AS_HELP_STRING([--enable-logfile-mask=ARG], [set mask for log files]))
+AC_ARG_ENABLE(realms,
+  AS_HELP_STRING([--enable-realms], [enable REALMS support under Linux]))
 
 AC_ARG_ENABLE(rtadv,
   AS_HELP_STRING([--disable-rtadv], [disable IPV6 router advertisement feature]))
@@ -631,6 +633,18 @@ esac
 
 AC_SYS_LARGEFILE
 
+dnl ------------------------
+dnl Integrated REALMS option
+dnl ------------------------
+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
+AM_CONDITIONAL([SUPPORT_REALMS], [test "${enable_realms}" = "yes"])
+
 dnl ---------------------
 dnl Integrated VTY option
 dnl ---------------------
diff --git a/lib/Makefile.am b/lib/Makefile.am
index ac51fc6..65f101d 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -46,6 +46,10 @@ memtypes.h: $(srcdir)/memtypes.c $(srcdir)/memtypes.awk
 route_types.h: $(srcdir)/route_types.txt $(srcdir)/route_types.pl
 	@PERL@ $(srcdir)/route_types.pl < $(srcdir)/route_types.txt > $@
 
+if SUPPORT_REALMS
+libzebra_la_SOURCES += rt_names.c
+endif
+
 if GIT_VERSION
 
 # bit of a trick here to always have up-to-date git stamps without triggering
diff --git a/lib/rt_names.c b/lib/rt_names.c
new file mode 100644
index 0000000..3ed3b16
--- /dev/null
+++ b/lib/rt_names.c
@@ -0,0 +1,208 @@
+/*
+ * 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, <[email protected]>
+ *
+ * Fix:		23 Apr 2005 	Calin Velea <[email protected]>
+ *		
+ *		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
+ *		
+ * Change:	June-July 2015	Kaloyan Kovachev
+ *		
+ *			- Leave only calls we need for realms and fix "discards 'const' qualifier" warnings
+ *			- Cache rtnl_tab until file has changed.
+ *			- Log events via Quagga.
+ *		
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/time.h>
+
+#include "zebra.h"
+#include <log.h>
+#include <sys/inotify.h>
+
+#ifdef SUPPORT_REALMS
+static void rtnl_tab_initialize(const 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) {
+			zlog_err("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_rtrealm_tab[256];
+
+static int rtnl_rtrealm_init = 0;
+
+#define INOTIFY_EVENT_SIZE		( sizeof (struct inotify_event) )
+#define INOTIFY_EVENT_BUF_LEN	( 1024 * ( INOTIFY_EVENT_SIZE + 16 ) )
+static int realms_fd = -1;
+static int realms_wd = -1;
+
+static void rtnl_rtrealm_initialize(void)
+{
+	int i;
+
+	if(!rtnl_rtrealm_init) {
+	    for(i = 0; i < 255; i++) {
+			rtnl_rtrealm_tab[i] = NULL;
+		}
+
+		if ( realms_fd < 0 ) {
+			realms_fd = inotify_init1(IN_NONBLOCK);
+			realms_wd = inotify_add_watch(realms_fd, "/etc/iproute2/rt_realms",
+				IN_CLOSE_WRITE | IN_DELETE_SELF | IN_MODIFY | IN_MOVE_SELF | IN_MOVED_FROM | IN_MOVED_TO );
+			if ( realms_wd < 0 ) {
+				zlog_err("Unable to register inotofy watch for realms change");
+				if ( realms_fd >= 0 ) {
+					close(realms_fd);
+					realms_fd = -1;
+				}
+			}
+		}
+	}
+
+	if ( realms_wd >= 0 ) {
+		char buffer[INOTIFY_EVENT_BUF_LEN];
+		int change_status = read(realms_fd, buffer, INOTIFY_EVENT_BUF_LEN);
+
+		if ( rtnl_rtrealm_init && change_status == EAGAIN)
+			return;
+
+		i = 0;
+		while ( i < change_status ) {
+			struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
+
+			if ( event->len && (event->mask & IN_DELETE_SELF || event->mask & IN_MOVE_SELF
+						|| event->mask & IN_MOVED_FROM || event->mask & IN_MOVED_TO) ) {
+				change_status = -1;
+			}
+		}
+
+		if ( change_status < 0 ) {
+			inotify_rm_watch(realms_fd, realms_wd);
+			close(realms_fd);
+			realms_fd = -1;
+			realms_wd = -1;
+		} else {
+			rtnl_rtrealm_init = 1;
+		}
+	}
+
+	zlog_info ("Initializing realms");
+	rtnl_tab_initialize("/etc/iproute2/rt_realms", rtnl_rtrealm_tab, 256);
+	if ( !rtnl_rtrealm_tab[0] )
+	    rtnl_rtrealm_tab[0] = strdup("unknown");
+}
+
+const 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, const 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;
+}
+#else
+
+const char * rtnl_rtrealm_n2a(int id, char *buf, int len)
+{
+	snprintf(buf, len, "%d", id);
+	return buf;
+}
+
+int rtnl_rtrealm_a2n(u_int32_t *id, const char *arg)
+{
+	return 0;
+}
+
+#endif
\ No newline at end of file
diff --git a/lib/rt_names.h b/lib/rt_names.h
new file mode 100644
index 0000000..be379de
--- /dev/null
+++ b/lib/rt_names.h
@@ -0,0 +1,7 @@
+#ifndef RT_NAMES_H_
+#define RT_NAMES_H_ 1
+
+extern const char* rtnl_rtrealm_n2a(int id, char *buf, int len);
+extern int rtnl_rtrealm_a2n(u_int32_t *id, const char *arg);
+
+#endif
diff --git a/lib/zclient.c b/lib/zclient.c
index 8e443e2..1fbe358 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -537,6 +537,8 @@ zapi_ipv4_route (u_char cmd, struct zclient *zclient, struct prefix_ipv4 *p,
     stream_putc (s, api->distance);
   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
     stream_putl (s, api->metric);
+  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_REALM))
+    stream_putw (s, api->realm);
 
   /* Put length at the first point of the stream. */
   stream_putw_at (s, 0, stream_get_endp (s));
@@ -591,6 +593,8 @@ zapi_ipv6_route (u_char cmd, struct zclient *zclient, struct prefix_ipv6 *p,
     stream_putc (s, api->distance);
   if (CHECK_FLAG (api->message, ZAPI_MESSAGE_METRIC))
     stream_putl (s, api->metric);
+  if (CHECK_FLAG (api->message, ZAPI_MESSAGE_REALM))
+    stream_putw (s, api->realm);
 
   /* 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 19b4f0e..a2b07f6 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -93,6 +93,7 @@ struct zclient
 #define ZAPI_MESSAGE_IFINDEX  0x02
 #define ZAPI_MESSAGE_DISTANCE 0x04
 #define ZAPI_MESSAGE_METRIC   0x08
+#define ZAPI_MESSAGE_REALM    0x10
 
 /* Zserv protocol message header */
 struct zserv_header
@@ -129,6 +130,8 @@ struct zapi_ipv4
   u_int32_t metric;
 
   vrf_id_t vrf_id;
+
+  u_int16_t realm;
 };
 
 /* Prototypes of zebra client service functions. */
@@ -199,6 +202,8 @@ struct zapi_ipv6
   u_int32_t metric;
 
   vrf_id_t vrf_id;
+
+  u_int16_t realm;
 };
 
 extern int zapi_ipv6_route (u_char cmd, struct zclient *zclient, 
diff --git a/lib/zebra.h b/lib/zebra.h
index 8586437..1ce62f3 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -252,6 +252,7 @@ typedef int socklen_t;
 #include "zassert.h"
 #include "str.h"
 
+#include "rt_names.h"
 
 #ifdef HAVE_BROKEN_CMSG_FIRSTHDR
 /* This bug is present in Solaris 8 and pre-patch Solaris 9 <sys/socket.h>;
diff --git a/zebra/connected.c b/zebra/connected.c
index 244f291..3e07a24 100644
--- a/zebra/connected.c
+++ b/zebra/connected.c
@@ -192,10 +192,10 @@ connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
     return;
 
   rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, NULL, ifp->ifindex,
-       ifp->vrf_id, RT_TABLE_MAIN, ifp->metric, 0, SAFI_UNICAST);
+       ifp->vrf_id, RT_TABLE_MAIN, ifp->metric, 0, SAFI_UNICAST, 0);
 
   rib_add_ipv4 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, NULL, ifp->ifindex,
-       ifp->vrf_id, RT_TABLE_MAIN, ifp->metric, 0, SAFI_MULTICAST);
+       ifp->vrf_id, RT_TABLE_MAIN, ifp->metric, 0, SAFI_MULTICAST, 0);
 
   rib_update (ifp->vrf_id);
 }
@@ -356,7 +356,7 @@ connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
 #endif
 
   rib_add_ipv6 (ZEBRA_ROUTE_CONNECT, 0, &p, NULL, ifp->ifindex, ifp->vrf_id,
-                RT_TABLE_MAIN, ifp->metric, 0, SAFI_UNICAST);
+                RT_TABLE_MAIN, ifp->metric, 0, SAFI_UNICAST, 0);
 
   rib_update (ifp->vrf_id);
 }
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index fd0d8fd..e535718 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -963,7 +963,7 @@ rtm_read (struct rt_msghdr *rtm)
           || rtm->rtm_type == RTM_ADD
           || rtm->rtm_type == RTM_CHANGE)
         rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gate.sin.sin_addr,
-                      NULL, 0, VRF_DEFAULT, 0, 0, 0, SAFI_UNICAST);
+                      NULL, 0, VRF_DEFAULT, 0, 0, 0, SAFI_UNICAST, 0);
       else
         rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,
                          &gate.sin.sin_addr, 0, VRF_DEFAULT, SAFI_UNICAST);
@@ -1005,7 +1005,7 @@ rtm_read (struct rt_msghdr *rtm)
           || rtm->rtm_type == RTM_ADD
           || rtm->rtm_type == RTM_CHANGE)
         rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p, &gate.sin6.sin6_addr,
-                      ifindex, VRF_DEFAULT, RT_TABLE_MAIN, 0, 0, SAFI_UNICAST);
+                      ifindex, VRF_DEFAULT, RT_TABLE_MAIN, 0, 0, SAFI_UNICAST, 0);
       else
         rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, zebra_flags, &p,
                          &gate.sin6.sin6_addr, ifindex,
diff --git a/zebra/rib.h b/zebra/rib.h
index 8328f23..1db6ca0 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -83,6 +83,9 @@ struct rib
   u_char nexthop_num;
   u_char nexthop_active_num;
   u_char nexthop_fib_num;
+
+  /* Realm information */
+  u_int16_t realm;
 };
 
 /* meta-queue structure:
@@ -199,6 +202,9 @@ struct static_ipv4
  see ZEBRA_FLAG_REJECT
      ZEBRA_FLAG_BLACKHOLE
  */
+
+  /* Realm information */
+  u_int16_t realm;
 };
 
 #ifdef HAVE_IPV6
@@ -231,6 +237,9 @@ struct static_ipv6
  see ZEBRA_FLAG_REJECT
      ZEBRA_FLAG_BLACKHOLE
  */
+
+  /* Realm information */
+  u_int16_t realm;
 };
 #endif /* HAVE_IPV6 */
 
@@ -497,7 +506,7 @@ extern struct route_table *zebra_vrf_static_table (afi_t, safi_t, vrf_id_t);
 extern int rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p, 
 			 struct in_addr *gate, struct in_addr *src,
 			 unsigned int ifindex, vrf_id_t vrf_id, int table_id,
-			 u_int32_t, u_char, safi_t);
+			 u_int32_t, u_char, safi_t, u_int16_t realm);
 
 extern int rib_add_ipv4_multipath (struct prefix_ipv4 *, struct rib *, safi_t);
 
@@ -525,7 +534,7 @@ extern unsigned long rib_score_proto (u_char proto);
 extern int
 static_add_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
 		      const char *ifname, u_char flags, u_char distance,
-		      vrf_id_t vrf_id);
+		      vrf_id_t vrf_id, u_int16_t realm);
 extern int
 static_delete_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
 			 const char *ifname, u_char distance, vrf_id_t vrf_id);
@@ -534,7 +543,7 @@ static_delete_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
 extern int
 rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
 	      struct in6_addr *gate, unsigned int ifindex, vrf_id_t vrf_id,
-	      int table_id, u_int32_t metric, u_char distance, safi_t safi);
+	      int table_id, u_int32_t metric, u_char distance, safi_t safi, u_int16_t realm);
 
 extern int
 rib_delete_ipv6 (int type, int flags, struct prefix_ipv6 *p,
@@ -549,7 +558,7 @@ extern struct route_table *rib_table_ipv6;
 extern int
 static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
 		 const char *ifname, u_char flags, u_char distance,
-		 vrf_id_t vrf_id);
+		 vrf_id_t vrf_id, u_int16_t realm);
 
 extern int
 static_delete_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 33fbc08..f2d0482 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -672,6 +672,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
   void *dest;
   void *gate;
   void *src;
+  u_int16_t realm = 0;
 
   rtm = NLMSG_DATA (h);
 
@@ -730,6 +731,16 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
   if (tb[RTA_PRIORITY])
     metric = *(int *) RTA_DATA(tb[RTA_PRIORITY]);
 
+#ifdef SUPPORT_REALMS
+  if (tb[RTA_FLOW])
+  {
+    u_int32_t rta_flow;
+
+    rta_flow = *(u_int32_t *) RTA_DATA (tb[RTA_FLOW]);
+    realm = rta_flow & 0xFFFF;
+  }
+#endif
+
   if (rtm->rtm_family == AF_INET)
     {
       struct prefix_ipv4 p;
@@ -739,7 +750,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
 
       if (!tb[RTA_MULTIPATH])
           rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, src, index,
-                        vrf_id, table, metric, 0, SAFI_UNICAST);
+                        vrf_id, table, metric, 0, SAFI_UNICAST, realm);
       else
         {
           /* This is a multipath route */
@@ -759,6 +770,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
           rib->table = table;
           rib->nexthop_num = 0;
           rib->uptime = time (NULL);
+          rib->realm = realm;
 
           for (;;)
             {
@@ -806,7 +818,7 @@ netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h,
       p.prefixlen = rtm->rtm_dst_len;
 
       rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, vrf_id,
-                    table, metric, 0, SAFI_UNICAST);
+                    table, metric, 0, SAFI_UNICAST, realm);
     }
 #endif /* HAVE_IPV6 */
 
@@ -846,6 +858,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
   void *dest;
   void *gate;
   void *src;
+  u_int16_t realm = 0;
 
   rtm = NLMSG_DATA (h);
 
@@ -920,6 +933,16 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
   if (tb[RTA_PREFSRC])
     src = RTA_DATA (tb[RTA_PREFSRC]);
 
+#ifdef SUPPORT_REALMS
+  if (tb[RTA_FLOW])
+  {
+	u_int32_t rta_flow;
+
+    rta_flow = *(u_int32_t *) RTA_DATA (tb[RTA_FLOW]);
+    realm = rta_flow & 0xFFFF;
+  }
+#endif
+
   if (h->nlmsg_type == RTM_NEWROUTE && tb[RTA_PRIORITY])
     metric = *(int *) RTA_DATA(tb[RTA_PRIORITY]);
 
@@ -942,7 +965,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
         {
           if (!tb[RTA_MULTIPATH])
             rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, src, index, vrf_id,
-                          table, metric, 0, SAFI_UNICAST);
+                          table, metric, 0, SAFI_UNICAST, realm);
           else
             {
               /* This is a multipath route */
@@ -962,6 +985,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
               rib->table = table;
               rib->nexthop_num = 0;
               rib->uptime = time (NULL);
+			  rib->realm = realm;
 
               for (;;)
                 {
@@ -1024,7 +1048,7 @@ netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h,
 
       if (h->nlmsg_type == RTM_NEWROUTE)
         rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, vrf_id, table,
-                      metric, 0, SAFI_UNICAST);
+                      metric, 0, SAFI_UNICAST, realm);
       else
         rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, vrf_id,
                          SAFI_UNICAST);
@@ -1636,6 +1660,12 @@ netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
   /* Metric. */
   addattr32 (&req.n, sizeof req, RTA_PRIORITY, rib->metric);
 
+#ifdef SUPPORT_REALMS
+  if (rib->realm) {
+      addattr32 (&req.n, sizeof req, RTA_FLOW, rib->realm);
+    }
+#endif
+
   if (discard)
     {
       if (cmd == RTM_NEWROUTE)
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 084af38..cd1903c 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -1806,7 +1806,7 @@ int
 rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p, 
 	      struct in_addr *gate, struct in_addr *src,
 	      unsigned int ifindex, vrf_id_t vrf_id, int table_id,
-	      u_int32_t metric, u_char distance, safi_t safi)
+	      u_int32_t metric, u_char distance, safi_t safi, u_int16_t realm)
 {
   struct rib *rib;
   struct rib *same = NULL;
@@ -1873,6 +1873,7 @@ rib_add_ipv4 (int type, int flags, struct prefix_ipv4 *p,
   rib->table = table_id;
   rib->nexthop_num = 0;
   rib->uptime = time (NULL);
+  rib->realm = realm;
 
   /* Nexthop settings. */
   if (gate)
@@ -2335,6 +2336,7 @@ static_install_ipv4 (safi_t safi, struct prefix *p, struct static_ipv4 *si)
       rib->vrf_id = si->vrf_id;
       rib->table = zebrad.rtm_table_default;
       rib->nexthop_num = 0;
+	  rib->realm = si->realm;
 
       switch (si->type)
         {
@@ -2438,7 +2440,7 @@ static_uninstall_ipv4 (safi_t safi, struct prefix *p, struct static_ipv4 *si)
 int
 static_add_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
 		      const char *ifname, u_char flags, u_char distance,
-		      vrf_id_t vrf_id)
+		      vrf_id_t vrf_id, u_int16_t realm)
 {
   u_char type = 0;
   struct route_node *rn;
@@ -2491,6 +2493,7 @@ static_add_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
   si->distance = distance;
   si->flags = flags;
   si->vrf_id = vrf_id;
+  si->realm = realm;
 
   if (gate)
     si->gate.ipv4 = *gate;
@@ -2597,8 +2600,8 @@ static_delete_ipv4_safi (safi_t safi, struct prefix *p, struct in_addr *gate,
 int
 rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
 	      struct in6_addr *gate, unsigned int ifindex,
-	      vrf_id_t vrf_id, int table_id,
-	      u_int32_t metric, u_char distance, safi_t safi)
+	      vrf_id_t vrf_id, int table_id, u_int32_t metric,
+		  u_char distance, safi_t safi, u_int16_t realm)
 {
   struct rib *rib;
   struct rib *same = NULL;
@@ -2658,6 +2661,7 @@ rib_add_ipv6 (int type, int flags, struct prefix_ipv6 *p,
   rib->table = table_id;
   rib->nexthop_num = 0;
   rib->uptime = time (NULL);
+  rib->realm = realm;
 
   /* Nexthop settings. */
   if (gate)
@@ -2883,6 +2887,7 @@ static_install_ipv6 (struct prefix *p, struct static_ipv6 *si)
       rib->vrf_id = si->vrf_id;
       rib->table = zebrad.rtm_table_default;
       rib->nexthop_num = 0;
+	  rib->realm = si->realm;
 
       switch (si->type)
 	{
@@ -2990,7 +2995,7 @@ static_uninstall_ipv6 (struct prefix *p, struct static_ipv6 *si)
 int
 static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
 		 const char *ifname, u_char flags, u_char distance,
-		 vrf_id_t vrf_id)
+		 vrf_id_t vrf_id, u_int16_t realm)
 {
   struct route_node *rn;
   struct static_ipv6 *si;
@@ -3033,6 +3038,7 @@ static_add_ipv6 (struct prefix *p, u_char type, struct in6_addr *gate,
   si->distance = distance;
   si->flags = flags;
   si->vrf_id = vrf_id;
+  si->realm = realm;
 
   switch (type)
     {
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index dd7df5c..3d7e32c 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -42,7 +42,8 @@ static int
 zebra_static_ipv4_safi (struct vty *vty, safi_t safi, int add_cmd,
 			const char *dest_str, const char *mask_str,
 			const char *gate_str, const char *flag_str,
-			const char *distance_str, const char *vrf_id_str)
+			const char *distance_str, const char *vrf_id_str,
+			const char *realm_str)
 {
   int ret;
   u_char distance;
@@ -52,6 +53,20 @@ zebra_static_ipv4_safi (struct vty *vty, safi_t safi, int add_cmd,
   const char *ifname;
   u_char flag = 0;
   vrf_id_t vrf_id = VRF_DEFAULT;
+  u_int16_t realm = 0;
+
+  if (realm_str != NULL) {
+      u_int32_t realmid;
+      int res;
+
+      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;
+    }
+    realm = (u_int16_t)realmid;
+  }
   
   ret = str2prefix (dest_str, &p);
   if (ret <= 0)
@@ -94,7 +109,7 @@ zebra_static_ipv4_safi (struct vty *vty, safi_t safi, int add_cmd,
           return CMD_WARNING;
         }
       if (add_cmd)
-        static_add_ipv4_safi (safi, &p, NULL, NULL, ZEBRA_FLAG_BLACKHOLE, distance, vrf_id);
+        static_add_ipv4_safi (safi, &p, NULL, NULL, ZEBRA_FLAG_BLACKHOLE, distance, vrf_id, realm);
       else
         static_delete_ipv4_safi (safi, &p, NULL, NULL, distance, vrf_id);
       return CMD_SUCCESS;
@@ -120,7 +135,7 @@ zebra_static_ipv4_safi (struct vty *vty, safi_t safi, int add_cmd,
   if (gate_str == NULL)
   {
     if (add_cmd)
-      static_add_ipv4_safi (safi, &p, NULL, NULL, flag, distance, vrf_id);
+      static_add_ipv4_safi (safi, &p, NULL, NULL, flag, distance, vrf_id, realm);
     else
       static_delete_ipv4_safi (safi, &p, NULL, NULL, distance, vrf_id);
 
@@ -136,7 +151,7 @@ zebra_static_ipv4_safi (struct vty *vty, safi_t safi, int add_cmd,
     ifname = gate_str;
 
   if (add_cmd)
-    static_add_ipv4_safi (safi, &p, ifname ? NULL : &gate, ifname, flag, distance, vrf_id);
+    static_add_ipv4_safi (safi, &p, ifname ? NULL : &gate, ifname, flag, distance, vrf_id, realm);
   else
     static_delete_ipv4_safi (safi, &p, ifname ? NULL : &gate, ifname, distance, vrf_id);
 
@@ -150,7 +165,7 @@ zebra_static_ipv4 (struct vty *vty, int add_cmd, const char *dest_str,
 		   const char *vrf_id_str)
 {
   return zebra_static_ipv4_safi (vty, SAFI_UNICAST, add_cmd, dest_str, mask_str,
-                                 gate_str, flag_str, distance_str, vrf_id_str);
+                                 gate_str, flag_str, distance_str, vrf_id_str, NULL);
 }
 
 /* Static unicast routes for multicast RPF lookup. */
@@ -166,7 +181,7 @@ DEFUN (ip_mroute_dist,
 {
   VTY_WARN_EXPERIMENTAL();
   return zebra_static_ipv4_safi(vty, SAFI_MULTICAST, 1, argv[0], NULL, argv[1],
-                                NULL, argc > 2 ? argv[2] : NULL, NULL);
+                                NULL, argc > 2 ? argv[2] : NULL, NULL, NULL);
 }
 
 ALIAS (ip_mroute_dist,
@@ -192,7 +207,7 @@ DEFUN (ip_mroute_dist_vrf,
   VTY_WARN_EXPERIMENTAL();
   return zebra_static_ipv4_safi(vty, SAFI_MULTICAST, 1, argv[0], NULL, argv[1],
                                 NULL, argc > 3 ? argv[2] : NULL,
-                                argc > 3 ? argv[3] : argv[2]);
+                                argc > 3 ? argv[3] : argv[2], NULL);
 }
 
 ALIAS (ip_mroute_dist_vrf,
@@ -217,7 +232,7 @@ DEFUN (no_ip_mroute_dist,
 {
   VTY_WARN_EXPERIMENTAL();
   return zebra_static_ipv4_safi(vty, SAFI_MULTICAST, 0, argv[0], NULL, argv[1],
-                                NULL, argc > 2 ? argv[2] : NULL, NULL);
+                                NULL, argc > 2 ? argv[2] : NULL, NULL, NULL);
 }
 
 ALIAS (no_ip_mroute_dist,
@@ -244,8 +259,66 @@ DEFUN (no_ip_mroute_dist_vrf,
   VTY_WARN_EXPERIMENTAL();
   return zebra_static_ipv4_safi(vty, SAFI_MULTICAST, 0, argv[0], NULL, argv[1],
                                 NULL, argc > 3 ? argv[2] : NULL,
-                                argc > 3 ? argv[3] : argv[2]);
+                                argc > 3 ? argv[3] : argv[2], NULL);
+}
+
+#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_safi (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1],
+                                NULL, 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_safi (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, 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_safi (vty, SAFI_UNICAST, 1, argv[0], NULL, argv[1], NULL, argv[2], NULL, 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_safi (vty, SAFI_UNICAST, 1, argv[0], argv[1], argv[2], NULL, argv[3], NULL, argv[4]);
+}
+#endif /* SUPPORT_REALMS */
 
 ALIAS (no_ip_mroute_dist_vrf,
        no_ip_mroute_vrf_cmd,
@@ -1295,6 +1368,8 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
         vty_out (vty, ", best");
       if (rib->refcnt)
         vty_out (vty, ", refcnt %ld", rib->refcnt);
+      if (rib->realm)
+       vty_out (vty, ", realm %5u", rib->realm);
       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_BLACKHOLE))
        vty_out (vty, ", blackhole");
       if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_REJECT))
@@ -1381,6 +1456,11 @@ vty_show_ip_route_detail (struct vty *vty, struct route_node *rn, int mcast)
           if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
             vty_out (vty, " (recursive)");
 
+          if (rib->realm) {
+            char realmbuf[50];
+            vty_out (vty, " realm %5s", rtnl_rtrealm_n2a (rib->realm, realmbuf, sizeof (realmbuf)));
+          }
+
           switch (nexthop->type)
             {
             case NEXTHOP_TYPE_IPV4:
@@ -1491,6 +1571,11 @@ vty_show_ip_route (struct vty *vty, struct route_node *rn, struct rib *rib)
       if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
         vty_out (vty, " (recursive)");
 
+      if (rib->realm) {
+        char realmbuf[50];
+        vty_out (vty, " realm %5s", rtnl_rtrealm_n2a (rib->realm, realmbuf, sizeof (realmbuf)));
+      }
+
       switch (nexthop->type)
         {
           case NEXTHOP_TYPE_IPV4:
@@ -2443,6 +2528,11 @@ static_config_ipv4 (struct vty *vty, safi_t safi, const char *cmd)
             if (si->vrf_id != VRF_DEFAULT)
               vty_out (vty, " vrf %u", si->vrf_id);
 
+            if (si->realm) {
+              char realmbuf[11];
+              vty_out (vty, " realm %s", rtnl_rtrealm_n2a (si->realm, realmbuf, sizeof realmbuf));
+            }
+
             vty_out (vty, "%s", VTY_NEWLINE);
 
             write = 1;
@@ -2569,7 +2659,7 @@ static int
 static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
 		  const char *gate_str, const char *ifname,
 		  const char *flag_str, const char *distance_str,
-		  const char *vrf_id_str)
+		  const char *vrf_id_str, const char *realm_str)
 {
   int ret;
   u_char distance;
@@ -2579,6 +2669,20 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
   u_char type = 0;
   vrf_id_t vrf_id = VRF_DEFAULT;
   u_char flag = 0;
+  u_int16_t realm = 0;
+
+  if (realm_str != NULL) {
+      u_int32_t realmid;
+      int res;
+
+      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;
+    }
+    realm = (u_int16_t)realmid;
+  }
   
   ret = str2prefix (dest_str, &p);
   if (ret <= 0)
@@ -2648,7 +2752,7 @@ static_ipv6_func (struct vty *vty, int add_cmd, const char *dest_str,
     VTY_GET_INTEGER ("VRF ID", vrf_id, vrf_id_str);
 
   if (add_cmd)
-    static_add_ipv6 (&p, type, gate, ifname, flag, distance, vrf_id);
+    static_add_ipv6 (&p, type, gate, ifname, flag, distance, vrf_id, realm);
   else
     static_delete_ipv6 (&p, type, gate, ifname, distance, vrf_id);
 
@@ -2665,7 +2769,7 @@ DEFUN (ipv6_route,
        "IPv6 gateway interface name\n")
 {
   return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL,
-                           NULL);
+                           NULL, NULL);
 }
 
 DEFUN (ipv6_route_flags,
@@ -2680,7 +2784,7 @@ DEFUN (ipv6_route_flags,
        "Silently discard pkts when matched\n")
 {
   return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL,
-                           NULL);
+                           NULL, NULL);
 }
 
 DEFUN (ipv6_route_ifname,
@@ -2693,7 +2797,7 @@ DEFUN (ipv6_route_ifname,
        "IPv6 gateway interface name\n")
 {
   return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL,
-                           NULL);
+                           NULL, NULL);
 }
 
 DEFUN (ipv6_route_ifname_flags,
@@ -2708,7 +2812,7 @@ DEFUN (ipv6_route_ifname_flags,
        "Silently discard pkts when matched\n")
 {
   return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL,
-                           NULL);
+                           NULL, NULL);
 }
 
 DEFUN (ipv6_route_pref,
@@ -2722,7 +2826,7 @@ DEFUN (ipv6_route_pref,
        "Distance value for this prefix\n")
 {
   return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2],
-                           NULL);
+                           NULL, NULL);
 }
 
 DEFUN (ipv6_route_flags_pref,
@@ -2738,7 +2842,7 @@ DEFUN (ipv6_route_flags_pref,
        "Distance value for this prefix\n")
 {
   return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3],
-                           NULL);
+                           NULL, NULL);
 }
 
 DEFUN (ipv6_route_ifname_pref,
@@ -2752,7 +2856,7 @@ DEFUN (ipv6_route_ifname_pref,
        "Distance value for this prefix\n")
 {
   return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3],
-                           NULL);
+                           NULL, NULL);
 }
 
 DEFUN (ipv6_route_ifname_flags_pref,
@@ -2768,9 +2872,66 @@ DEFUN (ipv6_route_ifname_flags_pref,
        "Distance value for this prefix\n")
 {
   return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4],
-                           NULL);
+                           NULL, NULL);
+}
+
+#ifdef SUPPORT_REALMS
+DEFUN (ipv6_route_realm,
+       ipv6_route_realm_cmd,
+       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) realm (<1-255>|WORD)",
+       IP_STR
+       "Establish static routes\n"
+       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+       "IPv6 gateway address\n"
+       "IPv6 gateway interface name\n"
+       "Destination realm value or name\n")
+{
+  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL,
+                           NULL, argv[2]);
+}
+
+DEFUN (ipv6_route_ifname_realm,
+       ipv6_route_ifname_realm_cmd,
+       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE realm (<1-255>|WORD)",
+       IP_STR
+       "Establish static routes\n"
+       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+       "IPv6 gateway address\n"
+       "IPv6 gateway interface name\n")
+{
+  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL,
+                           NULL, argv[3]);
+}
+
+DEFUN (ipv6_route_pref_realm,
+       ipv6_route_pref_realm_cmd,
+       "ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE) <1-255> realm (<1-255>|WORD)",
+       IP_STR
+       "Establish static routes\n"
+       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+       "IPv6 gateway address\n"
+       "IPv6 gateway interface name\n"
+       "Distance value for this prefix\n")
+{
+  return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2],
+                           NULL, argv[3]);
 }
 
+DEFUN (ipv6_route_ifname_pref_realm,
+       ipv6_route_ifname_pref_realm_cmd,
+       "ipv6 route X:X::X:X/M X:X::X:X INTERFACE <1-255> realm (<1-255>|WORD)",
+       IP_STR
+       "Establish static routes\n"
+       "IPv6 destination prefix (e.g. 3ffe:506::/32)\n"
+       "IPv6 gateway address\n"
+       "IPv6 gateway interface name\n"
+       "Distance value for this prefix\n")
+{
+  return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3],
+                           NULL, argv[4]);
+}
+#endif /* SUPPORT_REALMS */
+
 DEFUN (no_ipv6_route,
        no_ipv6_route_cmd,
        "no ipv6 route X:X::X:X/M (X:X::X:X|INTERFACE)",
@@ -2782,7 +2943,7 @@ DEFUN (no_ipv6_route,
        "IPv6 gateway interface name\n")
 {
   return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL,
-                           NULL);
+                           NULL, NULL);
 }
 
 ALIAS (no_ipv6_route,
@@ -2808,7 +2969,7 @@ DEFUN (no_ipv6_route_ifname,
        "IPv6 gateway interface name\n")
 {
   return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL,
-                           NULL);
+                           NULL, NULL);
 }
 
 ALIAS (no_ipv6_route_ifname,
@@ -2835,7 +2996,7 @@ DEFUN (no_ipv6_route_pref,
        "Distance value for this prefix\n")
 {
   return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2],
-                           NULL);
+                           NULL, NULL);
 }
 
 DEFUN (no_ipv6_route_flags_pref,
@@ -2853,7 +3014,7 @@ DEFUN (no_ipv6_route_flags_pref,
 {
   /* We do not care about argv[2] */
   return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3],
-                           NULL);
+                           NULL, NULL);
 }
 
 DEFUN (no_ipv6_route_ifname_pref,
@@ -2868,7 +3029,7 @@ DEFUN (no_ipv6_route_ifname_pref,
        "Distance value for this prefix\n")
 {
   return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3],
-                           NULL);
+                           NULL, NULL);
 }
 
 DEFUN (no_ipv6_route_ifname_flags_pref,
@@ -2885,7 +3046,7 @@ DEFUN (no_ipv6_route_ifname_flags_pref,
        "Distance value for this prefix\n")
 {
   return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4],
-                           NULL);
+                           NULL, NULL);
 }
 
 DEFUN (ipv6_route_vrf,
@@ -2899,7 +3060,7 @@ DEFUN (ipv6_route_vrf,
        VRF_CMD_HELP_STR)
 {
   return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, NULL,
-                           argv[2]);
+                           argv[2], NULL);
 }
 
 DEFUN (ipv6_route_flags_vrf,
@@ -2915,7 +3076,7 @@ DEFUN (ipv6_route_flags_vrf,
        VRF_CMD_HELP_STR)
 {
   return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], NULL,
-                           argv[3]);
+                           argv[3], NULL);
 }
 
 DEFUN (ipv6_route_ifname_vrf,
@@ -2929,7 +3090,7 @@ DEFUN (ipv6_route_ifname_vrf,
        VRF_CMD_HELP_STR)
 {
   return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, NULL,
-                           argv[3]);
+                           argv[3], NULL);
 }
 
 DEFUN (ipv6_route_ifname_flags_vrf,
@@ -2945,7 +3106,7 @@ DEFUN (ipv6_route_ifname_flags_vrf,
        VRF_CMD_HELP_STR)
 {
   return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], NULL,
-                           argv[4]);
+                           argv[4], NULL);
 }
 
 DEFUN (ipv6_route_pref_vrf,
@@ -2960,7 +3121,7 @@ DEFUN (ipv6_route_pref_vrf,
        VRF_CMD_HELP_STR)
 {
   return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, NULL, argv[2],
-                           argv[3]);
+                           argv[3], NULL);
 }
 
 DEFUN (ipv6_route_flags_pref_vrf,
@@ -2977,7 +3138,7 @@ DEFUN (ipv6_route_flags_pref_vrf,
        VRF_CMD_HELP_STR)
 {
   return static_ipv6_func (vty, 1, argv[0], argv[1], NULL, argv[2], argv[3],
-                           argv[4]);
+                           argv[4], NULL);
 }
 
 DEFUN (ipv6_route_ifname_pref_vrf,
@@ -2992,7 +3153,7 @@ DEFUN (ipv6_route_ifname_pref_vrf,
        VRF_CMD_HELP_STR)
 {
   return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], NULL, argv[3],
-                           argv[4]);
+                           argv[4], NULL);
 }
 
 DEFUN (ipv6_route_ifname_flags_pref_vrf,
@@ -3009,7 +3170,7 @@ DEFUN (ipv6_route_ifname_flags_pref_vrf,
        VRF_CMD_HELP_STR)
 {
   return static_ipv6_func (vty, 1, argv[0], argv[1], argv[2], argv[3], argv[4],
-                           argv[5]);
+                           argv[5], NULL);
 }
 
 DEFUN (no_ipv6_route_vrf,
@@ -3024,7 +3185,7 @@ DEFUN (no_ipv6_route_vrf,
        VRF_CMD_HELP_STR)
 {
   return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, NULL,
-                           (argc > 3) ? argv[3] : argv[2]);
+                           (argc > 3) ? argv[3] : argv[2], NULL);
 }
 
 ALIAS (no_ipv6_route_vrf,
@@ -3052,7 +3213,7 @@ DEFUN (no_ipv6_route_ifname_vrf,
        VRF_CMD_HELP_STR)
 {
   return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, NULL,
-                           (argc > 4) ? argv[4] : argv[3]);
+                           (argc > 4) ? argv[4] : argv[3], NULL);
 }
 
 ALIAS (no_ipv6_route_ifname_vrf,
@@ -3081,7 +3242,7 @@ DEFUN (no_ipv6_route_pref_vrf,
        VRF_CMD_HELP_STR)
 {
   return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, NULL, argv[2],
-                           argv[3]);
+                           argv[3], NULL);
 }
 
 DEFUN (no_ipv6_route_flags_pref_vrf,
@@ -3100,7 +3261,7 @@ DEFUN (no_ipv6_route_flags_pref_vrf,
 {
   /* We do not care about argv[2] */
   return static_ipv6_func (vty, 0, argv[0], argv[1], NULL, argv[2], argv[3],
-                           argv[4]);
+                           argv[4], NULL);
 }
 
 DEFUN (no_ipv6_route_ifname_pref_vrf,
@@ -3116,7 +3277,7 @@ DEFUN (no_ipv6_route_ifname_pref_vrf,
        VRF_CMD_HELP_STR)
 {
   return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], NULL, argv[3],
-                           argv[4]);
+                           argv[4], NULL);
 }
 
 DEFUN (no_ipv6_route_ifname_flags_pref_vrf,
@@ -3134,7 +3295,7 @@ DEFUN (no_ipv6_route_ifname_flags_pref_vrf,
        VRF_CMD_HELP_STR)
 {
   return static_ipv6_func (vty, 0, argv[0], argv[1], argv[2], argv[3], argv[4],
-                           argv[5]);
+                           argv[5], NULL);
 }
 
 DEFUN (show_ipv6_route,
@@ -3856,6 +4017,11 @@ static_config_ipv6 (struct vty *vty)
             if (si->vrf_id != VRF_DEFAULT)
               vty_out (vty, " vrf %u", si->vrf_id);
 
+            if (si->realm) {
+              char realmbuf[11];
+
+              vty_out (vty, " realm %s", rtnl_rtrealm_n2a (si->realm, realmbuf, sizeof realmbuf));
+            }
             vty_out (vty, "%s", VTY_NEWLINE);
 
             write = 1;
@@ -3955,6 +4121,19 @@ zebra_vty_init (void)
   install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance_cmd);
   install_element (CONFIG_NODE, &no_ip_route_mask_flags_distance2_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);
+#ifdef HAVE_IPV6
+  install_element (CONFIG_NODE, &ipv6_route_realm_cmd);
+  install_element (CONFIG_NODE, &ipv6_route_ifname_realm_cmd);
+  install_element (CONFIG_NODE, &ipv6_route_pref_realm_cmd);
+  install_element (CONFIG_NODE, &ipv6_route_ifname_pref_realm_cmd);
+#endif /* HAVE_IPV6 */
+#endif /* SUPPORT_REALMS */
+
   install_element (VIEW_NODE, &show_ip_route_cmd);
   install_element (VIEW_NODE, &show_ip_route_addr_cmd);
   install_element (VIEW_NODE, &show_ip_route_prefix_cmd);
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 8ca5615..31d840e 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -905,6 +905,12 @@ zread_ipv4_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
     
   /* Table */
   rib->table=zebrad.rtm_table_default;
+
+  if (CHECK_FLAG (message, ZAPI_MESSAGE_REALM))
+    rib->realm = stream_getw (s);
+  else
+    rib->realm = 0;
+
   rib_add_ipv4_multipath (&p, rib, safi);
   return 0;
 }
@@ -1093,14 +1099,19 @@ zread_ipv6_add (struct zserv *client, u_short length, vrf_id_t vrf_id)
   else
     api.metric = 0;
     
+  if (CHECK_FLAG (api.message, ZAPI_MESSAGE_REALM))
+    api.realm = stream_getw (s);
+  else
+    api.realm = 0;
+
   if (IN6_IS_ADDR_UNSPECIFIED (&nexthop))
     rib_add_ipv6 (api.type, api.flags, &p, NULL, ifindex,
                   vrf_id, zebrad.rtm_table_default, api.metric,
-                  api.distance, api.safi);
+                  api.distance, api.safi, api.realm);
   else
     rib_add_ipv6 (api.type, api.flags, &p, &nexthop, ifindex,
                   vrf_id, zebrad.rtm_table_default, api.metric,
-                  api.distance, api.safi);
+                  api.distance, api.safi, api.realm);
   return 0;
 }
 
_______________________________________________
Quagga-dev mailing list
[email protected]
https://lists.quagga.net/mailman/listinfo/quagga-dev

Reply via email to