AC_SUBST(iproutedir)
- # all_protocols="$proto_bfd bgp ospf pipe radv rip static"
-all_protocols="$proto_bfd bgp ospf pipe $proto_radv rip static"
-if test "$ip" = ipv6 ; then
- all_protocols="$all_protocols babel"
-fi
++# all_protocols="$proto_bfd babel bgp ospf pipe radv rip static"
+all_protocols="$proto_bfd ospf pipe radv rip static"
+
all_protocols=`echo $all_protocols | sed 's/ /,/g'`
if test "$with_protocols" = all ; then
* @fmt: format string
* @args: a list of arguments to be formatted
*
- * This functions acts like ordinary sprintf() except that it checks
- * available space to avoid buffer overflows and it allows some more
- * format specifiers: |%I| for formatting of IP addresses (any non-zero
- * width is automatically replaced by standard IP address width which
- * depends on whether we use IPv4 or IPv6; |%#I| gives hexadecimal format),
- * |%R| for Router / Network ID (u32 value printed as IPv4 address)
- * |%lR| for 64bit Router / Network ID (u64 value printed as eight :-separated octets)
- * and |%m| resp. |%M| for error messages (uses strerror() to translate @errno code to
- * message text). On the other hand, it doesn't support floating
- * point numbers.
+ * This functions acts like ordinary sprintf() except that it checks available
+ * space to avoid buffer overflows and it allows some more format specifiers:
+ * |%I| for formatting of IP addresses (width of 1 is automatically replaced by
+ * standard IP address width which depends on whether we use IPv4 or IPv6; |%I4|
+ * or |%I6| can be used for explicit ip4_addr / ip6_addr arguments, |%N| for
+ * generic network addresses (net_addr *), |%R| for Router / Network ID (u32
- * value printed as IPv4 address) and |%m| resp. |%M| for error messages (uses
- * strerror() to translate @errno code to message text). On the other hand, it
- * doesn't support floating point numbers.
++ * value printed as IPv4 address), |%lR| for 64bit Router / Network ID (u64
++ * value printed as eight :-separated octets) and |%m| resp. |%M| for error
++ * messages (uses strerror() to translate @errno code to message text). On the
++ * other hand, it doesn't support floating point numbers.
*
* Result: number of characters of the output string or -1 if
* the buffer space was insufficient.
unsigned long num;
int i, base;
u32 x;
+ u64 X;
char *str, *start;
const char *s;
- char ipbuf[MAX(STD_ADDRESS_P_LENGTH,ROUTER_ID_64_LENGTH)+1];
+ char ipbuf[NET_MAX_TEXT_LENGTH+1];
struct iface *iface;
int flags; /* flags to number() */
/* Router/Network ID - essentially IPv4 address in u32 value */
case 'R':
- x = va_arg(args, u32);
- ip4_ntop(ip4_from_u32(x), ipbuf);
- if(qualifier == 'l') {
++ if (qualifier == 'l') {
+ X = va_arg(args, u64);
+ bsprintf(ipbuf, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
+ ((X >> 56) & 0xff),
+ ((X >> 48) & 0xff),
+ ((X >> 40) & 0xff),
+ ((X >> 32) & 0xff),
+ ((X >> 24) & 0xff),
+ ((X >> 16) & 0xff),
+ ((X >> 8) & 0xff),
+ (X & 0xff));
+ }
+ else
+ {
+ x = va_arg(args, u32);
- bsprintf(ipbuf, "%d.%d.%d.%d",
- ((x >> 24) & 0xff),
- ((x >> 16) & 0xff),
- ((x >> 8) & 0xff),
- (x & 0xff));
++ ip4_ntop(ip4_from_u32(x), ipbuf);
+ }
s = ipbuf;
goto str;
dev_proto:
dev_proto_start proto_name '{'
| dev_proto proto_item ';'
+ | dev_proto proto_channel ';'
| dev_proto dev_iface_patt ';'
+ | dev_proto CHECK LINK bool ';' { DIRECT_CFG->check_link = $4; }
;
dev_iface_init:
proto_build(&proto_bfd);
bfd_init_all();
#endif
+ #ifdef CONFIG_BABEL
+ proto_build(&proto_babel);
+ #endif
proto_pool = rp_new(&root_pool, "Protocols");
- proto_flush_event = ev_new(proto_pool);
- proto_flush_event->hook = proto_flush_loop;
proto_shutdown_timer = tm_new(proto_pool);
proto_shutdown_timer->hook = proto_shutdown_loop;
}
#define DEF_PREF_DIRECT 240 /* Directly connected */
#define DEF_PREF_STATIC 200 /* Static route */
#define DEF_PREF_OSPF 150 /* OSPF intra-area, inter-area and type 1 external routes */
+ #define DEF_PREF_BABEL 130 /* Babel */
#define DEF_PREF_RIP 120 /* RIP */
#define DEF_PREF_BGP 100 /* BGP */
-#define DEF_PREF_PIPE 70 /* Routes piped from other tables */
#define DEF_PREF_INHERITED 10 /* Routes inherited from other routing daemons */
-
/*
* Route Origin Authorization
*/
DBG("dev_if_notify: %s:%I going up\n", ad->iface->name, ad->ip);
- if (P->check_link && !(ad->iface->flags & IF_LINK_UP))
++ if (cf->check_link && !(ad->iface->flags & IF_LINK_UP))
+ return;
+
/* Use iface ID as local source ID */
- struct rte_src *src = rt_get_source(p, ad->iface->index);
+ struct rte_src *src = rt_get_source(P, ad->iface->index);
rta a0 = {
.src = src,
}
}
+ static void
+ dev_if_notify(struct proto *p, uint c, struct iface *iface)
+ {
+ struct rt_dev_config *cf = (void *) p->cf;
+
+ if (c & (IF_CHANGE_UP | IF_CHANGE_DOWN))
+ return;
+
+ if ((c & IF_CHANGE_LINK) && cf->check_link)
+ {
+ uint ac = (iface->flags & IF_LINK_UP) ? IF_CHANGE_UP : IF_CHANGE_DOWN;
+
+ struct ifa *a;
+ WALK_LIST(a, iface->addrs)
+ dev_ifa_notify(p, ac, a);
+ }
+ }
+
+
static struct proto *
-dev_init(struct proto_config *c)
+dev_init(struct proto_config *CF)
{
- struct proto *p = proto_new(c, sizeof(struct proto));
+ struct proto *P = proto_new(CF);
+ struct rt_dev_proto *p = (void *) P;
+ // struct rt_dev_config *cf = (void *) CF;
+
+ proto_configure_channel(P, &p->ip4_channel, proto_cf_find_channel(CF, NET_IP4));
+ proto_configure_channel(P, &p->ip6_channel, proto_cf_find_channel(CF, NET_IP6));
+
++ P->if_notify = dev_if_notify;
+ P->ifa_notify = dev_ifa_notify;
- p->if_notify = dev_if_notify;
- p->ifa_notify = dev_ifa_notify;
- return p;
+ return P;
}
static int
-dev_reconfigure(struct proto *p, struct proto_config *new)
+dev_reconfigure(struct proto *P, struct proto_config *CF)
{
- struct rt_dev_config *o = (struct rt_dev_config *) p->cf;
- struct rt_dev_config *n = (struct rt_dev_config *) new;
+ struct rt_dev_proto *p = (void *) P;
+ struct rt_dev_config *o = (void *) P->cf;
+ struct rt_dev_config *n = (void *) CF;
+
- if (!iface_patts_equal(&o->iface_list, &n->iface_list, NULL))
++ if (!iface_patts_equal(&o->iface_list, &n->iface_list, NULL) ||
++ (o->check_link != n->check_link))
+ return 0;
+
+ return
+ proto_configure_channel(P, &p->ip4_channel, proto_cf_find_channel(CF, NET_IP4)) &&
+ proto_configure_channel(P, &p->ip6_channel, proto_cf_find_channel(CF, NET_IP6));
- return iface_patts_equal(&o->iface_list, &n->iface_list, NULL) &&
- (o->check_link == n->check_link);
+ return 1;
}
static void
struct rt_dev_config {
struct proto_config c;
list iface_list; /* list of struct iface_patt */
+ int check_link;
};
+struct rt_dev_proto {
+ struct proto p;
+ struct channel *ip4_channel;
+ struct channel *ip6_channel;
+};
+
#endif
| bgp_proto CAPABILITIES bool ';' { BGP_CFG->capabilities = $3; }
| bgp_proto ADVERTISE IPV4 bool ';' { BGP_CFG->advertise_ipv4 = $4; }
| bgp_proto PASSWORD text ';' { BGP_CFG->password = $3; }
- | bgp_proto ROUTE LIMIT expr ';' {
- this_proto->in_limit = cfg_allocz(sizeof(struct proto_limit));
- this_proto->in_limit->limit = $4;
- this_proto->in_limit->action = PLA_RESTART;
- log(L_WARN "%s: Route limit option is deprecated, use import limit", this_proto->name);
- }
+ | bgp_proto SETKEY bool ';' { BGP_CFG->setkey = $3; }
| bgp_proto PASSIVE bool ';' { BGP_CFG->passive = $3; }
| bgp_proto INTERPRET COMMUNITIES bool ';' { BGP_CFG->interpret_communities = $4; }
| bgp_proto SECONDARY bool ';' { BGP_CFG->secondary = $3; }
/**
* lsa_validate - check whether given LSA is valid
* @lsa: LSA header
- * @lsa_type: one of %LSA_T_xxx
- * @ospf2: %true means OSPF version 2, %false means OSPF version 3
++ * @lsa_type: internal LSA type (%LSA_T_xxx)
++ * @ospf2: %true for OSPFv2, %false for OSPFv3
* @body: pointer to LSA body
*
* Checks internal structure of given LSA body (minimal length,
/**
* ospf_rx_hook
* @sk: socket we received the packet.
- * @size: size of the packet
- * @len: size of the packet
++ * @len: length of the packet
*
* This is the entry point for messages from neighbors. Many checks (like
* authentication, checksums, size) are done before the packet is passed to
struct tcp_md5sig md5;
memset(&md5, 0, sizeof(md5));
- sockaddr_fill((sockaddr *) &md5.tcpm_addr, fam_to_af[s->fam], a, ifa, 0);
- sockaddr_fill((sockaddr *) &md5.tcpm_addr, s->af, remote, ifa, 0);
++ sockaddr_fill((sockaddr *) &md5.tcpm_addr, fam_to_af[s->fam], remote, ifa, 0);
if (passwd)
{