]>
Commit | Line | Data |
---|---|---|
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 | |
12 | struct ospf_lsreq_packet | |
13 | { | |
14 | struct ospf_packet ospf_packet; | |
15 | struct ospf_lsreq_header lsh[]; | |
16 | }; | |
17 | ||
18 | ||
8298d780 OZ |
19 | static 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 | 35 | void |
27f49a2c | 36 | ospf_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 | 90 | void |
c3226991 OZ |
91 | ospf_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 | } |