int metric = 0;
u_int32_t mtu = 0;
uint8_t distance = 0;
+ route_tag_t tag = 0;
void *dest = NULL;
void *gate = NULL;
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];
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 */
re->table = table;
re->nexthop_num = 0;
re->uptime = time(NULL);
+ re->tag = tag;
for (;;) {
if (len < (int)sizeof(*rtnh)
memcpy(&nh.gate, gate, sz);
rib_delete(afi, SAFI_UNICAST, vrf_id,
proto, 0, flags, &p, NULL, &nh,
- table, metric, true);
+ table, metric, true, NULL);
} else {
/* XXX: need to compare the entire list of nexthops
* here for NLM_F_APPEND stupidity */
rib_delete(afi, SAFI_UNICAST, vrf_id,
proto, 0, flags, &p, NULL, NULL,
- table, metric, true);
+ table, metric, true, NULL);
}
}
* 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;
return suc;
}
-int kernel_route_rib(struct prefix *p, struct prefix *src_p,
- struct route_entry *old, struct route_entry *new)
+void kernel_route_rib(struct prefix *p, struct prefix *src_p,
+ struct route_entry *old, struct route_entry *new)
{
+ int ret = 0;
+
assert(old || new);
- if (!old && new)
- return netlink_route_multipath(RTM_NEWROUTE, p, src_p, new, 0);
- if (old && !new)
- return netlink_route_multipath(RTM_DELROUTE, p, src_p, old, 0);
+ if (new) {
+ if (p->family == AF_INET)
+ ret = netlink_route_multipath(RTM_NEWROUTE, p, src_p,
+ new, (old) ? 1 : 0);
+ else {
+ /*
+ * So v6 route replace semantics are not in
+ * the kernel at this point as I understand it.
+ * So let's do a delete than an add.
+ * In the future once v6 route replace semantics
+ * are in we can figure out what to do here to
+ * allow working with old and new kernels.
+ *
+ * I'm also intentionally ignoring the failure case
+ * of the route delete. If that happens yeah we're
+ * screwed.
+ */
+ if (old)
+ netlink_route_multipath(RTM_DELROUTE, p,
+ src_p, old, 0);
+ ret = netlink_route_multipath(RTM_NEWROUTE, p,
+ src_p, new, 0);
+ }
+ kernel_route_rib_pass_fail(p, new,
+ (!ret) ?
+ SOUTHBOUND_INSTALL_SUCCESS :
+ SOUTHBOUND_INSTALL_FAILURE);
+ return;
+ }
- if (p->family == AF_INET)
- return netlink_route_multipath(RTM_NEWROUTE, p, src_p, new, 1);
+ if (old) {
+ ret = netlink_route_multipath(RTM_DELROUTE, p, src_p, old, 0);
- /*
- * So v6 route replace semantics are not in the kernel at this
- * point as I understand it.
- * So let's do a delete than an add.
- * In the future once v6 route replace semantics are in
- * we can figure out what to do here to allow working
- * with old and new kernels.
- *
- * I'm also intentionally ignoring the failure case
- * of the route delete. If that happens yeah we're
- * screwed.
- */
- netlink_route_multipath(RTM_DELROUTE, p, src_p, old, 0);
- return netlink_route_multipath(RTM_NEWROUTE, p, src_p, new, 0);
+ kernel_route_rib_pass_fail(p, old,
+ (!ret) ?
+ SOUTHBOUND_DELETE_SUCCESS :
+ SOUTHBOUND_DELETE_FAILURE);
+ }
}
int kernel_neigh_update(int add, int ifindex, uint32_t addr, char *lla,
_netlink_mpls_build_singlepath(routedesc, nhlfe,
&req.n, &req.r,
sizeof req, cmd);
- if (cmd == RTM_NEWROUTE) {
- SET_FLAG(nhlfe->flags,
- NHLFE_FLAG_INSTALLED);
- SET_FLAG(nexthop->flags,
- NEXTHOP_FLAG_FIB);
- } else {
- UNSET_FLAG(nhlfe->flags,
- NHLFE_FLAG_INSTALLED);
- UNSET_FLAG(nexthop->flags,
- NEXTHOP_FLAG_FIB);
- }
nexthop_num++;
break;
}
rta, rtnh, &req.r,
&src1);
rtnh = RTNH_NEXT(rtnh);
-
- if (cmd == RTM_NEWROUTE) {
- SET_FLAG(nhlfe->flags,
- NHLFE_FLAG_INSTALLED);
- SET_FLAG(nexthop->flags,
- NEXTHOP_FLAG_FIB);
- } else {
- UNSET_FLAG(nhlfe->flags,
- NHLFE_FLAG_INSTALLED);
- UNSET_FLAG(nexthop->flags,
- NEXTHOP_FLAG_FIB);
- }
}
}