]>
git.ipfire.org Git - thirdparty/bird.git/blob - proto/ospf/lsreq.c
a6c0cf246564768e9c8604e3a8d802c2149acb16
4 * (c) 2000--2004 Ondrej Filip <feela@network.cz>
5 * (c) 2009--2014 Ondrej Zajicek <santiago@crfreenet.org>
6 * (c) 2009--2014 CZ.NIC z.s.p.o.
8 * Can be freely distributed and used under the terms of the GNU GPL.
15 struct ospf_lsreq_packet
17 struct ospf_packet hdr;
18 // union ospf_auth auth;
20 struct ospf_lsreq_header lsrs[];
26 ospf_lsreq_body(struct ospf_proto
*p
, struct ospf_packet
*pkt
,
27 struct ospf_lsreq_header
**body
, uint
*count
)
29 uint plen
= ntohs(pkt
->length
);
30 uint hlen
= ospf_pkt_hdrlen(p
);
32 *body
= ((void *) pkt
) + hlen
;
33 *count
= (plen
- hlen
) / sizeof(struct ospf_lsreq_header
);
37 ospf_dump_lsreq(struct ospf_proto
*p
, struct ospf_packet
*pkt
)
39 struct ospf_lsreq_header
*lsrs
;
42 ASSERT(pkt
->type
== LSREQ_P
);
43 ospf_dump_common(p
, pkt
);
45 ospf_lsreq_body(p
, pkt
, &lsrs
, &lsr_count
);
46 for (i
= 0; i
< lsr_count
; i
++)
47 log(L_TRACE
"%s: LSR Type: %04x, Id: %R, Rt: %R", p
->p
.name
,
48 ntohl(lsrs
[i
].type
), ntohl(lsrs
[i
].id
), ntohl(lsrs
[i
].rt
));
53 ospf_send_lsreq(struct ospf_proto
*p
, struct ospf_neighbor
*n
)
55 struct ospf_iface
*ifa
= n
->ifa
;
56 struct ospf_lsreq_header
*lsrs
;
57 struct top_hash_entry
*en
;
58 struct ospf_packet
*pkt
;
59 uint i
, lsr_max
, length
;
63 if (EMPTY_SLIST(n
->lsrql
))
65 if (n
->state
== NEIGHBOR_LOADING
)
66 ospf_neigh_sm(n
, INM_LOADDONE
);
70 pkt
= ospf_tx_buffer(ifa
);
71 ospf_pkt_fill_hdr(ifa
, pkt
, LSREQ_P
);
72 ospf_lsreq_body(p
, pkt
, &lsrs
, &lsr_max
);
74 /* We send smaller LSREQ to prevent multiple LSACKs as answer */
75 lsr_max
= lsr_max
/ 4;
78 WALK_SLIST(en
, n
->lsrql
)
83 DBG("Requesting %uth LSA: Type: %04u, ID: %R, RT: %R, SN: 0x%x, Age %u\n",
84 i
, en
->lsa_type
, en
->lsa
.id
, en
->lsa
.rt
, en
->lsa
.sn
, en
->lsa
.age
);
86 u32 etype
= lsa_get_etype(&en
->lsa
, p
);
87 lsrs
[i
].type
= htonl(etype
);
88 lsrs
[i
].rt
= htonl(en
->lsa
.rt
);
89 lsrs
[i
].id
= htonl(en
->lsa
.id
);
93 length
= ospf_pkt_hdrlen(p
) + i
* sizeof(struct ospf_lsreq_header
);
94 pkt
->length
= htons(length
);
96 OSPF_PACKET(ospf_dump_lsreq
, pkt
, "LSREQ packet sent to %I via %s", n
->ip
, ifa
->ifname
);
97 ospf_send_to(ifa
, n
->ip
);
102 ospf_receive_lsreq(struct ospf_packet
*pkt
, struct ospf_iface
*ifa
,
103 struct ospf_neighbor
*n
)
105 struct ospf_proto
*p
= ifa
->oa
->po
;
106 struct ospf_lsreq_header
*lsrs
;
111 /* No need to check length, lsreq has only basic header */
113 OSPF_PACKET(ospf_dump_lsreq
, pkt
, "LSREQ packet received from %I via %s", n
->ip
, ifa
->ifname
);
115 if (n
->state
< NEIGHBOR_EXCHANGE
)
118 ospf_neigh_sm(n
, INM_HELLOREC
); /* Not in RFC */
120 ospf_lsreq_body(p
, pkt
, &lsrs
, &lsr_count
);
122 struct top_hash_entry
*en
, *entries
[lsr_count
];
124 for (i
= 0; i
< lsr_count
; i
++)
126 u32 id
, rt
, type
, domain
;
128 id
= ntohl(lsrs
[i
].id
);
129 rt
= ntohl(lsrs
[i
].rt
);
130 lsa_get_type_domain_(ntohl(lsrs
[i
].type
), ifa
, &type
, &domain
);
132 DBG("Processing requested LSA: Type: %04x, Id: %R, Rt: %R\n", type
, id
, rt
);
134 en
= ospf_hash_find(p
->gr
, domain
, id
, rt
, type
);
137 log(L_WARN
"%s: Received LSREQ from %I for missing LSA (Type: %04x, Id: %R, Rt: %R)",
138 p
->p
.name
, n
->ip
, type
, id
, rt
);
139 ospf_neigh_sm(n
, INM_BADLSREQ
);
146 ospf_send_lsupd(p
, entries
, lsr_count
, n
);