|| (proto == RTPROT_STATIC) || (proto == RTPROT_ZEBRA)
|| (proto == RTPROT_ISIS) || (proto == RTPROT_RIPNG)
|| (proto == RTPROT_NHRP) || (proto == RTPROT_EIGRP)
- || (proto == RTPROT_LDP) || (proto == RTPROT_BABEL)) {
+ || (proto == RTPROT_LDP) || (proto == RTPROT_BABEL)
+ || (proto == RTPROT_RIP)) {
return 1;
}
return 0;
}
-static inline int get_rt_proto(int proto)
+static inline int zebra2proto(int proto)
{
switch (proto) {
case ZEBRA_ROUTE_BABEL:
return proto;
}
+static inline int proto2zebra(int proto, int family)
+{
+ switch (proto) {
+ case RTPROT_BABEL:
+ proto = ZEBRA_ROUTE_BABEL;
+ break;
+ case RTPROT_BGP:
+ proto = ZEBRA_ROUTE_BGP;
+ break;
+ case RTPROT_OSPF:
+ proto = (family == AFI_IP) ?
+ ZEBRA_ROUTE_OSPF : ZEBRA_ROUTE_OSPF6;
+ break;
+ case RTPROT_ISIS:
+ proto = ZEBRA_ROUTE_ISIS;
+ break;
+ case RTPROT_RIP:
+ proto = ZEBRA_ROUTE_RIP;
+ break;
+ case RTPROT_RIPNG:
+ proto = ZEBRA_ROUTE_RIPNG;
+ break;
+ case RTPROT_NHRP:
+ proto = ZEBRA_ROUTE_NHRP;
+ break;
+ case RTPROT_EIGRP:
+ proto = ZEBRA_ROUTE_EIGRP;
+ break;
+ case RTPROT_LDP:
+ proto = ZEBRA_ROUTE_LDP;
+ break;
+ case RTPROT_STATIC:
+ proto = ZEBRA_ROUTE_STATIC;
+ break;
+ default:
+ proto = ZEBRA_ROUTE_KERNEL;
+ break;
+ }
+ return proto;
+}
+
/*
Pending: create an efficient table_id (in a tree/hash) based lookup)
*/
char anyaddr[16] = {0};
+ int proto = ZEBRA_ROUTE_KERNEL;
int index = 0;
int table;
int metric = 0;
}
/* Route which inserted by Zebra. */
- if (is_selfroute(rtm->rtm_protocol))
+ if (is_selfroute(rtm->rtm_protocol)) {
flags |= ZEBRA_FLAG_SELFROUTE;
-
+ proto = proto2zebra(rtm->rtm_protocol, rtm->rtm_family);
+ }
if (tb[RTA_OIF])
index = *(int *)RTA_DATA(tb[RTA_OIF]);
memcpy(&nh.src, prefsrc, sz);
if (gate)
memcpy(&nh.gate, gate, sz);
- rib_add(afi, SAFI_UNICAST, vrf_id, ZEBRA_ROUTE_KERNEL,
+
+ rib_add(afi, SAFI_UNICAST, vrf_id, proto,
0, flags, &p, NULL, &nh, table, metric, mtu, 0);
} else {
/* This is a multipath route */
len = RTA_PAYLOAD(tb[RTA_MULTIPATH]);
re = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
- re->type = ZEBRA_ROUTE_KERNEL;
+ re->type = proto;
re->distance = 0;
re->flags = flags;
re->metric = metric;
if (gate)
memcpy(&nh.gate, gate, sz);
rib_delete(afi, SAFI_UNICAST, vrf_id,
- ZEBRA_ROUTE_KERNEL, 0, flags, &p, NULL, &nh,
+ proto, 0, flags, &p, NULL, &nh,
table, metric);
} else {
/* XXX: need to compare the entire list of nexthops
* here for NLM_F_APPEND stupidity */
rib_delete(afi, SAFI_UNICAST, vrf_id,
- ZEBRA_ROUTE_KERNEL, 0, flags, &p, NULL, NULL,
+ proto, 0, flags, &p, NULL, NULL,
table, metric);
}
}
req.r.rtm_family = family;
req.r.rtm_dst_len = p->prefixlen;
req.r.rtm_src_len = src_p ? src_p->prefixlen : 0;
- req.r.rtm_protocol = get_rt_proto(re->type);
+ req.r.rtm_protocol = zebra2proto(re->type);
req.r.rtm_scope = RT_SCOPE_UNIVERSE;
req.r.rtm_type = RTN_UNICAST;
for (ALL_NEXTHOPS(re->nexthop, nexthop)) {
inet_ntop(p->family, &nexthop->gate, straddr, INET6_ADDRSTRLEN);
- zlog_debug("%s: %s %s with flags %s%s%s", func,
+ zlog_debug("%s: %s %s[%u] with flags %s%s%s", func,
(nexthop->rparent ? " NH" : "NH"), straddr,
+ nexthop->ifindex,
(CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE)
? "ACTIVE "
: ""),
struct route_node *rn;
struct route_entry *re;
struct route_entry *next;
+ struct nexthop *nexthop;
int ret = 0;
- if (table)
- for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
- RNODE_FOREACH_RE_SAFE(rn, re, next)
- {
- if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
- continue;
+ if (!table)
+ return;
- if (re->type == ZEBRA_ROUTE_KERNEL
- && CHECK_FLAG(re->flags,
- ZEBRA_FLAG_SELFROUTE)) {
- ret = rib_uninstall_kernel(rn, re);
- if (!ret)
- rib_delnode(rn, re);
- }
- }
+ for (rn = route_top(table); rn; rn = srcdest_route_next(rn)) {
+ RNODE_FOREACH_RE_SAFE(rn, re, next)
+ {
+ if (IS_ZEBRA_DEBUG_RIB)
+ route_entry_dump(&rn->p, NULL, re);
+
+ if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
+ continue;
+
+ if (!CHECK_FLAG(re->flags, ZEBRA_FLAG_SELFROUTE))
+ continue;
+
+ /*
+ * So we are starting up and have received
+ * routes from the kernel that we have installed
+ * from a previous run of zebra but not cleaned
+ * up ( say a kill -9 )
+ * But since we haven't actually installed
+ * them yet( we received them from the kernel )
+ * we don't think they are active.
+ * So let's pretend they are active to actually
+ * remove them.
+ * In all honesty I'm not sure if we should
+ * mark them as active when we receive them
+ * This is startup only so probably ok.
+ *
+ * If we ever decide to move rib_sweep_table
+ * to a different spot (ie startup )
+ * this decision needs to be revisited
+ */
+ for (ALL_NEXTHOPS(re->nexthop, nexthop))
+ SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
+
+ ret = rib_uninstall_kernel(rn, re);
+ if (!ret)
+ rib_delnode(rn, re);
+ }
+ }
}
/* Sweep all RIB tables. */
struct vrf *vrf;
struct zebra_vrf *zvrf;
- RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id)
- if ((zvrf = vrf->info) != NULL) {
+ RB_FOREACH(vrf, vrf_id_head, &vrfs_by_id) {
+ if ((zvrf = vrf->info) == NULL)
+ continue;
+
rib_sweep_table(zvrf->table[AFI_IP][SAFI_UNICAST]);
rib_sweep_table(zvrf->table[AFI_IP6][SAFI_UNICAST]);
}