Statistics
| Branch: | Revision:

iof-bird-daemon / proto / ospf / lsack.c @ 1a61882d

History | View | Annotate | Download (4.64 KB)

1 de769e24 Ondrej Filip
/*
2
 *        BIRD -- OSPF
3
 *
4 c76ba51a Ondrej Filip
 *        (c) 2000-2004 Ondrej Filip <feela@network.cz>
5 de769e24 Ondrej Filip
 *
6
 *        Can be freely distributed and used under the terms of the GNU GPL.
7
 */
8
9
#include "ospf.h"
10
11 fb9bf688 Ondrej Filip
char *s_queue[] = { "direct", "delayed" };
12 67315ef6 Ondrej Filip
13 c76ba51a Ondrej Filip
/*
14
 * =====================================
15
 * Note, that h is in network endianity!
16
 * =====================================
17
 */
18 fb9bf688 Ondrej Filip
19 67315ef6 Ondrej Filip
void
20 fb9bf688 Ondrej Filip
ospf_lsack_enqueue(struct ospf_neighbor *n, struct ospf_lsa_header *h,
21 8e15e048 Ondrej Filip
                   int queue)
22 67315ef6 Ondrej Filip
{
23 8e15e048 Ondrej Filip
  struct lsah_n *no = mb_alloc(n->pool, sizeof(struct lsah_n));
24 fb9bf688 Ondrej Filip
  memcpy(&no->lsa, h, sizeof(struct ospf_lsa_header));
25 c76ba51a Ondrej Filip
  add_tail(&n->ackl[queue], NODE no);
26 fb9bf688 Ondrej Filip
  DBG("Adding (%s) ack for %I, ID: %I, RT: %I, Type: %u\n", s_queue[queue],
27
      n->rid, ntohl(h->id), ntohl(h->rt), h->type);
28 67315ef6 Ondrej Filip
}
29
30
void
31 c76ba51a Ondrej Filip
ospf_lsack_send(struct ospf_neighbor *n, int queue)
32 67315ef6 Ondrej Filip
{
33
  struct ospf_packet *op;
34
  struct ospf_lsack_packet *pk;
35
  sock *sk;
36 fb9bf688 Ondrej Filip
  u16 len, i = 0;
37 67315ef6 Ondrej Filip
  struct ospf_lsa_header *h;
38
  struct lsah_n *no;
39 fb9bf688 Ondrej Filip
  struct ospf_iface *ifa = n->ifa;
40
  struct proto *p = &n->ifa->proto->proto;
41 67315ef6 Ondrej Filip
42 fb9bf688 Ondrej Filip
  if (EMPTY_LIST(n->ackl[queue]))
43
    return;
44 c76ba51a Ondrej Filip
45
  OSPF_TRACE(D_PACKETS, "LS ack sent to %I (%s)", n->ip, s_queue[queue]);
46 023f5e86 Ondrej Filip
47 fb9bf688 Ondrej Filip
  if (ifa->type == OSPF_IT_BCAST)
48
    sk = ifa->hello_sk;
49 67315ef6 Ondrej Filip
  else
50 fb9bf688 Ondrej Filip
    sk = ifa->ip_sk;
51 67315ef6 Ondrej Filip
52 fb9bf688 Ondrej Filip
  pk = (struct ospf_lsack_packet *) sk->tbuf;
53
  op = (struct ospf_packet *) sk->tbuf;
54 67315ef6 Ondrej Filip
55 89d6782d Ondrej Filip
  fill_ospf_pkt_hdr(n->ifa, pk, LSACK_P);
56 fb9bf688 Ondrej Filip
  h = (struct ospf_lsa_header *) (pk + 1);
57 67315ef6 Ondrej Filip
58 fb9bf688 Ondrej Filip
  while (!EMPTY_LIST(n->ackl[queue]))
59 67315ef6 Ondrej Filip
  {
60 fb9bf688 Ondrej Filip
    no = (struct lsah_n *) HEAD(n->ackl[queue]);
61
    memcpy(h + i, &no->lsa, sizeof(struct ospf_lsa_header));
62 67315ef6 Ondrej Filip
    i++;
63 fb9bf688 Ondrej Filip
    DBG("Iter %u ID: %I, RT: %I, Type: %u\n", i, ntohl((h + i)->id),
64
        ntohl((h + i)->rt), (h + i)->type);
65 023f5e86 Ondrej Filip
    rem_node(NODE no);
66 284c43ff Ondrej Filip
    mb_free(no);
67 fb9bf688 Ondrej Filip
    if ((i * sizeof(struct ospf_lsa_header) +
68
         sizeof(struct ospf_lsack_packet) + SIPH) > n->ifa->iface->mtu)
69 67315ef6 Ondrej Filip
    {
70 fb9bf688 Ondrej Filip
      if (!EMPTY_LIST(n->ackl[queue]))
71 67315ef6 Ondrej Filip
      {
72 fb9bf688 Ondrej Filip
        len =
73
          sizeof(struct ospf_lsack_packet) +
74
          i * sizeof(struct ospf_lsa_header);
75
        op->length = htons(len);
76 67315ef6 Ondrej Filip
        ospf_pkt_finalize(n->ifa, op);
77 fb9bf688 Ondrej Filip
        DBG("Sending and continuing! Len=%u\n", len);
78
        if (ifa->type == OSPF_IT_BCAST)
79 67315ef6 Ondrej Filip
        {
80 fb9bf688 Ondrej Filip
          if ((ifa->state == OSPF_IS_DR) || (ifa->state == OSPF_IS_BACKUP))
81
            sk_send_to(sk, len, AllSPFRouters, OSPF_PROTO);
82 67315ef6 Ondrej Filip
          else
83 fb9bf688 Ondrej Filip
            sk_send_to(sk, len, AllDRouters, OSPF_PROTO);
84 67315ef6 Ondrej Filip
        }
85
        else
86
        {
87 fb9bf688 Ondrej Filip
          if ((ifa->state == OSPF_IS_DR) || (ifa->state == OSPF_IS_BACKUP))
88
            sk_send_to_agt(sk, len, ifa, NEIGHBOR_EXCHANGE);
89 eb436e16 Ondrej Filip
          else
90 fb9bf688 Ondrej Filip
            sk_send_to_bdr(sk, len, ifa);
91 67315ef6 Ondrej Filip
        }
92 284c43ff Ondrej Filip
93 89d6782d Ondrej Filip
        fill_ospf_pkt_hdr(n->ifa, pk, LSACK_P);
94 fb9bf688 Ondrej Filip
        i = 0;
95 67315ef6 Ondrej Filip
      }
96
    }
97
  }
98
99 fb9bf688 Ondrej Filip
  len = sizeof(struct ospf_lsack_packet) + i * sizeof(struct ospf_lsa_header);
100
  op->length = htons(len);
101 67315ef6 Ondrej Filip
  ospf_pkt_finalize(n->ifa, op);
102 fb9bf688 Ondrej Filip
  DBG("Sending! Len=%u\n", len);
103
  if (ifa->type == OSPF_IT_BCAST)
104 67315ef6 Ondrej Filip
  {
105 fb9bf688 Ondrej Filip
    if ((ifa->state == OSPF_IS_DR) || (ifa->state == OSPF_IS_BACKUP))
106 67315ef6 Ondrej Filip
    {
107 c76ba51a Ondrej Filip
      sk_send_to(sk, len, AllSPFRouters, OSPF_PROTO);
108 67315ef6 Ondrej Filip
    }
109
    else
110
    {
111 c76ba51a Ondrej Filip
      sk_send_to(sk, len, AllDRouters, OSPF_PROTO);
112 67315ef6 Ondrej Filip
    }
113
  }
114
  else
115
  {
116
    sk_send_to_agt(sk, len, ifa, NEIGHBOR_EXCHANGE);
117
  }
118 de769e24 Ondrej Filip
}
119
120
void
121 8e15e048 Ondrej Filip
ospf_lsack_receive(struct ospf_lsack_packet *ps,
122 5e3436d2 Ondrej Filip
                   struct ospf_iface *ifa, struct ospf_neighbor *n)
123 de769e24 Ondrej Filip
{
124 fb9bf688 Ondrej Filip
  struct ospf_lsa_header lsa, *plsa;
125 5e3436d2 Ondrej Filip
  u16 nolsa;
126 4bf41ac8 Ondrej Filip
  struct top_hash_entry *en;
127 8e15e048 Ondrej Filip
  struct proto *p = (struct proto *) ifa->proto;
128 5e3436d2 Ondrej Filip
  unsigned int size = ntohs(ps->ospf_packet.length), i;
129 ebff007f Ondrej Filip
130 531a48d8 Ondrej Filip
  OSPF_TRACE(D_PACKETS, "Received LS ack from %I", n->ip);
131 4bb9ce56 Ondrej Filip
  ospf_neigh_sm(n, INM_HELLOREC);
132 9669362f Ondrej Filip
133 fb9bf688 Ondrej Filip
  if (n->state < NEIGHBOR_EXCHANGE)
134
    return;
135 9669362f Ondrej Filip
136 5e3436d2 Ondrej Filip
  nolsa = (size - sizeof(struct ospf_lsack_packet)) /
137 4bf41ac8 Ondrej Filip
    sizeof(struct ospf_lsa_header);
138 c8d1f3fe Ondrej Filip
139 5e3436d2 Ondrej Filip
  if ((nolsa < 1) || ((size - sizeof(struct ospf_lsack_packet)) !=
140 fb9bf688 Ondrej Filip
                      (nolsa * sizeof(struct ospf_lsa_header))))
141 c8d1f3fe Ondrej Filip
  {
142 7a03e29d Ondrej Filip
    log(L_ERR "Received corrupted LS ack from %I", n->ip);
143 c8d1f3fe Ondrej Filip
    return;
144
  }
145
146 fb9bf688 Ondrej Filip
  plsa = (struct ospf_lsa_header *) (ps + 1);
147 4bf41ac8 Ondrej Filip
148 fb9bf688 Ondrej Filip
  for (i = 0; i < nolsa; i++)
149 4bf41ac8 Ondrej Filip
  {
150 fb9bf688 Ondrej Filip
    ntohlsah(plsa + i, &lsa);
151
    if ((en = ospf_hash_find_header(n->lsrth, &lsa)) == NULL)
152 2e10a170 Ondrej Filip
      continue;                        /* pg 155 */
153 4bf41ac8 Ondrej Filip
154 9b7de4c4 Ondrej Filip
    if (lsa_comp(&lsa, &en->lsa) != CMP_SAME)        /* pg 156 */
155 4bf41ac8 Ondrej Filip
    {
156 fb9bf688 Ondrej Filip
      if ((lsa.sn == LSA_MAXSEQNO) && (lsa.age == LSA_MAXAGE))
157
        continue;
158 37282678 Ondrej Filip
159 fb9bf688 Ondrej Filip
      OSPF_TRACE(D_PACKETS, "Strange LS acknoledgement from %I", n->ip);
160 531a48d8 Ondrej Filip
      OSPF_TRACE(D_PACKETS, "Id: %I, Rt: %I, Type: %u",
161 fb9bf688 Ondrej Filip
                 lsa.id, lsa.rt, lsa.type);
162 531a48d8 Ondrej Filip
      OSPF_TRACE(D_PACKETS, "I have: Age: %4u, Seqno: 0x%08x, Sum: %u",
163 fb9bf688 Ondrej Filip
                 en->lsa.age, en->lsa.sn, en->lsa.checksum);
164 531a48d8 Ondrej Filip
      OSPF_TRACE(D_PACKETS, "He has: Age: %4u, Seqno: 0x%08x, Sum: %u",
165 fb9bf688 Ondrej Filip
                 lsa.age, lsa.sn, lsa.checksum);
166 4bf41ac8 Ondrej Filip
      continue;
167
    }
168
169 ebff007f Ondrej Filip
    DBG("Deleting LS Id: %I RT: %I Type: %u from LS Retl for neighbor %I\n",
170 fb9bf688 Ondrej Filip
        lsa.id, lsa.rt, lsa.type, n->rid);
171 4bf41ac8 Ondrej Filip
    s_rem_node(SNODE en);
172 fb9bf688 Ondrej Filip
    if (en->lsa_body != NULL)
173
      mb_free(en->lsa_body);
174
    en->lsa_body = NULL;
175
    ospf_hash_delete(n->lsrth, en);
176
  }
177 de769e24 Ondrej Filip
}