;
CF_CLI(DISABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Disable protocol]])
- { proto_xxable($2, XX_DISABLE); } ;
+ { proto_apply_cmd($2, proto_cmd_disable, 1, 0); } ;
CF_CLI(ENABLE, proto_patt, <protocol> | \"<pattern>\" | all, [[Enable protocol]])
- { proto_xxable($2, XX_ENABLE); } ;
+ { proto_apply_cmd($2, proto_cmd_enable, 1, 0); } ;
CF_CLI(RESTART, proto_patt, <protocol> | \"<pattern>\" | all, [[Restart protocol]])
- { proto_xxable($2, XX_RESTART); } ;
+ { proto_apply_cmd($2, proto_cmd_restart, 1, 0); } ;
CF_CLI(RELOAD, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol]])
- { proto_xxable($2, XX_RELOAD); } ;
+ { proto_apply_cmd($2, proto_cmd_reload, 1, CMD_RELOAD); } ;
CF_CLI(RELOAD IN, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just imported routes)]])
- { proto_xxable($3, XX_RELOAD_IN); } ;
+ { proto_apply_cmd($3, proto_cmd_reload, 1, CMD_RELOAD_IN); } ;
CF_CLI(RELOAD OUT, proto_patt, <protocol> | \"<pattern>\" | all, [[Reload protocol (just exported routes)]])
- { proto_xxable($3, XX_RELOAD_OUT); } ;
+ { proto_apply_cmd($3, proto_cmd_reload, 1, CMD_RELOAD_OUT); } ;
CF_CLI_HELP(DEBUG, ..., [[Control protocol debugging via BIRD logs]])
-CF_CLI(DEBUG, proto_patt debug_mask, (<protocol> | <pattern> | all) (all | off | { states | routes | filters | events | packets }), [[Control protocol debugging via BIRD logs]])
+CF_CLI(DEBUG, proto_patt debug_mask, (<protocol> | <pattern> | all) (all | off | { states | routes | filters | interfaces | events | packets }), [[Control protocol debugging via BIRD logs]])
- { proto_debug($2, 0, $3); }
- ;
+ { proto_apply_cmd($2, proto_cmd_debug, 1, $3); } ;
CF_CLI_HELP(MRTDUMP, ..., [[Control protocol debugging via MRTdump files]])
CF_CLI(MRTDUMP, proto_patt mrtdump_mask, (<protocol> | <pattern> | all) (all | off | { states | messages }), [[Control protocol debugging via MRTdump format]])
{
struct proto_ospf *po = ifa->oa->po;
struct proto *p = &po->proto;
- char *beg = "Bad OSPF HELLO packet from ", *rec = " received: ";
+ char *beg = "OSPF: Bad HELLO packet from ";
- unsigned int size, i, twoway, oldpriority, eligible, peers;
- u32 olddr, oldbdr, oldiface_id, tmp;
+ unsigned int size, i, twoway, eligible, peers;
+ u32 tmp;
u32 *pnrid;
size = ntohs(ps_i->length);
* non generic functions.
*/
int
-ospf_rx_hook(sock * sk, int size)
+ospf_rx_hook(sock *sk, int size)
{
- struct ospf_packet *ps;
- struct ospf_iface *ifa = (struct ospf_iface *) (sk->data);
+ char *mesg = "OSPF: Bad packet from ";
+
+ /* We want just packets from sk->iface. Unfortunately, on BSD we
+ cannot filter out other packets at kernel level and we receive
+ all packets on all sockets */
+ if (sk->lifindex != sk->iface->index)
+ return 1;
+
+ DBG("OSPF: RX hook called (iface %s, src %I, dst %I)\n",
+ sk->iface->name, sk->faddr, sk->laddr);
+
+ /* Initially, the packet is associated with the 'master' iface */
+ struct ospf_iface *ifa = sk->data;
struct proto_ospf *po = ifa->oa->po;
-- struct proto *p = &po->proto;
- struct ospf_neighbor *n;
- int osize;
- char *mesg = "Bad OSPF packet from ";
- struct ospf_iface *iff;
++ // struct proto *p = &po->proto;
+
+ int src_local = ifa_match_addr(ifa->addr, sk->faddr);
+ int dst_local = ipa_equal(sk->laddr, ifa->addr->ip);
+ int dst_mcast = ipa_equal(sk->laddr, AllSPFRouters) || ipa_equal(sk->laddr, AllDRouters);
- if (ifa->stub)
- return (1);
+#ifdef OSPFv2
+ /* First, we eliminate packets with strange address combinations.
+ * In OSPFv2, they might be for other ospf_ifaces (with different IP
+ * prefix) on the same real iface, so we don't log it. We enforce
+ * that (src_local || dst_local), therefore we are eliminating all
+ * such cases.
+ */
+ if (dst_mcast && !src_local)
+ return 1;
+ if (!dst_mcast && !dst_local)
+ return 1;
+
+#else /* OSPFv3 */
+
+ /* In OSPFv3, src_local and dst_local mean link-local.
+ * RFC 5340 says that local (non-vlink) packets use
+ * link-local src address, but does not enforce it. Strange.
+ */
+ if (dst_mcast && !src_local)
+ log(L_WARN "OSPF: Received multicast packet from %I (not link-local)", sk->faddr);
+#endif
- ps = (struct ospf_packet *) ip_skip_header(sk->rbuf, &size);
+ /* Second, we check packet size, checksum, and the protocol version */
+ struct ospf_packet *ps = (struct ospf_packet *) ip_skip_header(sk->rbuf, &size);
if (ps == NULL)
{
metric = ls->metric & METRIC_MASK;
options = 0;
type = ORT_NET;
- re = (ort *) fib_find(&po->rtf, &ip, pxlen);
+ re = fib_find(&po->rtf, &ip, pxlen);
}
- else if (en->lsa.type == LSA_T_SUM_RT)
+ else // en->lsa.type == LSA_T_SUM_RT
{
#ifdef OSPFv2
struct ospf_lsa_sum *ls = en->lsa_body;