CF_KEYWORDS(ROUTER, ID, PROTOCOL, TEMPLATE, PREFERENCE, DISABLED, DEBUG, ALL, OFF, DIRECT)
CF_KEYWORDS(INTERFACE, IMPORT, EXPORT, FILTER, NONE, TABLE, STATES, ROUTES, FILTERS)
- CF_KEYWORDS(LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE)
+CF_KEYWORDS(IPV4, IPVX, VPN4, VPN6, MPLS)
+ CF_KEYWORDS(LIMIT, ACTION, WARN, BLOCK, RESTART, DISABLE, KEEP, FILTERED)
CF_KEYWORDS(PASSWORD, FROM, PASSIVE, TO, ID, EVENTS, PACKETS, PROTOCOLS, INTERFACES)
-CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE, ROA, MAX, FLUSH)
+CF_KEYWORDS(PRIMARY, STATS, COUNT, FOR, COMMANDS, PREEXPORT, GENERATE, ROA, AS, MAX, FLUSH)
CF_KEYWORDS(LISTEN, BGP, V6ONLY, DUAL, ADDRESS, PORT, PASSWORDS, DESCRIPTION, SORTED)
CF_KEYWORDS(RELOAD, IN, OUT, MRTDUMP, MESSAGES, RESTRICT, MEMORY, IGP_METRIC)
| EXPORT imexport { this_proto->out_filter = $2; }
| IMPORT LIMIT limit_spec { this_proto->in_limit = $3; }
| EXPORT LIMIT limit_spec { this_proto->out_limit = $3; }
- | TABLE rtable { this_proto->table = $2; }
+ | IMPORT KEEP FILTERED bool { this_proto->in_keep_filtered = $4; }
+ | TABLE rtable {
+ if (!rt_match($2->addr_type, this_proto->protocol->tables))
+ cf_error("Incompatible table class");
+ this_proto->table = $2;
+ }
| ROUTER ID idval { this_proto->router_id = $3; }
| DESCRIPTION TEXT { this_proto->dsc = $2; }
;
} rte;
#define REF_COW 1 /* Copy this rte on write */
+ #define REF_FILTERED 2 /* Route is rejected by import filter */
+
+ /* Route is valid for propagation (may depend on other flags in the future), accepts NULL */
+ static inline int rte_is_valid(rte *r) { return r && !(r->flags & REF_FILTERED); }
+
+ /* Route just has REF_FILTERED flag */
+ static inline int rte_is_filtered(rte *r) { return !!(r->flags & REF_FILTERED); }
+
+/* Types of routing tables/entries */
+#define RT_IPV4 1
+#define RT_IPV6 2
+#define RT_VPN4 3
+#define RT_VPN6 4
+#define RT_MPLS 5
+
+#define RT_MAX 6
+
+/* Same tables using bit positions. Used for appropriate table linking on protocol init */
+#define RTB_IPV4 (1 << RT_IPV4)
+#define RTB_IPV6 (1 << RT_IPV6)
+#define RTB_VPN4 (1 << RT_VPN4)
+#define RTB_VPN6 (1 << RT_VPN6)
+#define RTB_MPLS (1 << RT_MPLS)
+
+#define RTB_IP (RTB_IPV4 | RTB_IPV6)
+
+// XXXX these should probably go away, check their users
+#define RT_IP RT_IPV6
+
+
/* Types of route announcement, also used as flags */
#define RA_OPTIMAL 1 /* Announcement of optimal route change */
#define RA_ACCEPTED 2 /* Announcement of first accepted route */
struct announce_hook *a;
int ok;
- bsprintf(ia, "%I/%d", n->n.prefix, n->n.pxlen);
+ fn_print(prefix, sizeof(prefix), &n->n);
- if (n->routes)
- d->net_counter++;
+
for(e=n->routes; e; e=e->next)
{
+ if (rte_is_filtered(e) != d->filtered)
+ continue;
+
struct ea_list *tmpa;
struct proto *p0 = e->attrs->proto;
struct proto *p1 = d->export_protocol;
struct proto *p2 = d->show_protocol;
- if (ia[0])
+
++ if (prefix[0])
+ d->net_counter++;
d->rt_counter++;
ee = e;
rte_update_lock(); /* We use the update buffer for filtering */
}
}
-static struct ospf_iface *
-ospf_iface_find_by_key(struct ospf_area *oa, struct ifa *a, int iid)
+
+static void
+ospf_ifaces_reconfigure2(struct ospf_area *oa, struct ospf_area_config *nac)
{
- struct ospf_iface *ifa;
- WALK_LIST(ifa, oa->po->iface_list)
- if ((ifa->addr == a) && (ifa->oa == oa) && (ifa->instance_id == iid) && (ifa->type != OSPF_IT_VLINK))
- return ifa;
+ struct ospf_iface_patt *ip;
+ struct iface *iface;
+ struct ifa *a;
- return NULL;
+ WALK_LIST(iface, iface_list)
++ {
++ if (! (iface->flags & IF_UP))
++ continue;
++
+ WALK_LIST(a, iface->addrs)
+ {
+ if (a->flags & IA_SECONDARY)
+ continue;
+
+ if (a->scope <= SCOPE_LINK)
+ continue;
+
+ if (ip = ospf_iface_patt_find2(oa->ac, a))
+ {
+ /* Main inner loop */
+ struct ospf_iface *ifa = ospf_iface_find_by_key2(oa, a);
+ if (ifa)
+ {
+ if (ospf_iface_reconfigure(ifa, ip))
+ continue;
+
+ /* Hard restart */
+ ospf_iface_shutdown(ifa);
+ ospf_iface_remove(ifa);
+ }
+
+ ospf_iface_new(oa, a, ip);
+ }
+ }
++ }
}
-void
-ospf_ifaces_reconfigure(struct ospf_area *oa, struct ospf_area_config *nac)
+static void
+ospf_ifaces_reconfigure3(struct ospf_area *oa, struct ospf_area_config *nac)
{
struct ospf_iface_patt *ip;
struct iface *iface;
ospf_iface_new(oa, a, ip);
}
}
+ }
}
-#endif
+void
+ospf_ifaces_reconfigure(struct ospf_area *oa, struct ospf_area_config *nac)
+{
+ if (ospf_is_v2(oa->po))
+ ospf_ifaces_reconfigure2(oa, nac);
+ else
+ ospf_ifaces_reconfigure3(oa, nac);
+}
+
static void
ospf_iface_change_mtu(struct proto_ospf *po, struct ospf_iface *ifa)
WALK_LIST(neigh, ifa->neigh_list)
if (neigh->state == NEIGHBOR_FULL)
{
- u32 data = (ifa->addr->flags & IA_PEER) ? ifa->iface_id : ipa_to_u32(ifa->addr->ip);
- add_rt2_lsa_link(po, LSART_PTP, neigh->rid, data, ifa->cost);
- ln = lsab_alloc(po, sizeof(struct ospf_lsa_rt_link));
- ln->type = LSART_PTP;
- ln->id = neigh->rid;
-
+ /*
+ * ln->data should be ifa->iface_id in case of no/ptp
+ * address (ifa->addr->flags & IA_PEER) on PTP link (see
+ * RFC 2328 12.4.1.1.), but the iface ID value has no use,
+ * while using IP address even in this case is here for
+ * compatibility with some broken implementations that use
+ * this address as a next-hop.
+ */
- ln->data = ipa_to_u32(ifa->addr->ip);
-
- ln->metric = ifa->cost;
- ln->padding = 0;
++ add_rt2_lsa_link(po, LSART_PTP, neigh->rid, ipa_to_u32(ifa->addr->ip), ifa->cost);
i++;
}
break;
#define _BIRD_CONFIG_H_
/* BIRD version */
- #define BIRD_VERSION "1.3.8"
+ #define BIRD_VERSION "1.3.9"
+// XXXX temporary define
+#define IPV1 1
+
/* Include parameters determined by configure script */
#include "sysdep/autoconf.h"