zebra: Add ability to support tags -> realms in linux

Linux has the ability to support a concept of 'realms'.
This concept allows you to mark routes with a realm id
value of 1-255.  If you have marked the realm
of a route then you can use the tc program to
apply policy to the routes.

This commit adds the ability of FRR to interpret
a tag from (1-255) as a realm when installing into
the kernel.  Please note that at this point in time
there is no way to set policy from within FRR.  This
must be done outside of it.

The normal methodology for setting tags is valid here
via a route-map.

Finally this is only applied if the --enable-realms configure
option is applied.

Signed-off-by: Kaloyan Kovachev <kkovachev@varna.net>
This commit is contained in:
Kaloyan Kovachev 2017-12-08 14:44:15 -05:00 committed by Donald Sharp
parent cb9cef73bd
commit 4e40b6d615
7 changed files with 39 additions and 9 deletions

View file

@ -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 ---------------------

View file

@ -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];

View file

@ -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,

View file

@ -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 *);

View file

@ -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;

View file

@ -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)

View file

@ -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();