Statistics
| Branch: | Revision:

iof-bird-daemon / proto / ospf / lsreq.c @ 23d67029

History | View | Annotate | Download (2.91 KB)

1
/*
2
 *        BIRD -- OSPF
3
 *
4
 *        (c) 2000--2004 Ondrej Filip <feela@network.cz>
5
 *
6
 *        Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8

    
9
#include "ospf.h"
10

    
11
void
12
ospf_lsreq_send(struct ospf_neighbor *n)
13
{
14
  snode *sn;
15
  struct top_hash_entry *en;
16
  struct ospf_lsreq_packet *pk;
17
  struct ospf_packet *op;
18
  struct ospf_lsreq_header *lsh;
19
  u16 length;
20
  int i, j;
21
  struct proto *p = &n->ifa->oa->po->proto;
22

    
23
  pk = (struct ospf_lsreq_packet *) n->ifa->ip_sk->tbuf;
24
  op = (struct ospf_packet *) n->ifa->ip_sk->tbuf;
25

    
26
  ospf_pkt_fill_hdr(n->ifa, pk, LSREQ_P);
27

    
28
  sn = SHEAD(n->lsrql);
29
  if (EMPTY_SLIST(n->lsrql))
30
  {
31
    if (n->state == NEIGHBOR_LOADING)
32
      ospf_neigh_sm(n, INM_LOADDONE);
33
    return;
34
  }
35

    
36
  i = j = (ospf_pkt_maxsize(n->ifa) - sizeof(struct ospf_lsreq_packet)) /
37
    sizeof(struct ospf_lsreq_header);
38
  lsh = (struct ospf_lsreq_header *) (pk + 1);
39

    
40
  for (; i > 0; i--)
41
  {
42
    en = (struct top_hash_entry *) sn;
43
    lsh->padd1 = 0;
44
    lsh->padd2 = 0;
45
    lsh->type = en->lsa.type;
46
    lsh->rt = htonl(en->lsa.rt);
47
    lsh->id = htonl(en->lsa.id);
48
    DBG("Requesting %uth LSA: Type: %u, ID: %I, RT: %I, SN: 0x%x, Age %u\n",
49
        i, en->lsa.type, en->lsa.id, en->lsa.rt, en->lsa.sn, en->lsa.age);
50
    lsh++;
51
    if (sn == STAIL(n->lsrql))
52
      break;
53
    sn = sn->next;
54
  }
55
  if (i != 0)
56
    i--;
57

    
58
  length =
59
    sizeof(struct ospf_lsreq_packet) + (j -
60
                                        i) * sizeof(struct ospf_lsreq_header);
61
  op->length = htons(length);
62
  ospf_send_to(n->ifa->ip_sk, n->ip, n->ifa);
63
  OSPF_TRACE(D_PACKETS, "LS request sent to: %I", n->rid);
64
}
65

    
66
void
67
ospf_lsreq_receive(struct ospf_lsreq_packet *ps,
68
                   struct ospf_iface *ifa, struct ospf_neighbor *n)
69
{
70
  struct ospf_lsreq_header *lsh;
71
  struct l_lsr_head *llsh;
72
  list uplist;
73
  slab *upslab;
74
  unsigned int size = ntohs(ps->ospf_packet.length);
75
  int i, lsano;
76
  struct ospf_area *oa = ifa->oa;
77
  struct proto_ospf *po = oa->po;
78
  struct proto *p = &po->proto;
79

    
80
  if (n->state < NEIGHBOR_EXCHANGE)
81
    return;
82

    
83
  OSPF_TRACE(D_EVENTS, "Received LS req from neighbor: %I", n->ip);
84
  ospf_neigh_sm(n, INM_HELLOREC);
85

    
86
  lsh = (void *) (ps + 1);
87
  init_list(&uplist);
88
  upslab = sl_new(n->pool, sizeof(struct l_lsr_head));
89

    
90
  lsano = (size - sizeof(struct ospf_lsreq_packet)) /
91
    sizeof(struct ospf_lsreq_header);
92
  for (i = 0; i < lsano; lsh++, i++)
93
  {
94
    u32 hid = ntohl(lsh->id);
95
    u32 hrt = ntohl(lsh->rt);
96
    DBG("Processing requested LSA: Type: %u, ID: %I, RT: %I\n", lsh->type, hid, hrt);
97
    llsh = sl_alloc(upslab);
98
    llsh->lsh.id = hid;
99
    llsh->lsh.rt = hrt;
100
    llsh->lsh.type = lsh->type;
101
    add_tail(&uplist, NODE llsh);
102
    if (ospf_hash_find(po->gr, oa->areaid, llsh->lsh.id, llsh->lsh.rt,
103
                       llsh->lsh.type) == NULL)
104
    {
105
      log(L_WARN
106
          "Received bad LS req from: %I looking: Type: %u, ID: %I, RT: %I",
107
          n->ip, lsh->type, hid, hrt);
108
      ospf_neigh_sm(n, INM_BADLSREQ);
109
      rfree(upslab);
110
      return;
111
    }
112
  }
113
  ospf_lsupd_send_list(n, &uplist);
114
  rfree(upslab);
115
}