summaryrefslogtreecommitdiffstats
path: root/pimd/TODO
blob: dc2ece5ff85e8d54907e820fed51c1664931238f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
# $QuaggaId: $Format:%an, %ai, %h$ $

T1 DONE Implement debug command
   test pim receive join

T2 DONE Implement debug command
   test pim receive prune

T3 DONE Per-interface Downstream (S,G) state machine
   (RFC 4601 4.5.3. Receiving (S,G) Join/Prune Messages)

T4 DONE Upstream (S,G) state machine
   (RFC 4601 4.5.7. Sending (S,G) Join/Prune Messages)

T5 DONE Verify Data Packet Forwarding Rules
   RFC 4601 4.2.  Data Packet Forwarding Rules
   RFC 4601 4.8.2.  PIM-SSM-Only Routers

   Additionally, the Packet forwarding rules of Section 4.2 can be
   simplified in a PIM-SSM-only router:

     iif is the incoming interface of the packet.
     oiflist = NULL
     if (iif == RPF_interface(S) AND UpstreamJPState(S,G) == Joined) {
       oiflist = inherited_olist(S,G)
     } else if (iif is in inherited_olist(S,G)) {
       send Assert(S,G) on iif
     }
     oiflist = oiflist (-) iif
     forward packet on all interfaces in oiflist

   Macro:
     inherited_olist(S,G) =
       joins(S,G) (+) pim_include(S,G) (-) lost_assert(S,G)

T6 DONE Implement (S,G) Assert state machine (RFC 4601, section 4.6.1).
   Changes in pim_ifchannel.ifassert_winner should trigger
   pim_upstream_update_join_desired().
   Depends on TODO T27.
   Depends on TODO T33.
   See also CAVEAT C7.
   See also: RFC 4601 4.5.7. Sending (S,G) Join/Prune Messages
    Transitions from Joined State
     RPF'(S,G) changes due to an Assert

   http://www.hep.ucl.ac.uk/~ytl/multi-cast/pim-dm_01.html:

     The PIM Assert mechanism is used to shutoff duplicate flows onto
     the same multiaccess network. Routers detect this condiction when
     they receive an (S,G) packet via a multi-access interface that is
     in the (S,G) OIL. This causes the routers to send Assert
     Messages.

   Note that neighbors will not accept Join/Prune or Assert messages
   from a router unless they have first heard a Hello message from that
   router.  Thus, if a router needs to send a Join/Prune or Assert
   message on an interface on which it has not yet sent a Hello message
   with the currently configured IP address, then it MUST immediately
   send the relevant Hello message without waiting for the Hello Timer
   to expire, followed by the Join/Prune or Assert message.

T7 DONE Implement hello option: LAN Prune Delay

T8 DONE Implement J/P_Override_Interval(I)
   Depends on TODO T7.
   See pim_ifchannel.c, pim_ifchannel_prune(), jp_override_interval.

T9 DONE Detect change in IGMPv3 RPF interface/next-hop for S and update.
   channel_oil vif index accordingly ?
   Beware accidentaly adding looped MFC entries (IIF=OIF).

T10 DONE React to (S,G) join directed to another upstream address. See
    also:
    
    RFC 4601: 4.5.7.  Sending (S,G) Join/Prune Messages

    If a router wishes to propagate a Join(S,G) upstream, it must also
    watch for messages on its upstream interface from other routers on
    that subnet, and these may modify its behavior.  If it sees a
    Join(S,G) to the correct upstream neighbor, it should suppress its
    own Join(S,G).  If it sees a Prune(S,G), Prune(S,G,rpt), or
    Prune(*,G) to the correct upstream neighbor towards S, it should
    be prepared to override that prune by scheduling a Join(S,G) to be
    sent almost immediately.

T11 DONE Review protocol modifications for SSM
    (RFC 4601 4.8.1.  Protocol Modifications for SSM Destination
    Addresses)

T12 DONE Review updates of RPF entries.
    FIXME pim_upstream.c send_join():
    Currently only one upstream state is affected by detection of RPF change.
    RPF change should affect all upstream states sharing the RPF cache.

T13 DONE Check that RFC macros using S,G,RPF_interface(S) are actually
    implemented with this strategy:
    rpf_ifch=find_ifch(up->rpf->interface).
    See pim_rpf.c pim_rpf_find_rpf_addr() for a correct example.

    $ grep -i macro pimd/*.c
    pimd/pim_iface.c:  RFC 4601: 4.1.6.  State Summarization Macros
    pimd/pim_ifchannel.c:    RFC 4601: 4.6.5.  Assert State Macros
    pimd/pim_ifchannel.c:  RFC 4601: 4.1.6.  State Summarization Macros
    pimd/pim_ifchannel.c:  RFC 4601: 4.1.6.  State Summarization Macros
    pimd/pim_ifchannel.c:  RFC 4601: 4.6.5.  Assert State Macros
    pimd/pim_ifchannel.c:  Macro:
    pimd/pim_rpf.c:  RFC 4601: 4.1.6.  State Summarization Macros

T14 DONE Send Assert(S,G) on iif as response to WRONGVIF kernel upcall.
    See pim_mroute.c mroute_msg().

T15 DONE Interface command to statically join (S,G).
    interface eth0
     ip igmp join-group 239.1.1.1 source 1.1.1.1

T16 DONE RPF'(S,G) lookup is not working for S reachable with default route.
    See "RPF'(S,G) not found" in pim_rpf_update() from pim_rpf.c.
    Zebra daemon RIB is not reflecting changes in kernel routes
    accurately?

T17 DONE Prevent CLI from creating bogus interfaces.
    Example:
    conf t
     interface xxx

T18 Consider reliable pim solution (refresh reduction)
    A Reliable Transport Mechanism for PIM
    http://tools.ietf.org/wg/pim/draft-ietf-pim-port/
    PORT=PIM-Over-Reliable-Transport

T19 DONE Fix self as neighbor 
    See mailing list post:
    http://lists.gnu.org/archive/html/qpimd-users/2009-04/msg00000.html

T20 DONE Fix debug message: "pim_neighbor_update: internal error:
    trying to replace same prefix list"
    See mailing list post:
    http://lists.gnu.org/archive/html/qpimd-users/2009-04/msg00000.html

T21 DONE Clean-up PIM/IGMP interface mismatch debugging
    See option PIM_CHECK_RECV_IFINDEX_SANITY in pimd/Makefile.am
    See mailing list post:
    http://lists.nongnu.org/archive/html/qpimd-users/2009-04/msg00003.html

T22 DONE IGMP must be protected against adding looped MFC entries
    created by both source and receiver attached to the same
    interface.

T23 DONE libzebra crash after zclient_lookup_nexthop.
    See mailing list post:
    http://lists.nongnu.org/archive/html/qpimd-users/2009-04/msg00008.html

T24 DONE zserv may return recursive routes:
     - nexthop type is set to ZEBRA_NEXTHOP_IPV4
     - ifindex is not reported
     - calls expecting ifindex (fib_lookup_if_vif_index) are disrupted
    See also this mailing list post:
    [PATCH 21/21] Link detect and recursive routes
    http://www.gossamer-threads.com/lists/quagga/dev/17564

T25 DONE Zclient nexthop lookup missing OSPF route to 1.1.1.1/32
    See also:
    pim_zlookup.c zclient_lookup_nexthop misses OSPF 1.1.1.1/32
    zebra/zebra_vty.c show_ip_route_addr_cmd hits OSPF 1.1.1.1/32

T26 DONE Zebra daemon is marking recursive static route as inactive.

    FIXED: zebra daemon was incorrectly marking recursive routes
    pointing to kernel routes as inactive:
      zebra/zebra_rib.c nexthop_active_ipv4:
        -- Original:
	  else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL))
        -- Fixed:
	  else if (CHECK_FLAG (rib->flags, ZEBRA_FLAG_INTERNAL) ||
		   match->type == ZEBRA_ROUTE_KERNEL)

    Old problem description:

    This prevents rib_match_ipv4 from returning its nexthop:
    client: pim_zlookup.c zclient_read_nexthop
    server: zebra/zserv.c zsend_ipv4_nexthop_lookup_v2 -> rib_match_ipv4

    Kernel route is injected into zebra in zebra_rib.c rib_add_ipv4
    Examples:
    rt_netlink.c:726: rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, src, index, table, metric, 0);
    rt_netlink.c:864: rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, src, index, table, 0, 0);

    This patch didn't fix the issue:
    [PATCH 21/21] Link detect and recursive routes
    http://www.gossamer-threads.com/lists/quagga/dev/17564

    See the example below for the route 2.2.2.2.

bash# route add -host 1.1.1.1 gw 127.0.0.1
bash# route add -host 2.2.2.2 gw 1.1.1.1
bash# netstat -nvr
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
2.2.2.2         1.1.1.1         255.255.255.255 UGH       0 0          0 lo
1.1.1.1         127.0.0.1       255.255.255.255 UGH       0 0          0 lo
192.168.0.0     0.0.0.0         255.255.255.0   U         0 0          0 eth0
0.0.0.0         192.168.0.2     0.0.0.0         UG        0 0          0 eth0
bash# 

zebra# sh ip route         
Codes: K - kernel route, C - connected, S - static, R - RIP, O - OSPF,
       I - ISIS, B - BGP, > - selected route, * - FIB route

K>* 0.0.0.0/0 via 192.168.0.2, eth0
K>* 1.1.1.1/32 via 127.0.0.1, lo
K * 2.2.2.2/32 via 1.1.1.1, lo inactive
C>* 127.0.0.0/8 is directly connected, lo
C>* 192.168.0.0/24 is directly connected, eth0

quagga-pimd-router# sh ip route 1.1.1.1
Address         NextHop         Interface Metric Preference
1.1.1.1         127.0.0.1       lo             0          0
quagga-pimd-router# 
quagga-pimd-router# sh ip route 2.2.2.2
Address         NextHop         Interface Metric Preference
2.2.2.2         192.168.0.2     eth0           0          0
quagga-pimd-router# 

T27 DONE Implement debug command
    test pim receive assert
    See also TODO T6: (S,G) Assert state machine.

T28 DONE Bad IPv4 address family=02 in Join/Prune dump
    Reported by Andrew Lunn <andrew.lunn@ascom.ch>
    
    # 58-byte pim v2 Join/Prune dump
    # ------------------------------
    # IPv4 address family=02 is wrong, correct IPv4 address family is 01
    # See http://www.iana.org/assignments/address-family-numbers
    #
    c8XX YY03 : ip src 200.xx.yy.3
    e000 000d : ip dst 224.0.0.13
    9404 0000 : ip router alert option 148.4.0.0
    2300 ab13 : pimv2,type=3 res=00 checksum=ab13
    0200      : upstream family=02, encoding=00
    c8XX YY08 : upstream 200.xx.yy.8
    0001 00d2 : res=00 groups=01 holdtime=00d2
    0200 0020 : group family=02, encoding=00, res=00, mask_len=20
    ef01 0101 : group address 239.1.1.1
    0001 0000 : joined=0001 pruned=0000
    0200 0020 : source family=02, encoding=00, res=00, mask_len=20
    0101 0101 : source address 1.1.1.1

T29 DONE Reset interface PIM-hello-sent counter when primary address changes
    See pim_ifp->pim_ifstat_hello_sent

    RFC 4601: 4.3.1.  Sending Hello Messages

    Thus, if a router needs to send a Join/Prune or Assert message on
    an interface on which it has not yet sent a Hello message with the
    currently configured IP address, then it MUST immediately send the
    relevant Hello message without waiting for the Hello Timer to
    expire, followed by the Join/Prune or Assert message.

T30 DONE Run interface DR election when primary address changes
    Reported by Andrew Lunn <andrew.lunn@ascom.ch>
    See pim_if_dr_election().

T31 If an interface changes one of its secondary IP addresses, a Hello
    message with an updated Address_List option and a non-zero
    HoldTime should be sent immediately.
    See also CAVEAT C15.
    See also RFC 4601: 4.3.1.  Sending Hello Messages

T32 Detection of interface primary address changes may fail when there
    are multiple addresses.
    See also CAVEAT C14.

    pim_find_primary_addr() should return interface primary address
    from connected list. Currently it returns the first address.

    Zebra daemon "show int" is able to keep the primary address as
    first address.

T33 DONE Implement debug command: test pim receive upcall
    See also TODO T6: (S,G) Assert state machine.

T34 DONE assert_action_a1

T35 DONE Review macros depending on interface I.

    See also: grep ,I\) pimd/*.c

    For the case (S,G,I) check if I is either
    1) interface attached to this per-interface S,G state (don't think so)
    or
    2) an arbitrary interface (most probably)

    For the arbitrary interface case (2), consider representing
    interface ifp as its primary address (struct in_addr ifaddr).  The
    benefit is in_addr does not need to be dereferenced, so it does
    not demand protection against crashes.

T36 DONE React to zebra daemon link-detect up/down notification.
    pim_ifp->primary_address is managed by detect_primary_address_change()
    depending on to ifp->connected (managed by zebra_interface_address_read()).

T37 DONE Review list of variables which may affect pim_upstream.c
    pim_upstream_evaluate_join_desired().
    Call pim_upstream_update_join_desired() accordingly.

    See the order of invokation:
      pim_if_dr_election(ifp);
      pim_if_update_join_desired(pim_ifp); /* depends on DR */
      pim_if_update_could_assert(ifp); /* depends on DR */
      pim_if_update_my_assert_metric(ifp); /* depends on could_assert */

    join_desired depends on:
      pim_ifp->primary_address
      pim_ifp->pim_dr_addr
      ch->ifassert_winner_metric
      ch->ifassert_winner
      ch->local_ifmembership 
      ch->ifjoin_state
      ch->upstream->rpf.source_nexthop.mrib_metric_preference
      ch->upstream->rpf.source_nexthop.mrib_route_metric
      ch->upstream->rpf.source_nexthop.interface

T38 DONE Detect change in AssertTrackingDesired(S,G,I)

    See the order of invokation:
      dr_election: none
      update_join_desired: depends on DR
      update_tracking_desired: depends on DR, join_desired

    AssertTrackingDesired(S,G,I) depends on:
      pim_ifp->primary_address
      pim_ifp->pim_dr_addr
      ch->local_ifmembership
      ch->ifassert_winner
      ch->ifjoin_state
      ch->upstream->rpf.source_nexthop.interface
      PIM_UPSTREAM_FLAG_TEST_DR_JOIN_DESIRED(ch->upstream->flags)

T39 DONE AssertTrackingDesired: flags is not matching evaluation
    
    # show ip pim assert-internal 
    CA:   CouldAssert
    ECA:  Evaluate CouldAssert
    ATD:  AssertTrackingDesired
    eATD: Evaluate AssertTrackingDesired

    Interface Address         Source          Group           CA  eCA ATD eATD
    eth0      192.168.1.100   1.1.1.1         239.1.1.1       no  no  no  yes 
    # 

T40 Lightweight MLDv2
    http://tools.ietf.org/html/draft-ietf-mboned-lightweight-igmpv3-mldv2-05
    http://www.ietf.org/internet-drafts/draft-ietf-mboned-lightweight-igmpv3-mldv2-05.txt
    http://www.ietf.org/html.charters/mboned-charter.html

T41 ssmping
    http://www.venaas.no/multicast/ssmping/

-x-