]> git.ipfire.org Git - thirdparty/bird.git/blame - proto/ospf/dbdes.c
ospf.c and ospc.h splitted into various files.
[thirdparty/bird.git] / proto / ospf / dbdes.c
CommitLineData
4364b47e
OF
1/*
2 * BIRD -- OSPF
3 *
4 * (c) 1999 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
11void
12ospf_dbdes_tx(struct ospf_neighbor *n)
13{
14 struct ospf_dbdes_packet *pkt;
15 struct ospf_packet *op;
16 struct ospf_iface *ifa;
17 u16 length;
18 struct proto *p;
19
20 ifa=n->ifa;
21
22 p=(struct proto *)(ifa->proto);
23
24 switch(n->state)
25 {
26 case NEIGHBOR_EXSTART: /* Send empty packets */
27 pkt=(struct ospf_dbdes_packet *)(ifa->ip_sk->tbuf);
28 op=(struct ospf_packet *)pkt;
29
30 fill_ospf_pkt_hdr(ifa, pkt, DBDES);
31 pkt->iface_mtu= ((struct iface *)ifa)->mtu;
32 pkt->options= ifa->options;
33 pkt->imms=n->myimms;
34 pkt->ddseq=n->dds;
35 length=sizeof(struct ospf_dbdes_packet);
36 op->length=htons(length);
37 ospf_pkt_finalize(ifa, op);
38 sk_send_to(ifa->ip_sk,length, n->ip, OSPF_PROTO);
39 debug("%s: DB_DES sent for %u.\n", p->name, n->rid);
40
41 /*case NEIGHBOR_EXCHANGE: */
42 default: /* Ignore it */
43 break;
44 }
45}
46
47void
48rxmt_timer_hook(timer *timer)
49{
50 struct ospf_iface *ifa;
51 struct proto *p;
52 struct ospf_neighbor *n;
53
54 ifa=(struct ospf_iface *)timer->data;
55 p=(struct proto *)(ifa->proto);
56 debug("%s: RXMT timer fired on interface %s.\n",
57 p->name, ifa->iface->name);
58 WALK_LIST (n, ifa->neigh_list) /* Try to send db_des */
59 {
60 ospf_dbdes_tx(n);
61 }
62}
63
64void
65ospf_dbdes_rx(struct ospf_dbdes_packet *ps, struct proto *p,
66 struct ospf_iface *ifa, u16 size)
67{
68 u32 nrid, myrid;
69 struct ospf_neighbor *n;
70 u8 i;
71
72 nrid=ntohl(((struct ospf_packet *)ps)->routerid);
73
74 myrid=p->cf->global->router_id;
75
76 if((n=find_neigh(ifa, nrid))==NULL)
77 {
78 debug("%s: Received dbdes from unknown neigbor! (%u)\n", p->name,
79 nrid);
80 return ;
81 }
82
83 if(ifa->iface->mtu<size)
84 {
85 debug("%s: Received dbdes larger than MTU from (%u)!\n", p->name, nrid);
86 return ;
87 }
88
89 switch(n->state)
90 {
91 case NEIGHBOR_DOWN:
92 case NEIGHBOR_ATTEMPT:
93 case NEIGHBOR_2WAY:
94 debug("%s: Received dbdes from %u in bad state. (%u)\n", p->name, nrid);
95 return;
96 break;
97 case NEIGHBOR_INIT:
98 ospf_neigh_sm(n, INM_2WAYREC);
99 if(n->state!=NEIGHBOR_EXSTART) return;
100 case NEIGHBOR_EXSTART:
101 if(ps->imms==(DBDES_I|DBDES_M|DBDES_MS) && (n->rid > myrid) &&
102 (size == sizeof(struct ospf_dbdes_packet)))
103 {
104 /* I'm slave! */
105 n->dds=ps->ddseq;
106 n->options=ps->options;
107 n->myimms=(n->myimms && DBDES_M);
108 n->ddr=ps->ddseq;
109 n->imms=ps->imms;
110 debug("%s: I'm slave to %u. \n", p->name, nrid);
111 ospf_neigh_sm(n, INM_NEGDONE);
112 }
113 else
114 {
115 if(((ps->imms & (DBDES_I|DBDES_MS))== 0) && (n->rid < myrid) &&
116 (n->dds == ps->ddseq))
117 {
118 /* I'm master! */
119 n->options=ps->options;
120 n->ddr=ps->ddseq;
121 n->imms=ps->imms;
122 debug("%s: I'm master to %u. \n", p->name, nrid);
123 ospf_neigh_sm(n, INM_NEGDONE);
124 }
125 else
126 {
127 debug("%s: Nothing happend to %u (imms=%u)", p->name, nrid,
128 ps->imms);
129 break;
130 }
131 }
132 break; /* I should probably continue processing packet */
133
134 case NEIGHBOR_EXCHANGE:
135 if((ps->imms==n->imms) && (ps->options=n->options) &&
136 (ps->ddseq==n->dds))
137 {
138 /* Duplicate packet */
139 debug("%s: Received duplicate dbdes from (%u)!\n", p->name, nrid);
140 if(!IAMMASTER(n->imms))
141 {
142 ospf_dbdes_tx(n);
143 }
144 return;
145 }
146
147 if(IAMMASTER(ps->imms)!=IAMMASTER(n->myimms)) /* M/S bit differs */
148 {
149 ospf_neigh_sm(n, INM_SEQMIS);
150 break;
151 }
152
153 if(INISET(ps->imms)) /* I bit is set */
154 {
155 ospf_neigh_sm(n, INM_SEQMIS);
156 break;
157 }
158
159 if(ps->options!=n->options) /* Options differs */
160 {
161 ospf_neigh_sm(n, INM_SEQMIS);
162 break;
163 }
164
165 if(IAMMASTER(n->myimms))
166 {
167 if(ps->ddseq!=n->dds)
168 {
169 ospf_neigh_sm(n, INM_SEQMIS);
170 break;
171 }
172 }
173 else
174 {
175 if(ps->ddseq!=(n->dds+1))
176 {
177 ospf_neigh_sm(n, INM_SEQMIS);
178 break;
179 }
180 }
181
182 /* FIXME: Packet accepted, go on */
183
184 break;
185 case NEIGHBOR_LOADING:
186 case NEIGHBOR_FULL:
187 if((ps->imms==n->imms) && (ps->options=n->options) &&
188 (ps->ddseq==n->dds)) /* Only duplicate are accepted */
189 {
190 debug("%s: Received duplicate dbdes from (%u)!\n", p->name, nrid);
191 return;
192 }
193 else
194 {
195 ospf_neigh_sm(n, INM_SEQMIS);
196 }
197 break;
198 defaut:
199 die("%s: Received dbdes from %u in unknown state. (%u)\n", p->name, nrid);
200 break;
201 }
202}
203