]> git.ipfire.org Git - thirdparty/bird.git/blame - proto/ospf/lsreq.c
Temporary OSPFv3 development commit (changing multicast support).
[thirdparty/bird.git] / proto / ospf / lsreq.c
CommitLineData
6d2b3211
OF
1/*
2 * BIRD -- OSPF
3 *
27f49a2c 4 * (c) 2000--2004 Ondrej Filip <feela@network.cz>
6d2b3211
OF
5 *
6 * Can be freely distributed and used under the terms of the GNU GPL.
7 */
8
9#include "ospf.h"
10
c3226991
OZ
11
12struct ospf_lsreq_packet
13{
14 struct ospf_packet ospf_packet;
15 struct ospf_lsreq_header lsh[];
16};
17
18
8298d780
OZ
19static void ospf_dump_lsreq(struct proto *p, struct ospf_lsreq_packet *pkt)
20{
21 struct ospf_packet *op = &pkt->ospf_packet;
22
23 ASSERT(op->type == LSREQ_P);
24 ospf_dump_common(p, op);
25
8298d780 26 int i, j;
c3226991 27 j = (ntohs(op->length) - sizeof(struct ospf_lsreq_packet)) /
8298d780
OZ
28 sizeof(struct ospf_lsreq_header);
29
30 for (i = 0; i < j; i++)
f9c799a0
OZ
31 log(L_TRACE "%s: LSR Id: %R, Rt: %R, Type: 0x%x", p->name,
32 htonl(pkt->lsh[i].id), htonl(pkt->lsh[i].rt), htonl(pkt->lsh[i].type));
8298d780
OZ
33}
34
6d2b3211 35void
27f49a2c 36ospf_lsreq_send(struct ospf_neighbor *n)
6d2b3211
OF
37{
38 snode *sn;
39 struct top_hash_entry *en;
40 struct ospf_lsreq_packet *pk;
41 struct ospf_packet *op;
42 struct ospf_lsreq_header *lsh;
43 u16 length;
27f49a2c 44 int i, j;
86c84d76 45 struct proto *p = &n->ifa->oa->po->proto;
6d2b3211 46
f9c799a0
OZ
47 pk = (struct ospf_lsreq_packet *) n->ifa->sk->tbuf;
48 op = (struct ospf_packet *) n->ifa->sk->tbuf;
6d2b3211 49
3e2bd0f1 50 ospf_pkt_fill_hdr(n->ifa, pk, LSREQ_P);
6d2b3211 51
27f49a2c
OF
52 sn = SHEAD(n->lsrql);
53 if (EMPTY_SLIST(n->lsrql))
76915ec9 54 {
27f49a2c
OF
55 if (n->state == NEIGHBOR_LOADING)
56 ospf_neigh_sm(n, INM_LOADDONE);
76915ec9
OF
57 return;
58 }
27f49a2c 59
3e2bd0f1 60 i = j = (ospf_pkt_maxsize(n->ifa) - sizeof(struct ospf_lsreq_packet)) /
ce0603a6 61 sizeof(struct ospf_lsreq_header);
c3226991 62 lsh = pk->lsh;
27f49a2c
OF
63
64 for (; i > 0; i--)
6d2b3211 65 {
27f49a2c 66 en = (struct top_hash_entry *) sn;
c3226991 67 lsh->type = htonl(en->lsa.type);
27f49a2c
OF
68 lsh->rt = htonl(en->lsa.rt);
69 lsh->id = htonl(en->lsa.id);
3aab39f5
OZ
70 DBG("Requesting %uth LSA: Type: %u, ID: %R, RT: %R, SN: 0x%x, Age %u\n",
71 i, en->lsa.type, en->lsa.id, en->lsa.rt, en->lsa.sn, en->lsa.age);
f45fd316 72 lsh++;
27f49a2c
OF
73 if (sn == STAIL(n->lsrql))
74 break;
75 sn = sn->next;
6d2b3211 76 }
27f49a2c
OF
77 if (i != 0)
78 i--;
6d2b3211 79
27f49a2c
OF
80 length =
81 sizeof(struct ospf_lsreq_packet) + (j -
82 i) * sizeof(struct ospf_lsreq_header);
83 op->length = htons(length);
8298d780 84
f9c799a0 85 OSPF_PACKET(ospf_dump_lsreq, (struct ospf_lsreq_packet *) n->ifa->sk->tbuf,
8298d780 86 "LSREQ packet sent to %I via %s", n->ip, n->ifa->iface->name);
f9c799a0 87 ospf_send_to(n->ifa, n->ip);
6d2b3211
OF
88}
89
6d2b3211 90void
c3226991
OZ
91ospf_lsreq_receive(struct ospf_packet *ps_i, struct ospf_iface *ifa,
92 struct ospf_neighbor *n)
6d2b3211 93{
c3226991 94 struct ospf_lsreq_packet *ps = (void *) ps_i;
6d2b3211 95 struct ospf_lsreq_header *lsh;
f45fd316
OF
96 struct l_lsr_head *llsh;
97 list uplist;
98 slab *upslab;
5e3436d2
OF
99 unsigned int size = ntohs(ps->ospf_packet.length);
100 int i, lsano;
86c84d76
OF
101 struct ospf_area *oa = ifa->oa;
102 struct proto_ospf *po = oa->po;
103 struct proto *p = &po->proto;
6d2b3211 104
8298d780
OZ
105 OSPF_PACKET(ospf_dump_lsreq, ps, "LSREQ packet received from %I via %s", n->ip, ifa->iface->name);
106
27f49a2c
OF
107 if (n->state < NEIGHBOR_EXCHANGE)
108 return;
9669362f 109
4bb9ce56 110 ospf_neigh_sm(n, INM_HELLOREC);
6d2b3211 111
c3226991 112 lsh = ps->lsh;
f45fd316 113 init_list(&uplist);
27f49a2c 114 upslab = sl_new(n->pool, sizeof(struct l_lsr_head));
f45fd316 115
5e3436d2 116 lsano = (size - sizeof(struct ospf_lsreq_packet)) /
92e8be8c 117 sizeof(struct ospf_lsreq_header);
27f49a2c 118 for (i = 0; i < lsano; lsh++, i++)
6d2b3211 119 {
73e53eb5
OF
120 u32 hid = ntohl(lsh->id);
121 u32 hrt = ntohl(lsh->rt);
c3226991
OZ
122 u32 htype = ntohl(lsh->type);
123 u32 dom = ospf_lsa_domain(htype, ifa);
3aab39f5 124 DBG("Processing requested LSA: Type: %u, ID: %R, RT: %R\n", lsh->type, hid, hrt);
27f49a2c 125 llsh = sl_alloc(upslab);
73e53eb5
OF
126 llsh->lsh.id = hid;
127 llsh->lsh.rt = hrt;
c3226991 128 llsh->lsh.type = htype;
f45fd316 129 add_tail(&uplist, NODE llsh);
b49e6f5a 130 if (ospf_hash_find(po->gr, dom, hid, hrt, htype) == NULL)
de769e24 131 {
2e10a170 132 log(L_WARN
3aab39f5 133 "Received bad LS req from: %I looking: Type: %u, ID: %R, RT: %R",
c3226991 134 n->ip, htype, hid, hrt);
27f49a2c 135 ospf_neigh_sm(n, INM_BADLSREQ);
f45fd316 136 rfree(upslab);
de769e24
OF
137 return;
138 }
6d2b3211 139 }
6f3203fa 140 ospf_lsupd_send_list(n, &uplist);
f45fd316 141 rfree(upslab);
6d2b3211 142}