Statistics
| Branch: | Revision:

iof-bird-daemon / proto / ospf / lsreq.c @ 9669362f

History | View | Annotate | Download (3.84 KB)

1
/*
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
  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);
27

    
28
  sn=SHEAD(n->lsrql);
29
  if(EMPTY_SLIST(n->lsrql))
30
  {
31
    if(n->state==NEIGHBOR_LOADING) ospf_neigh_sm(n, INM_LOADDONE);
32
    return;
33
  }
34
 
35
  i=j=(n->ifa->iface->mtu-SIPH-sizeof(struct ospf_lsreq_packet))/
36
    sizeof(struct ospf_lsreq_header);
37
  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
    DBG("Requesting %uth LSA: Type: %u, Id: %I, RT: %I\n",i, en->lsa.type,
47
                    en->lsa.id, en->lsa.rt);
48
    lsh++;
49
    if(sn==STAIL(n->lsrql)) break;
50
    sn=sn->next;
51
  }
52
  if(i!=0) i--;
53

    
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
  debug("%s: LS request sent to: %I\n", p->name, n->rid);
59
}
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
  struct top_hash_entry *en;
68

    
69
  n=(struct ospf_neighbor *)timer->data;
70
  ifa=n->ifa;
71
  p=(struct proto *)(ifa->proto);
72

    
73
  DBG("%s: LSRR timer fired on interface %s for neigh: %I.\n",
74
    p->name, ifa->iface->name, n->rid);
75
  if(n->state<NEIGHBOR_FULL) ospf_lsreq_tx(n);
76
  else
77
  {
78
    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
        DBG("Working on ID: %I, RT: %I, Type: %u\n",en->lsa.id,en->lsa.rt,en->lsa.type);
95
        add_tail(&uplist, NODE llsh);
96
      }
97
      ospf_lsupd_tx_list(n, &uplist);
98
      rfree(upslab);
99
    }
100
  }
101
}
102

    
103
void
104
ospf_lsreq_rx(struct ospf_lsreq_packet *ps, struct proto *p,
105
  struct ospf_iface *ifa, u16 size)
106
{
107
  u32 nrid, myrid;
108
  struct ospf_neighbor *n;
109
  struct ospf_lsreq_header *lsh;
110
  struct l_lsr_head *llsh;
111
  list uplist;
112
  slab *upslab;
113
  int length;
114
  u8 i;
115

    
116
  nrid=ntohl(ps->ospf_packet.routerid);
117

    
118
  myrid=p->cf->global->router_id;
119

    
120
  if((n=find_neigh(ifa, nrid))==NULL)
121
  {
122
    debug("%s: Received lsreq from unknown neighbor! (%I)\n", p->name,
123
      nrid);
124
    return ;
125
  }
126
  if(n->state<NEIGHBOR_EXCHANGE) return;
127

    
128
  debug("%s: Received LS req from neighbor: %I\n",p->name, n->ip);
129

    
130
  length=htons(ps->ospf_packet.length);
131
  lsh=(void *)(ps+1);
132
  init_list(&uplist);
133
  upslab=sl_new(p->pool,sizeof(struct l_lsr_head));
134

    
135
  for(i=0;i<(length-sizeof(struct ospf_lsreq_packet))/
136
    sizeof(struct ospf_lsreq_header);i++);
137
  {
138
    DBG("Processing LSA: ID=%I, Type=%u, Router=%I\n", ntohl(lsh->id),
139
    lsh->type, ntohl(lsh->rt));
140
    llsh=sl_alloc(upslab);
141
    llsh->lsh.id=ntohl(lsh->id);
142
    llsh->lsh.rt=ntohl(lsh->rt);
143
    llsh->lsh.type=lsh->type;
144
    add_tail(&uplist, NODE llsh);
145
    if(ospf_hash_find(n->ifa->oa->gr, llsh->lsh.id, llsh->lsh.rt,
146
      llsh->lsh.type)==NULL)
147
    {
148
      debug("Received bad LS req from: %I looking: RT: %I, ID: %I, Type: %u",
149
        n->ip, lsh->rt, lsh->id, lsh->type);
150
      ospf_neigh_sm(n,INM_BADLSREQ);
151
      rfree(upslab);
152
      return;
153
    }
154
  }
155
  ospf_lsupd_tx_list(n, &uplist);
156
  rfree(upslab);
157
}
158