Statistics
| Branch: | Revision:

iof-bird-daemon / proto / ospf / lsreq.c @ df49d4e1

History | View | Annotate | Download (3.88 KB)

1 6d2b3211 Ondrej Filip
/*
2
 *        BIRD -- OSPF
3
 *
4
 *        (c) 2000 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_tx(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 9669362f Ondrej Filip
  struct proto *p=&n->ifa->proto->proto;
22 6d2b3211 Ondrej Filip
23
  pk=(struct ospf_lsreq_packet *)n->ifa->ip_sk->tbuf;
24
  op=(struct ospf_packet *)n->ifa->ip_sk->tbuf;
25
26 89d6782d Ondrej Filip
  fill_ospf_pkt_hdr(n->ifa, pk, LSREQ_P);
27 6d2b3211 Ondrej Filip
28 ce0603a6 Ondrej Filip
  sn=SHEAD(n->lsrql);
29 921a93f2 Ondrej Filip
  if(EMPTY_SLIST(n->lsrql))
30 76915ec9 Ondrej Filip
  {
31
    if(n->state==NEIGHBOR_LOADING) ospf_neigh_sm(n, INM_LOADDONE);
32
    return;
33
  }
34 6d2b3211 Ondrej Filip
 
35
  i=j=(n->ifa->iface->mtu-SIPH-sizeof(struct ospf_lsreq_packet))/
36 ce0603a6 Ondrej Filip
    sizeof(struct ospf_lsreq_header);
37 6d2b3211 Ondrej Filip
  lsh=(struct ospf_lsreq_header *)(pk+1);
38
  
39
  for(;i>0;i--)
40
  {
41
    en=(struct top_hash_entry *)sn;
42
    lsh->padd1=0; lsh->padd2=0;
43
    lsh->type=en->lsa.type;
44
    lsh->rt=htonl(en->lsa.rt);
45
    lsh->id=htonl(en->lsa.id);
46 44724025 Ondrej Filip
    DBG("Requesting %uth LSA: Type: %u, Id: %I, RT: %I\n",i, en->lsa.type,
47 6d2b3211 Ondrej Filip
                    en->lsa.id, en->lsa.rt);
48 f45fd316 Ondrej Filip
    lsh++;
49 d8852b36 Ondrej Filip
    if(sn==STAIL(n->lsrql)) break;
50
    sn=sn->next;
51 6d2b3211 Ondrej Filip
  }
52 58313b24 Ondrej Filip
  if(i!=0) i--;
53 6d2b3211 Ondrej Filip
54
  length=sizeof(struct ospf_lsreq_packet)+(j-i)*sizeof(struct ospf_lsreq_header);
55
  op->length=htons(length);
56
  ospf_pkt_finalize(n->ifa, op);
57
  sk_send_to(n->ifa->ip_sk,length, n->ip, OSPF_PROTO);
58 9669362f Ondrej Filip
  debug("%s: LS request sent to: %I\n", p->name, n->rid);
59 6d2b3211 Ondrej Filip
}
60
61
void
62
lsrr_timer_hook(timer *timer)
63
{
64
  struct ospf_iface *ifa;
65
  struct proto *p;
66
  struct ospf_neighbor *n;
67 9669362f Ondrej Filip
  struct top_hash_entry *en;
68 6d2b3211 Ondrej Filip
69
  n=(struct ospf_neighbor *)timer->data;
70
  ifa=n->ifa;
71
  p=(struct proto *)(ifa->proto);
72 9669362f Ondrej Filip
73
  DBG("%s: LSRR timer fired on interface %s for neigh: %I.\n",
74 6d2b3211 Ondrej Filip
    p->name, ifa->iface->name, n->rid);
75 43e75f38 Ondrej Filip
  if(n->state<NEIGHBOR_FULL) ospf_lsreq_tx(n);
76
  else
77
  {
78 9669362f Ondrej Filip
    if(!EMPTY_SLIST(n->lsrtl))
79
    {
80
      list uplist;
81
      slab *upslab;
82
      struct l_lsr_head *llsh;
83
84
      init_list(&uplist);
85
      upslab=sl_new(p->pool,sizeof(struct l_lsr_head));
86
87
      WALK_SLIST(SNODE en,n->lsrtl)
88
      {
89
        if((SNODE en)->next==(SNODE en)) die("BUGGGGGG");
90
        llsh=sl_alloc(upslab);
91
        llsh->lsh.id=en->lsa.id;
92
        llsh->lsh.rt=en->lsa.rt;
93
        llsh->lsh.type=en->lsa.type;
94 92e8be8c Ondrej Filip
        DBG("Working on ID: %I, RT: %I, Type: %u\n",
95
          en->lsa.id, en->lsa.rt, en->lsa.type);
96 9669362f Ondrej Filip
        add_tail(&uplist, NODE llsh);
97
      }
98
      ospf_lsupd_tx_list(n, &uplist);
99
      rfree(upslab);
100
    }
101 43e75f38 Ondrej Filip
  }
102 6d2b3211 Ondrej Filip
}
103
104
void
105
ospf_lsreq_rx(struct ospf_lsreq_packet *ps, struct proto *p,
106
  struct ospf_iface *ifa, u16 size)
107
{
108
  u32 nrid, myrid;
109
  struct ospf_neighbor *n;
110
  struct ospf_lsreq_header *lsh;
111 f45fd316 Ondrej Filip
  struct l_lsr_head *llsh;
112
  list uplist;
113
  slab *upslab;
114 6d2b3211 Ondrej Filip
  int length;
115 92e8be8c Ondrej Filip
  int i,lsano;
116 6d2b3211 Ondrej Filip
117
  nrid=ntohl(ps->ospf_packet.routerid);
118
119
  myrid=p->cf->global->router_id;
120
121
  if((n=find_neigh(ifa, nrid))==NULL)
122
  {
123 9669362f Ondrej Filip
    debug("%s: Received lsreq from unknown neighbor! (%I)\n", p->name,
124 6d2b3211 Ondrej Filip
      nrid);
125
    return ;
126
  }
127 9669362f Ondrej Filip
  if(n->state<NEIGHBOR_EXCHANGE) return;
128
129
  debug("%s: Received LS req from neighbor: %I\n",p->name, n->ip);
130 6d2b3211 Ondrej Filip
131 92e8be8c Ondrej Filip
  length=ntohs(ps->ospf_packet.length);
132 6d2b3211 Ondrej Filip
  lsh=(void *)(ps+1);
133 f45fd316 Ondrej Filip
  init_list(&uplist);
134
  upslab=sl_new(p->pool,sizeof(struct l_lsr_head));
135
136 92e8be8c Ondrej Filip
  lsano=(length-sizeof(struct ospf_lsreq_packet))/
137
    sizeof(struct ospf_lsreq_header);
138
  for(i=0;i<lsano;lsh++,i++)
139 6d2b3211 Ondrej Filip
  {
140 44724025 Ondrej Filip
    DBG("Processing LSA: ID=%I, Type=%u, Router=%I\n", ntohl(lsh->id),
141 9f940976 Ondrej Filip
    lsh->type, ntohl(lsh->rt));
142 f45fd316 Ondrej Filip
    llsh=sl_alloc(upslab);
143
    llsh->lsh.id=ntohl(lsh->id);
144
    llsh->lsh.rt=ntohl(lsh->rt);
145 9f940976 Ondrej Filip
    llsh->lsh.type=lsh->type;
146 f45fd316 Ondrej Filip
    add_tail(&uplist, NODE llsh);
147
    if(ospf_hash_find(n->ifa->oa->gr, llsh->lsh.id, llsh->lsh.rt,
148
      llsh->lsh.type)==NULL)
149 de769e24 Ondrej Filip
    {
150 92e8be8c Ondrej Filip
      log("Received bad LS req from: %I looking: RT: %I, ID: %I, Type: %u",
151 5f743d96 Ondrej Filip
        n->ip, lsh->rt, lsh->id, lsh->type);
152 de769e24 Ondrej Filip
      ospf_neigh_sm(n,INM_BADLSREQ);
153 f45fd316 Ondrej Filip
      rfree(upslab);
154 de769e24 Ondrej Filip
      return;
155
    }
156 6d2b3211 Ondrej Filip
  }
157 f45fd316 Ondrej Filip
  ospf_lsupd_tx_list(n, &uplist);
158
  rfree(upslab);
159 6d2b3211 Ondrej Filip
}