summaryrefslogtreecommitdiff
path: root/proto
diff options
context:
space:
mode:
Diffstat (limited to 'proto')
-rw-r--r--proto/ospf/config.Y26
-rw-r--r--proto/ospf/dbdes.c11
-rw-r--r--proto/ospf/iface.c5
-rw-r--r--proto/ospf/lsalib.c1
-rw-r--r--proto/ospf/ospf.c22
-rw-r--r--proto/ospf/ospf.h14
-rw-r--r--proto/rip/rip.c39
-rw-r--r--proto/rip/rip.h20
8 files changed, 109 insertions, 29 deletions
diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y
index 24e125a7..38e59886 100644
--- a/proto/ospf/config.Y
+++ b/proto/ospf/config.Y
@@ -120,8 +120,10 @@ CF_KEYWORDS(NONE, SIMPLE, AUTHENTICATION, STRICT, CRYPTOGRAPHIC)
CF_KEYWORDS(ELIGIBLE, POLL, NETWORKS, HIDDEN, VIRTUAL, CHECK, LINK)
CF_KEYWORDS(RX, BUFFER, LARGE, NORMAL, STUBNET, HIDDEN, SUMMARY, TAG, EXTERNAL)
CF_KEYWORDS(WAIT, DELAY, LSADB, ECMP, LIMIT, WEIGHT, NSSA, TRANSLATOR, STABILITY)
+CF_KEYWORDS(GLOBAL, LSID, ROUTER, SELF)
%type <t> opttext
+%type <ld> lsadb_args
CF_GRAMMAR
@@ -217,7 +219,7 @@ ospf_stubnet_item:
ospf_vlink:
ospf_vlink_start '{' ospf_vlink_opts '}' { ospf_iface_finish(); }
- | ospf_vlink_start
+ | ospf_vlink_start { ospf_iface_finish(); }
;
ospf_vlink_opts:
@@ -386,7 +388,8 @@ CF_ADDTO(dynamic_attr, OSPF_METRIC2 { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF
CF_ADDTO(dynamic_attr, OSPF_TAG { $$ = f_new_dynamic_attr(EAF_TYPE_INT | EAF_TEMP, T_INT, EA_OSPF_TAG); })
CF_ADDTO(dynamic_attr, OSPF_ROUTER_ID { $$ = f_new_dynamic_attr(EAF_TYPE_ROUTER_ID | EAF_TEMP, T_QUAD, EA_OSPF_ROUTER_ID); })
-CF_CLI(SHOW OSPF, optsym, [<name>], [[Show information about OSPF protocol]])
+CF_CLI_HELP(SHOW OSPF, ..., [[Show information about OSPF protocol]]);
+CF_CLI(SHOW OSPF, optsym, [<name>], [[Show information about OSPF protocol XXX]])
{ ospf_sh(proto_get_named($3, &proto_ospf)); };
CF_CLI(SHOW OSPF NEIGHBORS, optsym opttext, [<name>] [\"<interface>\"], [[Show information about OSPF neighbors]])
@@ -411,8 +414,23 @@ CF_CLI(SHOW OSPF STATE, optsym opttext, [<name>], [[Show information about reach
CF_CLI(SHOW OSPF STATE ALL, optsym opttext, [<name>], [[Show information about all OSPF network state]])
{ ospf_sh_state(proto_get_named($5, &proto_ospf), 1, 0); };
-CF_CLI(SHOW OSPF LSADB, optsym opttext, [<name>], [[Show content of OSPF LSA database]])
-{ ospf_sh_lsadb(proto_get_named($4, &proto_ospf)); };
+CF_CLI_HELP(SHOW OSPF LSADB, ..., [[Show content of OSPF LSA database]]);
+CF_CLI(SHOW OSPF LSADB, lsadb_args, [global | area <id> | link] [type <num>] [lsid <id>] [self | router <id>] [<proto>], [[Show content of OSPF LSA database]])
+{ ospf_sh_lsadb($4); };
+
+lsadb_args:
+ /* empty */ {
+ $$ = cfg_allocz(sizeof(struct lsadb_show_data));
+ }
+ | lsadb_args GLOBAL { $$ = $1; $$->scope = LSA_SCOPE_AS; }
+ | lsadb_args AREA idval { $$ = $1; $$->scope = LSA_SCOPE_AREA; $$->area = $3 }
+ | lsadb_args LINK { $$ = $1; $$->scope = 1; /* hack, 0 is no filter */ }
+ | lsadb_args TYPE NUM { $$ = $1; $$->type = $3; }
+ | lsadb_args LSID idval { $$ = $1; $$->lsid = $3; }
+ | lsadb_args SELF { $$ = $1; $$->router = SH_ROUTER_SELF; }
+ | lsadb_args ROUTER idval { $$ = $1; $$->router = $3; }
+ | lsadb_args SYM { $$ = $1; $$->name = $2; }
+ ;
CF_CODE
diff --git a/proto/ospf/dbdes.c b/proto/ospf/dbdes.c
index 8cd7c8b2..75ecf24c 100644
--- a/proto/ospf/dbdes.c
+++ b/proto/ospf/dbdes.c
@@ -96,7 +96,7 @@ ospf_dbdes_send(struct ospf_neighbor *n, int next)
pkt = ospf_tx_buffer(ifa);
op = &pkt->ospf_packet;
ospf_pkt_fill_hdr(ifa, pkt, DBDES_P);
- pkt->iface_mtu = htons(ifa->iface->mtu);
+ pkt->iface_mtu = (ifa->type == OSPF_IT_VLINK) ? 0 : htons(ifa->iface->mtu);
pkt->options = hton_opt(oa->options);
pkt->imms = n->myimms;
pkt->ddseq = htonl(n->dds);
@@ -119,7 +119,7 @@ ospf_dbdes_send(struct ospf_neighbor *n, int next)
op = (struct ospf_packet *) pkt;
ospf_pkt_fill_hdr(ifa, pkt, DBDES_P);
- pkt->iface_mtu = htons(ifa->iface->mtu);
+ pkt->iface_mtu = (ifa->type == OSPF_IT_VLINK) ? 0 : htons(ifa->iface->mtu);
pkt->ddseq = htonl(n->dds);
pkt->options = hton_opt(oa->options);
@@ -260,6 +260,7 @@ ospf_dbdes_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
struct ospf_dbdes_packet *ps = (void *) ps_i;
u32 ps_ddseq = ntohl(ps->ddseq);
u32 ps_options = ntoh_opt(ps->options);
+ u16 ps_iface_mtu = ntohs(ps->iface_mtu);
OSPF_PACKET(ospf_dump_dbdes, ps, "DBDES packet received from %I via %s", n->ip, ifa->iface->name);
@@ -277,6 +278,12 @@ ospf_dbdes_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
if (n->state != NEIGHBOR_EXSTART)
return;
case NEIGHBOR_EXSTART:
+
+ if ((ps_iface_mtu != ifa->iface->mtu) && (ifa->type != OSPF_IT_VLINK)
+ && (ps_iface_mtu != 0) && (ifa->iface->mtu != 0))
+ log(L_WARN "OSPF: MTU mismatch with neighbour %I on interface %s (remote %d, local %d)",
+ n->ip, ifa->iface->name, ps_iface_mtu, ifa->iface->mtu);
+
if ((ps->imms.bit.m && ps->imms.bit.ms && ps->imms.bit.i)
&& (n->rid > po->router_id) && (size == sizeof(struct ospf_dbdes_packet)))
{
diff --git a/proto/ospf/iface.c b/proto/ospf/iface.c
index cced7105..405e49df 100644
--- a/proto/ospf/iface.c
+++ b/proto/ospf/iface.c
@@ -120,6 +120,8 @@ ospf_sk_open(struct ospf_iface *ifa)
sk->saddr = ifa->addr->ip;
if ((ifa->type == OSPF_IT_BCAST) || (ifa->type == OSPF_IT_PTP))
{
+ sk->ttl = 1; /* Hack, this will affect just multicast packets */
+
if (sk_setup_multicast(sk) < 0)
goto err;
@@ -568,6 +570,9 @@ ospf_iface_new(struct ospf_area *oa, struct ifa *addr, struct ospf_iface_patt *i
{
ifa->voa = ospf_find_area(oa->po, ip->voa);
ifa->vid = ip->vid;
+
+ ifa->hello_timer = tm_new_set(ifa->pool, hello_timer_hook, ifa, 0, ifa->helloint);
+
return; /* Don't lock, don't add sockets */
}
diff --git a/proto/ospf/lsalib.c b/proto/ospf/lsalib.c
index 538a7303..bcf7bcdd 100644
--- a/proto/ospf/lsalib.c
+++ b/proto/ospf/lsalib.c
@@ -512,7 +512,6 @@ lsa_validate(struct ospf_lsa_header *lsa, void *body)
* @lsa: LSA header
* @domain: domain of LSA
* @body: pointer to LSA body
-
*
* This function ensures installing new LSA into LSA database. Old instance is
* replaced. Several actions are taken to detect if new routing table
diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c
index 73c06c27..9872faf2 100644
--- a/proto/ospf/ospf.c
+++ b/proto/ospf/ospf.c
@@ -1471,8 +1471,9 @@ lsa_compare_for_lsadb(const void *p1, const void *p2)
}
void
-ospf_sh_lsadb(struct proto *p)
+ospf_sh_lsadb(struct lsadb_show_data *ld)
{
+ struct proto *p = proto_get_named(ld->name, &proto_ospf);
struct proto_ospf *po = (struct proto_ospf *) p;
int num = po->gr->hash_entries;
unsigned int i, j;
@@ -1486,6 +1487,9 @@ ospf_sh_lsadb(struct proto *p)
return;
}
+ if (ld->router == SH_ROUTER_SELF)
+ ld->router = po->router_id;
+
struct top_hash_entry *hea[num];
struct top_hash_entry *he;
@@ -1502,6 +1506,22 @@ ospf_sh_lsadb(struct proto *p)
{
struct ospf_lsa_header *lsa = &(hea[i]->lsa);
int dscope = LSA_SCOPE(lsa);
+
+ if (ld->scope && (dscope != (ld->scope & 0xf000)))
+ continue;
+
+ if ((ld->scope == LSA_SCOPE_AREA) && (hea[i]->domain != ld->area))
+ continue;
+
+ /* Ignore high nibble */
+ if (ld->type && ((lsa->type & 0x0fff) != (ld->type & 0x0fff)))
+ continue;
+
+ if (ld->lsid && (lsa->id != ld->lsid))
+ continue;
+
+ if (ld->router && (lsa->rt != ld->router))
+ continue;
if ((dscope != last_dscope) || (hea[i]->domain != last_domain))
{
diff --git a/proto/ospf/ospf.h b/proto/ospf/ospf.h
index d6961519..96da9aa7 100644
--- a/proto/ospf/ospf.h
+++ b/proto/ospf/ospf.h
@@ -846,7 +846,19 @@ void ospf_sh_neigh(struct proto *p, char *iff);
void ospf_sh(struct proto *p);
void ospf_sh_iface(struct proto *p, char *iff);
void ospf_sh_state(struct proto *p, int verbose, int reachable);
-void ospf_sh_lsadb(struct proto *p);
+
+#define SH_ROUTER_SELF 0xffffffff
+
+struct lsadb_show_data {
+ struct symbol *name; /* Protocol to request data from */
+ u16 type; /* LSA Type, 0 -> all */
+ u16 scope; /* Scope, 0 -> all, hack to handle link scope as 1 */
+ u32 area; /* Specified for area scope */
+ u32 lsid; /* LSA ID, 0 -> all */
+ u32 router; /* Advertising router, 0 -> all */
+};
+
+void ospf_sh_lsadb(struct lsadb_show_data *ld);
#define EA_OSPF_METRIC1 EA_CODE(EAP_OSPF, 0)
diff --git a/proto/rip/rip.c b/proto/rip/rip.c
index f0a41347..b41c3f8d 100644
--- a/proto/rip/rip.c
+++ b/proto/rip/rip.c
@@ -146,7 +146,11 @@ rip_tx( sock *s )
DBG( "Preparing packet to send: " );
packet->heading.command = RIPCMD_RESPONSE;
+#ifndef IPV6
packet->heading.version = RIP_V2;
+#else
+ packet->heading.version = RIP_NG;
+#endif
packet->heading.unused = 0;
i = !!P_CF->authtype;
@@ -281,7 +285,7 @@ rip_rte_update_if_better(rtable *tab, net *net, struct proto *p, rte *new)
* bird core with this route.
*/
static void
-advertise_entry( struct proto *p, struct rip_block *b, ip_addr whotoldme )
+advertise_entry( struct proto *p, struct rip_block *b, ip_addr whotoldme, struct iface *iface )
{
rta *a, A;
rte *r;
@@ -309,7 +313,7 @@ advertise_entry( struct proto *p, struct rip_block *b, ip_addr whotoldme )
/* No need to look if destination looks valid - ie not net 0 or 127 -- core will do for us. */
- neighbor = neigh_find( p, &A.gw, 0 );
+ neighbor = neigh_find2( p, &A.gw, iface, 0 );
if (!neighbor) {
log( L_REMOTE "%s: %I asked me to route %I/%d using not-neighbor %I.", p->name, A.from, b->network, pxlen, A.gw );
return;
@@ -353,7 +357,7 @@ advertise_entry( struct proto *p, struct rip_block *b, ip_addr whotoldme )
* process_block - do some basic check and pass block to advertise_entry
*/
static void
-process_block( struct proto *p, struct rip_block *block, ip_addr whotoldme )
+process_block( struct proto *p, struct rip_block *block, ip_addr whotoldme, struct iface *iface )
{
#ifndef IPV6
int metric = ntohl( block->metric );
@@ -380,7 +384,7 @@ process_block( struct proto *p, struct rip_block *block, ip_addr whotoldme )
return;
}
- advertise_entry( p, block, whotoldme );
+ advertise_entry( p, block, whotoldme, iface );
}
#define BAD( x ) { log( L_REMOTE "%s: " x, p->name ); return 1; }
@@ -389,7 +393,7 @@ process_block( struct proto *p, struct rip_block *block, ip_addr whotoldme )
* rip_process_packet - this is main routine for incoming packets.
*/
static int
-rip_process_packet( struct proto *p, struct rip_packet *packet, int num, ip_addr whotoldme, int port )
+rip_process_packet( struct proto *p, struct rip_packet *packet, int num, ip_addr whotoldme, int port, struct iface *iface )
{
int i;
int authenticated = 0;
@@ -406,7 +410,7 @@ rip_process_packet( struct proto *p, struct rip_packet *packet, int num, ip_addr
if (P_CF->honor == HO_NEVER)
BAD( "They asked me to send routing table, but I was told not to do it" );
- if ((P_CF->honor == HO_NEIGHBOR) && (!neigh_find( p, &whotoldme, 0 )))
+ if ((P_CF->honor == HO_NEIGHBOR) && (!neigh_find2( p, &whotoldme, iface, 0 )))
BAD( "They asked me to send routing table, but he is not my neighbor" );
rip_sendto( p, whotoldme, port, HEAD(P->interfaces) ); /* no broadcast */
break;
@@ -416,7 +420,7 @@ rip_process_packet( struct proto *p, struct rip_packet *packet, int num, ip_addr
return 1;
}
- if (!(neighbor = neigh_find( p, &whotoldme, 0 )) || neighbor->scope == SCOPE_HOST) {
+ if (!(neighbor = neigh_find2( p, &whotoldme, iface, 0 )) || neighbor->scope == SCOPE_HOST) {
log( L_REMOTE "%s: %I send me routing info but he is not my neighbor", p->name, whotoldme );
return 0;
}
@@ -443,7 +447,7 @@ rip_process_packet( struct proto *p, struct rip_packet *packet, int num, ip_addr
if (packet->heading.version == RIP_V1) /* FIXME (nonurgent): switch to disable this? */
block->netmask = ipa_class_mask(block->network);
#endif
- process_block( p, block, whotoldme );
+ process_block( p, block, whotoldme, iface );
}
break;
case RIPCMD_TRACEON:
@@ -463,12 +467,20 @@ rip_rx(sock *s, int size)
{
struct rip_interface *i = s->data;
struct proto *p = i->proto;
+ struct iface *iface = NULL;
int num;
/* In non-listening mode, just ignore packet */
if (i->mode & IM_NOLISTEN)
return 1;
+#ifdef IPV6
+ if (! i->iface || s->lifindex != i->iface->index)
+ return 1;
+
+ iface = i->iface;
+#endif
+
CHK_MAGIC;
DBG( "RIP: message came: %d bytes from %I via %s\n", size, s->faddr, i->iface ? i->iface->name : "(dummy)" );
size -= sizeof( struct rip_packet_heading );
@@ -477,17 +489,12 @@ rip_rx(sock *s, int size)
num = size / sizeof( struct rip_block );
if (num>PACKET_MAX) BAD( "Too many blocks" );
-#ifdef IPV6
- /* Try to absolutize link scope addresses */
- ipa_absolutize(&s->faddr, &i->iface->addr->ip);
-#endif
-
if (ipa_equal(i->iface->addr->ip, s->faddr)) {
DBG("My own packet\n");
return 1;
}
- rip_process_packet( p, (struct rip_packet *) s->rbuf, num, s->faddr, s->fport );
+ rip_process_packet( p, (struct rip_packet *) s->rbuf, num, s->faddr, s->fport, iface );
return 1;
}
@@ -701,6 +708,7 @@ new_iface(struct proto *p, struct iface *new, unsigned long flags, struct iface_
{
rif->sock->ttl = 1;
rif->sock->tos = IP_PREC_INTERNET_CONTROL;
+ rif->sock->flags = SKF_LADDR_RX;
}
if (new) {
@@ -712,7 +720,6 @@ new_iface(struct proto *p, struct iface *new, unsigned long flags, struct iface_
rif->sock->daddr = ipa_from_u32(0xe0000009);
#else
rif->sock->daddr = ipa_build(0xff020000, 0, 0, 9);
- rif->sock->saddr = new->addr->ip; /* Does not really work on Linux */
#endif
} else {
rif->sock->daddr = new->addr->brd;
@@ -976,7 +983,7 @@ rip_init_config(struct rip_proto_config *c)
{
init_list(&c->iface_list);
c->infinity = 16;
- c->port = 520;
+ c->port = RIP_PORT;
c->period = 30;
c->garbage_time = 120+180;
c->timeout_time = 120;
diff --git a/proto/rip/rip.h b/proto/rip/rip.h
index 5a6e36d8..896fab64 100644
--- a/proto/rip/rip.h
+++ b/proto/rip/rip.h
@@ -11,8 +11,19 @@
#define EA_RIP_TAG EA_CODE(EAP_RIP, 0)
#define EA_RIP_METRIC EA_CODE(EAP_RIP, 1)
-#define PACKET_MAX 25
-#define PACKET_MD5_MAX 18 /* FIXME */
+#define PACKET_MAX 25
+#define PACKET_MD5_MAX 18 /* FIXME */
+
+
+#define RIP_V1 1
+#define RIP_V2 2
+#define RIP_NG 1 /* A new version numbering */
+
+#ifndef IPV6
+#define RIP_PORT 520 /* RIP for IPv4 */
+#else
+#define RIP_PORT 521 /* RIPng */
+#endif
struct rip_connection {
node n;
@@ -37,8 +48,9 @@ struct rip_packet_heading { /* 4 bytes */
#define RIPCMD_TRACEOFF 4 /* turn it off */
#define RIPCMD_MAX 5
u8 version;
-#define RIP_V1 1
-#define RIP_V2 2
+#define RIP_V1 1
+#define RIP_V2 2
+#define RIP_NG 1 /* this is verion 1 of RIPng */
u16 unused;
};