Statistics
| Branch: | Revision:

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

History | View | Annotate | Download (5.08 KB)

1 de769e24 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 67315ef6 Ondrej Filip
/* Note, that h is in network endianity! */
12 de769e24 Ondrej Filip
void
13 67315ef6 Ondrej Filip
ospf_lsack_direct_tx(struct ospf_neighbor *n,struct ospf_lsa_header *h)
14 de769e24 Ondrej Filip
{
15 67315ef6 Ondrej Filip
  struct ospf_packet *op;
16
  struct ospf_lsack_packet *pk;
17
  sock *sk=n->ifa->ip_sk;
18 9669362f Ondrej Filip
  struct proto *p=&n->ifa->proto->proto;
19 67315ef6 Ondrej Filip
  u16 len;
20
21 26116eac Ondrej Filip
  DBG("Sending direct ACK to %I for Type: %u, ID: %I, RT: %I\n",n->rid,
22
    h->type, ntohl(h->id), ntohl(h->rt));
23 023f5e86 Ondrej Filip
24 67315ef6 Ondrej Filip
  pk=(struct ospf_lsack_packet *)sk->tbuf;
25
  op=(struct ospf_packet *)sk->tbuf;
26
27 89d6782d Ondrej Filip
  fill_ospf_pkt_hdr(n->ifa, pk, LSACK_P);
28 67315ef6 Ondrej Filip
29
  memcpy(pk+1,h,sizeof(struct ospf_lsa_header));
30
  len=sizeof(struct ospf_lsack_packet)+sizeof(struct ospf_lsa_header);
31
  op->length=htons(len);
32
  ospf_pkt_finalize(n->ifa, op);
33
  sk_send_to(sk,len, n->ip, OSPF_PROTO);
34 9669362f Ondrej Filip
  debug("%s: LS ack sent to %I\n", p->name, n->ip);
35 67315ef6 Ondrej Filip
}
36
37
void
38
ospf_lsa_delay(struct ospf_neighbor *n,struct ospf_lsa_header *h,
39
  struct proto *p)
40
{
41
  struct lsah_n *no;
42
43
  no=mb_alloc(p->pool,sizeof(struct lsah_n));
44
  memcpy(&no->lsa,h,sizeof(struct ospf_lsa_header));
45
  add_tail(&n->ackl, NODE no);
46 284c43ff Ondrej Filip
  DBG("Adding delay ack for %I, ID: %I, RT: %I, Type: %u\n",n->rid,
47
    ntohl(h->id), ntohl(h->rt),h->type);
48 67315ef6 Ondrej Filip
}
49
50
void
51
ackd_timer_hook(timer *t)
52
{
53
  struct ospf_neighbor *n=t->data;
54
  if(!EMPTY_LIST(n->ackl)) ospf_lsack_delay_tx(n);
55
}
56
57
void
58
ospf_lsack_delay_tx(struct ospf_neighbor *n)
59
{
60
  struct ospf_packet *op;
61
  struct ospf_lsack_packet *pk;
62
  sock *sk;
63
  u16 len,i=0;
64
  struct ospf_lsa_header *h;
65
  struct lsah_n *no;
66
  struct ospf_iface *ifa=n->ifa;
67
68 c8d1f3fe Ondrej Filip
  debug("%s: LS ack sent to %I (delayed)\n",n->ifa->proto->proto.name,n->ip);
69 023f5e86 Ondrej Filip
70 67315ef6 Ondrej Filip
  if(ifa->type==OSPF_IT_BCAST)
71
  {
72
    sk=ifa->hello_sk;
73
  }
74
  else
75
  {
76
    sk=ifa->ip_sk;
77
  }
78
79
  pk=(struct ospf_lsack_packet *)sk->tbuf;
80
  op=(struct ospf_packet *)sk->tbuf;
81
82 89d6782d Ondrej Filip
  fill_ospf_pkt_hdr(n->ifa, pk, LSACK_P);
83 67315ef6 Ondrej Filip
  h=(struct ospf_lsa_header *)(pk+1);
84
85
  while(!EMPTY_LIST(n->ackl))
86
  {
87
    no=(struct lsah_n *)HEAD(n->ackl);
88
    memcpy(h+i,&no->lsa, sizeof(struct ospf_lsa_header));
89
    i++;
90 023f5e86 Ondrej Filip
    DBG("Iter %u ID: %I, RT: %I, Type: %u\n",i, ntohl((h+i)->id),
91
      ntohl((h+i)->rt),(h+i)->type);
92
    rem_node(NODE no);
93 284c43ff Ondrej Filip
    mb_free(no);
94 023f5e86 Ondrej Filip
    if((i*sizeof(struct ospf_lsa_header)+sizeof(struct ospf_lsack_packet)+SIPH)>
95 67315ef6 Ondrej Filip
      n->ifa->iface->mtu)
96
    {
97
      if(!EMPTY_LIST(n->ackl))
98
      {
99
        len=sizeof(struct ospf_lsack_packet)+i*sizeof(struct ospf_lsa_header);
100
        op->length=htons(len);
101
        ospf_pkt_finalize(n->ifa, op);
102 284c43ff Ondrej Filip
        DBG("Sending and continueing! Len=%u\n",len);
103 67315ef6 Ondrej Filip
        if(ifa->type==OSPF_IT_BCAST)
104
        {
105
          if((ifa->state==OSPF_IS_DR)||(ifa->state==OSPF_IS_BACKUP))
106
          {
107
            sk_send_to(sk ,len, AllSPFRouters, OSPF_PROTO);
108
          }
109
          else
110
          {
111
            sk_send_to(sk ,len, AllDRouters, OSPF_PROTO);
112
          }
113
        }
114
        else
115
        {
116
          sk_send_to_agt(sk, len, ifa, NEIGHBOR_EXCHANGE);
117
        }
118 284c43ff Ondrej Filip
119 89d6782d Ondrej Filip
        fill_ospf_pkt_hdr(n->ifa, pk, LSACK_P);
120 67315ef6 Ondrej Filip
        i=0;
121
      }
122
    }
123
  }
124
125
  len=sizeof(struct ospf_lsack_packet)+i*sizeof(struct ospf_lsa_header);
126
  op->length=htons(len);
127
  ospf_pkt_finalize(n->ifa, op);
128 023f5e86 Ondrej Filip
  DBG("Sending! Len=%u\n",len);
129 67315ef6 Ondrej Filip
  if(ifa->type==OSPF_IT_BCAST)
130
  {
131
    if((ifa->state==OSPF_IS_DR)||(ifa->state==OSPF_IS_BACKUP))
132
    {
133
      sk_send_to(sk ,len, AllSPFRouters, OSPF_PROTO);
134
    }
135
    else
136
    {
137
      sk_send_to(sk ,len, AllDRouters, OSPF_PROTO);
138
    }
139
  }
140
  else
141
  {
142
    sk_send_to_agt(sk, len, ifa, NEIGHBOR_EXCHANGE);
143
  }
144 de769e24 Ondrej Filip
}
145
146 67315ef6 Ondrej Filip
147
148 de769e24 Ondrej Filip
void
149
ospf_lsack_rx(struct ospf_lsack_packet *ps, struct proto *p,
150
  struct ospf_iface *ifa, u16 size)
151
{
152
  u32 nrid, myrid;
153
  struct ospf_neighbor *n;
154 4bf41ac8 Ondrej Filip
  struct ospf_lsa_header lsa,*plsa;
155 de769e24 Ondrej Filip
  int length;
156 4bf41ac8 Ondrej Filip
  u16 nolsa,i;
157
  struct top_hash_entry *en;
158 c8d1f3fe Ondrej Filip
  u16 lenn=ntohs(ps->ospf_packet.length);
159 de769e24 Ondrej Filip
160
  nrid=ntohl(ps->ospf_packet.routerid);
161
162
  myrid=p->cf->global->router_id;
163
164
  if((n=find_neigh(ifa, nrid))==NULL)
165
  {
166 9669362f Ondrej Filip
    debug("%s: Received LS ack from unknown neigbor! (%I)\n", p->name,
167 de769e24 Ondrej Filip
      nrid);
168
    return ;
169
  }
170 ebff007f Ondrej Filip
171 c8d1f3fe Ondrej Filip
  debug("%s: Received LS ack from %I\n", p->name, n->ip);
172 9669362f Ondrej Filip
173 c8d1f3fe Ondrej Filip
  if(n->state<NEIGHBOR_EXCHANGE) return;
174 9669362f Ondrej Filip
175 c8d1f3fe Ondrej Filip
  nolsa=(lenn-sizeof(struct ospf_lsack_packet))/
176 4bf41ac8 Ondrej Filip
    sizeof(struct ospf_lsa_header);
177 c8d1f3fe Ondrej Filip
178
  if((nolsa<1)||((lenn-sizeof(struct ospf_lsack_packet))!=
179
    (nolsa*sizeof(struct ospf_lsa_header))))
180
  {
181 df49d4e1 Martin Mares
    log("%s: Received corrupted LS ack from %I", p->name, n->ip);
182 c8d1f3fe Ondrej Filip
    return;
183
  }
184
185
  plsa=(struct ospf_lsa_header *)(ps+1);
186 4bf41ac8 Ondrej Filip
187
  for(i=0;i<nolsa;i++)
188
  {
189
    ntohlsah(plsa+i,&lsa);
190
    if((en=ospf_hash_find_header(n->lsrth,&lsa))==NULL) continue;
191
192
    if(lsa_comp(&lsa,&en->lsa)!=CMP_SAME)
193
    {
194 37282678 Ondrej Filip
      if((lsa.sn==LSA_MAXSEQNO)&&(lsa.age==LSA_MAXAGE)) continue;
195
196 c8d1f3fe Ondrej Filip
      debug("%s: Strange LS acknoledgement from %I\n",p->name,n->ip);
197
      debug("%s: Id: %I, Rt: %I, Type: %u\n",p->name,lsa.id,lsa.rt,lsa.type);
198 7a5582ac Ondrej Filip
      debug("%s: I have: Age: %4u, Seqno: 0x%08x, Sum: %u\n",
199
        p->name, en->lsa.age, en->lsa.sn, en->lsa.checksum);
200
      debug("%s: He has: Age: %4u, Seqno: 0x%08x, Sum: %u\n",
201 83e50ffc Ondrej Filip
        p->name,lsa.age,lsa.sn,lsa.checksum);
202 4bf41ac8 Ondrej Filip
      continue;
203
    }
204
205 ebff007f Ondrej Filip
    DBG("Deleting LS Id: %I RT: %I Type: %u from LS Retl for neighbor %I\n",
206 4bf41ac8 Ondrej Filip
      lsa.id,lsa.rt,lsa.type,n->rid);
207
    s_rem_node(SNODE en);
208
    ospf_hash_delete(n->lsrth,en);
209
  }  
210 de769e24 Ondrej Filip
}