ce9ce4af5ab6d791e238e9299cde7b6c88179a7f
[oweals/openwrt.git] /
1 From db0f488ea8f5ded7c57400c9108ec3c9367d75c5 Mon Sep 17 00:00:00 2001
2 From: Simon Kelley <simon@thekelleys.org.uk>
3 Date: Thu, 7 Jun 2018 21:37:02 +0100
4 Subject: [PATCH 15/17] Handle some corner cases in RA contructed interfaces
5  with addresses changing interface.
6
7 Thanks to Vladislav Grishenko for work on this.
8
9 Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
10 ---
11  src/dhcp6.c | 16 ++++++++++------
12  1 file changed, 10 insertions(+), 6 deletions(-)
13
14 --- a/src/dhcp6.c
15 +++ b/src/dhcp6.c
16 @@ -640,7 +640,7 @@ static int construct_worker(struct in6_a
17      return 0;
18    
19    for (template = daemon->dhcp6; template; template = template->next)
20 -    if (!(template->flags & CONTEXT_TEMPLATE))
21 +    if (!(template->flags & (CONTEXT_TEMPLATE | CONTEXT_CONSTRUCTED)))
22        {
23         /* non-template entries, just fill in interface and local addresses */
24         if (prefix <= template->prefix &&
25 @@ -667,20 +667,23 @@ static int construct_worker(struct in6_a
26         end6 = *local;
27         setaddr6part(&end6, addr6part(&template->end6));
28         
29 -       /* If there's an absolute address context covering this address
30 -          then don't contruct one as well. */
31         for (context = daemon->dhcp6; context; context = context->next)
32           if (!(context->flags & CONTEXT_TEMPLATE) &&
33               IN6_ARE_ADDR_EQUAL(&start6, &context->start6) &&
34               IN6_ARE_ADDR_EQUAL(&end6, &context->end6))
35             {
36 -             if (context->flags & CONTEXT_CONSTRUCTED)
37 +             /* If there's an absolute address context covering this address
38 +                then don't construct one as well. */
39 +             if (!(context->flags & CONTEXT_CONSTRUCTED))
40 +               break;
41 +             
42 +             if (context->if_index == if_index)
43                 {
44                   int cflags = context->flags;
45                   context->flags &= ~(CONTEXT_GC | CONTEXT_OLD);
46                   if (cflags & CONTEXT_OLD)
47                     {
48 -                     /* address went, now it's back */
49 +                     /* address went, now it's back, and on the same interface */
50                       log_context(AF_INET6, context); 
51                       /* fast RAs for a while */
52                       ra_start_unsolicited(param->now, context);
53 @@ -688,9 +691,10 @@ static int construct_worker(struct in6_a
54                       /* Add address to name again */
55                       if (context->flags & CONTEXT_RA_NAME)
56                         param->newname = 1;
57 +                   
58 +                     break;
59                     }
60                 }
61 -             break;
62             }
63         
64         if (!context && (context = whine_malloc(sizeof (struct dhcp_context))))