Statistics
| Branch: | Revision:

iof-bird-daemon / proto / ospf / lsreq.c @ 48e5f32d

History | View | Annotate | Download (3.6 KB)

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