Statistics
| Branch: | Revision:

iof-bird-daemon / proto / ospf / lsreq.c @ 6f3203fa

History | View | Annotate | Download (3.04 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->proto->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
  fill_ospf_pkt_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 = (n->ifa->iface->mtu - SIPH - 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\n", i, en->lsa.type,
49
        en->lsa.id, en->lsa.rt);
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_pkt_finalize(n->ifa, op);
63
  sk_send_to(n->ifa->ip_sk, length, n->ip, OSPF_PROTO);
64
  OSPF_TRACE(D_PACKETS, "LS request sent to: %I", n->rid);
65
}
66

    
67
void
68
ospf_lsreq_receive(struct ospf_lsreq_packet *ps,
69
                   struct ospf_iface *ifa, u16 size)
70
{
71
  u32 nrid;
72
  struct ospf_neighbor *n;
73
  struct ospf_lsreq_header *lsh;
74
  struct l_lsr_head *llsh;
75
  list uplist;
76
  slab *upslab;
77
  int length, i, lsano;
78
  struct proto *p = (struct proto *) ifa->proto;
79

    
80
  nrid = ntohl(ps->ospf_packet.routerid);
81

    
82
  if ((n = find_neigh(ifa, nrid)) == NULL)
83
  {
84
    OSPF_TRACE(D_PACKETS, "Received lsreq from unknown neighbor! (%I)", nrid);
85
    return;
86
  }
87
  if (n->state < NEIGHBOR_EXCHANGE)
88
    return;
89

    
90
  OSPF_TRACE(D_EVENTS, "Received LS req from neighbor: %I", n->ip);
91
  ospf_neigh_sm(n, INM_HELLOREC);
92

    
93
  length = ntohs(ps->ospf_packet.length);
94
  lsh = (void *) (ps + 1);
95
  init_list(&uplist);
96
  upslab = sl_new(n->pool, sizeof(struct l_lsr_head));
97

    
98
  lsano = (length - sizeof(struct ospf_lsreq_packet)) /
99
    sizeof(struct ospf_lsreq_header);
100
  for (i = 0; i < lsano; lsh++, i++)
101
  {
102
    DBG("Processing LSA: ID=%I, Type=%u, Router=%I\n", ntohl(lsh->id),
103
        lsh->type, ntohl(lsh->rt));
104
    llsh = sl_alloc(upslab);
105
    llsh->lsh.id = ntohl(lsh->id);
106
    llsh->lsh.rt = ntohl(lsh->rt);
107
    llsh->lsh.type = lsh->type;
108
    add_tail(&uplist, NODE llsh);
109
    if (ospf_hash_find(n->ifa->oa->gr, llsh->lsh.id, llsh->lsh.rt,
110
                       llsh->lsh.type) == NULL)
111
    {
112
      log(L_WARN "Received bad LS req from: %I looking: RT: %I, ID: %I, Type: %u",
113
          n->ip, lsh->rt, lsh->id, lsh->type);
114
      ospf_neigh_sm(n, INM_BADLSREQ);
115
      rfree(upslab);
116
      return;
117
    }
118
  }
119
  ospf_lsupd_send_list(n, &uplist);
120
  rfree(upslab);
121
}