diff --git a/configure.ac b/configure.ac index 16cc8901a3..762ce14816 100755 --- a/configure.ac +++ b/configure.ac @@ -354,6 +354,8 @@ AC_ARG_ENABLE(logfile_mask, AS_HELP_STRING([--enable-logfile-mask=ARG], [set mask for log files])) AC_ARG_ENABLE(shell_access, AS_HELP_STRING([--enable-shell-access], [Allow users to access shell/telnet/ssh])) +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])) AC_ARG_ENABLE(irdp, @@ -897,6 +899,22 @@ AM_CONDITIONAL(SOLARIS, test "${SOLARIS}" = "solaris") AC_SYS_LARGEFILE +dnl ------------------------ +dnl Integrated REALMS option +dnl ------------------------ +if test "${enable_realms}" = "yes"; then + case "$host_os" in + linux*) + AC_DEFINE(SUPPORT_REALMS,, Realms support) + ;; + *) + echo "Sorry, only Linux has REALMS support" + exit 1 + ;; + esac +fi +AM_CONDITIONAL([SUPPORT_REALMS], [test "${enable_realms}" = "yes"]) + dnl --------------------- dnl Integrated VTY option dnl --------------------- diff --git a/zebra/connected.c b/zebra/connected.c index 18dc6a970b..9c0a3af8e3 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -239,10 +239,10 @@ void connected_up(struct interface *ifp, struct connected *ifc) } rib_add(afi, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, - &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0); + &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0); rib_add(afi, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0, - &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0); + &p, NULL, &nh, RT_TABLE_MAIN, ifp->metric, 0, 0, 0); if (IS_ZEBRA_DEBUG_RIB_DETAILED) { char buf[PREFIX_STRLEN]; diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 89c933f90f..d45a502543 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -1050,7 +1050,7 @@ void rtm_read(struct rt_msghdr *rtm) || rtm->rtm_type == RTM_CHANGE) rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - &nh, 0, 0, 0, 0); + &nh, 0, 0, 0, 0, 0); else rib_delete(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, @@ -1098,7 +1098,7 @@ void rtm_read(struct rt_msghdr *rtm) || rtm->rtm_type == RTM_CHANGE) rib_add(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, - &nh, 0, 0, 0, 0); + &nh, 0, 0, 0, 0, 0); else rib_delete(AFI_IP6, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, zebra_flags, &p, NULL, diff --git a/zebra/rib.h b/zebra/rib.h index 4b82e8d8d5..7e166f7e1c 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -296,7 +296,7 @@ extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, int flags, struct prefix *p, struct prefix_ipv6 *src_p, const struct nexthop *nh, u_int32_t table_id, u_int32_t metric, u_int32_t mtu, - uint8_t distance); + uint8_t distance, route_tag_t tag); extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *, struct prefix_ipv6 *src_p, struct route_entry *); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index cbe736e00c..910f9b3d93 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -230,6 +230,7 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, int metric = 0; u_int32_t mtu = 0; uint8_t distance = 0; + route_tag_t tag = 0; void *dest = NULL; void *gate = NULL; @@ -321,6 +322,11 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, if (tb[RTA_PRIORITY]) metric = *(int *)RTA_DATA(tb[RTA_PRIORITY]); +#if defined(SUPPORT_REALMS) + if (tb[RTA_FLOW]) + tag = *(uint32_t *)RTA_DATA(tb[RTA_FLOW]); +#endif + if (tb[RTA_METRICS]) { struct rtattr *mxrta[RTAX_MAX + 1]; @@ -429,7 +435,8 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, memcpy(&nh.gate, gate, sz); rib_add(afi, SAFI_UNICAST, vrf_id, proto, - 0, flags, &p, NULL, &nh, table, metric, mtu, distance); + 0, flags, &p, NULL, &nh, table, metric, + mtu, distance, tag); } else { /* This is a multipath route */ @@ -449,6 +456,7 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl, re->table = table; re->nexthop_num = 0; re->uptime = time(NULL); + re->tag = tag; for (;;) { if (len < (int)sizeof(*rtnh) @@ -1310,7 +1318,10 @@ static int netlink_route_multipath(int cmd, struct prefix *p, * by the routing protocol and for communicating with protocol peers. */ addattr32(&req.n, sizeof req, RTA_PRIORITY, NL_DEFAULT_ROUTE_METRIC); - +#if defined(SUPPORT_REALMS) + if (re->tag > 0 && re->tag <= 255) + addattr32(&req.n, sizeof req, RTA_FLOW, re->tag); +#endif /* Table corresponding to this route. */ if (re->table < 256) req.r.rtm_table = re->table; diff --git a/zebra/rtread_getmsg.c b/zebra/rtread_getmsg.c index 39ecdb335c..69e45f9a6c 100644 --- a/zebra/rtread_getmsg.c +++ b/zebra/rtread_getmsg.c @@ -98,7 +98,7 @@ static void handle_route_entry(mib2_ipRouteEntry_t *routeEntry) nh.gate.ipv4.s_addr = routeEntry->ipRouteNextHop; rib_add(AFI_IP, SAFI_UNICAST, VRF_DEFAULT, ZEBRA_ROUTE_KERNEL, 0, - zebra_flags, &prefix, NULL, &nh, 0, 0, 0, 0); + zebra_flags, &prefix, NULL, &nh, 0, 0, 0, 0, 0); } void route_read(struct zebra_ns *zns) diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 58b6965995..6406386b1a 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -2480,7 +2480,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, int flags, struct prefix *p, struct prefix_ipv6 *src_p, const struct nexthop *nh, u_int32_t table_id, u_int32_t metric, - u_int32_t mtu, uint8_t distance) + u_int32_t mtu, uint8_t distance, route_tag_t tag) { struct route_entry *re; struct nexthop *nexthop; @@ -2497,6 +2497,7 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance, re->vrf_id = vrf_id; re->nexthop_num = 0; re->uptime = time(NULL); + re->tag = tag; /* Add nexthop. */ nexthop = nexthop_new();